Software for DaysSoftware for absolute days.2023-05-22T00:00:00Zhttps://softwarefordays.com/Jonathan Milgromjbmilgrom@gmail.comFrom Law to Code2014-08-03T00:00:00Zhttps://softwarefordays.com/post/hello-code/<p>I had a birthday this year despite disliking my job. Apparently, my daily fight against workflow did not slow down time. Practicing law is not a peculiar result for someone who went to law school, but nonetheless that’s what it felt like to me, and increasingly so, every week, month and year that passed.</p>
<p>In retrospect, the seed that ultimately grew into my career move was planted in college. When curiosity was my only motivator, I studied math and physics as part of an applied math major that required that I take an introduction to programming class in C++. I loved that class because it appeared to almost completely flesh out the core of what I enjoyed most about my major. To quote one of my new favorite authors:</p>
<blockquote>
<p>“Refactor, not because you know the abstraction, but because you want to find it.” — <a href="http://confreaks.com/videos/240-goruco2009-solid-object-oriented-design">Sandi Metz</a></p>
</blockquote>
<p>Remembering this, the gulf between what I was <em>doing</em> and what I wanted <em>to do</em> shrank every time I shed a reason for staying put.</p>
<p>Recently, I left corporate law and began a web development immersive, a 3 month intensive into computer science fundamentals, information architecture and web development. And now, a little over three months into a profession into which I look forward to investing my time and energy, I know I have a lot to learn. But I’m eager to share what I’m learning.</p>
<p>If you’re an experienced programmer, great. I hope I don’t reveal so many nautical miles between myself and the boat, that I’ve missed the boat completely. But I also would love to hear what you think. I’m more concerned with learning than anything. If any of my posts find you, please comment. For anyone else that might stumble upon this post or another, I hope that it is relatable in some way. Happy coding!</p>
<p>Quotes of the day:</p>
<blockquote>
<p>There are these two young fish swimming along and they happen to meet an older fish swimming the other way, who nods at them and says “Morning, boys. How’s the water?” And the two young fish swim on for a bit, and then eventually one of them looks over at the other and goes “What the hell is water?” — <a href="http://web.ics.purdue.edu/~drkelly/DFWKenyonAddress2005.pdf">David Foster Wallace</a></p>
</blockquote>
<blockquote>
<p>Everything should be made as simple as possible, but not simpler. — <a href="http://en.wikiquote.org/wiki/Albert_Einstein">I like to think this was Albert Einstein</a></p>
</blockquote>
Active Record Join Tables: “Plain Vanilla” to Many-to-Many Self-Join2014-08-04T00:00:00Zhttps://softwarefordays.com/post/active-record-join-tables/<p><em>(For a summary, visit my <a href="http://stackoverflow.com/questions/25493368/many-to-many-self-join-in-rails/25493403#25493403">SO post</a>.)</em></p>
<h3 id="plain-vanilla-join-table">Plain Vanilla Join Table <a class="direct-link" href="https://softwarefordays.com/post/active-record-join-tables/#plain-vanilla-join-table">#</a></h3>
<p>Ordinarily, a join table works to account for a many-to-many relationship between two otherwise independent models. As an example, a <strong>Player</strong> may be a member of many :teams over the course of a career. Conversely, each <strong>Team</strong> may have many :players. Each <strong>Contract</strong> joins a <strong>Player</strong> to a <strong>Team</strong>.</p>
<p><a href="https://github.com/jbmilgrom/rails_crud_rspec/blob/master/app/models/team.rb">app/models/team.rb</a></p>
<pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">Team</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Base<br /> has_many <span class="token symbol">:players</span><span class="token punctuation">,</span> <span class="token symbol">through</span><span class="token operator">:</span> <span class="token symbol">:contracts</span><br /> has_many <span class="token symbol">:contracts</span><br /><span class="token keyword">end</span></code></pre>
<p><a href="https://github.com/jbmilgrom/rails_crud_rspec/blob/master/app/models/player.rb">app/models/player.rb</a></p>
<pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">Player</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Base<br /> has_many <span class="token symbol">:teams</span><span class="token punctuation">,</span> <span class="token symbol">through</span><span class="token operator">:</span> <span class="token symbol">:contracts</span><br /> has_many <span class="token symbol">:contracts</span><br /><span class="token keyword">end</span></code></pre>
<p><a href="https://github.com/jbmilgrom/rails_crud_rspec/blob/master/app/models/contract.rb">app/models/contract.rb</a></p>
<pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">Contract</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Base<br /> belongs_to <span class="token symbol">:player</span><br /> belongs_to <span class="token symbol">:team</span><br /><span class="token keyword">end</span></code></pre>
<p><a href="https://github.com/jbmilgrom/rails_crud_rspec/blob/master/db/schema.rb">db/schema.rb</a></p>
<pre class="language-ruby"><code class="language-ruby">ActiveRecord<span class="token double-colon punctuation">::</span>Schema<span class="token punctuation">.</span>define<span class="token punctuation">(</span><span class="token symbol">version</span><span class="token operator">:</span> <span class="token number">20140706210328</span><span class="token punctuation">)</span> <span class="token keyword">do</span><br /><br /> create_table <span class="token string-literal"><span class="token string">"contracts"</span></span><span class="token punctuation">,</span> <span class="token symbol">force</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">do</span> <span class="token operator">|</span>t<span class="token operator">|</span><br /> t<span class="token punctuation">.</span>integer <span class="token string-literal"><span class="token string">"team_id"</span></span><br /> t<span class="token punctuation">.</span>integer <span class="token string-literal"><span class="token string">"player_id"</span></span><br /> t<span class="token punctuation">.</span>integer <span class="token string-literal"><span class="token string">"term"</span></span><br /> t<span class="token punctuation">.</span>integer <span class="token string-literal"><span class="token string">"deal_value"</span></span><br /> <span class="token keyword">end</span><br /><br /> create_table <span class="token string-literal"><span class="token string">"players"</span></span><span class="token punctuation">,</span> <span class="token symbol">force</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">do</span> <span class="token operator">|</span>t<span class="token operator">|</span><br /> t<span class="token punctuation">.</span>string <span class="token string-literal"><span class="token string">"name"</span></span><br /> t<span class="token punctuation">.</span>integer <span class="token string-literal"><span class="token string">"height"</span></span><br /> t<span class="token punctuation">.</span>datetime <span class="token string-literal"><span class="token string">"created_at"</span></span><br /> t<span class="token punctuation">.</span>datetime <span class="token string-literal"><span class="token string">"updated_at"</span></span><br /> <span class="token keyword">end</span><br /><br /> create_table <span class="token string-literal"><span class="token string">"teams"</span></span><span class="token punctuation">,</span> <span class="token symbol">force</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">do</span> <span class="token operator">|</span>t<span class="token operator">|</span><br /> t<span class="token punctuation">.</span>string <span class="token string-literal"><span class="token string">"name"</span></span><br /> t<span class="token punctuation">.</span>string <span class="token string-literal"><span class="token string">"city"</span></span><br /> t<span class="token punctuation">.</span>datetime <span class="token string-literal"><span class="token string">"created_at"</span></span><br /> t<span class="token punctuation">.</span>datetime <span class="token string-literal"><span class="token string">"updated_at"</span></span><br /> <span class="token keyword">end</span><br /><br /><span class="token keyword">end</span></code></pre>
<p>Under the hood, the “player” in player_id and “team” in team_id in any instance of <strong>Contract</strong> are understood by Active Record to join such <strong>Player</strong> and <strong>Team</strong> through (as foreign keys of) an instance of <strong>Contract.</strong> @player.teams may then query the database for all :teams sharing an instance of <strong>Contract</strong> with @player and @team.players may query the database for all :players sharing an instance of <strong>Contract</strong> with @team.</p>
<h3 id="has_many-%7C-belongs_to-%E2%80%94-self-join-table">Has_many | Belongs_to — Self Join Table <a class="direct-link" href="https://softwarefordays.com/post/active-record-join-tables/#has_many-%7C-belongs_to-%E2%80%94-self-join-table">#</a></h3>
<p>A table may have models that have relationships with other models in the same table. Instead of creating two independent tables, it often makes more sense to create a self-join table to account for these types of relationships. Rails documentation provides <a href="http://guides.rubyonrails.org/association_basics.html#self-joins">a great example</a>. In addition to having a name, phone number and other attributes, an <strong>Employee</strong> may also be a manager of <em>other</em> <strong>Employees</strong>. In this example, a :subordinate may only have one :manager. Nonetheless, splitting the Employee model into two separate tables (maybe called Managers and Subordinates), duplicating code, and muddying entity relationships (what do you do when a subordinate gets promoted? How do you account for multilevel management, where a manager is the subordinate of another manager), offers a less-than-optimal solution. Here’s how a has_many | belongs_to self-join might work (taken from rails documentation linked above):</p>
<p>app/models/employee.rb</p>
<pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">Employee</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Base<br /> has_many <span class="token symbol">:subordinates</span><span class="token punctuation">,</span> <span class="token symbol">class_name</span><span class="token operator">:</span> “Employee”<span class="token punctuation">,</span> <span class="token symbol">foreign_key</span><span class="token operator">:</span> “manager_id”<br /><br /> belongs_to <span class="token symbol">:manager</span><span class="token punctuation">,</span> <span class="token symbol">class_name</span><span class="token operator">:</span> “Employee”<br /><span class="token keyword">end</span></code></pre>
<p>As can be seen in the above code, self-referential relationships offer added complexity. :manager and :subordinates are both <strong>Employees</strong> in the database, but must be identified as such and distinguished. This is handled by supplying the :subordinates and :manager “names” expressly, and explicitly referencing, in each case, the class_name: to which such names apply, in each case, <code>“Employee”</code>.</p>
<p>Since each :subordinate may have only one :manager, a single column may be added when creating the <strong>Employee</strong> table to store the manager_id of each <strong>Employee</strong>’s (:subordinate’s) :manager, as is done below:</p>
<pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">CreateEmployees</span> <span class="token operator"><</span> ActiveRecord<span class="token double-colon punctuation">::</span>Migration<br /> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">change</span></span><br /> create_table <span class="token symbol">:employees</span> <span class="token keyword">do</span> <span class="token operator">|</span>t<span class="token operator">|</span><br /> t<span class="token punctuation">.</span>references <span class="token symbol">:manager</span><br /><br /> t<span class="token punctuation">.</span>timestamps<br /> <span class="token keyword">end</span><br /> <span class="token keyword">end</span><br /><span class="token keyword">end</span></code></pre>
<p>To determine a :manager’s :subordinates (upon an @employee.subordinates call), Active Record may now look at each instance of <strong>Employee</strong> where the manager_id (i.e. foreign_key: :manager_id) of such :manager is stored in such <strong>Employee</strong>’s :manager column. To determine a :subordinate’s :manager (upon an @employee.manager call), Active Record may simply look at the :manager corresponding to the :manager_id stored in such <strong>Employee</strong>’s :manager column.</p>
<h3 id="has_many-%7C-has_many-%E2%80%94-self-join-table">Has_many | Has_many — Self Join Table <a class="direct-link" href="https://softwarefordays.com/post/active-record-join-tables/#has_many-%7C-has_many-%E2%80%94-self-join-table">#</a></h3>
<p>The above :subordinates | :manager example is useful only if a :subordinate belongs_to a single :manager. A different data structure is required if a :subordinate may have more than one :manager. The :follower | :followee paradigm used by Twitter and Instagram is analogous. A <strong>User</strong> can follow and be followed by any number of :users. In other words, a <strong>User</strong> can be both a :subordinate (:followee) and a :manager (:follower) without any restrictions on the number of :managers (:followers) associated with it in its :subordinate (:followee) capacity and the number of :subordinates (:followees) associated with it in its :manager (:follower) capacity. Here’s how a has_many | has_many self-join might work:</p>
<p><a href="https://github.com/jbmilgrom/LEAf/blob/master/app/models/user.rb">app/models/user.rb</a></p>
<img src="https://softwarefordays.com/media/many-to-many.png" />
<p><a href="https://github.com/jbmilgrom/LEAf/blob/master/app/models/follow.rb">app/models/follow.rb</a></p>
<img src="https://softwarefordays.com/media/many-to-many-follow.png" />
<p>The most important things to note are probably the terms :follower_follows and :followee_follows in user.rb, terms which I named as such for the following reasons (but could just as well been named :route_a and :route_b). Ordinarily, a join table between two independent objects is referenced identically in each model class. In the <strong>Player</strong> | <strong>Team</strong> example above, a <strong>Team</strong> may have many :players through :contracts. This is no different for a <strong>Player</strong>, who may have many :teams through :contracts as well. But in this case, where only one named model exists (i.e. a <strong>User</strong>), naming the through: relationship identically (i.e. through: :follow) would result in a naming collision for different use cases of, or access points into, the join table. Follower_follows and :followee_follows were created to avoid such a naming collision. Now, a <strong>User</strong> can have many :followers through :follower_follows and many :followees through :followee_follows.</p>
<p>To determine a <strong>User</strong>’s :followees (upon an @user.followees call), Active Record may now look at each instance of class_name: “Follow” where such <strong>User</strong> is the follower (i.e. foreign_key: :follower_id) through: such <strong>User</strong>’s :followee_follows. To determine a <strong>User</strong>’s :followers (upon an @user.followers call), Active Record may now look at each instance of class_name: “Follow” where such <strong>User</strong> is the followee (i.e. foreign_key: :followee_id) through: such <strong>User</strong>’s :follower_follows.</p>
AngularJS 1.x: Building Reusable Directives2015-06-23T00:00:00Zhttps://softwarefordays.com/post/angular-building-resuseable-directives/<p>Angular offers many benefits to developers building complex web applications. Expressive HTML, model and view syncing and dependency injection are a few of the most powerful. But the true power of Angular comes from the whole being greater than the sum of its parts. This is something that is difficult to relay in its entirety through a blog post or a single example (and difficult to grasp period!). Like with all programming languages or deeply thoughtful frameworks, an understanding of best practices is probably best teased out through experience solving real problems and maintaining real code. Nonetheless, I think the best place to begin digging is reusable directives: Angular provides the developer the unique ability to underwrite simple, elegant and importantly, reusable components around which maintainable domain specific applications can come into shape. There, much of Angular’s power comes into focus. And with the release of Angular 2 on the horizon, there’s no better time to write reusable directives (component-based directives anyone?). So let’s begin!</p>
<h2 id="nullifymodel">nullifyModel <a class="direct-link" href="https://softwarefordays.com/post/angular-building-resuseable-directives/#nullifymodel">#</a></h2>
<p>Client-side web applications often must expressly nullify “falsey” form data to correctly interact with a server-side API and effect the desired change to the database. Repeating such type conversion logic with every form would unnecessarily grow the code base, obscure the logic actually unique to each form and clearly violate the D.R.Y. (Don’t Repeat Yourself) principle. One solution might be to place such logic in a service and inject it into every controller or link function corresponding to the desired form. This is a fine solution that avoids repetition by ushering the logic into one place. However, this would require <strong>$watch</strong>ing each model of interest for any “falsey” value in order to expressly nullify the model upon such an event. This feels unnecessarily heavy handed. Why watch the model for all changes when the work that needs to be performed must happen only upon a prescribed and limited set of events (i.e. “falsey”ness)? Not to worry; with Angular, you can do one better. The ng-model controller API together with Angular’s powerful directive API allow you to cabin the logic in its proper place, avoid adding the unnecessary $watch and, ultimately, make your HTML come to life.</p>
<p>Here’s what the HTML consuming the directive might look like:</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">ng-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>modelName<span class="token punctuation">"</span></span> <span class="token attr-name">nullify-model</span> <span class="token punctuation">/></span></span></code></pre>
<p>Notice how the interface is exceedingly simple. Type ‘nullify-model’ (13 characters by my count) into any input tag, even one that’s already part of another custom form component, and any “falsey” value will be translated to ‘null’ for correct server-side processing. And the HTML is expressive! The behavior added to the input tag can be easily surmised from the attribute aptly named “nullifyModel”. Now, looking under the hood at the directive’s implementation:</p>
<pre class="language-js"><code class="language-js"><span class="token punctuation">.</span><span class="token function">directive</span><span class="token punctuation">(</span><span class="token string">'nullifyModel'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'$filter'</span><span class="token punctuation">,</span><br /> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">$filter</span><span class="token punctuation">)</span><span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">restrict</span><span class="token operator">:</span> <span class="token string">'A'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">require</span><span class="token operator">:</span> <span class="token string">"ngModel"</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">link</span><span class="token operator">:</span> link<br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /> <span class="token keyword">function</span> <span class="token function">link</span><span class="token punctuation">(</span><span class="token parameter">scope<span class="token punctuation">,</span> elem<span class="token punctuation">,</span> attrs<span class="token punctuation">,</span> ctrl</span><span class="token punctuation">)</span><span class="token punctuation">{</span><br /> ctrl<span class="token punctuation">.</span>$parsers<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token function">$filter</span><span class="token punctuation">(</span><span class="token string">'nullify'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Notice that I’ve moved the nullify logic into a separate filter so it’s accessible/reusable elsewhere throughout the application if necessary:</p>
<pre class="language-js"><code class="language-js"><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token string">'nullify'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span><span class="token punctuation">{</span><br /> <span class="token keyword">return</span> value <span class="token operator">?</span> value <span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Ahhhh… so easy to read and so simple! All values inputted into the input element by a user will be <strong>$parse</strong>d for “falsey” values and converted expressly to null. Ng-model controller’s $parse method runs the <code>nullify</code> filter <em>prior to</em> assigning any <em>return value</em> to the model. As a result, the model may never reference a “falsey” value and no longer needs to be <strong>$watch</strong>ed for such an event. Dependency injection allows the nullify logic to be what it is — a filter replacing one value with another — and only injected when needed, in this case, into the <code>nullifyModel</code> directive. The true “trick”, however, is that all of Angular’s power is on display. Data and view syncing, dependency injection and the Angular directive API allow for expressive HTML and the creation of a (hopefully!) reusable directive.</p>
<p>Quotes of the Day:</p>
<blockquote>
<p>Writing software as multiple layers is a powerful technique even within applications. Bottom-up programming means writing a program as a series of layers, each of which serves as a language for the one above. This approach tends to yield smaller, more flexible programs. It’s also the best route to that holy grail, reusability. A language is by definition reusable. The more of your application you can push down into a language for writing that type of application, the more of your software will be reusable. — <a href="http://www.paulgraham.com/hundred.html">Paul Graham</a></p>
</blockquote>
<blockquote>
<p>Code is inert. How do you make it ert? You run software that transforms it into machine language. The word “language” is a little ambitious here, given that you can make a computing device with wood and marbles. Your goal is to turn your code into an explicit list of instructions that can be carried out by interconnected logic gates, thus turning your code into something that can be executed — software. — <a href="http://www.bloomberg.com/graphics/2015-paul-ford-what-is-code/">Paul Ford</a></p>
</blockquote>
Where Javascript Memory Management Ends and Angular $destroy Begins2016-04-30T00:00:00Zhttps://softwarefordays.com/post/angular-garbage-collection/<h3 id="a-brief-look-inside-the-source-code-inspired-by-this-so-question">A brief look inside the source code inspired by this <a href="http://stackoverflow.com/questions/36273862/do-i-need-to-destroy-local-controller-variables-when-directive-is-destroyed/36390832#36390832">SO question</a> <a class="direct-link" href="https://softwarefordays.com/post/angular-garbage-collection/#a-brief-look-inside-the-source-code-inspired-by-this-so-question">#</a></h3>
<p>Keep this example controller function in mind:</p>
<pre class="language-js"><code class="language-js">angular<span class="token punctuation">.</span><span class="token function">module</span><span class="token punctuation">(</span><span class="token string">'myModule'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">controller</span><span class="token punctuation">(</span><span class="token string">'fileUploadCtrl'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">$scope<span class="token punctuation">,</span> FileUploader</span><span class="token punctuation">)</span><span class="token punctuation">{</span><br /><br /> $scope<span class="token punctuation">.</span>uploader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileUploader</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token literal-property property">settings</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /> <span class="token keyword">var</span> reader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> reader<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">var</span> img <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> img<span class="token punctuation">.</span>onload <span class="token operator">=</span> onLoadImage<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<h3 id="javascript-memory-management-%E2%80%94-garbage-collector">Javascript memory management — garbage collector <a class="direct-link" href="https://softwarefordays.com/post/angular-garbage-collection/#javascript-memory-management-%E2%80%94-garbage-collector">#</a></h3>
<p>Memory <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management">will be allocated for an object when created</a>.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> o <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">iThink</span><span class="token operator">:</span> ‘thereforeIAm’<span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// memory allocated for an object and a string</span></code></pre>
<p>You may then <em>console.log(o.iThink)</em> and <em>‘thereforeIAm’</em> will be read from its place in memory and printed to the console.</p>
<p>If you wanted to create a new string and lost the <em>need</em> for the <em>{iThink: ‘thereforeIAm’}</em> object, you may decide to overwrite <em>o</em> instead of introducing a new variable.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> o <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">iThink</span><span class="token operator">:</span> ‘thereforeIAm’<span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// memory allocated for an object and a string</span><br /><br />o <span class="token operator">=</span> ‘helloImANewString’<span class="token punctuation">;</span></code></pre>
<p>Fortunately, references (or lack thereof) send a clear message internally to javascript’s garbage collector as to whether a piece of finite memory should remain allocated or freed to perform other tasks. In this case, no reference remains to the object and string previously allocated for <em>{iThink: ‘thereforeIAm’}</em> and the corresponding memory may be freed (i.e. “garbage-collected”) as result.</p>
<p>Importantly, note that garbage collection happens internally. No code has to be written by you to that effect. All you need to concern yourself with is the value of <em>o</em> and the garbage collector can <em>infer need</em>, more or less, <em>from remaining reference</em>.</p>
<h3 id="angular-memory-management-%E2%80%94-%24scope.%24destroy">Angular memory management — $scope.$destroy <a class="direct-link" href="https://softwarefordays.com/post/angular-garbage-collection/#angular-memory-management-%E2%80%94-%24scope.%24destroy">#</a></h3>
<p>Unfortunately, the cleanup tasks related to <em>$scope</em> removal* cannot be inferred* by the javascript garbage collector based on* reference alone*; additional code is required.</p>
<p>That is because <em>$scope</em> objects embody a concept more complex than any ol’ javascript object. In particular, when no use remains in your application for a certain <em>$scope</em> object, no use *must also remain *for any associated <em>$$watchers</em> previously registered with the <em>$scope.$watch</em> method and no use <em>must also remain</em> for “children” <em>$scope</em> objects. The javascript garbage collector cannot infer this relationship from simple reference removal. Setting <em>$scope</em> to *null *will certainly clear the memory allocated directly for such object, but not much else can be accomplished.</p>
<pre class="language-js"><code class="language-js">$scope <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// $scope object will be garbage collected, but nothing else</span></code></pre>
<p>In other words, the garbage collector has to be told what to do (<a href="https://github.com/angular/angular.js/blob/v1.5.5/src/ng/directive/ngIf.js#L113">and when to do it</a>), which is exactly what the <a href="https://github.com/angular/angular.js/blob/v1.5.3/src/ng/rootScope.js#L895"><em>$scope.$destroy</em> method</a> does. Note these lines in particular:</p>
<pre class="language-js"><code class="language-js">$scope<span class="token punctuation">.</span>$parent <span class="token operator">=</span> $scope<span class="token punctuation">.</span>$$nextSibling <span class="token operator">=</span> $scope<span class="token punctuation">.</span>$$prevSibling <span class="token operator">=</span> $scope<span class="token punctuation">.</span>$$childHead <span class="token operator">=</span><br /> $scope<span class="token punctuation">.</span>$$childTail <span class="token operator">=</span> $scope<span class="token punctuation">.</span>$root <span class="token operator">=</span> $scope<span class="token punctuation">.</span>$$watchers <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></code></pre>
<h3 id="the-example-controller-function">The example controller function <a class="direct-link" href="https://softwarefordays.com/post/angular-garbage-collection/#the-example-controller-function">#</a></h3>
<p>When a function is invoked, the memory allocated for internally scoped objects will only remain allocated to the extent references remain past the life of the invocation (non-coincidentally, the essence of a closure).</p>
<p>In the example of the controller, <em>uploader</em> and <em>reader</em> objects are created and <em>uploader</em> is set to scope. No references remain to <em>reader</em> at all after the controller function is run, rendering <em>reader</em> eligible for garbage collection immediately thereafter. On the other hand, <em>uploader</em> is attached to an object that outlives the function’s invocation and so must remain an occupant of allocated memory until such object is destroyed. As a result, only a call to <em>$scope.$destroy</em> would enable the reallocation of memory once allocated to *uploader *as the lack of need cannot be inferred from reference alone.</p>
<p><strong>Quote of the day:</strong></p>
<blockquote>
<p>Each product era can be divided into two phases: 1) <em>the gestation phase</em>, when the new platform is first introduced but is expensive, incomplete, and/or difficult to use, 2) <em>the growth phase</em>, when a new product comes along that solves those problems, kicking off a period of exponential growth. The Apple II was released in 1977 (and the Altair in 1975), but it was the release of the IBM PC in 1981 that kicked off the PC growth phase. The internet’s gestation phase took place in the <a href="https://en.wikipedia.org/wiki/National_Science_Foundation_Network">80s and early 90s</a> when it was mostly a text-based tool used by academia and government. The release of the Mosaic web browser in 1993 started the growth phase, which has continued ever since.There were feature phones in the 90s and early smartphones like the Sidekick and Blackberry in the early 2000s, but the smartphone growth phase really started in 2007–8 with the release of the iPhone and then Android.
— <a href="https://medium.com/software-is-eating-the-world/what-s-next-in-computing-e54b870b80cc#.jszig85hi">Chris Dixon</a></p>
</blockquote>
Watch, watchGroup, watchCollection and Deep Watching in AngularJS2016-05-20T00:00:00Zhttps://softwarefordays.com/post/angular-change-detection/<h3 id="the-many-layers-of-change-detection-in-angular-1.x">The Many Layers of Change Detection in Angular 1.x <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#the-many-layers-of-change-detection-in-angular-1.x">#</a></h3>
<p>A user clicks the “upvote” button,</p>
<p><img src="https://cdn-images-1.medium.com/max/2000/1*kU6Q7pi0coovXxIOy8UaEw.png" alt="" /></p>
<p>attempting to increase the vote count to 1034. An action <code>$apply</code>ed through an <code>ng-click</code></p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon upvote<span class="token punctuation">"</span></span> <span class="token attr-name">ng-click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vm.user.upvote(vm.answer)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>i</span><span class="token punctuation">></span></span></code></pre>
<p>would trigger a <code>$digest</code> cycle under the hood, which checks all registered <code>$watch</code>es for changes. Then, an expression providing “voted” styling for answers, registered through <code>ng-class</code></p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon upvote<span class="token punctuation">"</span></span><br /> <span class="token attr-name">ng-click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vm.user.upvote(vm.answer)<span class="token punctuation">"</span></span><br /> <span class="token attr-name">ng-class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>{voted: vm.answer.isVotedFor(vm.user)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>i</span><span class="token punctuation">></span></span></code></pre>
<p>and an expression providing the aggregate number of votes, registered through double curly braces {</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon upvote<span class="token punctuation">"</span></span><br /> <span class="token attr-name">ng-click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vm.user.upvote(vm.answer)<span class="token punctuation">"</span></span><br /> <span class="token attr-name">ng-class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>{voted: vm.answer.isVotedFor(vm.user)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>i</span><span class="token punctuation">></span></span><br /> <br /><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon downvote<span class="token punctuation">"</span></span><br /> <span class="token attr-name">ng-click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vm.user.downvote(vm.answer)<span class="token punctuation">"</span></span><br /> <span class="token attr-name">ng-class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>{voted: vm.answer.isVotedAgainst(vm.user)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>i</span><span class="token punctuation">></span></span></code></pre>
<p>would trigger the appropriate DOM updates:</p>
<p><img src="https://cdn-images-1.medium.com/max/2000/1*CxheOXIunYTXze80R08l5A.png" alt="" /></p>
<p>Change detection is a fundamental part of AngularJS applications. Whether utilizing native AngularJS directives or building your own, an understanding of the many layers of data watching is essential to understanding Angular.</p>
<h2 id="some-interesting-(but-skippable)-background">Some Interesting (but skippable) background <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#some-interesting-(but-skippable)-background">#</a></h2>
<h3 id="an-angular-expression-can-produce-different-values-over-time.">An angular expression can produce different values over time. <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#an-angular-expression-can-produce-different-values-over-time.">#</a></h3>
<p>Watching consists of getting the value of an expression and performing a task when it has changed. In angular, an expression can take the form of a string or a javascript function:</p>
<p><em>1. any ol’ javascript function</em></p>
<pre class="language-js"><code class="language-js">scope<span class="token punctuation">.</span>greeting <span class="token operator">=</span> <span class="token string">'hi there'</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">var</span> <span class="token function-variable function">getGreeting</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">scope</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> scope<span class="token punctuation">.</span>greeting<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br />scope<span class="token punctuation">.</span><span class="token function">$watch</span><span class="token punctuation">(</span>getGreeting<span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">greeting</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'greeting: '</span><span class="token punctuation">,</span> greeting<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// greeting: hi there</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p><em>2. string</em></p>
<pre class="language-js"><code class="language-js">scope<span class="token punctuation">.</span>greeting <span class="token operator">=</span> <span class="token string">'hi there'</span><span class="token punctuation">;</span><br /><br />scope<span class="token punctuation">.</span><span class="token function">$watch</span><span class="token punctuation">(</span><span class="token string">'greeting'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">greeting</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'greeting: '</span><span class="token punctuation">,</span> greeting<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// greeting: hi there</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p><strong>Function or… string?</strong> Internally, the first thing the <em>$scope.$watch</em> method does is <a href="https://github.com/angular/angular.js/blob/v1.5.3/src/ng/rootScope.js#L387">pass its first parameter to the $parse service</a>. The <em>$parse</em> service is a function (obviously) that returns another function (let’s call it the “parseFn”). The <em>parseFn</em> expects to be called with the desired context object against which the original string or function may be evaluated e.g.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> context <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">'steph'</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">'curry'</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// with string</span><br /><span class="token keyword">var</span> string <span class="token operator">=</span> <span class="token string">'last + ", " + first'</span><span class="token punctuation">;</span><br /><span class="token keyword">var</span> parseFn <span class="token operator">=</span> <span class="token function">$parse</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token function">parseFn</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => curry, steph</span><br /><br /><span class="token comment">// with function</span><br /><span class="token keyword">var</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> context<span class="token punctuation">.</span>last <span class="token operator">+</span> <span class="token string">', '</span> <span class="token operator">+</span> context<span class="token punctuation">.</span>first<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><span class="token keyword">var</span> parseFn <span class="token operator">=</span> <span class="token function">$parse</span><span class="token punctuation">(</span>func<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token function">parseFn</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => curry, steph</span></code></pre>
<p>If the <em>$parse</em> service receives a string, <a href="https://github.com/angular/angular.js/blob/v1.5.3/src/ng/parse.js#L1791">work needs to be performed</a> in order to translate the string into proper javascript that is capable of evaluation against an object i.e. a function. On the other hand, if it receives a function, well… <a href="https://github.com/angular/angular.js/blob/v1.5.3/src/ng/parse.js#L1822">not much needs to happen</a>. Since the service has received what it must produce, it may assume the function has been properly prepared. As you can see, most of the angular “magic” lies in parsing the string parameter into such a function to enable the intake of a string.</p>
<p><strong>At any point in time</strong>. There is a reason angular has chosen the function-with-context-object-parameter structure: calls to the function reveal changes to underlying context, which means that the function can be invoked at any point in time to retrieve the value of the underlying expression or function <em>at such time</em>:</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> fullName <span class="token operator">=</span> <span class="token string">'last + ", " + first'</span><span class="token punctuation">;</span><br /><span class="token keyword">var</span> getFullName <span class="token operator">=</span> <span class="token function">$parse</span><span class="token punctuation">(</span>fullName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// getFullName is the parseFn!</span><br /><br /><span class="token keyword">var</span> context <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">'steph'</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">'curry'</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><span class="token function">getFullName</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => curry, steph</span><br />context <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">'russ'</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">'westbrook'</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><span class="token function">getFullName</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => westbrook, russ</span></code></pre>
<p>Since scope objects are…objects, this of course works with scope objects as well. The string <em>“vm.answer.isVotedFor(vm.user)”</em> from the “upvote” example above — after being passed to <em>parse</em> by <em>watch</em> and transformed into a function that is ready to accept an object — was ready to reveal any new <em>isVotedFor</em> status reflected in an updated scope object. Now the function-returning-a-function structure of the parse service also begins to make sense. The returned function (i.e the <em>parseFn</em>), prepped and ready to accept the latest scope object, is exactly what the digest cycle needs and <a href="https://github.com/angular/angular.js/blob/v1.5.3/src/ng/rootScope.js#L413">precisely what it receives</a> in order to get the latest value of an expression. Sensibly, the <em>parseFn</em> is <a href="https://github.com/angular/angular.js/blob/v1.5.3/src/ng/rootScope.js#L387">named “get” internally</a> because of these getter qualities.</p>
<p><strong>Against the last cached value</strong>. Now to determine change, all the <em>$digest</em> cycle has left to do is cache the <em>last</em> value retrieved by the registered <em>parseFn</em> and compare it to the next….which brings us to the topic of this post: this comparison between new and old values, what constitutes equality and the multiple levels of change detection in angular.</p>
<h2 id="%24watch-%E2%80%94-type-1">$watch — type 1 <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#%24watch-%E2%80%94-type-1">#</a></h2>
<p>The simplest and most common, this type of <em>watch</em> uses javascript’s <code>===</code> operator to compare old and new values, invoking the callback only upon <em>strict inequality</em>:</p>
<pre class="language-js"><code class="language-js">scope<span class="token punctuation">.</span><span class="token function">$watch</span><span class="token punctuation">(</span><span class="token string">'greeting'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">greeting</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'greeting: '</span><span class="token punctuation">,</span> greeting<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />scope<span class="token punctuation">.</span>greeting <span class="token operator">=</span> <span class="token string">'hi there'</span><span class="token punctuation">;</span> <span class="token comment">// greeting: hi there</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> scope<span class="token punctuation">.</span>greeting <span class="token operator">+=</span> <span class="token string">', Joe'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// greeting: hi there, Joe</span></code></pre>
<p>For expressions that evaluate to primitive types like Strings and Numbers, this has a predictable effect. Old and new values of <code>4</code> and <code>4</code> are considered equal, but <code>4</code> and <code>5</code> and <code>4</code> and <code>‘4’</code> are not. Similarly, <em>‘hello’</em> and <em>‘hello’</em> will not register a change, but <em>‘hello’</em> and <em>‘goodbye’</em> will. In the above “upvote” example, angular’s curly brackets <em>{{}}</em> registered <a href="https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L2782"><em>this</em> type of watch</a> for the expression <em>vm.answer.voteCount()</em>. When <em>1034</em> was compared against <em>1033</em>, a change was registered.</p>
<p>For expressions that evaluate to javascript <em>objects</em>, strict equality means something less intuitive. The same object, no matter how mutated between equality checks, will <em>not</em> register “change”, whereas, two different objects, no matter how similar, will:</p>
<pre class="language-js"><code class="language-js">scope<span class="token punctuation">.</span><span class="token function">$watch</span><span class="token punctuation">(</span><span class="token string">'obj1'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token parameter">newValue</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'obj1: '</span><span class="token punctuation">,</span> newValue<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// (when initialized) prints out: undefined</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>obj1 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'jonathan'</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// prints out: {name: 'jonathan'}</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>obj1<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'michael'</span><span class="token punctuation">;</span> <span class="token comment">// no "change" registered, no print out</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>obj1<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span> <span class="token comment">// no "change" registered, no print out</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token comment">// it's a new object! </span><br /> scope<span class="token punctuation">.</span>obj1 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'jonathan'</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// prints out: {name: 'jonathan'}</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1500</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>The important thing to note in determining how change is registered is not whether two objects have the same properties but whether two objects refer to the same address in memory i.e whether they are the same object. Notice in the above example that different objects with exactly the same properties and values nevertheless register change and print to the console with the latest object because they are different objects. Whereas, the same object reference prints nothing to the console no matter how mutated between equality checks.</p>
<h2 id="%24watchgroup-%E2%80%94-type-2">$watchGroup — type 2 <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#%24watchgroup-%E2%80%94-type-2">#</a></h2>
<p>This type of watch can handle multiple expressions instead of being limited to just one, invoking the registered callback when <em>any</em> of the expressions have changed.</p>
<pre class="language-js"><code class="language-js">scope<span class="token punctuation">.</span><span class="token function">$watchGroup</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'expression1'</span><span class="token punctuation">,</span> <span class="token string">'expression2'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">arrayOfExpressions</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>You may want to use this type of watch if two or more properties are coupled. In the above “upvote” example, you could use this watch to disable further voting if an answer has been voted for <em>or</em> against:</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> isVotedGroup <span class="token operator">=</span> <span class="token punctuation">[</span><br /> <span class="token string">'vm.answer.isVotedAgainst(vm.user)'</span><span class="token punctuation">,</span><br /> <span class="token string">'vm.answer.isVotedFor(vm.user)'</span><br /><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">var</span> unwatch <span class="token operator">=</span> scope<span class="token punctuation">.</span><span class="token function">$watchGroup</span><span class="token punctuation">(</span>isVotedGroup<span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">isVotedGroup</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">var</span> hasVoted <span class="token operator">=</span> isVotedGroup<span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">bool</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> bool<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>hasVoted<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> vm<span class="token punctuation">.</span>answer<span class="token punctuation">.</span><span class="token function">disableVoting</span><span class="token punctuation">(</span>vm<span class="token punctuation">.</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">unwatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>The important thing to note is that the containing array itself is <em>not</em> watched by *watchGroup, *in stark contrast to (maybe the more familiar) *watchCollection; <em>rather</em>, *each member of the array is. Much like the subject of a regular type 1 <em>watch</em>, each member of the array can itself be a string expression capable of contextual evaluation or a function ready to be passed a context object. As a result, <em>watchGroup</em> can be seen as simply a way to group together multiple regular type 1 *watch’*es with a single callback function. When *any of the grouped *watches registers a change, the callback is invoked. This set up has the benefit of allowing expressions to be members of the group as described. But members of the group cannot be dynamically added or subtracted and order is not an applicable concept…which brings us to <em>watchCollection</em>.</p>
<h2 id="%24watchcollection-%E2%80%94-type-3">$watchCollection — type 3 <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#%24watchcollection-%E2%80%94-type-3">#</a></h2>
<p>This type of watch is intended for javascript arrays, invoking the callback when collection level changes have occurred.</p>
<pre class="language-js"><code class="language-js">$scope<span class="token punctuation">.</span>firstTeam <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><br /> <span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">'steph'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">'curry'</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">'lebron'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">'james'</span><br /><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br />$scope<span class="token punctuation">.</span><span class="token function">$watchCollection</span><span class="token punctuation">(</span><span class="token string">'firstTeam'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">firstTeamArray</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"change to the first team! "</span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>firstTeamArray<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> $scope<span class="token punctuation">.</span>firstTeam<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">'russel'</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">'westbrook'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// new member, print!</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> $scope<span class="token punctuation">.</span>firstTeam<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">player1<span class="token punctuation">,</span> player2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>player1<span class="token punctuation">.</span>first <span class="token operator"><</span> player2<span class="token punctuation">.</span>first<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// reordering, print!</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> $scope<span class="token punctuation">.</span>firstTeam<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token number">75</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">600</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// member mutation, no print</span></code></pre>
<p>Where <em>watchGroup</em> allows multiple expressions capable of contextual evaluation to point to one callback, <em>watchCollection</em> allows only one — in the above example, <em>‘firstTeam’</em>. On the other hand, the type of watch applied to such expression is more involved. Type 1 watchers care only about addresses for objects and values for primitives. As objects themselves, arrays are no different. Subject to a type 1 watch, expressions that evaluate to an array will not register change no matter how mutated between checks until switched out for an entirely new array and address in memory. <em>watchCollection</em> is vastly different. Mutation is the name of the game. In particular, <em>watchCollection</em> keeps its eye on two types of surface level array mutations: (1) addition/subtraction and (2) reordering. Adding or subtracting members of the array and reordering members of the array result in change being recognized and the registered callback being invoked. watchCollection only stops short of watching below-surface mutation i.e. deep mutation, mutations to the members themselves… which brings us to deep watching.</p>
<h2 id="%24watch(%E2%80%A6%2C-%E2%80%A6%2C-true)-%E2%80%94-type-4">$watch(…, …, true) — type 4 <a class="direct-link" href="https://softwarefordays.com/post/angular-change-detection/#%24watch(%E2%80%A6%2C-%E2%80%A6%2C-true)-%E2%80%94-type-4">#</a></h2>
<p>The most expensive watch, this type of watch is also the most thorough, recursively scaling the depths of any complex object and invoking the registered callback when any branch of the tree has undergone change. Note the <em>true</em> flag, which tells angular to perform this type of watch instead of a type 1:</p>
<pre class="language-js"><code class="language-js">scope<span class="token punctuation">.</span>tree <span class="token operator">=</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">'oak'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">branches</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><br /> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'brown'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token string">'11'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">leaves</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><br /> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'green'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">shape</span><span class="token operator">:</span> <span class="token string">'oval'</span><span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'brown'</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">shape</span><span class="token operator">:</span> <span class="token string">'leafy'</span><br /> <span class="token punctuation">}</span><span class="token punctuation">]</span><br /> <span class="token punctuation">}</span><span class="token punctuation">]</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br />scope<span class="token punctuation">.</span><span class="token function">$watch</span><span class="token punctuation">(</span><span class="token string">'tree'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">tree</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'change to tree!'</span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringfiy</span><span class="token punctuation">(</span>tree<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> scope<span class="token punctuation">.</span>tree<span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">'sequoia'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// mutation, print!</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>tree<span class="token punctuation">.</span>branches<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">12</span><span class="token punctuation">;</span> <span class="token comment">// mutation, print!</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>tree<span class="token punctuation">.</span>branches<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>leaves<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>color <span class="token operator">=</span> <span class="token string">'clementine'</span><span class="token punctuation">;</span> <span class="token comment">// mutation, print!</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>tree<span class="token punctuation">.</span>branches<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>leaves<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token comment">// mutation, print!</span><br /> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'rosemary'</span><br /> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">$timeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> scope<span class="token punctuation">.</span>tree <span class="token operator">=</span> <span class="token string">'hello!'</span><span class="token punctuation">;</span> <span class="token comment">// mutation, print!</span><br /><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">400</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Deep watching has no limitations, other than performance of course — the last thing your application needs is recursive journeys into the depths of complex objects <em>every</em> digest cycle. On the other hand, deep watching can keep any complex data in sync with the view and, as a result, may be the easiest to understand: all change is change.</p>
<p>This has been a discussion of the many layers of data watching in AngularJS. I hope it helps inform your choice among them!</p>
<p>Quote of the Day:</p>
<blockquote>
<p>Reporter: Why do you shoot so many 3’s?</p>
</blockquote>
<blockquote>
<p><a href="http://espn.go.com/blog/truehoop/post/_/id/22316/behold-the-4-pointer">Antoine Walker</a>: Because there aren’t any 4’s.</p>
</blockquote>
Functional Programming and the Semantics of Change, State & Time2020-03-09T00:00:00Zhttps://softwarefordays.com/post/functional-programming-and-identity-state-and-time/<p>The “functions vs. objects” cliche is an artifact of a profound truth about program structure and semantics. Like oil and water, functions expel objects and objects functions. Moreover, the choice between them has dramatic implications for our programs, installing a “world-view” that involves concepts as fundamental as identity, change, state and even time. The object-oriented world-view may seem so obvious as to be without alternative. Look around the room, bus, park or wherever you find yourself reading this sentence, and you will likely identify objects, such as dogs, people and trees, changing over time. Many programmers approach program design the same way, identifying “distinct objects whose behaviors may change over time.” (<a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3) The ubiquity of this interpretation, however, belies the fact of interpretation. Change can be reformulated along different lines. Functional programs do not include identifiable objects. Yet, they may include state. They shift the paradigm. Instead of objects that change over time, functional programs consist of state transitions between <em>discrete</em> <em>moments in time</em> that may be seen together as “streams of information that flow.” (<a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3)</p>
<nav id="toc" class="table-of-contents"><ol><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#preface%3A-why-javascript">Preface: Why JavaScript </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#object-oriented-programming">Object-Oriented Programming </a><ol><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#an-evolution-of-imperative-programming">An Evolution of Imperative Programming </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#place-oriented-programming">Place-Oriented Programming </a></li></ol></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#functional-programming">Functional Programming </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#semantics%2C-not-syntax">Semantics, Not Syntax </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#changeability-is-fundamental-to-object-semantics">Changeability is Fundamental to Object Semantics </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#unchangeability-is-fundamental-to-functional-semantics">Unchangeability is Fundamental to Functional Semantics </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#%E2%80%9Cobject%E2%80%9D-names-changeability">“Object” Names Changeability </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#diametric-opposites">Diametric Opposites </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#programs-though!">Programs Though! </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful-object-oriented-programs">Stateful Object-Oriented Programs </a><ol><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#time">Time </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful">Stateful </a></li></ol></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful-functional-programs">Stateful Functional Programs </a><ol><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#time-as-a-series-of-states">Time as a Series of States </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#reified-state">Reified State </a></li></ol></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#resolving-the-time-paradox">Resolving the Time Paradox </a></li><li><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#addendum%3A-functional-programming-as-a-scientific-revolution">Addendum: Functional Programming as a Scientific Revolution </a></li></ol></nav><h2 id="preface%3A-why-javascript">Preface: Why JavaScript <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#preface%3A-why-javascript">#</a></h2>
<p>Many of the insights underlying this post can be found in original form in the <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">Structure and Interpretation of Computer Programs </a> (SICP). There you may find a life-altering discussion of the same topics using Scheme, a Lisp dialect like Clojure. All code examples included in this post, however, will be couched in terms of JavaScript. If you know JavaScript and are unfamiliar with Scheme, this post may be immediately accessible to you without first learning how “<a href="https://crockford.com/javascript/javascript.html">to balance all those parens</a>.” Little is lost in translation as well. JavaScript has first-class functions (i.e. lambdas), closures (i.e. function-delimited lexical scoping) and generally thrives when used functionally.</p>
<blockquote>
<p>JavaScript’s functions are first class objects with (mostly) lexical scoping. JavaScript is the first lambda language to go mainstream. Deep down, JavaScript has more in common with Lisp and Scheme than with Java. It is Lisp in C’s clothing. — Douglas Crockford, <a href="https://www.oreilly.com/library/view/javascript-the-good/9780596517748/ch01s02.html">JavaScript: The Good Parts</a></p>
</blockquote>
<p>There is even an ongoing <a href="https://sicp.comp.nus.edu.sg/">academic effort</a> to translate the full text of SICP into JavaScript. Also considered, JavaScript is a close cousin of TypeScript, which enables traditional object-oriented constructs like <code>private</code> and <code>public</code> and functional constructs like <code>readonly</code> and <code>as const</code> at compile time. Perhaps in JavaScript (and TypeScript), we get enough support of functional and object-oriented programming paradigms to enable a discussion of both within a single, ubiquitous language.</p>
<h2 id="object-oriented-programming">Object-Oriented Programming <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#object-oriented-programming">#</a></h2>
<p><em>Object-oriented programming</em> has come to signify a common language for modeling the behavior of objects.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn1" id="fnref1">[1]</a></sup> <em>Methods</em> leverage privileged access to proscribe the ways in which private attributes may be viewed or changed. A <em>class</em> specifies the blueprint for creating object instances of a certain kind. Together, these constructs may create computational objects that simulate real objects. This <code>bankAccount</code> object in TypeScript, for example,</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">private</span> balance<span class="token punctuation">;</span><br /><br /> <span class="token function">constructor</span><span class="token punctuation">(</span>funds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> funds<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<figcaption>This example is based on the "withdraw" procedure introduced in SICP Section 3.1.</figcaption>
<p>stores balance data in a private attribute and exposes privileged methods <code>checkBalance</code> and <code>withdraw</code>, which proscribe the manner in which access to <code>balance</code> can occur. Together, these constructs create a computational object <code>bankAccount</code> that behaves like a “bank account”, carrying a balance that may be diminished through “withdraw” and viewed through “check balance” actions. Less abstract objects can be modeled with the same set of tools. An <code>apple</code> may have a <code>bite</code> method that reduces an internal <code>bites</code> state in order to model an “apple” and a <code>house</code> may have a <code>paint</code> method that changes an internal <code>color</code> state in order to model a “house.” More abstract objects can be modeled with the same set of tools as well. A <code>userMetaData</code> object may have a <code>setEmail</code> method that updates an internal <code>email</code> state in order to model “user meta data.”</p>
<h3 id="an-evolution-of-imperative-programming">An Evolution of Imperative Programming <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#an-evolution-of-imperative-programming">#</a></h3>
<blockquote>
<p>And a key characteristic here is that objects have methods… They are operationally defined. And we use them to provide a layer of abstraction over the places that our program uses. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>Private state enforces the object abstraction together with privileged, public methods. Expose <code>balance</code> directly (i.e. make it public), for example, and it can “magically” change from say <code>100</code> to <code>10</code> despite no <code>withdraw</code>al ever having occurred.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> balance<span class="token punctuation">;</span><br /> <span class="token operator">...</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token number">80</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<figcaption>Did a withdrawal occur? Does <code>bankAccount</code> accurately represent a "bank account"?</figcaption>
<p>Expose <code>color</code> directly and it can magically change from say <code>WHITE</code> to <code>BLUE</code> despite no <code>paint</code>ing ever having occurred. In other words, object-oriented programming provides the means for identifying objects (<code>bankAccount</code>) and associated behaviors (<code>withdraw</code>)</p>
<pre class="language-js"><code class="language-js">bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>in place of imperative, direct manipulation of variables (<code>balance</code>) ad hoc.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> balance <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br />balance <span class="token operator">=</span> balance <span class="token operator">-</span> <span class="token number">20</span><span class="token punctuation">;</span></code></pre>
<figcaption>Did a withdrawal occur? Does <code>balance</code> represent a "bank account" or something else entirely?</figcaption>
<p>Coincidentally, the private data / public methods dynamic also provides the means for data encapsulation. That data is stored in private attributes, accessible only through privileged methods, proscribes the ways in which such data may be viewed or changed. The <code>balance</code> data of <code>bankAccount</code> can only be changed by <code>withdraw</code> or read by <code>checkBalance</code>, in one sense, because it may not be accessed directly.</p>
<h3 id="place-oriented-programming">Place-Oriented Programming <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#place-oriented-programming">#</a></h3>
<p>Nevertheless, object-oriented and imperative programming share a fundamental orientation towards places in memory.</p>
<blockquote>
<p>But mutable objects are actually abstractions of places. They do not actually have meaning other than that. They are little barricades we have set up in front of memory, so that we do not have to directly manipulate memory addresses any more. So we have this abstraction that is an object, that helps us manipulate that place without too much craziness…So I have a new label for this. It is called PLOP, and PLOP is place-oriented programming. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>A method call to <code>withdraw</code> effectively overwrites a <code>balance</code> reference</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (this.balance = 100)</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (this.balance = this.balance - 20)</span></code></pre>
<p>just as any direct assignment that circumvents a method.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> balance <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br />balance <span class="token operator">=</span> balance <span class="token operator">-</span> <span class="token number">20</span><span class="token punctuation">;</span></code></pre>
<p>A mutable variable underlies the reassignment in both cases, whether or not an object method mediates such reassignment, and a place in memory underlies every mutable variable.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn2" id="fnref2">[2]</a></sup></p>
<h2 id="functional-programming">Functional Programming <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#functional-programming">#</a></h2>
<p>Procedures that produce the same result when provided the same argument can be viewed as computing mathematical functions. For example, a <code>decrement100</code> procedure in JavaScript,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">decrement100</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token number">100</span> <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">decrement100</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>or, more succinctly,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">decrement100</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token number">100</span> <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrement100</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>can be viewed as computing the mathematical function <code>f(x) = 100 — x</code>:</p>
<pre class="language-text"><code class="language-text">f(20) = 80; where f(x) = 100 - x</code></pre>
<p>since the return value of <code>decrement100</code> depends only on the input value just as <code>f(x)</code> depends only on <code>x</code>. Invoke <code>decrement100</code> a second time with <code>20</code> and it will return <code>80</code> once again, regardless of time and place within a program’s runtime. By contrast, an alternative implementation</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> oneHundred <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">decrementOneHundred</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> oneHundred <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />oneHundred <span class="token operator">=</span> <span class="token number">80</span><span class="token punctuation">;</span><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 60</span></code></pre>
<p>involving a mutable binding does not model computing a mathematical function, since its behavior may depend on variable information in addition to its input. Invoke <code>decrementOneHundred</code> a second time with <code>20</code> and it will <em>not</em> return <code>80</code> once again when such binding is intermediately reassigned.</p>
<p>Functional procedures are not limited to numbers. Procedures that involve character strings, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">space</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">w1<span class="token punctuation">,</span> w2</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>w1<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>w2<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span><br /><br /><span class="token function">space</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"world"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => "hello world"</span></code></pre>
<figcaption><code>“hello world”</code> will result from <code>("hello", "world")</code> regardless of program context.</figcaption>
<p>a list of strings,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">space</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">w1<span class="token punctuation">,</span> w2</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>w1<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>w2<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">sentence</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">words</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>words<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>space<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span><br /><br /><span class="token function">sentence</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"i"</span><span class="token punctuation">,</span> <span class="token string">"heart"</span><span class="token punctuation">,</span> <span class="token string">"functions"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => "i heart functions."</span></code></pre>
<figcaption><code>"i heart functions"</code> will result from <code>["i", "heart", "functions"]</code> regardless of program context.</figcaption>
<p>or other arbitrary data types and compositions may return the same value provided the same argument. Larger functional procedures can be composed of smaller ones,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">square</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">*</span> x<span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> <span class="token function-variable function">sumOfSquares</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">square</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">sumOfSquares</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 14</span></code></pre>
<p>as can programs themselves.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">square</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">*</span> x<span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><br /><br /><span class="token comment">// PSUEDO CODE</span><br /><span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">square</span><span class="token punctuation">(</span><span class="token constant">USER_INPUT_1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span><span class="token constant">USER_INPUT_2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span><span class="token constant">USER_INPUT_3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// REPL PSUEDO CODE</span><br /><span class="token comment">// > run functionalProgram.js with USER_INPUT_1=1, USER_INPUT_2=2, USER_INPUT_3=3,</span><br /><span class="token comment">// > 14</span></code></pre>
<p>When the output of one functional procedure becomes the input of another, the wrapping program or procedure itself can be viewed as computing a mathematical function; a second run with the same input results in the same output.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn3" id="fnref3">[3]</a></sup></p>
<h2 id="semantics%2C-not-syntax">Semantics, Not Syntax <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#semantics%2C-not-syntax">#</a></h2>
<p>Syntactic constructs like <code>this</code>, <code>new</code>, <code>class</code>, <code>private</code> and <code>public</code> clearly express object-oriented intent — <em>this</em> instance of a <em>class</em> of things <em>private</em>ly maintains data through <em>public</em>ly available APIs — and are common to object-oriented programming languages. However, they are not necessary. Object-oriented semantics may be achieved with nontraditional syntax. For example, this <code>bankAccount</code> object also stores the <code>balance</code> data privately;</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p><code>balance</code> is accessible only through the functions <code>checkBalance</code> and <code>withdraw</code>, which proscribe the manner in which such access can occur. <code>bankAccount</code> behaves like a “bank account” even though the functions <code>checkBalance</code> and <code>withdraw</code> have gained privileged access to private data through the use of a function closure, instead of through explicit syntax. Object-oriented syntax is also insufficient in and of itself to achieve object-oriented semantics. A <code>bankAccount</code> “object” that avoids maintaining any underlying balance state</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>balance<span class="token punctuation">,</span> amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span>balance<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100; whoops, shouldn't this be 80?</span></code></pre>
<figcaption>Is <code>bankAccount</code> really a "bank account"?</figcaption>
<p>allows “its” balance to evolve in an unspecified manner, undermining the “bank account” abstraction. <code>new</code>, <code>class</code> and <code>public</code> constructs belie the actual semantics in this case. The same can be said of a <code>bankAccount</code> object that publicly exposes the balance attribute, as was alluded to above.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> balance<span class="token punctuation">;</span> <span class="token comment">// <-- now public</span><br /><br /> <span class="token function">constructor</span><span class="token punctuation">(</span>funds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> funds<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token number">80</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80, eventhough no funds have been withdrawn</span></code></pre>
<figcaption>Is <code>bankAccount</code> really a "bank account"?</figcaption>
<p>Now, <code>balance</code> can magically change without a <code>withdraw</code>al ever having occurred, which undermines the “bank account” abstraction. <code>new</code>, <code>class</code> and <code>public</code> constructs belie the actual semantics in this case.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn4" id="fnref4">[4]</a></sup></p>
<p>With functional programming, syntax is also beside the point. The use of functional syntactic constructs is necessary to perform computation against arguments. <code>function</code> and <code>=></code> (the “arrow function”) constructs may express functional programming intent as well. However, they cannot alone achieve functional semantics. Indeed, a method of an object may use the <code>=></code> construct without correctly modeling computing mathematical functions.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Subsequent calls to <code>checkBalance</code> return different results despite identical inputs (i.e. <code>undefined</code>) by design.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>Additionally, an alternative implementation of “decrement one hundred” in JavaScript may fall short of correctly modeling a mathematical function even though an <code>=></code> construct is used, as was alluded to above.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> oneHundred <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">decrementOneHundred</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> oneHundred <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />oneHundred <span class="token operator">=</span> <span class="token number">80</span><span class="token punctuation">;</span><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 60</span></code></pre>
<p>Invoking this procedure a second time with the same argument produces a different result when the <code>let</code> binding is amended between invocations.</p>
<h2 id="changeability-is-fundamental-to-object-semantics">Changeability is Fundamental to Object Semantics <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#changeability-is-fundamental-to-object-semantics">#</a></h2>
<p>Since objects can change - an apple can be bitten, a house painted, and a bank account withdrawn from - effective object representations must follow suit.</p>
<blockquote>
<p>[W]e make computational objects…whose behavior changes with time. We model state with local state variables, and we model the changes of state with assignments to those variables. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.1.2</p>
</blockquote>
<p><code>bite</code>ing an <code>apple</code> changes <code>bites</code> state, <code>paint</code>ing a <code>house</code> changes <code>color</code> state and <code>withdraw</code>ing from a <code>bankAccount</code> changes <code>balance</code> state. The class implementation of a bank account object</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">private</span> balance<span class="token punctuation">;</span><br /><br /> <span class="token function">constructor</span><span class="token punctuation">(</span>funds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> funds<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span> <span class="token comment">// <-- assign `this.balance` a new value</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<figcaption>The bank account’s balance is overwritten by the withdraw method.</figcaption>
<p>involves overwriting <code>balance</code> as much as the closure implementation does.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// <-- assign `balance` a new value</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<figcaption>The bank account’s balance is overwritten by the withdraw method.</figcaption>
<p>As mentioned above, a state<em>less</em> “object” (e.g. <code>bankAccount</code>) that avoids maintaining any underlying state (e.g. <code>balance</code>)</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>balance<span class="token punctuation">,</span> amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span>balance<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100; whoops, shouldn't this be 80?</span></code></pre>
<figcaption>Is <code>bankAccount</code> really a "bank account"?</figcaption>
<p>also avoids modeling any underlying object (e.g. “bank account”).</p>
<h2 id="unchangeability-is-fundamental-to-functional-semantics">Unchangeability is Fundamental to Functional Semantics <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#unchangeability-is-fundamental-to-functional-semantics">#</a></h2>
<p>On the other hand, changeable things undermine functional semantics. The <code>decrement100</code> procedure can be viewed as computing a mathematical function because its output depends only on its input; there is no other <em>variable</em> information on which it depends. By contrast, as the value of the mutable <code>let</code> binding underlying <code>decrementOneHundred</code> <em>changes</em>, so does the behavior of <code>decrementOneHundred</code> as a side-effect. Consequently, <code>decrementOneHundred</code> depends on the ongoing value of some contextual thing in addition to its input <code>x</code> and cannot resemble computing a mathematical function.</p>
<p>Conversely, unchangeability restores functional semantics. No contextual changes means no side-effects, and no side-effects means functional behavior:</p>
<blockquote>
<p>So long as we do not use assignments, two evaluations of the same procedure with the same arguments will produce the same result, so that procedures can be viewed as computing mathematical functions. Programming without any use of assignment…is accordingly known as <em>functional programming</em>. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.1.3</p>
</blockquote>
<p>Even an externally scoped variable cannot change the semantics of <code>decrementOneHundred</code> when unchangeable.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> oneHundred <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">// <-- now a `const` instead of a `let`</span><br /><span class="token keyword">const</span> <span class="token function-variable function">decrementOneHundred</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> oneHundred <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br /><span class="token comment">// oneHundred = 80; <-- would be runtime error: "TypeError: Assignment to constant variable."</span><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>Since JavaScript’s <code>const</code> binding endows <code>oneHundred</code> with immutability, it simply cannot change (without throwing a runtime error). And without change, the output of <code>decrementOneHundred</code> can depend only on the single thing that can: its input.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn5" id="fnref5">[5]</a></sup></p>
<h2 id="%E2%80%9Cobject%E2%80%9D-names-changeability">“Object” Names Changeability <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#%E2%80%9Cobject%E2%80%9D-names-changeability">#</a></h2>
<p>Moreover, changeability <em>implies</em> an object. The rational number “2/3” cannot change, for example. Change the denominator of “2/3” from 3 to 5 and its identity changes as well to “2/5”. Neither can the integer “24.” Increase the number of units represented by “24” and it may change to “25.”</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">HOURS_IN_DAY</span> <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span><br /><br /><span class="token comment">/**<br /> * NOT VALID; imagined API for mutating numbers<br /> */</span><br /><span class="token number">24.</span><span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token constant">HOURS_IN_DAY</span> <span class="token operator">===</span> <span class="token number">25</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre>
<figcaption>JavaScript implements number literals as immutable primitive values, preventing this unexpected behavior.
</figcaption>
<p>The rational number “2/3” and the integer “24” are unchangeable things, and are not recognizable as objects. Similarly, change the molecular construction of “iron” and it may very well change to “gold,” or the wave length of “green” and it may change to “red”. Conversely, find changeability and find an object. A cup that is two-thirds full of water can be poured, an iron rod can be dented and a green house can be painted. “That cup” remains that cup notwithstanding less water; “that rod” remains that rod notwithstanding a dent; “that house” remains that house notwithstanding a fresh coat of paint. A “cup”, “rod” and “house” are changeable things that <em>are</em> recognizable as objects. Coincidence of “changeability” and “object” is not happenstance. That parts can change without changing the identity of the whole <em>distinguishes</em> an identity distinct from underlying parts. Changeability distinguishes an object. “Object” in a sense articulates this ability to change.</p>
<p>Said another way, a new notion of “sameness” emerges with changeability. Unchangeable things can be identified as “the same” simply by examining contents. For example, because <em>immutable</em> rational number implementations, <code>r1</code> and <code>r2</code>,</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">type</span> <span class="token class-name">RationalNumber</span> <span class="token operator">=</span> <span class="token keyword">readonly</span> <span class="token punctuation">[</span><br /> <span class="token builtin">number</span> <span class="token comment">/* numerator */</span><span class="token punctuation">,</span><br /> <span class="token builtin">number</span> <span class="token comment">/* denominator */</span><br /><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// turn into decimal form before comparing in order to reduce fraction</span><br /><span class="token keyword">const</span> <span class="token function-variable function">isEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> RationalNumber<span class="token punctuation">,</span> b<span class="token operator">:</span> RationalNumber<span class="token punctuation">)</span> <span class="token operator">=></span><br /> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> b<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> r1<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r2<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r3<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre>
<figcaption>TypeScript’s <code>readonly</code> qualifier prevents mutative actions (e.g. <code>p2[1] = 3</code>) at compile time.
</figcaption>
<p>will <em>always</em> be comprised of <code>2</code> in the first slot and <code>3</code> in the second and reduce to two-thirds, a reasonable conclusion is that they are the same. To be sure, substitute one for the other and the meaning of a program is unchanged.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn6" id="fnref6">[6]</a></sup> By contrast, consider when two <em>mutable</em> rational number implementations may be deemed the “same.”</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">type</span> <span class="token class-name">RationalNumber</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">number</span> <span class="token comment">/* numerator */</span><span class="token punctuation">,</span> <span class="token builtin">number</span> <span class="token comment">/* denominator */</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// turn into decimal form before comparing in order to reduce fraction</span><br /><span class="token keyword">const</span> <span class="token function-variable function">isEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> RationalNumber<span class="token punctuation">,</span> b<span class="token operator">:</span> RationalNumber<span class="token punctuation">)</span> <span class="token operator">=></span><br /> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> b<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> r1<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r2<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r3<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br />r2<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span><br /><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r2<span class="token punctuation">,</span> r3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre>
<figcaption>
Absent the <code>readonly</code> qualifier, <code>RationalNumber</code>'s are mutable at compile time. And at runtime, JavaScript’s <code>const</code> binding only prevents reassignment of such binding; it does not prevent mutations of an underlying array.
</figcaption>
<p><code>r1</code> may have the same contents as <code>r2</code> to start, but this affect is shortly lived. Substitute one for the other and the meaning of the program is changed — references to r2 now incorrectly reduce to two-fifths instead of two-thirds. <code>r1</code> and <code>r2</code> are not exactly “the same” in this case. Since two changeable things may evolve independently notwithstanding an analysis of parts performed at any one point in time, a new notion of “sameness” above an examination of parts must be admitted. Remarkably, this “new” notion is less remarkable with intentional object-oriented programming, where the creation of a new identity — i.e. an <em>object</em> — is precisely the goal. <code>georgesAccount</code> and <code>elainesAccount</code>, for example,</p>
<pre class="language-ts"><code class="language-ts"><span class="token comment">/**<br /> * Reference equality check<br /> */</span><br /><span class="token keyword">const</span> <span class="token function-variable function">areAccountsEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> BankAccount<span class="token punctuation">,</span> b<span class="token operator">:</span> BankAccount<span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">===</span> b<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> elainesAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> georgesAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />elainesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />georgesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br /><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> elainesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> georgesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (eventhough identical funds)</span><br /><br />georgesAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">75</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />elainesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />georgesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 25</span><br /><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> elainesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> georgesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre>
<figcaption>We may determine equality b/w 2 objects by whether they are the same object — i.e. reference equality.
</figcaption>
<p>may share a balance at some point in time. But even if they start with the same funds, <code>georgesAccount</code> and <code>elainesAccount</code> can register different balances at some other point in time because they are in fact different <em>objects</em>. Of course, that two distinct objects can evolve independently goes without saying. That is because “object” clearly articulates the creation of an identity that is not tied to any part, arrangement or quality; “object” names the ability to change.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn7" id="fnref7">[7]</a></sup></p>
<h2 id="diametric-opposites">Diametric Opposites <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#diametric-opposites">#</a></h2>
<p>In this light, object-oriented programming can be seen as the diametric opposite of functional programming. Objects are inherently changeable. Moreover, changeability and “object” are intertwined as concepts. Yet, changeability undermines functional programming. Just as oil cannot inhabit the same physical space as water, object-oriented programming cannot occupy the same virtual space as functional programming. Use of one excludes the other. As a result, when writing programs, we may choose mutability or immutability, objects or functions, but not both at once.</p>
<h2 id="programs-though!">Programs Though! <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#programs-though!">#</a></h2>
<p>Thus far, we have only shown excerpts; the remainder of any surrounding program has been omitted. Of particular concern, our functional excerpts have been stateless. Some complete programs are stateless, designed to produce output based solely on input - compilers ideally output the same binaries provided the same input files. More frequently, however, programs require state. Some input <em>together</em> with the current state of the program determine the output (or next state) of the program. Such is the case with our ATM example, where the current balance is crucial to calculating any subsequent balance post withdrawal. To be generally useful, a programming paradigm should include a model for state.</p>
<h2 id="stateful-object-oriented-programs">Stateful Object-Oriented Programs <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful-object-oriented-programs">#</a></h2>
<blockquote>
<p>Modeling with objects is powerful and intuitive, largely because this matches the perception of interacting with a world of which we are part. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>Creating stateful object-oriented programs is straightforward. An ATM program, for example, that allows the user to set a “withdrawal amount” and effect a withdraw,</p>
<script async="" src="https://jsfiddle.net/jmilgrom/notc93Lv/embed/"></script>
<p>decomposes naturally into <code>withdrawalAmount</code> and and <code>bankAccount</code> objects, representing the chosen amount to be withdrawn and the user account underlying the session, respectively. The withdrawal amounts are incorporated by and read from <code>withdrawalAmount</code>. Withdrawals are incorporated by, and balance confirmations are read from, <code>bankAccount</code>. The current balance and the amount to potentially withdraw — the state of the program — are reflected directly by the state of <code>bankAccount</code> and <code>withdrawalAmount</code> — the state of its composite objects.</p>
<h3 id="time">Time <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#time">#</a></h3>
<blockquote>
<p>If we wish to write programs that model this kind of natural decomposition in our world (as we see it from our viewpoint as a part of that world) with structures in our computer, we make computational objects that… must change with time. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>When we model objects, we also model time. Objects change — as we discussed, the notion of an “object,” having parts that change without changing the identity of the whole, articulates this ability. The flip-side to changing objects is time. Since objects change, <em>when</em> an object is examined is vital to the examination, it goes without saying.</p>
<p>Look no further than the object representations of our computer programs. The “having parts that can change without changing the identity of the whole” quality of <code>bankAccount</code> in our ATM program, for example, is implemented by <code>withdraw</code>.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token operator">...</span><br /><span class="token punctuation">}</span></code></pre>
<p>Underlying <code>withdraw</code> lies a mutable <code>balance</code> binding that may be assigned new values. Calls to <code>withdraw</code> change the associated balance of <code>bankAccount</code> as a side-effect, without altering the identity of <code>bankAccount</code>, by design.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>The flip-side to changing objects is time. In addition to changing the associated balance, any call to <code>withdraw</code> also “delineates moments in time” <em>when</em> <code>balance</code> <em>may</em> change. Whether <code>bankAccount.checkBalance()</code> resolves to <code>100</code> or <code>80</code> “depends not only on the expression itself, but also on whether the evaluation occurs before or after these moments.” As a result, by modeling objects, “we are forced to admit time into our computational models.” (<a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.4)</p>
<h3 id="stateful">Stateful <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful">#</a></h3>
<p>Object-oriented programming reifies objects. Further, objects can be composed in other objects, received by object methods, and generally manipulated like numbers, strings and other <a href="https://en.wikipedia.org/wiki/First-class_citizen">first-class citizens</a> of the program. No such affordances are made for state, on the other hand. State is a quality (i.e. “stateful” or “statefulness”) adjacent to objects. Unlike the objects to which they belong, state can only be <em>observed</em> at runtime, rather than <em>expressed</em> through language.</p>
<p><code>bankAccount</code> and <code>withdrawalAmount</code> identify objects, for example. They can be composed in other objects, received by object methods and generally manipulated like other first-class citizens of the program. By reifying these objects, however, <code>balance</code> and <code>amount</code> state are relegated to object qualities, observable at runtime only through calls to <code>bankAccount.checkBalance</code> and <code>withdrawalAmount.get</code>.</p>
<p>That objects indeed lack any express notion of state is highlighted by object signatures with more than one getter, where any such notion may only exist through definition, signature by signature:</p>
<blockquote>
<p>How can you perceive a mutable object that has more than one getter? … How do you it? … Who could say right now how to do this? No one can, right? You cannot do this, because you need this other thing. You need the recipe for doing this, and the recipe is something that everybody has to make up over and over and over again. … We cannot actually perceive the whole. Cannot do it without help. Without these recipes. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>An object with a single read method (like <code>bankAccount</code>) in a sense defines <em>the</em> method for accessing the whole of an object’s state. However, each additional read method dilutes this claim, underscoring the need for a method specific to the task (e.g. <code>toJSON</code>, <code>serialize</code>, <code>inspect</code>, etc.). In stark contrast to numbers, string and objects themselves, state may be expressed only through programmer-defined constructs evaluated at runtime.</p>
<h2 id="stateful-functional-programs">Stateful Functional Programs <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful-functional-programs">#</a></h2>
<blockquote>
<p>Is there another approach? Can we avoid identifying time in the computer with time in the modeled world? Must we make the model change with time in order to model phenomena in a changing world? — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5</p>
</blockquote>
<p>Building stateful functional programs is less straightforward. To start, notice that imperative iteration can be restructured into functional iteration by recursively calling an iterative function with the results of the previous call. An imperative implementation of factorial, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">factorial</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">let</span> total <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> total <span class="token operator">=</span> total <span class="token operator">*</span> n<span class="token punctuation">;</span><br /> n <span class="token operator">=</span> n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> total<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 6</span></code></pre>
<p>maintains iteration and running total state through assignments to <code>n</code> and <code>total</code>, respectively, with every iteration. An alternative implementation avoids mutation by returning the iteration and running total state from an iteration function,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">factorial</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">const</span> <span class="token function-variable function">iterate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">total<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> total<span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">iterate</span><span class="token punctuation">(</span>total <span class="token operator">*</span> i<span class="token punctuation">,</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">iterate</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 6</span></code></pre>
<p>which may be used by the same function to calculate the next values in the next iteration.</p>
<p>Stateful functional programs can be constructed in a similar fashion — state that is returned from the previous turn of some larger, iterative “program” function becomes the starter state for the next — with one caveat. With <em>synchronous</em> iteration, results of the previous run can simply be passed to the next. The <code>total</code> result from <code>factorial</code> iteration, for example, is passed directly to the next. In a JavaScript web application, however, events are initiated <em>asynchronously</em> as the user interacts with the page, calling callbacks bound to such events, which run pieces of the program so encoded.</p>
<pre class="language-text"><code class="language-text">event → callback → javascript<br />event → callback → javascript<br />...</code></pre>
<p>Communication between <em>asynchronous</em> scripts is performed through shared references. One script updates (mutates!) a place in memory from which another script may later read. Look no further than the object-oriented ATM program above for a concrete example. A user may begin the program by first selecting a withdrawal amount, <em>then</em> clicking withdraw:</p>
<pre class="language-text"><code class="language-text">select → onchange → "withdrawalAmount.set(value)"<br />click → onclick → "bankAccount.withdraw(withdrawalAmount.get())"<br />...</code></pre>
<p>The “click withdraw” script occurs asynchronously sometime after the “select withdrawal amount” script has completed. Communication between the two scripts occurs through shared reference to the <code>amount</code> variable underlying the <code>withdrawalAmount</code> object. Calls to <code>withdrawalAmount.get()</code> will return updates by <code>withdrawalAmount.set(value)</code>, notwithstanding the asynchrony of such reads and writes.</p>
<p>Synchronous functions can communicate by simply passing around results. The result from one function becomes the input of another. Asynchronous scripts, by contrast, share a mutable place in memory instead of the values themselves. Consequently, we must also share a mutable place in memory to communicate between asynchronous scripts in the functional program implementation. On the other hand, with a light amount of infrastructure, we can usher such imperative code to the application perimeter and carve out space for a functional core, creating a “<a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">functional core, imperative shell</a>.”</p>
<script async="" src="https://jsfiddle.net/jmilgrom/mv2187zo/embed/js,html,result/"></script>
<p>The program now consists of functions <code>parseInt</code> and <code>withdraw</code>, called against specific events <code>WITHDRAWAL_AMOUNT</code> and <code>WITHDRAW</code>. The state of the program has not been reflected directly into distinct objects. Instead, a <code>program</code> <em>function</em> is called with the state resulting from the previous call, together with event data from any user interaction, in order to produce the starter state for the next. <code>program</code> resembles an iterative, recursive function. Yet, calls to <code>program</code> occur asynchronously. Just as with the object-oriented ATM program, a user may begin the functional ATM program by first selecting a withdrawal amount, <em>then</em> clicking withdraw:</p>
<pre class="language-text"><code class="language-text">select → onchange → "store.publish('WITHDRAWAL_AMOUNT', {amount:value})"<br />click → onclick → "store.publish('WITHDRAW')"<br />...</code></pre>
<p>The imperative shell (i.e the <code>store</code>) maintains a reference to the <code>state</code> resulting from the previous call to <code>program</code>, in order to pass such <code>state</code> to the next, orchestrating communication between asynchronous calls to <code>program</code>.</p>
<h3 id="time-as-a-series-of-states">Time as a Series of States <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#time-as-a-series-of-states">#</a></h3>
<p>Unlike object-oriented programming, functional programming provides no model for traditional time. Mathematical functions are time<em>less</em>. Computation of a function <code>f(x)</code> a “second time” with the same argument will produce the same result <em>whenever</em> computed; a mathematical statement like <code>f(20) = 80</code> will not be made any less true by insinuating time. Similarly, time is no matter against procedures that model mathematical function computation. Simple functions,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">decrement100</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token number">100</span> <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrement100</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>compositions of functions,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">square</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">*</span> x<span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> <span class="token function-variable function">sumOfSquares</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">square</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">sumOfSquares</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 14</span></code></pre>
<p>as well as “program” functions like the ATM program introduced above,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">withdraw</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance<span class="token punctuation">,</span> amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> <span class="token function-variable function">ATM</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">balance</span><span class="token operator">:</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token literal-property property">amount</span><span class="token operator">:</span> <span class="token number">10</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">switch</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">case</span> <span class="token string">"WITHDRAW"</span><span class="token operator">:</span><br /> <span class="token keyword">return</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span>state<span class="token punctuation">,</span><br /> <span class="token literal-property property">balance</span><span class="token operator">:</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>balance<span class="token punctuation">,</span> state<span class="token punctuation">.</span>amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token keyword">case</span> <span class="token string">"WITHDRAWAL_AMOUNT"</span><span class="token operator">:</span><br /> <span class="token keyword">return</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span>state<span class="token punctuation">,</span><br /> <span class="token literal-property property">amount</span><span class="token operator">:</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token keyword">default</span><span class="token operator">:</span><br /> <span class="token keyword">return</span> state<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>will produce the same output provided the same input <em>whenever</em> evaluated, independent of time.</p>
<p>Where we once saw object state change as time <em>elapsed</em>, we now see the program jump from one state to the next at individual (i.e. discrete!) <em>moments in time</em>, as if producing entries in a list, log, “stream of information,” or other time-denominated series. Iterative, recursive functions model this same behavior. The functional <code>factorial</code> implementation shown above, for example, produces a value, say <code>F</code>, for each step, say <code>i</code>:</p>
<pre class="language-text"><code class="language-text">F₀: 1<br />F₁: 1<br />F₂: 2<br />...<br />factorial(i): iterate(Fᵢ₋₁ * i, i - 1)</code></pre>
<p>Each run of <code>iterate</code> against the result of the previous run produces a new value just <em>after</em> <em>the</em> <em>last</em> — a discrete piece of information that can viewed together with the rest on the same list. Individual program events can be similarly listed,</p>
<pre class="language-text"><code class="language-text">E₀: DEFAULT_EVENT<br />E₁: WITHDRAWAL_AMOUNT, amount:20<br />E₂: WITHDRAWAL<br />...<br />E(i): Eᵢ</code></pre>
<p>as can individual program states:</p>
<pre class="language-text"><code class="language-text">S₀: balance:100, amount:10<br />S₁: balance:100, amount:20<br />S₂: balance:80, amount:20<br />...<br />S(i): program(Sᵢ₋₁, Eᵢ)</code></pre>
<p>Each run of <code>program</code> against the result of the previous run, together with event data, produces a new value <em>after</em> the last. Yet, <code>program</code> is a timeless function.</p>
<p>With the object-oriented approach, we decompose the state of the program into objects <em>within</em> the program. Each object houses mutable state, and each piece of state may underly a mutative expression that “delineates moments in time” when evaluated.</p>
<blockquote>
<p>We modeled real-world objects with local state by computational objects with local variables. We identified time variation in the real world with time variation in the computer. We implemented the time variation of the states of the model objects in the computer with assignments to the local variables of the model objects. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5</p>
</blockquote>
<p>A collection of objects, each delineating moments in time when state may change <em>within</em> the program, embeds a simulation of time within the program. By contrast, with the functional approach, state is kept at the application perimeter and <em>functions</em> are composed together in order to transition the program from one state to another. No simulation of time can be found <em>within</em> the program; no moments can be found within the program <em>when</em> state <em>may</em> change. Rather, the program <em>provides</em> change from one state to the next (i.e. it produces state). As a result, program states represent <em>discrete</em> moments in time when state <em>has</em> changed.</p>
<blockquote>
<p>Think about the issue in terms of mathematical functions. We can describe the time-varying behavior of a quantity x as a function of time x(t). If we concentrate on x instant by instant, we think of it as a changing quantity. Yet if we concentrate on the entire time history of values, we do not emphasize change — the function itself does not change — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5</p>
</blockquote>
<p>Said another way, in object-oriented programs, we hold the identity of objects constant through change. Objects endure change as time elapses, and thus we model time. In functional programs, we forgo object identity. Change creates something new instead of altering something of old, and thus we model change directly. Change is described succinctly by functions as well as by an “entire time history,” list, log, stream, or other series of resulting states.</p>
<h3 id="reified-state">Reified State <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#reified-state">#</a></h3>
<p>Unlike object-oriented programs, functional programs reify state. State can be passed to functions, returned by functions, and generally manipulated like numbers, strings, lists, and other <a href="https://en.wikipedia.org/wiki/First-class_citizen">citizens</a> of the program. With a small addition to the ATM program, for example,</p>
<script async="" src="https://jsfiddle.net/jmilgrom/jfmea63q/embed/js,html,result/"></script>
<p>we can print (to the console) a representation of the each state of the program in sequence. This change is trivial precisely because state is a known quantity of the program and generally manipulable by program code. <code>inspectReturn</code> takes direct advantage of this quality, printing state to the console and returning state from the internal curried function.</p>
<h2 id="resolving-the-time-paradox">Resolving the Time Paradox <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#resolving-the-time-paradox">#</a></h2>
<blockquote>
<p>“No man can ever cross the same river twice.” Because what’s a river? I mean, we love this idea of objects; like there’s this thing that changes. Right? There’s no river. Right? There’s water there at one point-in-time. And another point-in-time, there’s other water there. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/AreWeThereYet.md">Are We There Yet</a>, quoting Heraclitus.</p>
</blockquote>
<p>From the perspective of a user, a functional program may appear stateful. Interact with the functional ATM program above and notice the program remembering previous encounters. On the one hand, this is not surprising. We included an imperative layer to remember previous states. Instead of decomposing the state of the program into distinct objects, like <code>bankAccount</code> and <code>withdrawalAmount</code>, we created a single global object, the <code>store</code>. On the other hand, focusing on the “object” portion of the program betrays an object-oriented predisposition. The imperative piece of the program is merely a construct used to facilitate a computation based asynchronously on another. One can even imagine a programming language where such a construct is built into the language itself, hiding any imperative implementation from the programmer’s view. In fact, such a language exists that compiles to JavaScript.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn8" id="fnref8">[8]</a></sup> In other words, it is syntax, not semantics. The semantics of the program better align with the semantics of a recursive, iterative function, having state <code>S</code> at a discrete step <code>i</code> — run the functional ATM program with the output of the previous run to produce the input for the next.</p>
<p>That a program with a functional, stateless and timeless core can maintain state is surprising, to say the least. Look around the room, bus, park or wherever you find yourself reading this sentence, and you will likely identify “a collection of distinct objects,” such as dogs, people, and trees, “whose behaviors may change over time.” Look around the functional ATM program, on the other hand, and there are no identifiable objects to be found. Yet, the program appears to have state just like any other object in the room.</p>
<p>However, the ostensible paradox dissipates when the augmentation of our conception of time extends beyond the functional program to include the rest of our physical reality.</p>
<blockquote>
<p>One way to resolve this paradox is to realize that it is the user’s temporal existence that imposes state on the system. If the user could step back from the interaction and think in terms of streams of balances rather than individual transactions, the system would appear stateless — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>Instead of viewing the <em>world</em> as the sum of its objects, each reflecting its latest state as time elapses, we may also think in terms of discrete state histories. We may interpret the dog at the park as moving in discrete steps <code>S(i)</code> to <code>S(i+1)</code>, just as we interpret the state of our functional program as moving in discrete steps <code>S(i)</code> to <code>S(i+1)</code>.</p>
<p>Consider video media. To movie scenes, we may attribute the same object-oriented semantics. Character and inanimate objects shift, interact and evolve as time elapses.</p>
<video id="metavideo" poster="https://softwarefordays.com/media/metavideoposter.gif" preload="none" style="margin:0;padding:0" width="480" controls="">
<source src="https://softwarefordays.com/media/metavideo.mp4" type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"" />
<img src="https://softwarefordays.com/media/metavideo.mp4" title="Your browser does not support the mp4 video codec." />
</video>
<p>While playing the above video, for example, we may conclude that “a cat is dancing.” Yet, videos are comprised of static frames stitched together in a certain sequence at discrete time intervals. Each frame corresponds to a state of the video at a moment in time and the frames, taken together, a time-denominated series of discrete states. The media chosen above is intentionally “meta”: the video includes a TV animation of a scene mirrored by a flip-book<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn9" id="fnref9">[9]</a></sup>, showing static frames strung together at discrete time intervals, which itself is mirrored by a flip-book in “real” life, showing static frames strung together at discrete time intervals. Take another step back to notice that the above gif media (or mp4 if your browser supports html5) being played on <em>your</em> computer is comprised of static frames, strung together at discrete time intervals.</p>
<p>There is nothing stopping you from taking another step back and interpreting the real world in which your computer currently sits as static frames, strung together at discrete time intervals. We <em>may</em> attribute normal object-oriented semantics to the above gif, concluding that “a cat is dancing.” However, we may also attribute functional semantics, concluding that “a cat has arms above its head on frame fᵢ.” At a park in the real world, we may conclude that “a dog is chasing a squirrel.” However, we may also conclude that “a dog is in the running motion behind a squirrel in the running motion on frame fᵢ.” In both cases, we may identify a time-series of states instead of objects that change over time. The functional programming paradigm can be coherently applied to world and program alike.</p>
<p>With a model for discrete time in mind, it is less surprising that functional programs can appear stateful. A user of the program may be viewed as a series of states, just like the program itself. A specific series of user states, for example,</p>
<pre class="language-text"><code class="language-text">U₀: "Open up this blog post"<br />U₁: “Select 20 option”<br />U₂: “Click withdraw”<br />...<br />U(i): Uᵢ</code></pre>
<p>directly precipitate a series of program states:</p>
<pre class="language-text"><code class="language-text">S₀: balance:100, amount:10<br />S₁: balance:100, amount:20<br />S₂: balance:80, amount:20<br />...<br />S(i): program(Sᵢ₋₁, Eᵢ)</code></pre>
<p>In both cases, pieces of static information may be listed, one <em>after</em> another. Moreover, both lists can be plotted along the same discrete timeline <code>i</code>. User interactions come in a certain order <code>U(i)</code>, triggering a run of the program function against the result of the previous run <code>S(i-1)</code> and event data <code>E(i)</code>, in order to produce <code>S(i)</code>. Our reality can be viewed as a time-series of states, just as it can be viewed as a collection of objects. Functional programming models a time-series of states, just as as object-oriented programming models objects. When the program and world <em>alike</em> can be viewed as “streams of information that flow in the system,” (Section 3) the world can flow into the program, and the program back into the world.</p>
<h2 id="addendum%3A-functional-programming-as-a-scientific-revolution">Addendum: Functional Programming as a Scientific Revolution <a class="direct-link" href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#addendum%3A-functional-programming-as-a-scientific-revolution">#</a></h2>
<blockquote>
<p>We were all object-oriented programmers at one point in time — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>Assimilation of functional semantics with any regular conception of the physical world is no easy task. Look again around the room, bus or park and you will likely still identify distinct objects that may change over time. I kicked around chapter 3 of <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> for over a year before wrapping my head around it. That we may still be experiencing disbelief at the thought of a new model for time suggests a larger game at play.</p>
<p>Dominant scientific paradigms pervade our language, on the one hand, and way of thinking, on the other.</p>
<blockquote>
<p>Scientific practice always involves the production and the explanation of generalizations about nature; those activities presuppose a language with some minimal richness; and the acquisition of such a language brings knowledge of nature with it. When the exhibit of examples is part of the process of learning terms like “motion,” ‘‘cell,‘‘ or ‘‘energy element,’’ what is acquired is knowledge of language and of the world together. <strong>On the one hand</strong>, the student learns what these terms mean, what features are relevant to attaching them to nature, what things cannot be said of them on pain of self-contradiction, and so on. <strong>On the other hand</strong>, the student learns what categories of things populate the world, what their salient features are, and something about the behavior that is and is not permitted to them. In much of language learning these two sorts of knowledge — <strong>knowledge of words and knowledge of nature</strong> — are acquired together, not really two sorts of knowledge at all, but two faces of the single coinage that a language provides. — Thomas Kuhn, <a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">What are Scientific Revolutions?</a></p>
</blockquote>
<p>As a result, a new discovery “that cannot be accommodated within the concepts in use before” may elicit surprise or even disbelief. “One cannot get from the old to the new simply by an addition to what was already known. Nor can one quite describe the new in the vocabulary of the old or vice versa.” (<a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">Thomas Kuhn</a>) Rather, in order to “make or to assimilate such a discovery one must alter the way one thinks about and describes some range of natural phenomena”; even the articulation of an observation that runs counter to the dominant paradigm can only be “formulated by altering the language with which nature [is] described.” (<a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">Thomas Kuhn</a>)</p>
<blockquote>
<p>Consider the compound sentence, “In the Ptolemaic system planets revolve about the earth; in the Copernican they revolve about the sun.” Strictly construed, that sentence is incoherent. The first occurrence of the term “planet” is Ptolemaic, the second Copernican, and the two attach to nature differently. For no univocal reading of the term “planet” is the compound sentence true. — Thomas Kuhn, <a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">What are Scientific Revolutions?</a></p>
</blockquote>
<p>Similarly, object-orientation pervades our language, on the one hand. That “objects change as time elapses” is a statement of obvious fact betrays the object-oriented presumption embedded in our language. “Object” (and “identity”), “change” (and “state”), and “time” work together to describe a coherent <em>object-oriented</em> view. On the other hand, objects orient our perception of our own physical reality.</p>
<blockquote>
<p>Modeling with objects is powerful and intuitive, largely because this matches the perception of interacting with a world of which we are part. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>Look again around the room, bus, park or wherever you find yourself reading this sentence, and you will likely identify “a collection of distinct objects,” such as dogs, people, and trees, “whose behaviors may change over time.”</p>
<p>Yet, the behavior of a functional program cannot be described in terms that attribute change to the enduring identity of objects as time elapses. And because of the dominance of object-orientation as reflected in the presumptions of our natural language, we cannot so much as describe the semantics of a functional program except through altering our language and reconstituting our physical reality. Meaningful “identity” must disappear in favor of change itself. “State” must describe the result of change instead of an object quality. “Time” must describe discrete state changes rather than any continuous dynamicness attributable to all objects.</p>
<p>No wonder the functional model may still elicit disbelief. This essay can be seen as an uphill climb against the gravity of a dominant paradigm; the functional view is perhaps expressible now, but only because of the arduous work put in above. Our natural language is not so easily distorted, violated and repurposed and our thought patterns are comorbid with our language.</p>
<blockquote>
<p>Until those changes had occurred, language itself resisted the invention and introduction of the sought after new theories. The same resistance by language is, I take it, the reason for Planck’s switch from ‘‘element’’ and ‘‘resonator’’ to ‘‘quantum’’ and ‘‘oscillator.’’ Violation or distortion of a previously unproblematic scientific language is the touchstone for revolutionary change. — Thomas Kuhn, <a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">What are Scientific Revolutions?</a></p>
</blockquote>
<p>As a result, teaching functional programming to anyone is like teaching Copernican astronomy to a Ptolemaic astronomer or quantum mechanics to a Newtonian physicist. We lack the basic language to articulate the underlying concepts. Worse still, the language we do have is endemic to a conflicting paradigm. Perhaps the disparity between the efficacy<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn10" id="fnref10">[10]</a></sup> and popularity<sup class="footnote-ref"><a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fn11" id="fnref11">[11]</a></sup> of functional programming languages is best explained in this light.</p>
<blockquote>
<p>A new scientific truth does not triumph by convincing its opponents and making them see the light, but rather because its opponents eventually die, and a new generation grows up that is familiar with it — Max Plank, <a href="https://pubs.acs.org/doi/pdf/10.1021/ed027p288.1">autobiography</a>, quoted by Thomas Kuhn, <a href="https://en.wikipedia.org/wiki/The_Structure_of_Scientific_Revolutions">The Structure of Scientific Revolutions</a></p>
</blockquote>
<p>Nevertheless, the functional view is indeed expressible as a result of the work put in above. We can see change as creating something new, instead of altering something of old, and time as a series of successive states. We can alter our language and reimagine our physical reality to support a functional view of change, state and time.</p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Traditionally, <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented programming</a> is also associated with data abstraction and code reuse through inheritance, among other patterns, that reinforce the object model. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>The creator of Clojure at it again:</p>
<blockquote>
<p>But as soon as we introduce… the idea that the value of a variable can change, a variable can no longer be simply a name. Now a variable somehow refers to a place where a value can be stored, and the value stored at this place can change.” — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref2" class="footnote-backref">↩︎</a></li>
<li id="fn3" class="footnote-item"><p>Immutability is an important part of the equation as well. We’ll cover this soon in the section titled <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#unchangeability-is-fundamental-to-functional-semantics">Unchangeability is Fundamental to Functional Programming</a>. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref3" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p>Never has the delineation between syntax and semantics been more pronounced than with <a href="https://martinfowler.com/bliki/ValueObject.html">value objects</a>, which commandeer object-oriented syntax to effect <em>non</em>-object semantics — i.e. immutable values. If not for the divergence between syntax and semantics, so-called “value objects” would be a contradiction in terms. We’ll cover the inherent mutability of objects soon in the sections titled <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#changeability-is-fundamental-to-object-semantics">Changeability is Fundamental to Object Semantics</a> and <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#%E2%80%9Cobject%E2%80%9D-names-changeability">“Object” Names Changeability</a>. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p>Contextual immutability says nothing of local variables. In fact, a variable that is reassigned within the same procedure in which it was initialized cannot impact the semantics of such procedure.</p>
<blockquote>
<p>…any mutation that is ever done to any of these is to rebind local variables…that doesn’t affect the fact that these objects are immutable from an outside perspective” Gary Bernhardt, <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">Functional Core, Imperative Shell</a></p>
</blockquote>
<p><code>decrement100</code> may be implemented with internal mutability, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">decrement100</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">let</span> r <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br /> r <span class="token operator">=</span> <span class="token number">100</span> <span class="token operator">-</span> x<span class="token punctuation">;</span><br /> <span class="token keyword">return</span> r<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">decrement100</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 80</span></code></pre>
<p>without affecting external semantics; the output of <code>decrement100</code> still depends only on the input. Even block-scoped looping constructs like <code>while</code>, <code>for</code> and <code>do</code> may be part of procedures that produce the same output provided the same input, notwithstanding reassignment of variables tracking iteration state (e.g. <code>i</code>, <code>j</code>, <code>k</code>, <code>n</code>, etc.) with every loop.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">factorial</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">let</span> total <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> total <span class="token operator">=</span> total <span class="token operator">*</span> n<span class="token punctuation">;</span><br /> n <span class="token operator">=</span> n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> total<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 6</span></code></pre>
<figcaption>The mutability of <code>f</code> and <code>n</code> does not impact the functional semantics of <code>factorial</code></figcaption>
<p><code>factorial</code> will produce the same output provided the same input. On the other hand, changeability that is internal to one procedure definition may be positioned externally to another when <a href="https://en.wikipedia.org/wiki/Nested_function">lexical procedural nesting is supported</a>. <code>balance</code>, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>is external to <code>withdraw</code> although internal to <code>makeBankAccount</code> and undermines the functional semantics of <code>withdraw</code> as a result, as discussed above. <a href="https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example/750506">Notoriously unintuitive effects</a> manifest when looping is combined with procedural nesting.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">buildCallbacks</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">items</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">const</span> callbacks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">let</span> i<span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> items<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> callbacks<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> items<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> callbacks<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> callbacks <span class="token operator">=</span> <span class="token function">buildCallbacks</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"cruel"</span><span class="token punctuation">,</span> <span class="token string">"world"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />callbacks<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token comment">// => 3</span><br />callbacks<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span><br />callbacks<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span><br />callbacks<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span></code></pre>
<figcaption>Initializing <code>let</code> above the block scopes the variable above the for-loop. Each iteration points at the same reference in memory as a result. By the time the callbacks are called, i has been updated to <code>3</code> and is outside the <code>callback</code>'s upper bound.</figcaption>
<p>As a result, comprehensive immutability can be seen as defending functional programming in the face of procedural nesting. It also appears that functional semantics could theoretically coincide with traditional looping constructs and other locally-scoped mutation so long as procedural nesting was prohibited. Nevertheless, immutability is generally considered an inseparable part of functional programming; no distinction is made in SICP and elsewhere (that I have encountered). Perhaps there is something else to be said here about lambda calculus and a more formal definition of functional programming. Or, perhaps the many benefits of nested procedures (e.g. modules, closures, etc.) so obviously outweigh the superficial “costs” of forgoing looping to even consider such crazy talk. Recursive procedures can do anything looping constructs can and without performance regressions because of tail recursion and other optimization techniques at the compiler level. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref5" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p>That two equivalent expressions may be substituted for one another without altering the meaning of the program is known as <a href="https://en.wikipedia.org/wiki/Referential_transparency">referential transparency</a>.</p>
<blockquote>
<p>A language that supports the concept that “equals can be substituted for equals” in an expression without changing the value of the expression is said to be referentially transparent — SICP Section 3.1.3</p>
</blockquote>
<a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref6" class="footnote-backref">↩︎</a></li>
<li id="fn7" class="footnote-item"><p>❤️ The original insight️ ❤️</p>
<blockquote>
<p>In general, so long as we never modify data objects, we can regard a compound data object to be precisely the totality of its pieces. For example, a rational number is determined by giving its numerator and its denominator. But this view is no longer valid in the presence of change, where a compound data object has an “identity” that is something different from the pieces of which it is composed. A bank account is still “the same” bank account even if we change the balance by making a withdrawal; conversely, we could have two different bank accounts with the same state information. This complication is a consequence, not of our programming language, but of our perception of a bank account as an object. — SICP Section 3.1.3</p>
</blockquote>
<p>Rich Hickey on the same subject:</p>
<blockquote>
<p>If it is immutable, it now taps into that definition of value we saw before. Because by being immutable we can go and take a string value, and another string value, and say: are they the same? Do they have the same magnitude? Are they talking about the same thing? Are they expressing the same specific meaning? All of those definitions of values apply to something that is not mutable. So that relative worth thing kicks in. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref7" class="footnote-backref">↩︎</a></li>
<li id="fn8" class="footnote-item"><p><a href="https://guide.elm-lang.org/">Elm</a> programs are trivially made to be stateful, notwithstanding the exclusive use of pure functions <em>and</em> the asynchrony of user interactions! This counter program</p>
<pre class="language-elm"><code class="language-elm"><span class="token import-statement"><span class="token keyword">import</span> Browser</span><br /><span class="token import-statement"><span class="token keyword">import</span> Html <span class="token keyword">exposing</span> </span><span class="token punctuation">(</span><span class="token constant">Html</span><span class="token punctuation">,</span> <span class="token hvariable">button</span><span class="token punctuation">,</span> <span class="token hvariable">div</span><span class="token punctuation">,</span> <span class="token hvariable">text</span><span class="token punctuation">)</span><br /><span class="token import-statement"><span class="token keyword">import</span> Html.Events <span class="token keyword">exposing</span> </span><span class="token punctuation">(</span><span class="token hvariable">onClick</span><span class="token punctuation">)</span><br /><br /><span class="token hvariable">main</span> <span class="token operator">=</span><br /><span class="token hvariable">Browser.sandbox</span> <span class="token punctuation">{</span> <span class="token hvariable">init</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token hvariable">update</span> <span class="token operator">=</span> <span class="token hvariable">update</span><span class="token punctuation">,</span> <span class="token hvariable">view</span> <span class="token operator">=</span> <span class="token hvariable">view</span> <span class="token punctuation">}</span><br /><br /><span class="token keyword">type</span> <span class="token constant">Msg</span> <span class="token operator">=</span> <span class="token constant">Increment</span> <span class="token operator">|</span> <span class="token constant">Decrement</span><br /><br /><span class="token hvariable">update</span> <span class="token hvariable">msg</span> <span class="token hvariable">model</span> <span class="token operator">=</span><br /><span class="token keyword">case</span> <span class="token hvariable">msg</span> <span class="token keyword">of</span><br /><span class="token constant">Increment</span> <span class="token operator">-></span><br /> <span class="token hvariable">model</span> <span class="token operator">+</span> <span class="token number">1</span><br /><br /><span class="token constant">Decrement</span> <span class="token operator">-></span><br /> <span class="token hvariable">model</span> <span class="token operator">-</span> <span class="token number">1</span><br /><br /><span class="token hvariable">view</span> <span class="token hvariable">model</span> <span class="token operator">=</span><br /><span class="token hvariable">div</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><br /><span class="token punctuation">[</span> <span class="token hvariable">button</span> <span class="token punctuation">[</span> <span class="token hvariable">onClick</span> <span class="token constant">Decrement</span> <span class="token punctuation">]</span> <span class="token punctuation">[</span> <span class="token hvariable">text</span> <span class="token string">"-"</span> <span class="token punctuation">]</span><br /><span class="token punctuation">,</span> <span class="token hvariable">div</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">[</span> <span class="token hvariable">text</span> <span class="token punctuation">(</span><span class="token hvariable">String.fromInt</span> <span class="token hvariable">model</span><span class="token punctuation">)</span> <span class="token punctuation">]</span><br /><span class="token punctuation">,</span> <span class="token hvariable">button</span> <span class="token punctuation">[</span> <span class="token hvariable">onClick</span> <span class="token constant">Increment</span> <span class="token punctuation">]</span> <span class="token punctuation">[</span> <span class="token hvariable">text</span> <span class="token string">"+"</span> <span class="token punctuation">]</span><br /><span class="token punctuation">]</span></code></pre>
<p>can be seen <a href="https://elm-lang.org/examples/buttons">here</a> tracking counter state, even though a user may of course click the counter buttons asynchronously. Like garbage collection in JavaScript, Elm hides any imperative code dedicated to communication between asynchronous scripts from the programmer’s view. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref8" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn9" class="footnote-item"><p>A flip-book <a href="https://softwareengineering.stackexchange.com/a/245409/369472">has been suggested</a> as a valuable mental model for state in functional programming <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref9" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn10" class="footnote-item"><p>There are many advantages to functional programming. Programs that deal with mutation are “drastically more difficult” to reason about than ones that do not.</p>
<blockquote>
<p>Referential transparency is violated when we include set! [i.e. assignment operations] in our computer language. This makes it tricky to determine when we can simplify expressions by substituting equivalent expressions. Consequently, reasoning about programs that use assignment becomes drastically more difficult — SICP Section 3.1.3</p>
</blockquote>
<p>In particular, functions avoid <a href="https://www.yegor256.com/2015/12/08/temporal-coupling-between-method-calls.html">temporal coupling</a> since there is no time,</p>
<blockquote>
<p>In general, programming with assignment forces us to carefully consider the relative orders of the assignments to make sure that each statement is using the correct version of the variables that have been changed. This issue simply does not arise in functional programs. — SICP Section 3.1.3</p>
</blockquote>
<p>and dramatically reduce debugging and unit testing complexity since there is no meaningful context.</p>
<blockquote>
<p>“And that is the problem with places. You have this sort of global state that you have to reproduce in order to debug a field problem. That is very very tough.” Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>Reified state couches in writing what must otherwise live in a programmer’s heads — each member of a team can read a function signature instead of building up (hopefully) the same working memory for each object. Couching state in language makes it accessible to static language analysis tools. <a href="https://blog.ploeh.dk/2019/07/01/yes-silver-bullet/#bd2d47d8dac2401e936ca7902bc9109d">A compiler may exhaustively permute the set of application states</a> without actually running manually-written (exhaust<em>ing</em>) unit tests. Functional programs are more easily parallelized since they are just functions with no internal model for time.</p>
<blockquote>
<p>Unfortunately, the complexities introduced by assignment become even more problematic in the presence of concurrency. — SICP Section 3.4</p>
</blockquote>
<p>These advantages have been known for decades. John Backus “gave high visibility to functional programming” (SICP Section 3.5.5; also see Simon Peyton-Jones, <a href="https://www.youtube.com/watch?v=re96UgMk6GQ">Escape from the ivory tower: the Haskel journey</a>) through his <a href="https://www.thocp.net/biographies/papers/backus_turingaward_lecture.pdf">Turing Award lecture</a> in 1978, seven years before the creation of <a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> and thirteen before <a href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref10" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn11" class="footnote-item"><p>The <a href="https://www.tiobe.com/tiobe-index/">20 most popular languages</a> are predominantly imperative or object-oriented. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#fnref11" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
Hello, World2020-06-21T00:00:00Zhttps://softwarefordays.com/post/hello-world/<p>Had a good run using Medium as my blogging platform. It served as a “google doc,” a web-based document editor with automatic content uploads, and a content-management system, publishing drafts that correspond one-to-one in appearance with the published form. Medium was seemingly optimized for a reader-writer experience, including clean styling out-of-the-box, draft-sharing, and gist and other code-sharing embeds. Some of these features remain. However, over the last year, the reader-writer experience began to deteriorate. Now, draft sharing is login-gated. Content recommendation surfaces click-bait’y titles instead of interest areas (e.g. software). Finally, anchor tags break ostensibly because of “become a member” prompts in the page header, the anvil that broke this camel’s back.</p>
<p>So, I’ve moved to a self-managed website.</p>
<h2 id="theme">Theme <a class="direct-link" href="https://softwarefordays.com/post/hello-world/#theme">#</a></h2>
<p>The primary colors, link interactions and list layout were adapted from <a href="https://tonsky.me/">this beautifully simple blog</a> by <a href="https://twitter.com/nikitonsky">Niki Tonsky</a>. The serif font and sans-serif title combination was inspired by <a href="https://medium.com/">Medium</a>. The purple and gold that can be seen draping the “Software for Days” badge in championship appeal are indeed the <a href="https://teamcolorcodes.com/los-angeles-lakers-color-codes/">purple and gold</a> of the venerable Los Angeles Lakers organization.</p>
<h2 id="build-tech">Build Tech <a class="direct-link" href="https://softwarefordays.com/post/hello-world/#build-tech">#</a></h2>
<p>This site is statically generated; each page of HTML, including this one, is generated from source files at build time, in advance of any request for this page.</p>
<p>Posts are written in markdown and converted to HTML using <a href="https://github.com/markdown-it/markdown-it">markdown-it</a> in combination with the templating engine <a href="https://liquidjs.com/">liquidjs</a>. This post, for example, currently looks like this, as I write:</p>
<pre class="language-md"><code class="language-md"><span class="token front-matter-block"><span class="token punctuation">---</span><br /><span class="token front-matter yaml language-yaml">title: Hello, World<br />date: 2020-06-21<br />tags: post<br />layout: layouts/post.liquid</span><br /><span class="token punctuation">---</span></span><br /><br />Had a good run using Medium as my blogging platform. It served as my "google doc," a web-based document editor with automatic content uploads, and my content-management system, publishing drafts that correspond one-to-one in appearance with the published form. Medium was seemingly optimized for a reader-writer experience, including clean out-of-the-box styling, draft-sharing, and gist and other code-sharing embeds. Some of these features remain. However, over the last year, the reader-writer experience began to deteriorate. Now, draft sharing is login-gated. Content recommendation surfaces click-bait'y titles instead of interest areas (e.g. software). Finally, anchor tags break ostensibly because of "become a member" prompts in the page header, the anvil that broke this camel's back. <br /><br />So, I've moved to a self-managed website.<br /><br /><span class="token title important"><span class="token punctuation">##</span> Theme</span><br /><br />The primary colors, link interactions and list layout were adapted from <span class="token url">[<span class="token content">this beautifully simple blog</span>](<span class="token url">https://tonsky.me/</span>)</span> by <span class="token url">[<span class="token content">Niki Tonsky</span>](<span class="token url">https://twitter.com/nikitonsky</span>)</span>. The serif font and sans-serif title combination was inspired by <span class="token url">[<span class="token content">Medium</span>](<span class="token url">https://medium.com</span>)</span>. The purple and gold colors that can be seen in the "Software for Days" badge and elsewhere are the championship colors of <span class="token url">[<span class="token content">Los Angeles Lakers Purple and Gold</span>](<span class="token url">https://teamcolorcodes.com/los-angeles-lakers-color-codes/</span>)</span>. <br /><br /><span class="token title important"><span class="token punctuation">##</span> Build Tech</span><br /><br />This site is statically generated; each page of HTML, including this one, is generated from sources files at build time, in advance of any request for this page.<br /><br />Posts are written in markdown and converted to HTML using <span class="token url">[<span class="token content">markdown-it</span>](<span class="token url">https://github.com/markdown-it/markdown-it</span>)</span> in combination with the templating engine <span class="token url">[<span class="token content">liquidjs</span>](<span class="token url">https://liquidjs.com/</span>)</span>. This post, for example, currently looks like this as I write</code></pre>
<figcaption>Partial source of the generated HTML file that you are currently viewing <span class="emoji">😳</span></figcaption>
<p><code>markdown-it</code> converts the above markdown file into HTML. <code>liquidjs</code> is directed by the XML header at the top of such file to embed the generated HTML file inside <code>layouts/post.liquid</code> template,</p>
<pre class="language-html"><code class="language-html">---<br />layout: layouts/layout.liquid<br />templateClass: post<br />---<br /><br /><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span>{{ title }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></span></span><br /><br />{{ content }}<br /><br /><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>footer<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><br /> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>badge<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>← Home<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span><br /><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span></code></pre>
<p>resulting in the page of HTML you are viewing.</p>
<p>This process is orchestrated by <a href="https://www.11ty.dev/">llty</a>, a “a simpler static site generator,” as advertised. The command <code>yarn eleventy --serve</code> tells <code>eleventy</code> to read this config file</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> syntaxHighlight <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"@11ty/eleventy-plugin-syntaxhighlight"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> markdownIt <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"markdown-it"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> markdownItAnchor <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"markdown-it-anchor"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> markdownItFootnote <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"markdown-it-footnote"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> sourceDirectory <span class="token operator">=</span> <span class="token string">"src"</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> md <span class="token operator">=</span> <span class="token function">markdownIt</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token literal-property property">html</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">linkify</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">typographer</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />md<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>markdownItAnchor<span class="token punctuation">,</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">permalink</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">permalinkClass</span><span class="token operator">:</span> <span class="token string">"direct-link"</span><span class="token punctuation">,</span><br /> <span class="token literal-property property">permalinkSymbol</span><span class="token operator">:</span> <span class="token string">"#"</span><span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>markdownItFootnote<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">eleventyConfig</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> eleventyConfig<span class="token punctuation">.</span><span class="token function">addPassthroughCopy</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>sourceDirectory<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/media</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> eleventyConfig<span class="token punctuation">.</span><span class="token function">addPassthroughCopy</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>sourceDirectory<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/css</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /> eleventyConfig<span class="token punctuation">.</span><span class="token function">addPlugin</span><span class="token punctuation">(</span>syntaxHighlight<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /> eleventyConfig<span class="token punctuation">.</span><span class="token function">setLibrary</span><span class="token punctuation">(</span><span class="token string">"md"</span><span class="token punctuation">,</span> md<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /> <span class="token keyword">return</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">dir</span><span class="token operator">:</span> <span class="token punctuation">{</span><br /> <span class="token literal-property property">input</span><span class="token operator">:</span> sourceDirectory<span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>and generate a static site</p>
<img src="https://softwarefordays.com/media/static-site.png" />
<p>from the source files specified in the same directory.</p>
<p>You may notice in the above config file that <code>markdown-it</code> manifests ultimately as a plugin into <code>eleventy</code>’s build; <code>liquidjs</code> isn’t mentioned explicitly only because it is used by <code>eleventy</code> by default.</p>
<p>Additional technologies plugged into the <code>eleventy</code> build include:</p>
<ol>
<li>
<p><a href="https://github.com/11ty/eleventy-plugin-syntaxhighlight">@11ty/eleventy-plugin-syntaxhighlight</a> converts code blocks into semantic HTML that is compatible with <a href="https://prismjs.com/">prismjs</a> css. As a result, the syntax-highlighting-ready HTML you see above is generated at build time.</p>
</li>
<li>
<p>Automatic anchor tag generation with <a href="https://github.com/valeriangalliat/markdown-it-anchor">markdown-it-anchor</a>.</p>
</li>
<li>
<p>And my personal favorite, automatic footnote anchor tag generation with <a href="https://github.com/markdown-it/markdown-it-footnote">markdown-it-footnote</a>.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/hello-world/#fn1" id="fnref1">[1]</a></sup></p>
</li>
</ol>
<p>The complete repository can be found <a href="https://github.com/jbmilgrom/blogg">on github</a>.</p>
<h2 id="medium-migration-tech">Medium Migration Tech <a class="direct-link" href="https://softwarefordays.com/post/hello-world/#medium-migration-tech">#</a></h2>
<p>The migration off of Medium was kick-started by <a href="https://github.com/xdamman/mediumexporter">mediumexporter</a>, which downloads and converts Medium HTML into markdown.</p>
<h2 id="deploy%2Fhosting-tech">Deploy/Hosting Tech <a class="direct-link" href="https://softwarefordays.com/post/hello-world/#deploy%2Fhosting-tech">#</a></h2>
<p>Wow this was easier than expected. With <a href="https://www.netlify.com/">netlify</a>, I have continuous deployment, despite no configuration or set up. I’m not exaggerating when I say it was as easy as signing up, connecting my github account, selecting a specific repo (in this case, <a href="https://github.com/jbmilgrom/blogg">blogg</a>), and… that’s it. A <a href="https://happy-dijkstra-744386.netlify.app/">domain</a> was automatically generated. Now, all changes pushed to <code>blogg</code> result in a fresh build and automatic deploy. <a href="https://pages.github.com/">GitHub Pages</a> provides something similar. However, I would’ve had to create two repositories, one for my source files and one for the generated site, and manually copy files from one to the other. Not the worst thing in the world. However, with netlify, I also get SSL certificate and domain name management for free and analytics for a monthly fee.</p>
<h2 id="how-i-feel-now">How I Feel Now <a class="direct-link" href="https://softwarefordays.com/post/hello-world/#how-i-feel-now">#</a></h2>
<p>Great.</p>
<p>Medium does (did?) a great job at providing managed-blog services. However, it goes without saying that no finite <em>product</em> can serve the idiosyncratic needs of one person better than that person. Ultimately, the deterioration in Medium’s services forced what would always have been a beneficial move. I now have complete control over the development, presentation and distribution of my content - if Lakers colors aren’t enough, well there’s always automatic footnote generation with bi-directional anchor tag navigation for the obvious win.</p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>How cool is this? I get footnote generation and bi-directional anchor tag navigation from just this markdown:</p>
<pre class="language-md"><code class="language-md"> <span class="token list punctuation">-</span> and my personal favorite, automatic footnote anchor tag generation with <span class="token url">[<span class="token content">markdown-it-footnote</span>](<span class="token url">https://github.com/markdown-it/markdown-it-footnote</span>)</span>[^1]<br /> <span class="token url-reference url"><span class="token punctuation">[</span><span class="token variable">^1</span><span class="token punctuation">]</span><span class="token punctuation">:</span> How</span> cool is this? I get footnote generation and bi-directional anchor tag navigation form just this markdown:</code></pre>
<a href="https://softwarefordays.com/post/hello-world/#fnref1" class="footnote-backref">↩︎</a></li>
</ol>
</section>
Functional Programming as a Scientific Revolution2020-12-24T00:00:00Zhttps://softwarefordays.com/post/fp-as-a-scientific-revolution/<p class="introductory-caveat">Excerpted from <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/">Functional Programming and the Semantics of Change, State & Time</a> because sometimes you need to see the waterfall to want to take the hike.</p>
<blockquote>
<p>We were all object-oriented programmers at one point in time — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>Assimilation of functional semantics with any regular conception of the physical world is no easy task. Look again around the room, bus or park and you will likely still identify distinct objects that may change over time. I kicked around chapter 3 of <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> for over a year before wrapping my head around it. That we may still be experiencing disbelief at the thought of a new model for time suggests a larger game at play.</p>
<p>Dominant scientific paradigms pervade our language, on the one hand, and way of thinking, on the other.</p>
<blockquote>
<p>Scientific practice always involves the production and the explanation of generalizations about nature; those activities presuppose a language with some minimal richness; and the acquisition of such a language brings knowledge of nature with it. When the exhibit of examples is part of the process of learning terms like “motion,” ‘‘cell,‘‘ or ‘‘energy element,’’ what is acquired is knowledge of language and of the world together. <strong>On the one hand</strong>, the student learns what these terms mean, what features are relevant to attaching them to nature, what things cannot be said of them on pain of self-contradiction, and so on. <strong>On the other hand</strong>, the student learns what categories of things populate the world, what their salient features are, and something about the behavior that is and is not permitted to them. In much of language learning these two sorts of knowledge — <strong>knowledge of words and knowledge of nature</strong> — are acquired together, not really two sorts of knowledge at all, but two faces of the single coinage that a language provides. — Thomas Kuhn, <a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">What are Scientific Revolutions?</a></p>
</blockquote>
<p>As a result, a new discovery “that cannot be accommodated within the concepts in use before” may elicit surprise or even disbelief. “One cannot get from the old to the new simply by an addition to what was already known. Nor can one quite describe the new in the vocabulary of the old or vice versa.” (<a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">Thomas Kuhn</a>) Rather, in order to “make or to assimilate such a discovery one must alter the way one thinks about and describes some range of natural phenomena”; even the articulation of an observation that runs counter to the dominant paradigm can only be “formulated by altering the language with which nature [is] described.” (<a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">Thomas Kuhn</a>)</p>
<blockquote>
<p>Consider the compound sentence, “In the Ptolemaic system planets revolve about the earth; in the Copernican they revolve about the sun.” Strictly construed, that sentence is incoherent. The first occurrence of the term “planet” is Ptolemaic, the second Copernican, and the two attach to nature differently. For no univocal reading of the term “planet” is the compound sentence true. — Thomas Kuhn, <a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">What are Scientific Revolutions?</a></p>
</blockquote>
<p>Similarly, object-orientation pervades our language, on the one hand. That “objects change as time elapses” is a statement of obvious fact betrays the object-oriented presumption embedded in our language. “Object” (and “identity”), “change” (and “state”), and “time” work together to describe a coherent <em>object-oriented</em> view. On the other hand, objects orient our perception of our own physical reality.</p>
<blockquote>
<p>Modeling with objects is powerful and intuitive, largely because this matches the perception of interacting with a world of which we are part. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>Look again around the room, bus, park or wherever you find yourself reading this sentence, and you will likely identify “a collection of distinct objects,” such as dogs, people, and trees, “whose behaviors may change over time.”</p>
<p>Yet, the behavior of a functional program cannot be described in terms that attribute change to the enduring identity of objects as time elapses. And because of the dominance of object-orientation as reflected in the presumptions of our natural language, we cannot so much as describe the semantics of a functional program except through altering our language and reconstituting our physical reality. Meaningful “identity” must disappear in favor of change itself. “State” must describe the result of change instead of an object quality. “Time” must describe discrete state changes rather than any continuous dynamicness attributable to all objects.</p>
<p>No wonder the functional model may still elicit disbelief. <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time">This essay</a> can be seen as an uphill climb against the gravity of a dominant paradigm; the functional view is perhaps expressible now, but only because of <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time">the arduous work put in above</a>. Our natural language is not so easily distorted, violated and repurposed and our thought patterns are comorbid with our language.</p>
<blockquote>
<p>Until those changes had occurred, language itself resisted the invention and introduction of the sought after new theories. The same resistance by language is, I take it, the reason for Planck’s switch from ‘‘element’’ and ‘‘resonator’’ to ‘‘quantum’’ and ‘‘oscillator.’’ Violation or distortion of a previously unproblematic scientific language is the touchstone for revolutionary change. — Thomas Kuhn, <a href="http://sites.fas.harvard.edu/~hsci161/Sci._Rev._Reader/12_S6_Kuhn.pdf">What are Scientific Revolutions?</a></p>
</blockquote>
<p>As a result, teaching functional programming to anyone is like teaching Copernican astronomy to a Ptolemaic astronomer or quantum mechanics to a Newtonian physicist. We lack the basic language to articulate the underlying concepts. Worse still, the language we do have is endemic to a conflicting paradigm. Perhaps the disparity between the efficacy<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-as-a-scientific-revolution/#fn1" id="fnref1">[1]</a></sup> and popularity<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-as-a-scientific-revolution/#fn2" id="fnref2">[2]</a></sup> of functional programming languages is best explained in this light.</p>
<blockquote>
<p>A new scientific truth does not triumph by convincing its opponents and making them see the light, but rather because its opponents eventually die, and a new generation grows up that is familiar with it — Max Plank, <a href="https://pubs.acs.org/doi/pdf/10.1021/ed027p288.1">autobiography</a>, quoted by Thomas Kuhn, <a href="https://en.wikipedia.org/wiki/The_Structure_of_Scientific_Revolutions">The Structure of Scientific Revolutions</a></p>
</blockquote>
<p>Nevertheless, the functional view is indeed expressible as a result of the <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time">work put in above</a>. We can see change as creating something new, instead of altering something of old, and time as a series of successive states. We can alter our language and reimagine our physical reality to support a functional view of change, state and time.</p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>There are many advantages to functional programming. Programs that deal with mutation are “drastically more difficult” to reason about than ones that do not.</p>
<blockquote>
<p>Referential transparency is violated when we include set! [i.e. assignment operations] in our computer language. This makes it tricky to determine when we can simplify expressions by substituting equivalent expressions. Consequently, reasoning about programs that use assignment becomes drastically more difficult — SICP Section 3.1.3</p>
</blockquote>
<p>In particular, functions avoid <a href="https://www.yegor256.com/2015/12/08/temporal-coupling-between-method-calls.html">temporal coupling</a> since there is no time,</p>
<blockquote>
<p>In general, programming with assignment forces us to carefully consider the relative orders of the assignments to make sure that each statement is using the correct version of the variables that have been changed. This issue simply does not arise in functional programs. — SICP Section 3.1.3</p>
</blockquote>
<p>and dramatically reduce debugging and unit testing complexity since there is no meaningful context.</p>
<blockquote>
<p>“And that is the problem with places. You have this sort of global state that you have to reproduce in order to debug a field problem. That is very very tough.” Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>Reified state couches in writing what must otherwise live in a programmer’s heads — each member of a team can read a function signature instead of building up (hopefully) the same working memory for each object. Couching state in language makes it accessible to static language analysis tools. <a href="https://blog.ploeh.dk/2019/07/01/yes-silver-bullet/#bd2d47d8dac2401e936ca7902bc9109d">A compiler may exhaustively permute the set of application states</a> without actually running manually-written (exhaust<em>ing</em>) unit tests. Functional programs are more easily parallelized since they are just functions with no internal model for time.</p>
<blockquote>
<p>Unfortunately, the complexities introduced by assignment become even more problematic in the presence of concurrency. — SICP Section 3.4</p>
</blockquote>
<p>These advantages have been known for decades. John Backus “gave high visibility to functional programming” (SICP Section 3.5.5; also see Simon Peyton-Jones, <a href="https://www.youtube.com/watch?v=re96UgMk6GQ">Escape from the ivory tower: the Haskel journey</a>) through his <a href="https://www.thocp.net/biographies/papers/backus_turingaward_lecture.pdf">Turing Award lecture</a> in 1978, seven years before the creation of <a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> and thirteen before <a href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>. <a href="https://softwarefordays.com/post/fp-as-a-scientific-revolution/#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>The <a href="https://www.tiobe.com/tiobe-index/">20 most popular languages</a> are predominantly imperative or object-oriented. <a href="https://softwarefordays.com/post/fp-as-a-scientific-revolution/#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
Resolving the Time Paradox Implied by Functional Programs2020-12-27T00:00:00Zhttps://softwarefordays.com/post/resolving-the-fp-time-paradox/<p class="introductory-caveat">Excerpted from <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#resolving-the-time-paradox">Functional Programming and the Semantics of Change, State & Time</a>.</p>
<blockquote>
<p>“No man can ever cross the same river twice.” Because what’s a river? I mean, we love this idea of objects; like there’s this thing that changes. Right? There’s no river. Right? There’s water there at one point-in-time. And another point-in-time, there’s other water there. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/AreWeThereYet.md">Are We There Yet</a>, quoting Heraclitus.</p>
</blockquote>
<p>From the perspective of a user, a functional program may appear stateful. Interact with <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#stateful-functional-programs">the functional ATM program above</a> and notice the program remembering previous encounters. On the one hand, this is not surprising. We included an imperative layer to remember previous states. Instead of decomposing the state of the program into distinct objects, like <code>bankAccount</code> and <code>withdrawalAmount</code>, we created a single global object, the <code>store</code>. On the other hand, focusing on the “object” portion of the program betrays an object-oriented predisposition. The imperative piece of the program is merely a construct used to facilitate a computation based asynchronously on another. One can even imagine a programming language where such a construct is built into the language itself, hiding any imperative implementation from the programmer’s view. In fact, such a language exists that compiles to JavaScript.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/resolving-the-fp-time-paradox/#fn1" id="fnref1">[1]</a></sup> In other words, it is syntax, not semantics. The semantics of the program better align with the semantics of a recursive, iterative function, having state <code>S</code> at a discrete step <code>i</code> — run the functional ATM program with the output of the previous run to produce the input for the next.</p>
<p>That a program with a functional, stateless and timeless core can maintain state is surprising, to say the least. Look around the room, bus, park or wherever you find yourself reading this sentence, and you will likely identify “a collection of distinct objects,” such as dogs, people, and trees, “whose behaviors may change over time.” (<a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a>, Section 3) Look around the functional ATM program, on the other hand, and there are no identifiable objects to be found. Yet, the program appears to have state just like any other object in the room.</p>
<p>However, the ostensible paradox dissipates when the augmentation of our conception of time extends beyond the functional program to include the rest of our physical reality.</p>
<blockquote>
<p>One way to resolve this paradox is to realize that it is the user’s temporal existence that imposes state on the system. If the user could step back from the interaction and think in terms of streams of balances rather than individual transactions, the system would appear stateless — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>Instead of viewing the <em>world</em> as the sum of its objects, each reflecting its latest state as time elapses, we may also think in terms of discrete state histories. We may interpret the dog at the park as moving in discrete steps <code>S(i)</code> to <code>S(i+1)</code>, just as we interpret the state of our functional program as moving in discrete steps <code>S(i)</code> to <code>S(i+1)</code>.</p>
<p>Consider video media. To movie scenes, we may attribute the same object-oriented semantics. Character and inanimate objects shift, interact and evolve as time elapses.</p>
<video id="metavideo" poster="https://softwarefordays.com/media/metavideoposter.gif" preload="none" style="margin:0;padding:0" width="480" controls="">
<source src="https://softwarefordays.com/media/metavideo.mp4" type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"" />
<img src="https://softwarefordays.com/media/metavideo.mp4" title="Your browser does not support the mp4 video codec." />
</video>
<p>While playing the above video, for example, we may conclude that “a cat is dancing.” Yet, videos are comprised of static frames stitched together in a certain sequence at discrete time intervals. Each frame corresponds to a state of the video at a moment in time and the frames, taken together, a time-denominated series of discrete states. The media chosen above is intentionally “meta”: the video includes a TV animation of a scene mirrored by a flip-book<sup class="footnote-ref"><a href="https://softwarefordays.com/post/resolving-the-fp-time-paradox/#fn2" id="fnref2">[2]</a></sup>, showing static frames strung together at discrete time intervals, which itself is mirrored by a flip-book in “real” life, showing static frames strung together at discrete time intervals. Take another step back to notice that the above gif media (or mp4 if your browser supports html5) being played on <em>your</em> computer is comprised of static frames, strung together at discrete time intervals.</p>
<p>There is nothing stopping you from taking another step back and interpreting the real world in which your computer currently sits as static frames, strung together at discrete time intervals. We <em>may</em> attribute normal object-oriented semantics to the above gif, concluding that “a cat is dancing.” However, we may also attribute functional semantics, concluding that “a cat has arms above its head on frame fᵢ.” At a park in the real world, we may conclude that “a dog is chasing a squirrel.” However, we may also conclude that “a dog is in the running motion behind a squirrel in the running motion on frame fᵢ.” In both cases, we may identify a time-series of states instead of objects that change over time. The functional programming paradigm can be coherently applied to world and program alike.</p>
<p>With a model for discrete time in mind, it is less surprising that functional programs can appear stateful. A user of the program may be viewed as a series of states, just like the program itself. A specific series of user states, for example,</p>
<pre class="language-text"><code class="language-text">U₀: "Open up this blog post"<br />U₁: “Select 20 option”<br />U₂: “Click withdraw”<br />...<br />U(i): Uᵢ</code></pre>
<p>directly precipitate a series of program states:</p>
<pre class="language-text"><code class="language-text">S₀: balance:100, amount:10<br />S₁: balance:100, amount:20<br />S₂: balance:80, amount:20<br />...<br />S(i): program(Sᵢ₋₁, Eᵢ)</code></pre>
<p>In both cases, pieces of static information may be listed, one <em>after</em> another. Moreover, both lists can be plotted along the same discrete timeline <code>i</code>. User interactions come in a certain order <code>U(i)</code>, triggering a run of the program function against the result of the previous run <code>S(i-1)</code> and event data <code>E(i)</code>, in order to produce <code>S(i)</code>. Our reality can be viewed as a time-series of states, just as it can be viewed as a collection of objects. Functional programming models a time-series of states, just as as object-oriented programming models objects. When the program and world <em>alike</em> can be viewed as “streams of information that flow in the system,” (<a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3) the world can flow into the program, and the program back into the world.</p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><a href="https://guide.elm-lang.org/">Elm</a> programs are trivially made to be stateful, notwithstanding the exclusive use of pure functions <em>and</em> the asynchrony of user interactions! This counter program</p>
<pre class="language-elm"><code class="language-elm"><span class="token import-statement"><span class="token keyword">import</span> Browser</span><br /><span class="token import-statement"><span class="token keyword">import</span> Html <span class="token keyword">exposing</span> </span><span class="token punctuation">(</span><span class="token constant">Html</span><span class="token punctuation">,</span> <span class="token hvariable">button</span><span class="token punctuation">,</span> <span class="token hvariable">div</span><span class="token punctuation">,</span> <span class="token hvariable">text</span><span class="token punctuation">)</span><br /><span class="token import-statement"><span class="token keyword">import</span> Html.Events <span class="token keyword">exposing</span> </span><span class="token punctuation">(</span><span class="token hvariable">onClick</span><span class="token punctuation">)</span><br /><br /><span class="token hvariable">main</span> <span class="token operator">=</span><br /><span class="token hvariable">Browser.sandbox</span> <span class="token punctuation">{</span> <span class="token hvariable">init</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token hvariable">update</span> <span class="token operator">=</span> <span class="token hvariable">update</span><span class="token punctuation">,</span> <span class="token hvariable">view</span> <span class="token operator">=</span> <span class="token hvariable">view</span> <span class="token punctuation">}</span><br /><br /><span class="token keyword">type</span> <span class="token constant">Msg</span> <span class="token operator">=</span> <span class="token constant">Increment</span> <span class="token operator">|</span> <span class="token constant">Decrement</span><br /><br /><span class="token hvariable">update</span> <span class="token hvariable">msg</span> <span class="token hvariable">model</span> <span class="token operator">=</span><br /><span class="token keyword">case</span> <span class="token hvariable">msg</span> <span class="token keyword">of</span><br /><span class="token constant">Increment</span> <span class="token operator">-></span><br /> <span class="token hvariable">model</span> <span class="token operator">+</span> <span class="token number">1</span><br /><br /><span class="token constant">Decrement</span> <span class="token operator">-></span><br /> <span class="token hvariable">model</span> <span class="token operator">-</span> <span class="token number">1</span><br /><br /><span class="token hvariable">view</span> <span class="token hvariable">model</span> <span class="token operator">=</span><br /><span class="token hvariable">div</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><br /><span class="token punctuation">[</span> <span class="token hvariable">button</span> <span class="token punctuation">[</span> <span class="token hvariable">onClick</span> <span class="token constant">Decrement</span> <span class="token punctuation">]</span> <span class="token punctuation">[</span> <span class="token hvariable">text</span> <span class="token string">"-"</span> <span class="token punctuation">]</span><br /><span class="token punctuation">,</span> <span class="token hvariable">div</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">[</span> <span class="token hvariable">text</span> <span class="token punctuation">(</span><span class="token hvariable">String.fromInt</span> <span class="token hvariable">model</span><span class="token punctuation">)</span> <span class="token punctuation">]</span><br /><span class="token punctuation">,</span> <span class="token hvariable">button</span> <span class="token punctuation">[</span> <span class="token hvariable">onClick</span> <span class="token constant">Increment</span> <span class="token punctuation">]</span> <span class="token punctuation">[</span> <span class="token hvariable">text</span> <span class="token string">"+"</span> <span class="token punctuation">]</span><br /><span class="token punctuation">]</span></code></pre>
<p>can be seen <a href="https://elm-lang.org/examples/buttons">here</a> tracking counter state, even though a user may of course click the counter buttons asynchronously. Like garbage collection in JavaScript, Elm hides any imperative code dedicated to communication between asynchronous scripts from the programmer’s view. <a href="https://softwarefordays.com/post/resolving-the-fp-time-paradox/#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>A flip-book <a href="https://softwareengineering.stackexchange.com/a/245409/369472">has been suggested</a> as a valuable mental model for state in functional programming <a href="https://softwarefordays.com/post/resolving-the-fp-time-paradox/#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
Using JavaScript to Implement the Same Stateful Program in both Object-Oriented and Functional Styles2021-01-05T00:00:00Zhttps://softwarefordays.com/post/paradigm-comparison-js/<p class="introductory-caveat">Excerpted from <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#now%2C-what-about-programs">Functional Programming and the Semantics of Change, State & Time</a>.</p>
<p>Some real programs are designed to produce output based solely on input. Ideally, compilers output the same binaries provided the same input files, for example. More frequently, however, programs require state, and user input <em>together</em> with the current state of the program determine the next state or output of the program. Such is the case with our ATM example, where the current balance is crucial to calculating any subsequent balance post withdrawal. To be generally useful, either paradigm must include a model for state, and perhaps time, even if composed entirely of well-behaved state<em>less</em> mathematical functions.</p>
<h2 id="stateful-object-oriented-programs">Stateful Object-Oriented Programs <a class="direct-link" href="https://softwarefordays.com/post/paradigm-comparison-js/#stateful-object-oriented-programs">#</a></h2>
<blockquote>
<p>Modeling with objects is powerful and intuitive, largely because this matches the perception of interacting with a world of which we are part. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>Creating stateful object-oriented programs is straightforward. An ATM program, for example, that allows the user to set a “withdrawal amount” and effect a withdraw,</p>
<script async="" src="https://jsfiddle.net/jmilgrom/notc93Lv/embed/"></script>
<p>decomposes naturally into <code>withdrawalAmount</code> and and <code>bankAccount</code> objects, representing the chosen amount to be withdrawn and the user account underlying the session, respectively. The withdrawal amounts are incorporated by and read from <code>withdrawalAmount</code>. Withdrawals are incorporated by, and balance confirmations are read from, <code>bankAccount</code>. The current balance and the amount to potentially withdraw — the state of the program — are reflected directly by the state of <code>bankAccount</code> and <code>withdrawalAmount</code> — the state of its composite objects.</p>
<h3 id="time">Time <a class="direct-link" href="https://softwarefordays.com/post/paradigm-comparison-js/#time">#</a></h3>
<blockquote>
<p>If we wish to write programs that model this kind of natural decomposition in our world (as we see it from our viewpoint as a part of that world) with structures in our computer, we make computational objects that… must change with time. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5.5</p>
</blockquote>
<p>When we model objects, we also model time. Objects change — as we discussed, the notion of an “object,” having parts that change without changing the identity of the whole, articulates this ability. The flip-side to changing objects is time. Since objects change, <em>when</em> an object is examined is vital to the examination, it goes without saying.</p>
<p>Look no further than the object representations of our computer programs. The “having parts that can change without changing the identity of the whole” quality of <code>bankAccount</code> in our ATM program, for example, is implemented by <code>withdraw</code>.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token operator">...</span><br /><span class="token punctuation">}</span></code></pre>
<p>Underlying <code>withdraw</code> lies a mutable <code>balance</code> binding that may be assigned new values. Calls to <code>withdraw</code> change the associated balance of <code>bankAccount</code> as a side-effect, without altering the identity of <code>bankAccount</code>, by design.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>The flip-side to changing objects is time. In addition to changing the associated balance, any call to <code>withdraw</code> also “delineates moments in time” <em>when</em> <code>balance</code> <em>may</em> change. Whether <code>bankAccount.checkBalance()</code> resolves to <code>100</code> or <code>80</code> “depends not only on the expression itself, but also on whether the evaluation occurs before or after these moments.” As a result, by modeling objects, “we are forced to admit time into our computational models.” (<a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.4)</p>
<h3 id="stateful">Stateful <a class="direct-link" href="https://softwarefordays.com/post/paradigm-comparison-js/#stateful">#</a></h3>
<p>Object-oriented programming reifies objects. Further, objects can be composed in other objects, received by object methods, and generally manipulated like numbers, strings and other <a href="https://en.wikipedia.org/wiki/First-class_citizen">first-class citizens</a> of the program. No such affordances are made for state, on the other hand. State is a quality (i.e. “stateful” or “statefulness”) adjacent to objects. Unlike the objects to which they belong, state can only be <em>observed</em> at runtime, rather than <em>expressed</em> through language.</p>
<p><code>bankAccount</code> and <code>withdrawalAmount</code> identify objects, for example. They can be composed in other objects, received by object methods and generally manipulated like other first-class citizens of the program. By reifying these objects, however, <code>balance</code> and <code>amount</code> state are relegated to object qualities, observable at runtime only through calls to <code>bankAccount.checkBalance</code> and <code>withdrawalAmount.get</code>.</p>
<p>That objects indeed lack any express notion of state is highlighted by object signatures with more than one getter, where any such notion may only exist through definition, signature by signature:</p>
<blockquote>
<p>How can you perceive a mutable object that has more than one getter? … How do you it? … Who could say right now how to do this? No one can, right? You cannot do this, because you need this other thing. You need the recipe for doing this, and the recipe is something that everybody has to make up over and over and over again. … We cannot actually perceive the whole. Cannot do it without help. Without these recipes. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>An object with a single read method (like <code>bankAccount</code>) in a sense defines <em>the</em> method for accessing the whole of an object’s state. However, each additional read method dilutes this claim, underscoring the need for a method specific to the task (e.g. <code>toJSON</code>, <code>serialize</code>, <code>inspect</code>, etc.). In stark contrast to numbers, string and objects themselves, state may be expressed only through programmer-defined constructs evaluated at runtime.</p>
<h2 id="stateful-functional-programs">Stateful Functional Programs <a class="direct-link" href="https://softwarefordays.com/post/paradigm-comparison-js/#stateful-functional-programs">#</a></h2>
<blockquote>
<p>Is there another approach? Can we avoid identifying time in the computer with time in the modeled world? Must we make the model change with time in order to model phenomena in a changing world? — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5</p>
</blockquote>
<p>Building stateful functional programs is less straightforward. To start, notice that imperative iteration can be restructured into functional iteration by recursively calling an iterative function with the results of the previous call. An imperative implementation of factorial, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">factorial</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">let</span> total <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> total <span class="token operator">=</span> total <span class="token operator">*</span> n<span class="token punctuation">;</span><br /> n <span class="token operator">=</span> n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> total<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 6</span></code></pre>
<p>maintains iteration and running total state through assignments to <code>n</code> and <code>total</code>, respectively, with every iteration. An alternative implementation avoids mutation by returning the iteration and running total state from an iteration function,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">factorial</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">const</span> <span class="token function-variable function">iterate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">total<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> total<span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">iterate</span><span class="token punctuation">(</span>total <span class="token operator">*</span> i<span class="token punctuation">,</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">iterate</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 6</span></code></pre>
<p>which may be used by the same function to calculate the next values in the next iteration.</p>
<p>Stateful functional programs can be constructed in a similar fashion — state that is returned from the previous turn of some larger, iterative “program” function becomes the starter state for the next — with one caveat. With <em>synchronous</em> iteration, results of the previous run can simply be passed to the next. The <code>total</code> result from <code>factorial</code> iteration, for example, is passed directly to the next. In a JavaScript web application, however, events are initiated <em>asynchronously</em> as the user interacts with the page, calling callbacks bound to such events, which run pieces of the program so encoded.</p>
<pre class="language-text"><code class="language-text">event → callback → javascript<br />event → callback → javascript<br />...</code></pre>
<p>Communication between <em>asynchronous</em> scripts is performed through shared references. One script updates (mutates!) a place in memory from which another script may later read. Look no further than the object-oriented ATM program above for a concrete example. A user may begin the program by first selecting a withdrawal amount, <em>then</em> clicking withdraw:</p>
<pre class="language-text"><code class="language-text">select → onchange → "withdrawalAmount.set(value)"<br />click → onclick → "bankAccount.withdraw(withdrawalAmount.get())"<br />...</code></pre>
<p>The “click withdraw” script occurs asynchronously sometime after the “select withdrawal amount” script has completed. Communication between the two scripts occurs through shared reference to the <code>amount</code> variable underlying the <code>withdrawalAmount</code> object. Calls to <code>withdrawalAmount.get()</code> will return updates by <code>withdrawalAmount.set(value)</code>, notwithstanding the asynchrony of such reads and writes.</p>
<p>Synchronous functions can communicate by simply passing around results. The result from one function becomes the input of another. Asynchronous scripts, by contrast, share a mutable place in memory instead of the values themselves. Consequently, we must also share a mutable place in memory to communicate between asynchronous scripts in the functional program implementation. On the other hand, with a light amount of infrastructure, we can usher such imperative code to the application perimeter and carve out space for a functional core, creating a “<a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">functional core, imperative shell</a>.”</p>
<script async="" src="https://jsfiddle.net/jmilgrom/mv2187zo/embed/js,html,result/"></script>
<p>The program now consists of functions <code>parseInt</code> and <code>withdraw</code>, called against specific events <code>WITHDRAWAL_AMOUNT</code> and <code>WITHDRAW</code>. The state of the program has not been reflected directly into distinct objects. Instead, a <code>program</code> <em>function</em> is called with the state resulting from the previous call, together with event data from any user interaction, in order to produce the starter state for the next. <code>program</code> resembles an iterative, recursive function. Yet, calls to <code>program</code> occur asynchronously. Just as with the object-oriented ATM program, a user may begin the functional ATM program by first selecting a withdrawal amount, <em>then</em> clicking withdraw:</p>
<pre class="language-text"><code class="language-text">select → onchange → "store.publish('WITHDRAWAL_AMOUNT', {amount:value})"<br />click → onclick → "store.publish('WITHDRAW')"<br />...</code></pre>
<p>The imperative shell (i.e the <code>store</code>) maintains a reference to the <code>state</code> resulting from the previous call to <code>program</code>, in order to pass such <code>state</code> to the next, orchestrating communication between asynchronous calls to <code>program</code>.</p>
<h3 id="time-as-a-series-of-states">Time as a Series of States <a class="direct-link" href="https://softwarefordays.com/post/paradigm-comparison-js/#time-as-a-series-of-states">#</a></h3>
<p>Unlike object-oriented programming, functional programming provides no model for traditional time. Mathematical functions are time<em>less</em>. Computation of a function <code>f(x)</code> a “second time” with the same argument will produce the same result <em>whenever</em> computed; a mathematical statement like <code>f(20) = 80</code> will not be made any less true by insinuating time. Similarly, time is no matter against procedures that model mathematical function computation. Simple functions,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">decrement100</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token number">100</span> <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrement100</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>compositions of functions,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">square</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">*</span> x<span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> <span class="token function-variable function">sumOfSquares</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token function">square</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">square</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token function">sumOfSquares</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 14</span></code></pre>
<p>as well as “program” functions like the ATM program introduced above,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">withdraw</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance<span class="token punctuation">,</span> amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> <span class="token function-variable function">ATM</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">balance</span><span class="token operator">:</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token literal-property property">amount</span><span class="token operator">:</span> <span class="token number">10</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">switch</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">case</span> <span class="token string">"WITHDRAW"</span><span class="token operator">:</span><br /> <span class="token keyword">return</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span>state<span class="token punctuation">,</span><br /> <span class="token literal-property property">balance</span><span class="token operator">:</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>balance<span class="token punctuation">,</span> state<span class="token punctuation">.</span>amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token keyword">case</span> <span class="token string">"WITHDRAWAL_AMOUNT"</span><span class="token operator">:</span><br /> <span class="token keyword">return</span> <span class="token punctuation">{</span><br /> <span class="token operator">...</span>state<span class="token punctuation">,</span><br /> <span class="token literal-property property">amount</span><span class="token operator">:</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token keyword">default</span><span class="token operator">:</span><br /> <span class="token keyword">return</span> state<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>will produce the same output provided the same input <em>whenever</em> evaluated, independent of time.</p>
<p>Where we once saw object state change as time <em>elapsed</em>, we now see the program jump from one state to the next at individual (i.e. discrete!) <em>moments in time</em>, as if producing entries in a list, log, “stream of information,” or other time-denominated series. Iterative, recursive functions model this same behavior. The functional <code>factorial</code> implementation shown above, for example, produces a value, say <code>F</code>, for each step, say <code>i</code>:</p>
<pre class="language-text"><code class="language-text">F₀: 1<br />F₁: 1<br />F₂: 2<br />...<br />factorial(i): iterate(Fᵢ₋₁ * i, i - 1)</code></pre>
<p>Each run of <code>iterate</code> against the result of the previous run produces a new value just <em>after</em> <em>the</em> <em>last</em> — a discrete piece of information that can viewed together with the rest on the same list. Individual program events can be similarly listed,</p>
<pre class="language-text"><code class="language-text">E₀: DEFAULT_EVENT<br />E₁: WITHDRAWAL_AMOUNT, amount:20<br />E₂: WITHDRAWAL<br />...<br />E(i): Eᵢ</code></pre>
<p>as can individual program states:</p>
<pre class="language-text"><code class="language-text">S₀: balance:100, amount:10<br />S₁: balance:100, amount:20<br />S₂: balance:80, amount:20<br />...<br />S(i): program(Sᵢ₋₁, Eᵢ)</code></pre>
<p>Each run of <code>program</code> against the result of the previous run, together with event data, produces a new value <em>after</em> the last. Yet, <code>program</code> is a timeless function.</p>
<p>With the object-oriented approach, we decompose the state of the program into objects <em>within</em> the program. Each object houses mutable state, and each piece of state may underly a mutative expression that “delineates moments in time” when evaluated.</p>
<blockquote>
<p>We modeled real-world objects with local state by computational objects with local variables. We identified time variation in the real world with time variation in the computer. We implemented the time variation of the states of the model objects in the computer with assignments to the local variables of the model objects. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5</p>
</blockquote>
<p>A collection of objects, each delineating moments in time when state may change <em>within</em> the program, embeds a simulation of time within the program. By contrast, with the functional approach, state is kept at the application perimeter and <em>functions</em> are composed together in order to transition the program from one state to another. No simulation of time can be found <em>within</em> the program; no moments can be found within the program <em>when</em> state <em>may</em> change. Rather, the program <em>provides</em> change from one state to the next (i.e. it produces state). As a result, program states represent <em>discrete</em> moments in time when state <em>has</em> changed.</p>
<blockquote>
<p>Think about the issue in terms of mathematical functions. We can describe the time-varying behavior of a quantity x as a function of time x(t). If we concentrate on x instant by instant, we think of it as a changing quantity. Yet if we concentrate on the entire time history of values, we do not emphasize change — the function itself does not change — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.5</p>
</blockquote>
<p>Said another way, in object-oriented programs, we hold the identity of objects constant through change. Objects endure change as time elapses, and thus we model time. In functional programs, we forgo object identity. Change creates something new instead of altering something of old, and thus we model change directly. Change is described succinctly by functions as well as by an “entire time history,” list, log, stream, or other series of resulting states.</p>
<h3 id="reified-state">Reified State <a class="direct-link" href="https://softwarefordays.com/post/paradigm-comparison-js/#reified-state">#</a></h3>
<p>Unlike object-oriented programs, functional programs reify state. State can be passed to functions, returned by functions, and generally manipulated like numbers, strings, lists, and other <a href="https://en.wikipedia.org/wiki/First-class_citizen">citizens</a> of the program. With a small addition to the ATM program, for example,</p>
<script async="" src="https://jsfiddle.net/jmilgrom/jfmea63q/embed/js,html,result/"></script>
<p>we can print (to the console) a representation of the each state of the program in sequence. This change is trivial precisely because state is a known quantity of the program and generally manipulable by program code. <code>inspectReturn</code> takes direct advantage of this quality, printing state to the console and returning state from the internal curried function.</p>
Functional & Object-Oriented Programming are Diametrically Opposed2021-01-07T00:00:00Zhttps://softwarefordays.com/post/fp-diametrically-opposes-oop/<p class="introductory-caveat">Excerpted from <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/">Functional Programming and the Semantics of Change, State & Time</a>.</p>
<p>That functional programming opposes object-oriented programming in some fundamental way is a widely-held programming cliche. We list features like immutability, functions and composition in contrast to mutability, classes and inheritance. We tout Clojure and Haskel as functional languages on one end of the spectrum and C++ and Java as object-oriented languages on the other. Articulating the makeup of the spectrum is another story altogether however. None of this trivia reveals why certain features are seen together or apart, why languages themselves may skew in one direction or another, or any inherent differences in program semantics.</p>
<p>Nevertheless, the “functions vs. objects” cliche is an artifact of a profound truth about program structures and semantics. Like up and down and oil and water, functional and object-oriented programming indeed cannot coexist. We may choose objects or functions, but not both at once, as advertised.</p>
<nav id="toc" class="table-of-contents"><ol><li><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#semantics%2C-not-syntax">Semantics, Not Syntax </a></li><li><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#changeability-is-fundamental-to-object-semantics">Changeability is Fundamental to Object Semantics </a></li><li><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#unchangeability-is-fundamental-to-functional-semantics">Unchangeability is Fundamental to Functional Semantics </a></li><li><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#%E2%80%9Cobject%E2%80%9D-names-changeability">“Object” Names Changeability </a></li><li><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#diametrically-opposed">Diametrically Opposed </a></li></ol></nav><h2 id="semantics%2C-not-syntax">Semantics, Not Syntax <a class="direct-link" href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#semantics%2C-not-syntax">#</a></h2>
<p>Syntactic constructs like <code>this</code>, <code>new</code>, <code>class</code>, <code>private</code> and <code>public</code> clearly express object-oriented intent — <em>this</em> instance of a <em>class</em> of things <em>private</em>ly maintains data through <em>public</em>ly available APIs — and are common to object-oriented programming languages. However, they are not necessary. Object-oriented semantics may be achieved with nontraditional syntax. For example, this <code>bankAccount</code> object also stores the <code>balance</code> data privately (in JavaScript<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fn1" id="fnref1">[1]</a></sup>);</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p><code>balance</code> is accessible only through the functions <code>checkBalance</code> and <code>withdraw</code>, which proscribe the manner in which such access can occur. <code>bankAccount</code> behaves like a “bank account” even though the functions <code>checkBalance</code> and <code>withdraw</code> have gained privileged access to private data through the use of a function closure, instead of through explicit syntax. Object-oriented syntax is also insufficient in and of itself to achieve object-oriented semantics. A <code>bankAccount</code> “object” that avoids maintaining any underlying balance state</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>balance<span class="token punctuation">,</span> amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span>balance<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100; whoops, shouldn't this be 80?</span></code></pre>
<figcaption>Is <code>bankAccount</code> really a "bank account"?</figcaption>
<p>allows “its” balance to evolve in an unspecified manner, undermining the “bank account” abstraction. <code>new</code>, <code>class</code> and <code>public</code> constructs obscure the actual semantics in this case. The same can be said of a <code>bankAccount</code> object that publicly exposes the balance attribute, as was alluded to above.</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> balance<span class="token punctuation">;</span> <span class="token comment">// <-- now public</span><br /><br /> <span class="token function">constructor</span><span class="token punctuation">(</span>funds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> funds<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token number">80</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80, eventhough no funds have been withdrawn</span></code></pre>
<figcaption>Is <code>bankAccount</code> really a "bank account"?</figcaption>
<p>Now, <code>balance</code> can magically change without a <code>withdraw</code>al ever having occurred, which undermines the “bank account” abstraction. <code>new</code>, <code>class</code> and <code>public</code> constructs obscure the actual semantics in this case.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fn2" id="fnref2">[2]</a></sup></p>
<p>With functional programming, syntax is also beside the point. The use of functional syntactic constructs is necessary to perform computation against arguments. <code>function</code> and <code>=></code> (the “arrow function”) constructs may express functional programming intent as well. However, they cannot alone achieve functional semantics. Indeed, a method of an object may use the <code>=></code> construct without correctly modeling computing mathematical functions.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Subsequent calls to <code>checkBalance</code> return different results despite identical inputs (i.e. <code>undefined</code>) by design.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>Additionally, an alternative implementation of “decrement one hundred” in JavaScript may fall short of correctly modeling a mathematical function even though an <code>=></code> construct is used, as was alluded to above.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> oneHundred <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> <span class="token function-variable function">decrementOneHundred</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> oneHundred <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />oneHundred <span class="token operator">=</span> <span class="token number">80</span><span class="token punctuation">;</span><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 60</span></code></pre>
<p>Invoking this procedure a second time with the same argument produces a different result when the <code>let</code> binding is amended between invocations.</p>
<h2 id="changeability-is-fundamental-to-object-semantics">Changeability is Fundamental to Object Semantics <a class="direct-link" href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#changeability-is-fundamental-to-object-semantics">#</a></h2>
<p>Since objects can change - an apple can be bitten, a house painted, and a bank account withdrawn from - effective object representations must follow suit.</p>
<blockquote>
<p>[W]e make computational objects…whose behavior changes with time. We model state with local state variables, and we model the changes of state with assignments to those variables. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.1.2</p>
</blockquote>
<p><code>bite</code>ing an <code>apple</code> changes <code>bites</code> state, <code>paint</code>ing a <code>house</code> changes <code>color</code> state and <code>withdraw</code>ing from a <code>bankAccount</code> changes <code>balance</code> state. The class implementation of a bank account object</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">private</span> balance<span class="token punctuation">;</span><br /><br /> <span class="token function">constructor</span><span class="token punctuation">(</span>funds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> funds<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance <span class="token operator">-</span> amount<span class="token punctuation">;</span> <span class="token comment">// <-- assign `this.balance` a new value</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<figcaption>The bank account’s balance is overwritten by the withdraw method.</figcaption>
<p>involves overwriting <code>balance</code> as much as the closure implementation does.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// <-- assign `balance` a new value</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<figcaption>The bank account’s balance is overwritten by the withdraw method.</figcaption>
<p>As mentioned above, a state<em>less</em> “object” (e.g. <code>bankAccount</code>) that avoids maintaining any underlying state (e.g. <code>balance</code>)</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">class</span> <span class="token class-name">BankAccount</span> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">withdraw</span><span class="token punctuation">(</span>balance<span class="token punctuation">,</span> amount<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance <span class="token operator">-</span> amount<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">public</span> <span class="token function">checkBalance</span><span class="token punctuation">(</span>balance<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100; whoops, shouldn't this be 80?</span></code></pre>
<figcaption>Is <code>bankAccount</code> really a "bank account"?</figcaption>
<p>also avoids modeling any underlying object (e.g. “bank account”).</p>
<h2 id="unchangeability-is-fundamental-to-functional-semantics">Unchangeability is Fundamental to Functional Semantics <a class="direct-link" href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#unchangeability-is-fundamental-to-functional-semantics">#</a></h2>
<p>On the other hand, changeable things undermine functional semantics. The <code>decrement100</code> procedure can be viewed as computing a mathematical function because its output depends only on its input; there is no other <em>variable</em> information on which it depends. By contrast, as the value of the mutable <code>let</code> binding underlying <code>decrementOneHundred</code> <em>changes</em>, so does the behavior of <code>decrementOneHundred</code> as a side-effect. Consequently, <code>decrementOneHundred</code> depends on the ongoing value of some contextual thing in addition to its input <code>x</code> and cannot resemble computing a mathematical function.</p>
<p>Conversely, unchangeability restores functional semantics. No contextual changes means no side-effects, and no side-effects means functional behavior:</p>
<blockquote>
<p>So long as we do not use assignments, two evaluations of the same procedure with the same arguments will produce the same result, so that procedures can be viewed as computing mathematical functions. Programming without any use of assignment…is accordingly known as <em>functional programming</em>. — <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">SICP</a> Section 3.1.3</p>
</blockquote>
<p>Even an externally scoped variable cannot change the semantics of <code>decrementOneHundred</code> when unchangeable.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> oneHundred <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">// <-- now a `const` instead of a `let`</span><br /><span class="token keyword">const</span> <span class="token function-variable function">decrementOneHundred</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> oneHundred <span class="token operator">-</span> x<span class="token punctuation">;</span><br /><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span><br /><span class="token comment">// oneHundred = 80; <-- would be runtime error: "TypeError: Assignment to constant variable."</span><br /><span class="token function">decrementOneHundred</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>Since JavaScript’s <code>const</code> binding endows <code>oneHundred</code> with immutability, it simply cannot change (without throwing a runtime error). And without change, the output of <code>decrementOneHundred</code> can depend only on the single thing that can: its input.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fn3" id="fnref3">[3]</a></sup></p>
<h2 id="%E2%80%9Cobject%E2%80%9D-names-changeability">“Object” Names Changeability <a class="direct-link" href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#%E2%80%9Cobject%E2%80%9D-names-changeability">#</a></h2>
<p>Moreover, changeability <em>implies</em> an object. The rational number “2/3” cannot change, for example. Change the denominator of “2/3” from 3 to 5 and its identity changes as well to “2/5”. Neither can the integer “24.” Increase the number of units represented by “24” and it may change to “25.”</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">HOURS_IN_DAY</span> <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span><br /><br /><span class="token comment">/**<br /> * NOT VALID; imagined API for mutating numbers<br /> */</span><br /><span class="token number">24.</span><span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token constant">HOURS_IN_DAY</span> <span class="token operator">===</span> <span class="token number">25</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre>
<figcaption>JavaScript implements number literals as immutable primitive values, preventing this unexpected behavior.
</figcaption>
<p>The rational number “2/3” and the integer “24” are unchangeable things, and are not recognizable as objects. Similarly, change the molecular construction of “iron” and it may very well change to “gold,” or the wave length of “green” and it may change to “red”. Conversely, find changeability and find an object. A cup that is two-thirds full of water can be poured, an iron rod can be dented and a green house can be painted. “That cup” remains that cup notwithstanding less water; “that rod” remains that rod notwithstanding a dent; “that house” remains that house notwithstanding a fresh coat of paint. A “cup”, “rod” and “house” are changeable things that <em>are</em> recognizable as objects. Coincidence of “changeability” and “object” is not happenstance. That parts can change without changing the identity of the whole <em>distinguishes</em> an identity distinct from underlying parts. Changeability distinguishes an object. “Object” in a sense articulates this ability to change.</p>
<p>Said another way, a new notion of “sameness” emerges with changeability. Unchangeable things can be identified as “the same” simply by examining contents. For example, because <em>immutable</em> rational number implementations, <code>r1</code> and <code>r2</code>,</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">type</span> <span class="token class-name">RationalNumber</span> <span class="token operator">=</span> <span class="token keyword">readonly</span> <span class="token punctuation">[</span><br /> <span class="token builtin">number</span> <span class="token comment">/* numerator */</span><span class="token punctuation">,</span><br /> <span class="token builtin">number</span> <span class="token comment">/* denominator */</span><br /><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// turn into decimal form before comparing in order to reduce fraction</span><br /><span class="token keyword">const</span> <span class="token function-variable function">isEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> RationalNumber<span class="token punctuation">,</span> b<span class="token operator">:</span> RationalNumber<span class="token punctuation">)</span> <span class="token operator">=></span><br /> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> b<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> r1<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r2<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r3<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre>
<figcaption>TypeScript’s <code>readonly</code> qualifier prevents mutative actions (e.g. <code>p2[1] = 3</code>) at compile time.
</figcaption>
<p>will <em>always</em> be comprised of <code>2</code> in the first slot and <code>3</code> in the second and reduce to two-thirds, a reasonable conclusion is that they are the same. To be sure, substitute one for the other and the meaning of a program is unchanged.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fn4" id="fnref4">[4]</a></sup> By contrast, consider when two <em>mutable</em> rational number implementations may be deemed the “same.”</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">type</span> <span class="token class-name">RationalNumber</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">number</span> <span class="token comment">/* numerator */</span><span class="token punctuation">,</span> <span class="token builtin">number</span> <span class="token comment">/* denominator */</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// turn into decimal form before comparing in order to reduce fraction</span><br /><span class="token keyword">const</span> <span class="token function-variable function">isEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> RationalNumber<span class="token punctuation">,</span> b<span class="token operator">:</span> RationalNumber<span class="token punctuation">)</span> <span class="token operator">=></span><br /> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> b<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> r1<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r2<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r3<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br />r2<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span><br /><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r2<span class="token punctuation">,</span> r3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre>
<figcaption>
Absent the <code>readonly</code> qualifier, <code>RationalNumber</code>'s are mutable at compile time. And at runtime, JavaScript’s <code>const</code> binding only prevents reassignment of such binding; it does not prevent mutations of an underlying array.
</figcaption>
<p><code>r1</code> may have the same contents as <code>r2</code> to start, but this affect is shortly lived. Substitute one for the other and the meaning of the program is changed — references to r2 now incorrectly reduce to two-fifths instead of two-thirds. <code>r1</code> and <code>r2</code> are not exactly “the same” in this case. Since two changeable things may evolve independently notwithstanding an analysis of parts performed at any one point in time, a new notion of “sameness” above an examination of parts must be admitted. Remarkably, this “new” notion is less remarkable with intentional object-oriented programming, where the creation of a new identity — i.e. an <em>object</em> — is precisely the goal. <code>georgesAccount</code> and <code>elainesAccount</code>, for example,</p>
<pre class="language-ts"><code class="language-ts"><span class="token comment">/**<br /> * Reference equality check<br /> */</span><br /><span class="token keyword">const</span> <span class="token function-variable function">areAccountsEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> BankAccount<span class="token punctuation">,</span> b<span class="token operator">:</span> BankAccount<span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">===</span> b<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> elainesAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> georgesAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />elainesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />georgesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br /><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> elainesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> georgesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (eventhough identical funds)</span><br /><br />georgesAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">75</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />elainesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />georgesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 25</span><br /><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> elainesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> georgesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre>
<figcaption>We may determine equality b/w 2 objects by whether they are the same object — i.e. reference equality.
</figcaption>
<p>may share a balance at some point in time. But even if they start with the same funds, <code>georgesAccount</code> and <code>elainesAccount</code> can register different balances at some other point in time because they are in fact different <em>objects</em>. Of course, that two distinct objects can evolve independently goes without saying. That is because “object” clearly articulates the creation of an identity that is not tied to any part, arrangement or quality; “object” names the ability to change.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fn5" id="fnref5">[5]</a></sup></p>
<h2 id="diametrically-opposed">Diametrically Opposed <a class="direct-link" href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#diametrically-opposed">#</a></h2>
<p>In this light, object-oriented programming can be seen as the diametric opposite of functional programming. Objects are inherently changeable. Moreover, changeability and “object” are intertwined as concepts. Yet, changeability undermines functional programming. Just as oil cannot inhabit the same physical space as water, object-oriented programming cannot occupy the same virtual space as functional programming. Use of one excludes the other. As a result, when writing programs, we may choose mutability or immutability, objects or functions, but not both at once.</p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Many of the insights underlying this post can be found in original form in the <a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">Structure and Interpretation of Computer Programs </a> (SICP). There you will find a life-altering discussion of the same topics using Scheme, a Lisp dialect like Clojure. All code examples included in this post, however, will be couched in terms of JavaScript, even if borrowed. If you know JavaScript and are unfamiliar with Scheme, this post may be immediately accessible to you without first learning how “<a href="https://crockford.com/javascript/javascript.html">to balance all those parens</a>.” Little is lost in translation as well. JavaScript has first-class functions (i.e. lambdas), closures (i.e. function-delimited lexical scoping) and generally thrives when used functionally.</p>
<blockquote>
<p>JavaScript’s functions are first class objects with (mostly) lexical scoping. JavaScript is the first lambda language to go mainstream. Deep down, JavaScript has more in common with Lisp and Scheme than with Java. It is Lisp in C’s clothing. — Douglas Crockford, <a href="https://www.oreilly.com/library/view/javascript-the-good/9780596517748/ch01s02.html">JavaScript: The Good Parts</a></p>
</blockquote>
<p>There is even an ongoing <a href="https://sicp.comp.nus.edu.sg/">academic effort</a> to translate the full text of SICP into JavaScript. Also considered, JavaScript is a close cousin of TypeScript, which enables traditional object-oriented constructs like <code>private</code> and <code>public</code> and functional constructs like <code>readonly</code> and <code>as const</code> at compile time. Perhaps in JavaScript (and TypeScript), we get enough support of functional and object-oriented programming paradigms to enable a discussion of both within a single, ubiquitous language. <a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>Never has the delineation between syntax and semantics been more pronounced than with <a href="https://martinfowler.com/bliki/ValueObject.html">value objects</a>, which commandeer object-oriented syntax to effect <em>non</em>-object semantics — i.e. immutable values. If not for the divergence between syntax and semantics, so-called “value objects” would be a contradiction in terms. We’ll cover the inherent mutability of objects soon in the sections titled <a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#changeability-is-fundamental-to-object-semantics">Changeability is Fundamental to Object Semantics</a> and <a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#%E2%80%9Cobject%E2%80%9D-names-changeability">“Object” Names Changeability</a>. <a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p>Contextual immutability says nothing of local variables. In fact, a variable that is reassigned within the same procedure in which it was initialized cannot impact the semantics of such procedure.</p>
<blockquote>
<p>…any mutation that is ever done to any of these is to rebind local variables…that doesn’t affect the fact that these objects are immutable from an outside perspective” Gary Bernhardt, <a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell">Functional Core, Imperative Shell</a></p>
</blockquote>
<p><code>decrement100</code> may be implemented with internal mutability, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">decrement100</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">let</span> r <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><br /> r <span class="token operator">=</span> <span class="token number">100</span> <span class="token operator">-</span> x<span class="token punctuation">;</span><br /> <span class="token keyword">return</span> r<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">decrement100</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 80</span></code></pre>
<p>without affecting external semantics; the output of <code>decrement100</code> still depends only on the input. Even block-scoped looping constructs like <code>while</code>, <code>for</code> and <code>do</code> may be part of procedures that produce the same output provided the same input, notwithstanding reassignment of variables tracking iteration state (e.g. <code>i</code>, <code>j</code>, <code>k</code>, <code>n</code>, etc.) with every loop.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">factorial</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">let</span> total <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> total <span class="token operator">=</span> total <span class="token operator">*</span> n<span class="token punctuation">;</span><br /> n <span class="token operator">=</span> n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> total<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2</span><br /><span class="token function">factorial</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 6</span></code></pre>
<figcaption>The mutability of <code>f</code> and <code>n</code> does not impact the functional semantics of <code>factorial</code></figcaption>
<p><code>factorial</code> will produce the same output provided the same input. On the other hand, changeability that is internal to one procedure definition may be positioned externally to another when <a href="https://en.wikipedia.org/wiki/Nested_function">lexical procedural nesting is supported</a>. <code>balance</code>, for example,</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">makeBankAccount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">balance</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span><br /> <span class="token function-variable function">withdraw</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">amount</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>balance <span class="token operator">=</span> balance <span class="token operator">-</span> amount<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function-variable function">checkBalance</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> balance<span class="token punctuation">,</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> bankAccount <span class="token operator">=</span> <span class="token function">makeBankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br />bankAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 80</span></code></pre>
<p>is external to <code>withdraw</code> although internal to <code>makeBankAccount</code> and undermines the functional semantics of <code>withdraw</code> as a result, as discussed above. <a href="https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example/750506">Notoriously unintuitive effects</a> manifest when looping is combined with procedural nesting.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">buildCallbacks</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">items</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">const</span> callbacks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">let</span> i<span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> items<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> callbacks<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> items<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> callbacks<span class="token punctuation">;</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> callbacks <span class="token operator">=</span> <span class="token function">buildCallbacks</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"cruel"</span><span class="token punctuation">,</span> <span class="token string">"world"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />callbacks<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token comment">// => 3</span><br />callbacks<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span><br />callbacks<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span><br />callbacks<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span></code></pre>
<figcaption>Initializing <code>let</code> above the block scopes the variable above the for-loop. Each iteration points at the same reference in memory as a result. By the time the callbacks are called, i has been updated to <code>3</code> and is outside the <code>callback</code>'s upper bound.</figcaption>
<p>As a result, comprehensive immutability can be seen as defending functional programming in the face of procedural nesting. It also appears that functional semantics could theoretically coincide with traditional looping constructs and other locally-scoped mutation so long as procedural nesting was prohibited. Nevertheless, immutability is generally considered an inseparable part of functional programming; no distinction is made in SICP and elsewhere (that I have encountered). Perhaps there is something else to be said here about lambda calculus and a more formal definition of functional programming. Or, perhaps the many benefits of nested procedures (e.g. modules, closures, etc.) so obviously outweigh the superficial “costs” of forgoing looping to even consider such crazy talk. Recursive procedures can do anything looping constructs can and without performance regressions because of tail recursion and other optimization techniques at the compiler level. <a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fnref3" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p>That two equivalent expressions may be substituted for one another without altering the meaning of the program is known as <a href="https://en.wikipedia.org/wiki/Referential_transparency">referential transparency</a>.</p>
<blockquote>
<p>A language that supports the concept that “equals can be substituted for equals” in an expression without changing the value of the expression is said to be referentially transparent — SICP Section 3.1.3</p>
</blockquote>
<a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fnref4" class="footnote-backref">↩︎</a></li>
<li id="fn5" class="footnote-item"><p>❤️ The original insight️ ❤️</p>
<blockquote>
<p>In general, so long as we never modify data objects, we can regard a compound data object to be precisely the totality of its pieces. For example, a rational number is determined by giving its numerator and its denominator. But this view is no longer valid in the presence of change, where a compound data object has an “identity” that is something different from the pieces of which it is composed. A bank account is still “the same” bank account even if we change the balance by making a withdrawal; conversely, we could have two different bank accounts with the same state information. This complication is a consequence, not of our programming language, but of our perception of a bank account as an object. — SICP Section 3.1.3</p>
</blockquote>
<p>Rich Hickey on the same subject:</p>
<blockquote>
<p>If it is immutable, it now taps into that definition of value we saw before. Because by being immutable we can go and take a string value, and another string value, and say: are they the same? Do they have the same magnitude? Are they talking about the same thing? Are they expressing the same specific meaning? All of those definitions of values apply to something that is not mutable. So that relative worth thing kicks in. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<a href="https://softwarefordays.com/post/fp-diametrically-opposes-oop/#fnref5" class="footnote-backref">↩︎</a></li>
</ol>
</section>
Object Names Changeability2022-12-21T00:00:00Zhttps://softwarefordays.com/post/object-names-changeability/<p class="introductory-caveat">Excerpted from <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/#%E2%80%9Cobject%E2%80%9D-names-changeability">Functional Programming and the Semantics of Change, State & Time</a>.</p>
<p>Changeability <em>implies</em> an object. The rational number “2/3” cannot change, for example. Change the denominator of “2/3” from 3 to 5 and its identity changes as well to “2/5”. Neither can the integer “24.” Increase the number of units represented by “24” and it may change to “25.”</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">HOURS_IN_DAY</span> <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span><br /><br /><span class="token comment">/**<br /> * NOT VALID; imagined API for mutating numbers<br /> */</span><br /><span class="token number">24.</span><span class="token function">increment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /><span class="token constant">HOURS_IN_DAY</span> <span class="token operator">===</span> <span class="token number">25</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre>
<figcaption>JavaScript implements number literals as immutable primitive values, preventing this unexpected behavior.
</figcaption>
<p>The rational number “2/3” and the integer “24” are unchangeable things, and are not recognizable as objects. Similarly, change the molecular construction of “iron” and it may very well change to “gold,” or the wave length of “green” and it may change to “red”. Conversely, find changeability and find an object. A cup that is two-thirds full of water can be poured, an iron rod can be dented and a green house can be painted. “That cup” remains that cup notwithstanding less water; “that rod” remains that rod notwithstanding a dent; “that house” remains that house notwithstanding a fresh coat of paint. A “cup”, “rod” and “house” are changeable things that <em>are</em> recognizable as objects. Coincidence of “changeability” and “object” is not happenstance. That parts can change without changing the identity of the whole <em>distinguishes</em> an identity distinct from underlying parts. Changeability distinguishes an object. “Object” in a sense articulates this ability to change.</p>
<p>Said another way, a new notion of “sameness” emerges with changeability. Unchangeable things can be identified as “the same” simply by examining contents. For example, because <em>immutable</em> rational number implementations, <code>r1</code> and <code>r2</code>,</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">type</span> <span class="token class-name">RationalNumber</span> <span class="token operator">=</span> <span class="token keyword">readonly</span> <span class="token punctuation">[</span><br /> <span class="token builtin">number</span> <span class="token comment">/* numerator */</span><span class="token punctuation">,</span><br /> <span class="token builtin">number</span> <span class="token comment">/* denominator */</span><br /><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// turn into decimal form before comparing in order to reduce fraction</span><br /><span class="token keyword">const</span> <span class="token function-variable function">isEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> RationalNumber<span class="token punctuation">,</span> b<span class="token operator">:</span> RationalNumber<span class="token punctuation">)</span> <span class="token operator">=></span><br /> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> b<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> r1<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r2<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r3<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre>
<figcaption>TypeScript’s <code>readonly</code> qualifier prevents mutative actions (e.g. <code>p2[1] = 3</code>) at compile time.
</figcaption>
<p>will <em>always</em> be comprised of <code>2</code> in the first slot and <code>3</code> in the second and reduce to two-thirds, a reasonable conclusion is that they are the same. To be sure, substitute one for the other and the meaning of a program is unchanged.[^7] By contrast, consider when two <em>mutable</em> rational number implementations may be deemed the “same.”</p>
<pre class="language-ts"><code class="language-ts"><span class="token keyword">type</span> <span class="token class-name">RationalNumber</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token builtin">number</span> <span class="token comment">/* numerator */</span><span class="token punctuation">,</span> <span class="token builtin">number</span> <span class="token comment">/* denominator */</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token comment">// turn into decimal form before comparing in order to reduce fraction</span><br /><span class="token keyword">const</span> <span class="token function-variable function">isEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> RationalNumber<span class="token punctuation">,</span> b<span class="token operator">:</span> RationalNumber<span class="token punctuation">)</span> <span class="token operator">=></span><br /> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> b<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> r1<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r2<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> r3<span class="token operator">:</span> RationalNumber <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /><br />r2<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span><br /><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r1<span class="token punctuation">,</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span><br /><span class="token function">isEqual</span><span class="token punctuation">(</span>r2<span class="token punctuation">,</span> r3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre>
<figcaption>
Absent the <code>readonly</code> qualifier, <code>RationalNumber</code>'s are mutable at compile time. And at runtime, JavaScript’s <code>const</code> binding only prevents reassignment of such binding; it does not prevent mutations of an underlying array.
</figcaption>
<p><code>r1</code> may have the same contents as <code>r2</code> to start, but this affect is shortly lived. Substitute one for the other and the meaning of the program is changed — references to r2 now incorrectly reduce to two-fifths instead of two-thirds. <code>r1</code> and <code>r2</code> are not exactly “the same” in this case. Since two changeable things may evolve independently notwithstanding an analysis of parts performed at any one point in time, a new notion of “sameness” above an examination of parts must be admitted. Remarkably, this “new” notion is less remarkable with intentional object-oriented programming, where the creation of a new identity — i.e. an <em>object</em> — is precisely the goal. <code>georgesAccount</code> and <code>elainesAccount</code>, for example,</p>
<pre class="language-ts"><code class="language-ts"><span class="token comment">/**<br /> * Reference equality check<br /> */</span><br /><span class="token keyword">const</span> <span class="token function-variable function">areAccountsEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token operator">:</span> BankAccount<span class="token punctuation">,</span> b<span class="token operator">:</span> BankAccount<span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">===</span> b<span class="token punctuation">;</span><br /><br /><span class="token keyword">const</span> elainesAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token keyword">const</span> georgesAccount <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BankAccount</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />elainesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />georgesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br /><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> elainesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> georgesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (eventhough identical funds)</span><br /><br />georgesAccount<span class="token punctuation">.</span><span class="token function">withdraw</span><span class="token punctuation">(</span><span class="token number">75</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br />elainesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span><br />georgesAccount<span class="token punctuation">.</span><span class="token function">checkBalance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 25</span><br /><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> elainesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><br /><span class="token function">areAccountsEqual</span><span class="token punctuation">(</span>elainesAccount<span class="token punctuation">,</span> georgesAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre>
<figcaption>We may determine equality b/w 2 objects by whether they are the same object — i.e. reference equality.
</figcaption>
<p>may share a balance at some point in time. But even if they start with the same funds, <code>georgesAccount</code> and <code>elainesAccount</code> can register different balances at some other point in time because they are in fact different <em>objects</em>. Of course, that two distinct objects can evolve independently goes without saying. That is because “object” clearly articulates the creation of an identity that is not tied to any part, arrangement or quality; “object” names the ability to change.<sup class="footnote-ref"><a href="https://softwarefordays.com/post/object-names-changeability/#fn1" id="fnref1">[1]</a></sup></p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>❤️ The original insight️ ❤️</p>
<blockquote>
<p>In general, so long as we never modify data objects, we can regard a compound data object to be precisely the totality of its pieces. For example, a rational number is determined by giving its numerator and its denominator. But this view is no longer valid in the presence of change, where a compound data object has an “identity” that is something different from the pieces of which it is composed. A bank account is still “the same” bank account even if we change the balance by making a withdrawal; conversely, we could have two different bank accounts with the same state information. This complication is a consequence, not of our programming language, but of our perception of a bank account as an object. — SICP Section 3.1.3</p>
</blockquote>
<p>Rich Hickey on the same subject:</p>
<blockquote>
<p>If it is immutable, it now taps into that definition of value we saw before. Because by being immutable we can go and take a string value, and another string value, and say: are they the same? Do they have the same magnitude? Are they talking about the same thing? Are they expressing the same specific meaning? All of those definitions of values apply to something that is not mutable. So that relative worth thing kicks in. — Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<a href="https://softwarefordays.com/post/object-names-changeability/#fnref1" class="footnote-backref">↩︎</a></li>
</ol>
</section>
Paradigmatic Advantages of Functional Programming2023-05-22T00:00:00Zhttps://softwarefordays.com/post/fp-advantages-synopsis/<p class="introductory-caveat">Excerpted from <a href="https://softwarefordays.com/post/functional-programming-and-identity-state-and-time/">Functional Programming and the Semantics of Change, State & Time</a> because sometimes 100 words are worth a 1000.</p>
<p>There are many advantages to functional programming. Programs that deal with mutation are “drastically more difficult” to reason about than ones that do not.</p>
<blockquote>
<p>Referential transparency is violated when we include set! [i.e. assignment operations] in our computer language. This makes it tricky to determine when we can simplify expressions by substituting equivalent expressions. Consequently, reasoning about programs that use assignment becomes drastically more difficult — SICP Section 3.1.3</p>
</blockquote>
<p>In particular, functions avoid <a href="https://www.yegor256.com/2015/12/08/temporal-coupling-between-method-calls.html">temporal coupling</a> since there is no time,</p>
<blockquote>
<p>In general, programming with assignment forces us to carefully consider the relative orders of the assignments to make sure that each statement is using the correct version of the variables that have been changed. This issue simply does not arise in functional programs. — SICP Section 3.1.3</p>
</blockquote>
<p>and dramatically reduce debugging and unit testing complexity since there is no meaningful context.</p>
<blockquote>
<p>“And that is the problem with places. You have this sort of global state that you have to reproduce in order to debug a field problem. That is very very tough.” Rich Hickey, <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValuesLong.md">The Value of Values</a></p>
</blockquote>
<p>Reified state couches in writing what must otherwise live in a programmer’s heads — each member of a team can read a function signature instead of building up (hopefully) the same working memory for each object. Couching state in language makes it accessible to static language analysis tools. <a href="https://blog.ploeh.dk/2019/07/01/yes-silver-bullet/#bd2d47d8dac2401e936ca7902bc9109d">A compiler may exhaustively permute the set of application states</a> without actually running manually-written (exhaust<em>ing</em>) unit tests. Functional programs are more easily parallelized since they are just functions with no internal model for time.</p>
<blockquote>
<p>Unfortunately, the complexities introduced by assignment become even more problematic in the presence of concurrency. — SICP Section 3.4</p>
</blockquote>
<p>These advantages have been known for decades. John Backus “gave high visibility to functional programming” (SICP Section 3.5.5; also see Simon Peyton-Jones, <a href="https://www.youtube.com/watch?v=re96UgMk6GQ">Escape from the ivory tower: the Haskel journey</a>) through his <a href="https://www.thocp.net/biographies/papers/backus_turingaward_lecture.pdf">Turing Award lecture</a> in 1978, seven years before the creation of <a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> and thirteen before <a href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>. The <a href="https://softwarefordays.com/post/fp-as-a-scientific-revolution/">resistance from an alternative linguistic paradigm</a> perhaps explains the dominance of object-oriented and imperative programming languages, notwithstanding the long-standing advantages of functional programming.</p>