<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://brokenco.de//feed/by_tag/smalltalk.xml" rel="self" type="application/atom+xml" /><link href="https://brokenco.de//" rel="alternate" type="text/html" /><updated>2026-05-03T00:12:50+00:00</updated><id>https://brokenco.de//feed/by_tag/smalltalk.xml</id><title type="html">rtyler</title><subtitle>a moderately technical blog</subtitle><author><name>R. Tyler Croy</name></author><entry><title type="html">Taking inspiration from Smalltalk for Otto steps</title><link href="https://brokenco.de//2020/10/22/smalltalk-inspiring-otto.html" rel="alternate" type="text/html" title="Taking inspiration from Smalltalk for Otto steps" /><published>2020-10-22T00:00:00+00:00</published><updated>2020-10-22T00:00:00+00:00</updated><id>https://brokenco.de//2020/10/22/smalltalk-inspiring-otto</id><content type="html" xml:base="https://brokenco.de//2020/10/22/smalltalk-inspiring-otto.html"><![CDATA[<p>I have recently been spending more time thinking about how
<a href="https://github.com/rtyler/otto">Otto</a> should handle “steps” in a CI/CD
pipeline. As I mentioned in my previous post on the <a href="/2020/10/18/otto-steps.html">step libraries
concept</a>, one of the big unanswered questions with
the prototype has been managing flow-control of the pipeline from a step. To
recap, a “step” is currently being defined as an artifact (<code class="language-plaintext highlighter-rouge">.tar.gz</code>) which
self-describes its parameters, an entrypoint, and contains all the code/assets
necessary to execute the step. The execution flow is fairly linear in this
concept: an agent iterates through a sequence of steps, executing each along
the way, end. In order for a step to change the state of the pipeline, this
direction of flow control must be reversed. Allowing steps to communicate changes
to the agent which spawned them requires a <strong>control socket</strong>.</p>

<p>The agent control socket will allow steps to send a fixed number of message
types <em>back</em> to the agent during their execution. My current thinking is that
the control socket should speak <a href="https://nanomsg.org/">Nanomsg</a>, which puts a
little bit more system level requirements on the steps to be able to
communicate with that protocol. My first thought was just lines of JSON encoded
over the wire, but there are a number of practical problems with trying to send
JSON over a unix socket, for example.</p>

<hr />
<p><strong>Update 2020-10-30</strong>: I have since decided to shy away from Nanomsg for the
control socket and instead have opted for a small HTTP server listening on a
unix socket. I chose this approach to make the debugging and client
interactions much easier, even a totally bash-based shell step would be able to
interact with it!</p>

<hr />

<p>For the first implementation, I am planning to have a single long-lived socket
for the duration of a pipeline’s execution by the agent. By adding the <code class="language-plaintext highlighter-rouge">ipc</code>
field to the invocation file (below), I should have the flexibility to allow an
agent to create a single IPC socket for <em>each</em> step to avoid any accidental
overlap.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">configuration</span><span class="pi">:</span>
  <span class="na">ipc</span><span class="pi">:</span> <span class="s1">'</span><span class="s">ipc:///tmp/agent-5171.ipc'</span>
<span class="na">parameters</span><span class="pi">:</span>
  <span class="na">script</span><span class="pi">:</span> <span class="s1">'</span><span class="s">ls</span><span class="nv"> </span><span class="s">-lah'</span>
</code></pre></div></div>

<p>The types of messages that come to mind are:</p>

<ul>
  <li>Terminate the pipeline</li>
  <li>Change the pipeline’s running status (e.g. <code class="language-plaintext highlighter-rouge">unstable</code>)</li>
  <li>Capture a variable</li>
</ul>

<p>The last item really struck me as <strong>necessary</strong> but I have been struggling with
it quite a bit. In a declarative <code class="language-plaintext highlighter-rouge">Jenkinsfile</code> there is no provision for
setting variables. It wouldn’t otherwise be very <em>declarative</em>! This
restriction leads to some confusing hacks in real-world pipelines. The most
common hack is to use the <code class="language-plaintext highlighter-rouge">script {}</code> block as an escape hatch, such as:</p>

<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">stage</span><span class="o">(</span><span class="s1">'Build'</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">steps</span> <span class="o">{</span>
        <span class="n">sh</span> <span class="s1">'make'</span>

        <span class="n">script</span> <span class="o">{</span>
            <span class="kt">def</span> <span class="n">output</span> <span class="o">=</span> <span class="n">readYaml</span> <span class="nl">file:</span> <span class="s1">'output.yml'</span>
            <span class="n">sh</span> <span class="s2">"./deploy.sh ${output.stage}"</span>
        <span class="o">}</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>There are numerous legitimate reasons to capture and utilize variables inside
of a CI/CD pipeline. I <em>want</em> to support variables in some fashion without
building a full-on interpreter <em>or</em> sacrificing clarity in the pipeline
modeling language.</p>

<p>As I wrestled with the concept, I noticed that my pseudo-code I was writing for
how variables might be used looked familiar:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>prompt msg: <span class="s1">'What is the best color for a bike shed?'</span>, into: <span class="s1">'color'</span>
</code></pre></div></div>

<p>To me, this looks a <em>lot</em> like Smalltalk. Mmmm
<a href="https://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a>. If you have some spare
time, and haven’t yet experienced Smalltalk, you should go download
<a href="https://pharo.org/">Pharo</a> and explore! It’s a wonderful language and
development environment, and well-worth experimenting with in your career.</p>

<p>Anyways, back to Otto.</p>

<p>The syntax above would be the <code class="language-plaintext highlighter-rouge">prompt</code> step saving some user-provided string
(hand-waves right now on how that would manifest in a GUI) and storing it
in the <code class="language-plaintext highlighter-rouge">color</code> variable.</p>

<p>With variables, storing is one part of the problem, but <em>using</em> is the other
much more interesting part. I knew I didn’t want <code class="language-plaintext highlighter-rouge">if color == 'red' { }</code> type
blocks littering the code, lest a user think that this pipeline language is a
programming language for them to build application in! (<em>This is a very real
problem with Scripted Jenkins Pipelines</em>).</p>

<p>A related problem I had set aside the day prior was how to handle “block-scoped
steps”, such as the following in Jenkins:</p>

<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">stage</span><span class="o">(</span><span class="s1">'Build'</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">steps</span> <span class="o">{</span>
        <span class="n">sh</span> <span class="s1">'make'</span>
        <span class="n">dir</span><span class="o">(</span><span class="s1">'deploy'</span><span class="o">)</span> <span class="o">{</span>
            <span class="n">echo</span> <span class="s1">'Deploying from the deploy/ directory'</span>
            <span class="n">sh</span> <span class="s1">'./shipit.sh'</span>
        <span class="o">}</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>All steps executed within the <code class="language-plaintext highlighter-rouge">dir</code> block are executed with a current working
directory of <code class="language-plaintext highlighter-rouge">deploy/</code>.</p>

<p>Variable use and block-scoped steps both led me to a <em>very</em> Smalltalk syntax,
which honestly has me quite excited to explore further! In Smalltalk there is no control
structures in the traditional sense. No <code class="language-plaintext highlighter-rouge">if</code>, no <code class="language-plaintext highlighter-rouge">for</code>, etc. Instead one can
send the <code class="language-plaintext highlighter-rouge">ifTrue</code>/<code class="language-plaintext highlighter-rouge">ifFalse</code> message to a <code class="language-plaintext highlighter-rouge">Boolean</code>:</p>

<div class="language-smalltalk highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">color</span> <span class="nf">=</span> <span class="s">'red'</span>
    <span class="nb">ifTrue:</span> <span class="p">[</span>
        <span class="c">"Great choice!"</span>
    <span class="p">]</span>
    <span class="nb">ifFalse:</span> <span class="p">[</span>
        <span class="c">"Why did you chose wrong?!"</span>
    <span class="p">]</span>
</code></pre></div></div>

<p>Fully embracing this Smalltalk-inspired concept would also be convenient
to implement. Anything that isn’t a defined step can be looked at like a
variable, using an approach similar to <code class="language-plaintext highlighter-rouge">#method_missing</code> in Ruby (which is
actually just Smalltalk striking again! It’s called the <code class="language-plaintext highlighter-rouge">doesNotUnderstand</code>
message in Smalltalk).</p>

<p>Exploring what this would look like in a more concrete pipeline snippet:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sh <span class="s1">'ls -lah'</span>
prompt msg: <span class="s1">'Which file should I dump?'</span>, into: <span class="s1">'filename'</span>

filename equals: <span class="s1">'/etc/password'</span>,
    <span class="k">then</span>: <span class="o">[</span>
        <span class="nb">echo</span> <span class="s1">'Stop trying to pwn me!'</span>
    <span class="o">]</span>,
    <span class="k">else</span>: <span class="o">[</span>
        <span class="c"># Not sure on this yet, I _think_ I want to avoid raw string interpolation syntax</span>
        format pattern: <span class="s1">'cat {}'</span>, with: <span class="o">[</span>filename], into: <span class="s1">'dumpcmd'</span>
        sh script: dumpcmd
    <span class="o">]</span>

<span class="nb">dir</span> <span class="s1">'deploy'</span> <span class="o">[</span>
    <span class="nb">echo</span> <span class="s1">'Deploying from the deploy/ directory'</span>
    sh <span class="s1">'./shipit.sh'</span>
<span class="o">]</span>

<span class="c"># Intentionally drop the `filename` variable, which would go out of scope</span>
<span class="c"># at the end of the stage anyways</span>
drop <span class="s1">'filename'</span>
</code></pre></div></div>

<p>A couple notes on the above pseudo-code:</p>

<ul>
  <li>I’m not yet sold on the syntax. The benefit of this approach rather than
copying Smalltalk directly is that this syntax will make it easier support
more robust string operations in the future. The other benefit of
this syntax is that it makes <em>everything</em> behave step-like, insofar as a
<code class="language-plaintext highlighter-rouge">stringvariable</code> internal/hidden step could use the parameters, including the
two blocks, and just execute the block scoped steps like any other step.</li>
  <li>The block syntax is intentionally <em>different</em> from the directive syntax (to use Jenkins
terminology) of curly braces I <em>think</em> will help make the code more readable.</li>
  <li>I don’t want to actually implement a full Smalltalk interpreter here, but I am
liking that the syntax does keep things (subjectively) simple.</li>
</ul>

<p>In order to implement block-scope steps, I am planning to refactor some of the
step execution code into an <code class="language-plaintext highlighter-rouge">agent</code> crate which will allow steps to re-use the
logic for executing steps. From a data structure standpoint the invocation file
for the <code class="language-plaintext highlighter-rouge">dir</code> in the example might look like:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">configuration</span><span class="pi">:</span>
  <span class="na">ipc</span><span class="pi">:</span> <span class="s1">'</span><span class="s">ipc:///tmp/foo.ipc'</span>
<span class="na">parameters</span><span class="pi">:</span>
  <span class="na">directory</span><span class="pi">:</span> <span class="s1">'</span><span class="s">deploy'</span>
  <span class="na">block</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">symbol</span><span class="pi">:</span> <span class="s">echo</span>
      <span class="na">parameters</span><span class="pi">:</span>
        <span class="na">msg</span><span class="pi">:</span> <span class="s1">'</span><span class="s">Deploying</span><span class="nv"> </span><span class="s">from</span><span class="nv"> </span><span class="s">the</span><span class="nv"> </span><span class="s">deploy/</span><span class="nv"> </span><span class="s">directory'</span>
    <span class="pi">-</span> <span class="na">symbol</span><span class="pi">:</span> <span class="s">sh</span>
      <span class="na">parameters</span><span class="pi">:</span>
        <span class="na">script</span><span class="pi">:</span> <span class="s1">'</span><span class="s">./shipit.sh'</span>
</code></pre></div></div>

<p>At runtime the process tree on the agent machine would look something like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.
└── agent
    └── dir
        └── echo
</code></pre></div></div>

<p>Despite the state of these ideas right now I haven’t actually implemented them!
I typically like to sketch out syntax and run through use-cases before I go
running into Rust code.</p>

<hr />

<p>Part of why I am sharing these early thoughts is because I want to make sure my
love of Smalltalk is not blinding me to usability issues with this approach. I
<em>think</em> this pattern will allow some non-declarative functionality in the
pipeline without requiring an actual interpreted language to be used, but these
thoughts are still fresh. If you’ve got some thoughts on what could be
improved, or pitfalls to be aware of, feel free to join <code class="language-plaintext highlighter-rouge">#otto</code> on Freenode, or
email me (<a href="/about">about</a>)!</p>]]></content><author><name>R. Tyler Croy</name></author><category term="otto" /><category term="smalltalk" /><summary type="html"><![CDATA[I have recently been spending more time thinking about how Otto should handle “steps” in a CI/CD pipeline. As I mentioned in my previous post on the step libraries concept, one of the big unanswered questions with the prototype has been managing flow-control of the pipeline from a step. To recap, a “step” is currently being defined as an artifact (.tar.gz) which self-describes its parameters, an entrypoint, and contains all the code/assets necessary to execute the step. The execution flow is fairly linear in this concept: an agent iterates through a sequence of steps, executing each along the way, end. In order for a step to change the state of the pipeline, this direction of flow control must be reversed. Allowing steps to communicate changes to the agent which spawned them requires a control socket.]]></summary></entry><entry><title type="html">FOSDEM: Smalltalk Pairing</title><link href="https://brokenco.de//2012/02/09/fosdem-smalltalk-pairing.html" rel="alternate" type="text/html" title="FOSDEM: Smalltalk Pairing" /><published>2012-02-09T00:00:00+00:00</published><updated>2012-02-09T00:00:00+00:00</updated><id>https://brokenco.de//2012/02/09/fosdem-smalltalk-pairing</id><content type="html" xml:base="https://brokenco.de//2012/02/09/fosdem-smalltalk-pairing.html"><![CDATA[<p>As I <a href="/2012/01/14/realtalk.html">previously mentioned</a>, I’ve been learning
Smalltalk lately, in an attempt the understand the language that inspired two
of my other favorite languages: Objective-C and Ruby.</p>

<p>This past weekend at FOSDEM, I was fortunate enough to attend a few sessions in
the “Smalltalk devroom”, which from my understanding made its debut appearance
at this year’s conference. I’ll save my thoughts on
<a href="http://www.amber-lang.net">Amber.js</a> for another time, but in this post I
wanted to talk about the Smalltalk Workshop which was held at the end of the
day.</p>

<p>One of my major stumbling blocks with Smalltalk has been general unfamiliarity
with the development environment, the workshop was the <em>perfect</em> opportunity to
resolve some of this. The structure was to pair one experienced Smalltalker
with one noob, and for both to work through a pre-planned exercise with an
existing image and application set up.</p>

<center><a href="http://www.a3aan.st/fosdem2012/index.php/view/23/01+DevRoom/IMG_6452.JPG" target="_blank"><img src="http://agentdero.cachefly.net/unethicalblogger.com/images/pairing-on-smalltalk-at-fosdem.JPG" alt="Pairing on Smalltalk" width="500" /></a><br /><em>Haxx haxx haxx</em> (Photo courtesy of Adriaan van Os)</center>

<p>While my partner (Norbert) and I did not complete all the exercises, we did
spend a good amount of time discussing and working through the “Smalltalk way”,
or at least Norbert’s Smalltalk way, of solving particular problems,
refactoring and method structure.</p>

<p>One of the things that struck me as we worked through the exercises was how
small the ideal method body is for most things in Smalltalk. I don’t think
there was a single method that was longer than 10 lines, except for some test
methods which certainly had a bad code smell.</p>

<p>Below is a sample of one of the longest methods I wrote in the entire workshop:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>vote: aVote for: aUser
  author ~= aUser ifTrue: [
    self votes
      detect: [ :vote | vote author = aUser and: [ vote direction = aVote direction]]
      ifNone: [ self votes add: aVote ]]
</code></pre></div></div>

<p>I’m quite happy with the way things turned out, while I didn’t anything I
didn’t know already about <a href="http://www.seaside.st">Seaside</a>, I did learn a <em>lot</em>
about using the development environment effectively and test-driven development
“the Smalltalk way” which as it turns out is quite impressive.</p>

<p>I’m looking forward to learning more about the ways of the
<a href="http://www.pharo-project.org">Pharo</a>, maybe next year I’ll count as one of the
experienced Smalltalkers.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="smalltalk" /><category term="fosdem" /><category term="fosdem2012" /><category term="tripdiary" /><summary type="html"><![CDATA[As I previously mentioned, I’ve been learning Smalltalk lately, in an attempt the understand the language that inspired two of my other favorite languages: Objective-C and Ruby.]]></summary></entry><entry><title type="html">Real talk (about Smalltalk)</title><link href="https://brokenco.de//2012/01/14/realtalk.html" rel="alternate" type="text/html" title="Real talk (about Smalltalk)" /><published>2012-01-14T00:00:00+00:00</published><updated>2012-01-14T00:00:00+00:00</updated><id>https://brokenco.de//2012/01/14/realtalk</id><content type="html" xml:base="https://brokenco.de//2012/01/14/realtalk.html"><![CDATA[<p>Somehow I found myself reading an interesting article on Smalltalk yesterday
which led to a couple of comments in IRC:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tyler:  man, I am getting that "I should really learn smalltalk"
        feeling again
tyler:  everytime I get close I find myself downloading a squeak
        VM and then going "LOLWTF IS THIS SHIT"
</code></pre></div></div>

<p>I said this before I left the office and somewhere in the back of my mind I
kept thinking “why can’t I crack Smalltalk?” This continued through most of the
evening until 9 pm (21:00) rolled around and I decided that I wouldn’t let that
commie <a href="https://en.wikipedia.org/wiki/Alan_Kay">Alan Kay</a> defeat me.</p>

<p>After finding <a href="https://www.youtube.com/playlist?list=PL61A023880D3529DB&amp;feature=plcp">this fantastic series of
screencasts</a>
I set about learning some Smalltalk. Not enough to build anything major, but
enough to really understand Smalltalk’s core concepts.</p>

<p>In exploring the world of <a href="http://squeak.org/">Squeak</a>,
<a href="http://www.pharo-project.org/home">Pharo</a> and <a href="http://amber-lang.net/">Amber</a>
I believe I have experienced the full spectrum of emotions that my circuits
provide, all the way from unfettered rage to mild bemusement. Despite all of
this, around 2 a.m. I found myself lying awake in bed wanting to marvelling at
the design of the language and wanting to learn <em>more</em>.</p>

<p>A couple of things still bug the hell out of me:</p>

<ul>
  <li>The VM concept while novel is a completely jarring experience for anybody who
has done <strong>any</strong> programming in any other environment <em>ever</em>.</li>
  <li>I hate mice. I also have no trackpad on my laptop which means if i’m not at
my desk using a mouse-heavy program becomes painful (quite literally). Both
Squeak and Pharo have this sick mouse fetish that makes me want to <code class="language-plaintext highlighter-rouge">（╯°□°）╯︵┻━┻</code></li>
  <li>GNU/Smalltalk feels closer to development environments that I’m familiar with,
but VisualGST is incredibly buggy and I think part of what makes Smalltalk
special is the integrated “live environment.”</li>
</ul>

<hr />

<p>The things that I do <strong>really</strong> like however:</p>

<ul>
  <li>The integrated “live environment” is something out of programmer fairy tales.
Inspect/debug/edit anything and everything? Yes please!</li>
  <li>Everything is an object which receives messages, the syntax for conditionals helps drive it home. A
boolean object can receive an <code class="language-plaintext highlighter-rouge">ifTrue</code> or an <code class="language-plaintext highlighter-rouge">ifFalse</code> message which takes a
block argument. This means there is no real for <code class="language-plaintext highlighter-rouge">if</code> statements, it’s all
implemented with the basic Smalltalk primitives:
      1 &lt; 3
          ifTrue:  [Transcript show: ‘Truthy!’]
          ifFalse: [Transcript show: ‘Untruthy!’]
How about a for loop? Surely the language must have a for loop! No way
José! Instead an Array object just takes a <code class="language-plaintext highlighter-rouge">do</code> message with a block, fancy!
      #(‘tom’ ‘dick’ ‘harry’) do:
          [ :each | Transcript show: (‘Hello ‘, each); cr]</li>
  <li>No magic, that I’ve seen thus far. One of my biggest criticisms of Ruby comes
out of the Rails tradition of magic methods by using <code class="language-plaintext highlighter-rouge">method_missing</code> to
magically generate methods on-demand, leaving a system that’s abominably
difficult to inspect and debug. Thus far I’ve not found any slight-of-hand in
Smalltalk, which is a good thing.</li>
</ul>

<hr />

<p>I can really see where Objective-C pulled from Smalltalk having now experienced
some Smalltalk myself. That said, it’s rather unfortunate that C and some
additional custom bits have creeped into Objective-C making it less Smalltalky
than it once was.</p>

<p>I am definitely going to continue to tinker with Smalltalk, likely with
<a href="http://pharo-project.org/home">Pharo</a> as my VM of choice. My only concern is
that I will grow to resent the other languages I use regularly which feel
dumber than a language invented almost 40 years ago.</p>

<hr />

<p><strong>Update:</strong> <a href="http://sebastianconcept.com/brandIt/10-reasons-why-im-using-smalltalk-for-airflowing">This is the original
post</a>
that pushed me over the edge on tinkering with Smalltalk.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="smalltalk" /><category term="opinion" /><category term="programming" /><summary type="html"><![CDATA[Somehow I found myself reading an interesting article on Smalltalk yesterday which led to a couple of comments in IRC:]]></summary></entry></feed>