<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Robin Heggelund Hansen</title>
    <description>The latest articles on DEV Community by Robin Heggelund Hansen (@robinheghan).</description>
    <link>https://dev.to/robinheghan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F63483%2F847d5061-8645-4cf4-8bd6-99995ee0f6db.png</url>
      <title>DEV Community: Robin Heggelund Hansen</title>
      <link>https://dev.to/robinheghan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robinheghan"/>
    <language>en</language>
    <item>
      <title>Play: A new programming language that targets Web Assembly, based on Forth</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Mon, 23 Nov 2020 11:15:58 +0000</pubDate>
      <link>https://dev.to/robinheghan/play-a-new-programming-language-that-targets-web-assembly-based-on-forth-5cnf</link>
      <guid>https://dev.to/robinheghan/play-a-new-programming-language-that-targets-web-assembly-based-on-forth-5cnf</guid>
      <description>&lt;p&gt;Today marks the first release of Play, a new programming language inspired by Forth.&lt;/p&gt;

&lt;p&gt;Play might look a lot like Forth, but improves on the language in several ways. Play includes a strong static type system like the ones found in Elm and Haskell. All data structures are immutable, and side effects are tightly controlled, which leads to code that is easy to reason about.&lt;/p&gt;

&lt;p&gt;Code written in Play is compiled to web assembly, which means it can run pretty much everywhere, even in browsers.&lt;/p&gt;

&lt;p&gt;The goal of today's release is not to present a finished product, but rather give people an idea of what writing code in Play would be like.&lt;/p&gt;

&lt;p&gt;To learn more, you can take a look at the &lt;a href="https://www.play-lang.dev"&gt;website&lt;/a&gt; and toy with some examples at the &lt;a href="https://www.play-lang.dev/playground.html"&gt;playground&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>play</category>
      <category>forth</category>
      <category>programming</category>
      <category>language</category>
    </item>
    <item>
      <title>Getting started with Elm Warrior</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Mon, 14 Sep 2020 10:40:15 +0000</pubDate>
      <link>https://dev.to/robinheghan/getting-started-with-elm-warrior-5b2n</link>
      <guid>https://dev.to/robinheghan/getting-started-with-elm-warrior-5b2n</guid>
      <description>&lt;p&gt;&lt;em&gt;You wake up in a dungeon. You're alone, freezing and nearly starved to death. In the darkness ahead, you can hear footsteps and the sharpening of blades. The only weapon at your disposal is Elm, the programming language. Will you find your way out alive?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Elm-warrior is a programming game created to answer the question: &lt;em&gt;Ok, now I know basic Elm syntax, what do I do next?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the course of several levels of ascending difficulty, you'll program the intelligence of At, a slow but strong-willed warrior, trying to get him out of the dungeon alive.&lt;/p&gt;

&lt;p&gt;When you've successfully escaped the dungeon, you can compare your solution with others in a free-for-all deathmatch, or continue challenging yourself by creating your own maps.&lt;/p&gt;

&lt;p&gt;Are you ready?&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;You're going to need to have git and node installed. &lt;/p&gt;

&lt;p&gt;After that, you can clone the &lt;a href="https://github.com/robinheghan/elm-warrior-starter"&gt;elm-warrior-starter repo&lt;/a&gt;. The starter repo contains the minimal amount of boilerplate required to start playing, while the &lt;a href="https://github.com/robinheghan/elm-warrior"&gt;elm-warrior repo&lt;/a&gt; contains the actual framework and documentation you'll use.&lt;/p&gt;

&lt;p&gt;To clone the starter-repo, you can run the following command in your command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/robinheghan/elm-warrior-starter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When done, you're going to need to download elm and parcel for your code to compile and run. We can do this using node's package manager, npm, as those dependencies are already declared in the repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;elm-warrior-start
npm ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have everything setup, ready to begin coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the first level
&lt;/h2&gt;

&lt;p&gt;As a first step, we're going to compile the code and spin up a web server to see how our code affects the elm warrior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should start a web server at &lt;code&gt;http://localhost:1234&lt;/code&gt;, so enter that address in your web browser. You should see the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BjtW48E6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uy4y433q9t1f6p7bt2lm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BjtW48E6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uy4y433q9t1f6p7bt2lm.png" alt="At waiting for instructions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal is to have the warrior reach the other side of the room. Since we've yet to write a single line of code, the warrior just does nothing. Let's fix that!&lt;/p&gt;

&lt;p&gt;Using your prefered IDE or text editor, open &lt;code&gt;src/elm/Player.elm&lt;/code&gt;. This file should contain the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Player&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;takeTurn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;History&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;History&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;takeTurn&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;History&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Action&lt;/span&gt;
&lt;span class="n"&gt;takeTurn&lt;/span&gt; &lt;span class="n"&gt;warrior&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Wait&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementing the intelligence of an elm warrior is as simple as implementing a function. The function is called once every turn, and is required to return an action that specifies what the warrior should do next. As you can see, this function simply returns the &lt;code&gt;Wait&lt;/code&gt; action, and so our warrior will always stand still.&lt;/p&gt;

&lt;p&gt;To get past the first level, we need to return an action that makes the warrior move to the right. To figure out which actions our warrior can take, we need to &lt;a href="https://package.elm-lang.org/packages/robinheghan/elm-warrior/latest/Warrior"&gt;consult the documentation&lt;/a&gt;. Here we can see that there is a &lt;code&gt;Move&lt;/code&gt; action which takes a &lt;code&gt;Direction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we change the function to return a move action, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Player&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;takeTurn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;History&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;History&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Direction&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Direction&lt;/span&gt;


&lt;span class="n"&gt;takeTurn&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;History&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Action&lt;/span&gt;
&lt;span class="n"&gt;takeTurn&lt;/span&gt; &lt;span class="n"&gt;warrior&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Move&lt;/span&gt; &lt;span class="kt"&gt;Direction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Right&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our warrior should now move right every single turn. Just save the file and refresh the browser, you do not need to run &lt;code&gt;npm start&lt;/code&gt; again. The warrior should now reach the exit point quite easily.&lt;/p&gt;

&lt;p&gt;Once the warrior reaches the exit point, it will transition to a new level of greater difficulty, requiring more intelligence in your turn function. Can you get through all the levels and escape the dungeon?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the next levels
&lt;/h2&gt;

&lt;p&gt;You may have noticed that the turn function takes three arguments.&lt;/p&gt;

&lt;p&gt;The first argument contains information &lt;em&gt;about&lt;/em&gt; the warrior itself. Its current health, current position, current items in the inventory, and so forth.&lt;/p&gt;

&lt;p&gt;The second argument contains information about what the warrior can &lt;em&gt;see&lt;/em&gt;. You can use this to look for the exit, or possible obstacles and dangers in its path.&lt;/p&gt;

&lt;p&gt;The final argument contains information about &lt;em&gt;all previous actions&lt;/em&gt; the warrior has taken, and the state of the warrior and map at those times. You can use this information to figure out if the warrior has been somewhere before, or remember where the warrior has seen something.&lt;/p&gt;

&lt;p&gt;You'll need to make use of all these arguments to help the warrior escape the dungeon, and the operations you can perform on them is listed in &lt;a href="https://package.elm-lang.org/packages/robinheghan/elm-warrior/latest/"&gt;the documentation&lt;/a&gt;, so make sure to read this carefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---dsAYFU4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pb52oqvcawosdz0yqfxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---dsAYFU4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pb52oqvcawosdz0yqfxf.png" alt="Clicking the Elm logo opens the time-travelling debugger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might have noticed a little Elm logo at the bottom right of the browser window. Clicking this opens up the time-travelling Elm debugger.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KPHIWVbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/elzi9x28ugcpu3trl3m3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KPHIWVbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/elzi9x28ugcpu3trl3m3.png" alt="The time-travelling debugger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The debugger allows you to step backwards in time to see what the state of the program was at a particular turn, which might make it easier to figure out why your function returned the action it did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speeding things up, or slowing things down
&lt;/h2&gt;

&lt;p&gt;After a couple of runs, you might wish that the warrior moved a little faster, or a little slower. You can change this by opening &lt;code&gt;src/elm/Main.elm&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Player&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Progression&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Progression&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Maps&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Maps&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;maps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Maps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;players&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Player"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;takeTurn&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msPerTurn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;progressionFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Progression&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reachExitPoint&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change the &lt;code&gt;msPerTurn&lt;/code&gt; setting to whatever value you'd like. Setting it to 100 will speed things up significantly. Setting it to 0 will speed it up even more, but it might be difficult to see the individual actions the warrior takes. Slowing it down is just a matter of increasing the value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Focusing on a single level
&lt;/h2&gt;

&lt;p&gt;You might have seen that there is a &lt;code&gt;maps&lt;/code&gt; setting in &lt;code&gt;Main.elm&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;At some point, you might not wish to run through every single map when you know that the warrior struggles with one in particular. You can see a &lt;a href="https://package.elm-lang.org/packages/robinheghan/elm-warrior/latest/Warrior-Maps"&gt;list of all available maps&lt;/a&gt; in the documentation. If you make a list containing just the map you'd wish to run, and pass that to the &lt;code&gt;maps&lt;/code&gt; setting, you can avoid spending time in maps you already know works well.&lt;/p&gt;

&lt;p&gt;For instance, if you're mostly focusing on the second to last level, you can avoid having the warrior run through all the others by changing the &lt;code&gt;Main.elm&lt;/code&gt; file to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Player&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Progression&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Progression&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Maps&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Maps&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Program&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Warrior&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;maps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;Maps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;straightGuardPickupPotion&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;players&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Player"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;takeTurn&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msPerTurn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;progressionFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Progression&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reachExitPoint&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Further challenges
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2ow4ZyII--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7zt6kyy24dzdlhb31oic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ow4ZyII--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7zt6kyy24dzdlhb31oic.png" alt="Free-for-all deathmatch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you've successfully escaped the dungeon, you might wish you had more challenges. Elm warrior allows for both creating your own maps (and sharing with others) as well as a free-for-all deathmatch.&lt;/p&gt;

&lt;p&gt;To create your own maps you can draw some inspiration from &lt;a href="https://github.com/robinheghan/elm-warrior/blob/master/src/Warrior/Maps.elm"&gt;looking at the code of the maps you've just tried out&lt;/a&gt; as well as reading the &lt;a href="https://package.elm-lang.org/packages/robinheghan/elm-warrior/latest/Warrior-Map-Builder"&gt;map builder documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For playing deathmatches, there is a separate &lt;a href="https://github.com/robinheghan/elm-warrior-multiplayer"&gt;multiplayer starter repo&lt;/a&gt; you can clone to get started. For extra fun, you can challenge your friends and see who has programmed the best warrior. May the best Elm programmer, win!&lt;/p&gt;

</description>
      <category>elm</category>
      <category>warrior</category>
      <category>game</category>
    </item>
    <item>
      <title>Become an Elm warrior</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Sat, 13 Jun 2020 20:53:23 +0000</pubDate>
      <link>https://dev.to/robinheghan/become-an-elm-warrior-4cl1</link>
      <guid>https://dev.to/robinheghan/become-an-elm-warrior-4cl1</guid>
      <description>&lt;p&gt;In the last two years I've been given several opportunities to teach people Elm through talks and workshops. What I've come to learn is that no matter how well your talks and presentations are, people need to write Elm on their own to actually learn anything of it.&lt;/p&gt;

&lt;p&gt;This might not be surprising to any of you, but it does present one a huge challenge: time.&lt;/p&gt;

&lt;p&gt;You might not have time to let people write enough Elm to get comfortable. You can almost be certain that half the people that attend your workshop is going to have problems getting everything setup or, if they were kind enough to come prepared, experienced problems setting everything up before they arrived. &lt;/p&gt;

&lt;p&gt;Then you'll find yourself answering many more questions than you'd originally hoped for, only to discover that you're not answering nearly enough of them.&lt;/p&gt;

&lt;p&gt;Before you know it, it's the end of the day and you haven't even gotten to the point were the actual benefits of Elm begin to make themselves apparent.&lt;/p&gt;

&lt;p&gt;If you've been given several days to teach people Elm this won't be a problem, but you won't always have that luxury.&lt;/p&gt;

&lt;h2&gt;
  
  
  How about a game?
&lt;/h2&gt;

&lt;p&gt;For the past couple of months I've worked on a game that I hope can make it easier to teach people Elm. Why a game?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want people to have a fun first meeting with Elm.&lt;/li&gt;
&lt;li&gt;Any workshop assignment that feels like work won't motivate people to spend any time in Elm after the workshop ends. When our biggest adversary is time, motivating people to make time is key. It also helps if they remain motivated throughout the day, learning things is hard.&lt;/li&gt;
&lt;li&gt;A game is complex enough that people can discover some of the benefits of Elm on their own, while simple enough to not be overwhelming, especially if we keep commands, subscriptions and html out of it.&lt;/li&gt;
&lt;li&gt;The few people in the workshop who already know a little Elm will, hopefully, not get bored.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Announcing Elm Warrior
&lt;/h2&gt;

&lt;p&gt;The game is called Elm Warrior and is in large part inspired by &lt;a href="https://warriorjs.com"&gt;warrior-js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The goal of the game is to implement the intelligence of a warrior, named at, as it navigates mazes and battles dangerous opponents.&lt;/p&gt;

&lt;p&gt;As a player you're implementing a single pure function, which is called once every round to determine the action of your warrior. You use whatever you would use to program in Elm proper, and you don't need to learn the elm architecture or the html library to do anything useful. The API is small and simple to learn.&lt;/p&gt;

&lt;p&gt;There are 12 builtin maps to keep you busy. Should you get bored, there are API's for making your own maps and customising the rules for when a game is won or lost. It is also possible to define a multiplayer game, where several players create their own warriors and fight to the virtual death. I recently hosted a deathmatch with some colleagues at work and it was a blast!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0oh84J6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/robinheghan/elm-warrior-multiplayer/blob/master/screen.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0oh84J6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/robinheghan/elm-warrior-multiplayer/blob/master/screen.png%3Fraw%3Dtrue" alt="Multiplayer game in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elm Warrior is not enough to learn Elm on its own, but I'm hoping it will serve as a fun and simple enough tool to get people comfortable with Elm's syntax og basic constructs.&lt;/p&gt;

&lt;p&gt;Even if that does not prove to be the case, it's still a lot of fun to play.&lt;/p&gt;

&lt;p&gt;To get started, click &lt;a href="https://package.elm-lang.org/packages/robinheghan/elm-warrior/latest/"&gt;this link&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>programming</category>
      <category>warrior</category>
      <category>game</category>
    </item>
    <item>
      <title>Improving Elm's compiler output</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Sat, 25 May 2019 14:50:43 +0000</pubDate>
      <link>https://dev.to/robinheghan/improving-elm-s-compiler-output-5e1h</link>
      <guid>https://dev.to/robinheghan/improving-elm-s-compiler-output-5e1h</guid>
      <description>&lt;p&gt;Elm is fast.&lt;/p&gt;

&lt;p&gt;This is not because of any innovation in the compiler. In fact, the Elm compiler hardly does any optimization at all.&lt;/p&gt;

&lt;p&gt;Elm is fast because it compiles to Javascript, which dedicated and talented engineers from all over the globe have been optimizing for more than a decade.&lt;/p&gt;

&lt;p&gt;But here's a question: does the Elm compiler output Javascript which makes it easy for browsers to optimize it and, if not, is there any performance to gain by changing how the compiler outputs Javascript?&lt;/p&gt;

&lt;p&gt;Let's have a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden classes
&lt;/h2&gt;

&lt;p&gt;Javascript is a dynamic language. Javascript allows objects to change in shape at any time. Variables and data structures can contain different values of different types at any time. In practice, however, most programs are fairly static and browsers try to take advantage of this.&lt;/p&gt;

&lt;p&gt;In Chrome, every object literal and class is seen as a shape. If the shape of an object or class changes, like a property being dynamicly added or removed, Chrome will see the resultant new shape and try to convert between them. In some cases, Chrome will just treat objects as hashmaps (kinda like Elm's &lt;code&gt;Dict&lt;/code&gt;) if it has trouble figuring out the precise shape of something. We call these shapes for hidden classes.&lt;/p&gt;

&lt;p&gt;We get the best performance when our Javascript code doesn't seem to deal with many different shapes at a time. Fortunately, Elm is a static language so this should be pretty common. There is, however, a case where Elm does produce different shapes that can pass as the same type. Let's look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how Elm's &lt;code&gt;Maybe&lt;/code&gt; is defined. It is compiled into the following Javascript (using &lt;code&gt;--optimized&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;elm$core$Maybe$Just&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;elm$core$Maybe$Nothing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the Javascript object literal for &lt;code&gt;Just&lt;/code&gt; and &lt;code&gt;Nothing&lt;/code&gt; has different shapes. As a result, every Javascript code which deals with &lt;code&gt;Maybe&lt;/code&gt; has to be able to deal with two different shapes. But is that costly?&lt;/p&gt;

&lt;p&gt;To measure the effect I've done two things:&lt;/p&gt;

&lt;p&gt;1) Make a benchmark which can hopefully pick up the performance difference, then make two versions where one is handcoded to avoid the overhead.&lt;br&gt;
2) Look at the assembly code which Node outputs (Node and Chrome uses the same JS engine, V8).&lt;/p&gt;

&lt;p&gt;You can find the code for this experiment at &lt;a href="https://github.com/Skinney/elm-code-gen-experiments"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've focused on Elm' built-in &lt;code&gt;List&lt;/code&gt; type, as it's used in pretty much every program. A performance improvement here would be a big benefit to everyone who uses Elm.&lt;/p&gt;

&lt;p&gt;We'll be focusing on the following benchmark:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;benchmark&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;int +"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;
  &lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldl&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;intList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply a left fold over all the elements, adding them together. A change in performance here will tell us how quickly we can iterate through a &lt;code&gt;List&lt;/code&gt;, the theory being that removing any overhead dealing with multiple hidden classes should increase performance.&lt;/p&gt;

&lt;p&gt;We compile the benchmark. Looking through the compiled JS output, we can find this piece of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_List_Nil&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;_List_Cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The empty &lt;code&gt;List&lt;/code&gt; looks different from a &lt;code&gt;List&lt;/code&gt; element (if you're wondering how &lt;code&gt;List&lt;/code&gt;s work, I explained it decently well at &lt;a href="https://www.youtube.com/watch?v=mmiNobpx7eI"&gt;Elm Europe 2017&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We copy the JS file, and make the following modificaiton:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_List_Nil&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;_List_Cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;List&lt;/code&gt; should no longer be polymorphic (of many shapes).&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firefox, before modification: 75,843 ops/sec&lt;/li&gt;
&lt;li&gt;Firefox, after modification: 84,549 ops/sec&lt;/li&gt;
&lt;li&gt;Safari, before modification: 248,531 ops/sec&lt;/li&gt;
&lt;li&gt;Safari, after modification: 248,530 ops/sec&lt;/li&gt;
&lt;li&gt;Chrome, before modification: 294,434 ops/sec&lt;/li&gt;
&lt;li&gt;Chrome, after modification: 302,569 ops/sec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, no difference in Safari, however both Chrome and Firefox see a pretty decent improvement: ~11% in Firefox, ~4% in Chrome. Keep in mind that this is something that can be implemented in the compiler, no Elm code would have to change, it's a performance improvement for no effort on the part of application developers.&lt;/p&gt;

&lt;p&gt;We can also look at the code that V8 generates by running the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--print-opt-code&lt;/span&gt; &lt;span class="nt"&gt;--code-comments&lt;/span&gt; index.js &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; jit_log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By reading the &lt;code&gt;jit_log&lt;/code&gt; for the benchmark run without modifications, we can see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--------&lt;/span&gt; Optimized code &lt;span class="nt"&gt;---&lt;/span&gt;
optimization_id &lt;span class="o"&gt;=&lt;/span&gt; 1
source_position &lt;span class="o"&gt;=&lt;/span&gt; 48049
kind &lt;span class="o"&gt;=&lt;/span&gt; OPTIMIZED_FUNCTION
name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$List$foldl&lt;/span&gt;
stack_slots &lt;span class="o"&gt;=&lt;/span&gt; 10
compiler &lt;span class="o"&gt;=&lt;/span&gt; turbofan
address &lt;span class="o"&gt;=&lt;/span&gt; 0x28bd2bd6e9a1
Body &lt;span class="o"&gt;(&lt;/span&gt;size &lt;span class="o"&gt;=&lt;/span&gt; 2292&lt;span class="o"&gt;)&lt;/span&gt;
Instructions &lt;span class="o"&gt;(&lt;/span&gt;size &lt;span class="o"&gt;=&lt;/span&gt; 2012&lt;span class="o"&gt;)&lt;/span&gt;
&amp;lt;Assembly code&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While for the modified code we see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--------&lt;/span&gt; Optimized code &lt;span class="nt"&gt;---&lt;/span&gt;
optimization_id &lt;span class="o"&gt;=&lt;/span&gt; 0
source_position &lt;span class="o"&gt;=&lt;/span&gt; 48067
kind &lt;span class="o"&gt;=&lt;/span&gt; OPTIMIZED_FUNCTION
name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$List$foldl&lt;/span&gt;
stack_slots &lt;span class="o"&gt;=&lt;/span&gt; 10
compiler &lt;span class="o"&gt;=&lt;/span&gt; turbofan
address &lt;span class="o"&gt;=&lt;/span&gt; 0x2081135eec01
Body &lt;span class="o"&gt;(&lt;/span&gt;size &lt;span class="o"&gt;=&lt;/span&gt; 1848&lt;span class="o"&gt;)&lt;/span&gt;
Instructions &lt;span class="o"&gt;(&lt;/span&gt;size &lt;span class="o"&gt;=&lt;/span&gt; 1600&lt;span class="o"&gt;)&lt;/span&gt;
&amp;lt;Assembly code&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected, it generated less code when the code doesn't have to deal with polymorphism.&lt;/p&gt;

&lt;p&gt;There is, however, something in both of this logs which give me pause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Inlined functions &lt;span class="o"&gt;(&lt;/span&gt;count &lt;span class="o"&gt;=&lt;/span&gt; 1&lt;span class="o"&gt;)&lt;/span&gt;
 0x3f2705632551 &amp;lt;SharedFunctionInfo A2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section of the log lists how many functions have been inlined. In this case, only a function which evaluates the passed in function has been inlined (I'll explain what this mean in a second). This isn't actually that surprising. &lt;code&gt;foldl&lt;/code&gt; only contains a single function call, which is done once per loop. This function is usually never the same either, so it makes sense that it wasn't inlined. However, if you look at all the other functions that have been optimized, the only functions which are inlined are either functions which take a single argument (also called arity-1 functions) or functions called A2, A3, A4 etc.&lt;/p&gt;

&lt;p&gt;What gives?&lt;/p&gt;

&lt;h2&gt;
  
  
  Inlining
&lt;/h2&gt;

&lt;p&gt;Inlining function calls (replacing the function call with the implementation of the function) is one of the most important optimizations a compiler can make. This is not necessarily because function calls are all that expensive, but because it allows the compiler to better understand what the code does and perform optimizations based on that.&lt;/p&gt;

&lt;p&gt;Let's look at our benchmark again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;benchmark&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;int +"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;
  &lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldl&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;intList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without inlining, this would call the &lt;code&gt;foldl&lt;/code&gt; function, which is a loop calling a function for every element in the list. Since &lt;code&gt;foldl&lt;/code&gt; can accept any function, it would store the intermediary number value as a reference (even though it could be stored as a number on the stack), performing a lookup in memory each time the function is called. If we weren't storing ints as intermediary values, as it would be the case if we were folding over other things, the Javscript optimizer would likely treat all values as a generic hashmap inside of &lt;code&gt;foldl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With inlining, however, this function is likely to be compiled down to a single javascript loop, without any function calls at all, and with specialized code for the types actually used in the loop. This is like getting the benefits of a monomorphising compiler, without actually having a monomorphishing compiler.&lt;/p&gt;

&lt;p&gt;But why aren't many functions being inlined, and what are all these A2 things?&lt;/p&gt;

&lt;h2&gt;
  
  
  Currying
&lt;/h2&gt;

&lt;p&gt;Elm has this concept of currying. Given the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create a new function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;add2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;add2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you call a function with enough arguments, it will execute. If you call a function without all the arguments it requires, it returns a new function which accepts the missing arguments.&lt;/p&gt;

&lt;p&gt;This is how the above &lt;code&gt;add&lt;/code&gt; function is compiled to JS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;F&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;F2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;F&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;author$project$Main$add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;F2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;add&lt;/code&gt; function, as well as every other Elm function, is wrapped in an object which contains the original function, the arity that function expects, and a curried function. Calling the function has to be done with &lt;code&gt;A2&lt;/code&gt;, which is implemented like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So A2 takes a F2 object, and calls the function directly if the provided function actually takes two arguments, or does a curried call if not.&lt;/p&gt;

&lt;p&gt;From the perspective of a javascript engine, this has a big problem: unless we do whole program analysis (which is too expensive) there's no way to know if the function itself should be called, or if it is to be called using currying. The A2 call itself can be inlined, but nothing more.&lt;/p&gt;

&lt;p&gt;But what if we made the Elm compiler smarter? If the Elm compiler knew how many arguments a function required, it could re-write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;author$project$Main$add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;author$project$Main$add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We make a copy of our benchmark, and make these changes by hand for every function call in our benchmark, and in the functions called by the benchmark.&lt;/p&gt;

&lt;p&gt;This time we're going to focus on the results for the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;benchmark&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;* 2"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;
  &lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;intList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firefox, before modification: 24,291 ops/sec&lt;/li&gt;
&lt;li&gt;Firefox, after modification: 50,927 ops/sec&lt;/li&gt;
&lt;li&gt;Safari, before modification: 35,723 ops/sec&lt;/li&gt;
&lt;li&gt;Safari, after modification: 49,029 ops/sec&lt;/li&gt;
&lt;li&gt;Chrome, before modification: 39,253 ops/sec&lt;/li&gt;
&lt;li&gt;Chrome, after modification: 58,491 ops/sec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty good. The performance in Firefox is doubled, while we're seeing ~30% improvements in Chrome and Safari.&lt;/p&gt;

&lt;p&gt;When looking at the inlining results of the unmodified code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Inlined functions &lt;span class="o"&gt;(&lt;/span&gt;count &lt;span class="o"&gt;=&lt;/span&gt; 1&lt;span class="o"&gt;)&lt;/span&gt;
 0x13f84c332341 &amp;lt;SharedFunctionInfo A2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see there's been some changes after the modifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Inlined functions &lt;span class="o"&gt;(&lt;/span&gt;count &lt;span class="o"&gt;=&lt;/span&gt; 5&lt;span class="o"&gt;)&lt;/span&gt;
 0x1f31bec396e1 &amp;lt;SharedFunctionInfo &lt;span class="nv"&gt;$map&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 0x1f31bec395a9 &amp;lt;SharedFunctionInfo &lt;span class="nv"&gt;$foldr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 0x1f31bec39541 &amp;lt;SharedFunctionInfo &lt;span class="nv"&gt;$foldrHelper&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 0x1f31bec32049 &amp;lt;SharedFunctionInfo F2&amp;gt;
 0x1f31bec31fe1 &amp;lt;SharedFunctionInfo F&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, looking over the generated assembly code I'm seeing a lot of lines containing the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;call 0x1e5fad48abe0  &lt;span class="o"&gt;(&lt;/span&gt;Call_ReceiverIsNotNullOrUndefined&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we're calling functions using &lt;code&gt;someObject.f(args)&lt;/code&gt;, Chrome has to make sure that &lt;code&gt;someObject&lt;/code&gt; isn't &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I've run one more benchmark. This time I've placed functions outside of &lt;code&gt;F&lt;/code&gt; wrappers, and call them directly.&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firefox, before modification: 50,927 ops/sec&lt;/li&gt;
&lt;li&gt;Firefox, after modification: 59,632 ops/sec&lt;/li&gt;
&lt;li&gt;Safari, before modification: 49,029 ops/sec&lt;/li&gt;
&lt;li&gt;Safari, after modification: 43,695 ops/sec&lt;/li&gt;
&lt;li&gt;Chrome, before modification: 58,491 ops/sec&lt;/li&gt;
&lt;li&gt;Chrome, after modification: 63,619 ops/sec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chrome and Firefox see some nice speedups, ~16% for Firefox and ~8% for Chrome. Safari actually sees a slowdown but I don't know why. Re-running the benchmarks several times gives wildly different results, and I don't know what to make of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Elm is fast, but there's still room to become faster. By making changes to how the Elm compiler outputs Javascript, we can increase the performance of Elm programs by a significant margin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;If you want to know more on how Chrome makes Javascript fast, these are the two best resources I came across:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html"&gt;Whats up with monomorphism&lt;/a&gt;&lt;br&gt;
&lt;a href="https://v8.dev/blog/elements-kinds"&gt;V8 Kinds&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elm</category>
      <category>compilers</category>
      <category>optimization</category>
      <category>performance</category>
    </item>
    <item>
      <title>Language Idea: Limit custom types to three arguments</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Sun, 23 Sep 2018 19:35:20 +0000</pubDate>
      <link>https://dev.to/robinheghan/language-idea-limit-custom-types-to-three-arguments-27p1</link>
      <guid>https://dev.to/robinheghan/language-idea-limit-custom-types-to-three-arguments-27p1</guid>
      <description>&lt;p&gt;&lt;em&gt;Language Idea is a new series where I note down some ideas I have on how Elm could improve as a language. Each post isn't necessarily a fully thought out idea, as part of my thinking process is writing stuff down. This is more a discussion starter than anything else.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In Elm 0.19 you can no longer create tuples which contains more than three elements. The reasoning behind this is that it's easy to lose track of what the elements represents after that. As an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is a bit more cryptic than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;xPosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yPosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;
&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule here is quite simple, if you feel yourself in need of a tuple containing more than three elements you're better of using a record with named fields.&lt;/p&gt;

&lt;p&gt;There is, however, another way in which you can work around this restriction in Elm 0.19.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Types
&lt;/h2&gt;

&lt;p&gt;Yes. Custom types can still contain more than three parameters. Which is strange, as there is little to separate tuples from custom types with the exception of syntax and comparability.&lt;/p&gt;

&lt;p&gt;Let me be clear though, you should prefer records with named fields. Names provide basic documentation, and records let you forget about what order parameters are in. I'd say that even when you're using custom types, you should always limit them to three (maybe even two) parameters and use records if you need more than that.&lt;/p&gt;

&lt;p&gt;As to why Elm allows more than three parameters in custom types; I don't know. It might just be an oversight.&lt;/p&gt;

&lt;p&gt;So here is a question: should Elm limit the number of parameters in custom types to three, as it does with tuples?&lt;/p&gt;

&lt;p&gt;I think it should.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: The idea here is that one can do &lt;code&gt;type Person = Person { name : String, age : Int }&lt;/code&gt; instead of &lt;code&gt;type Person = Person String Int&lt;/code&gt; as it would make it more obious what each parameter is. It should then be encouraged to use records within custom types if there are many fields to store within the custom type.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>Elm 0.19 brings better collections</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Tue, 21 Aug 2018 19:39:22 +0000</pubDate>
      <link>https://dev.to/robinheghan/elm-019-brings-better-collections-3320</link>
      <guid>https://dev.to/robinheghan/elm-019-brings-better-collections-3320</guid>
      <description>&lt;p&gt;You're probably aware of this already but Elm 0.19 has just been released. When you read through the release notes and the documentation of the core library, you might to think that nothing has changed with regards to the built-in collection types: &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;Dict&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You'd be wrong.&lt;/p&gt;

&lt;p&gt;While it is true that the API remains entirely the same, there are huge changes under the covers which results in more performance, and a bug-free &lt;code&gt;Array&lt;/code&gt; implementation. Let's take a closer look.&lt;/p&gt;

&lt;h2&gt;
  
  
  List
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;List&lt;/code&gt; is the data structure which have changed the least. In fact, the underlying data structure hasn't changed at all. The only thing which have changed is the implementation of &lt;code&gt;List.foldr&lt;/code&gt; which is now faster by about 30%.&lt;/p&gt;

&lt;p&gt;This alone might not seem to be that big of a deal, but considering &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;append&lt;/code&gt; are all implemented on top of &lt;code&gt;foldr&lt;/code&gt;, this means that &lt;code&gt;List&lt;/code&gt; is quite a bit faster across the board.&lt;/p&gt;

&lt;p&gt;If you want to know more about the actual implementation, you can take a look at this &lt;a href="https://github.com/elm/core/pull/872"&gt;PR&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dict and Set
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Dict&lt;/code&gt; has actually been re-written from scratch while retaining the original API. The benefits of this new implementation is mostly that of performance. We're talking 170% faster inserts and about 30% faster removals.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Set&lt;/code&gt; is just a thin wrapper around &lt;code&gt;Dict&lt;/code&gt;, and so &lt;code&gt;Set&lt;/code&gt; benefits from the new implementation as well.&lt;/p&gt;

&lt;p&gt;More info in the &lt;a href="https://github.com/elm/core/pull/959"&gt;PR&lt;/a&gt; and these development updates: &lt;a href="https://groups.google.com/forum/#!topic/elm-dev/--fK-wMoDig"&gt;#1&lt;/a&gt;, &lt;a href="https://groups.google.com/forum/#!topic/elm-dev/T-PHQNrkNss"&gt;#2&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array
&lt;/h2&gt;

&lt;p&gt;Like &lt;code&gt;Dict&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt; has been totally re-written. The original code was in Javascript, and suffered from grave bugs that could cause runtime crashes and mutations. The new implementation is in mostly Elm, and all known bugs are fixed.&lt;/p&gt;

&lt;p&gt;From a performance stand point, the implementation is faster in some cases, while slower in others. More information in this &lt;a href="https://groups.google.com/forum/#!topic/elm-dev/TPUKXVXr1Hs"&gt;development update&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The API might be the same, however, a huge amount of work has been done to make these data structures better than ever before.&lt;/p&gt;

&lt;p&gt;There is a similar story for the &lt;code&gt;Random&lt;/code&gt; module, which has been re-implemented by Max Goldstein to be faster and more, you know, random. You can learn more by checking out this &lt;a href="https://github.com/elm/core/pull/778"&gt;PR&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>The case for replacing Array.slice</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Fri, 10 Aug 2018 18:28:14 +0000</pubDate>
      <link>https://dev.to/robinheghan/the-case-for-replacing-arrayslice-4gfc</link>
      <guid>https://dev.to/robinheghan/the-case-for-replacing-arrayslice-4gfc</guid>
      <description>&lt;p&gt;I recently did some work which required me to create a sub-section of an &lt;code&gt;Array&lt;/code&gt;. This can be done by using &lt;code&gt;Array.slice&lt;/code&gt; but doing so always gives me the feeling that there is room for improvement.&lt;/p&gt;

&lt;p&gt;To explain why, let's start by looking at a small example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Array.slice 2 5 someArray&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It isn't immediately obvious to me what this does. I know it creates a sub section, but when reading this I always have to stop up and calculate what the result will be. Usually, because I don't use this function too often, I also have to look up the documentation to check if the from and to indices are exclusive or inclusive.&lt;/p&gt;

&lt;p&gt;The conclusion is that this particular code will create a new array, containing the values of indices 2, 3 and 4 of &lt;code&gt;someArray&lt;/code&gt;. This might not seem too bad when you actually want to extract a sub-section of an array from some index and to (but not including) another, but in my experience that is rarely the case.&lt;/p&gt;

&lt;p&gt;Usually what you -- well, I -- want is either to remove the first couple of elements, or to remove the last couple of elements. Since &lt;code&gt;slice&lt;/code&gt; is all we got, we've always got to consider what value to use for both arguments, which adds a slight, but unnecessary, mental overhead.&lt;/p&gt;

&lt;p&gt;For instance, removing the first two elements is implemented as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Array.slice 2 (Array.length someArray) someArray&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This doesn't read as easily as &lt;code&gt;Array.drop 2 someArray&lt;/code&gt;, but another problem is that it doesn't play well with pipelines. Removing the last element is easier as &lt;code&gt;slice&lt;/code&gt; supports negative indices, although it is a little more cryptic than it has to be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Array.slice 0 -1 someArray&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Even if you actually want a true sub-section, I'd argue that it would be easier to understand the code if you expressed it as two separate operations, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;someArray
  |&amp;gt; Array.drop 2
  |&amp;gt; Array.take 3  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;someArray
  |&amp;gt; Array.drop 2
  |&amp;gt; Array.dropLast 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, I believe &lt;code&gt;slice&lt;/code&gt; is a bad fit for functional programming. Using functions which have a clear intent and an intuitive usage is a better fit, and so I believe &lt;code&gt;slice&lt;/code&gt; should be replaced with &lt;code&gt;take&lt;/code&gt;, &lt;code&gt;takeLast&lt;/code&gt;, &lt;code&gt;drop&lt;/code&gt; and &lt;code&gt;dropLast&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>api</category>
    </item>
    <item>
      <title>Exploring how Elm can target Web Assembly</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Mon, 28 May 2018 21:43:53 +0000</pubDate>
      <link>https://dev.to/robinheghan/exploring-how-elm-can-target-web-assembly-2050</link>
      <guid>https://dev.to/robinheghan/exploring-how-elm-can-target-web-assembly-2050</guid>
      <description>&lt;p&gt;Title sounds interesting, doesn't it? Last week I got this idea into my head that wouldn't leave. And so, I'm announcing ELS.&lt;/p&gt;

&lt;p&gt;What's ELS? It's an experimental compiler for a statically typed Lisp which compiles to Web Assembly. As to what ELS actually means... I'm not sure yet, but I'll be sure to let you know once I find a phrase it can be a fitting acronym for =)&lt;/p&gt;

&lt;p&gt;I imagine you might be a bit confused at this point. You might even have double checked the title to make sure it actually contains the word Elm, which it does. So why am I talking about Lisp?&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Assembly
&lt;/h2&gt;

&lt;p&gt;There are several people who've asked if, or when, Elm will target Web Assembly (WASM). I do believe Elm will target WASM eventually as it will let us escape some wierd Javascript semantics (like 53-bit ints, ugh), promises smaller asset sizes and (maybe) better performance.&lt;/p&gt;

&lt;p&gt;It's early days, however, and targeting WASM isn't as easy as targeting Javascript. There are no objects in WASM. No arrays, strings or closures. Heck, there isn't even a builtin memory allocator, let alone a garbage collector.&lt;/p&gt;

&lt;p&gt;Now, a garbage collector will come sometime in the future. So in the meantime, the time of Evan (author of Elm) is better spent on other things.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's this ELS thing about?
&lt;/h2&gt;

&lt;p&gt;Well. Even though adding Elm support in the compiler will be a huge effort for potentially little gain (let's be honest, there are better ways to improve Elm than what it compiles to), that doesn't mean that exploring the space is wasted effort. As Evan has said previously: "Code is the easy part."&lt;/p&gt;

&lt;p&gt;How should ports work in a WASM world? How should strings work? Would using the future builtin GC be best, or could a language like Elm do better with a custom GC scheme? How do we compile curried functions to WASM? How would the REPL work? Could Erlang like processes be implemented?&lt;/p&gt;

&lt;p&gt;There are a bunch of questions to answer, and there is no reason not to explore that space early on. If we're lucky, by the time Elm is ready to target WASM, some of the ground work will be done already.&lt;/p&gt;

&lt;h2&gt;
  
  
  But... Lisp?
&lt;/h2&gt;

&lt;p&gt;So, I had a problem. I wanted to explore how Elm could compile down to WASM, but I don't really know how the Elm compiler works and, more importantly, don't know Haskell. Luckily, the important thing isn't actually to compile Elm, but compiling a language which has the same semantics as Elm. So I decided to build my own language in Javascript which meets that requirement. Since I don't really care what the language looks like, I chose syntax which was easy to parse, and that was Lisp (with type annotations, of course).&lt;/p&gt;

&lt;p&gt;There where other considerations as well. There already are tools for WASM in Javascript, and being able to execute WASM requires a Javascript environment. Writing the compiler in JS therefore makes things a bit simpler.&lt;/p&gt;

&lt;p&gt;The big downside is that none of the compiler work I do can be merged into the Elm compiler sometime down the road. But that's fine. This is an experiment, and I don't expect that the code I write is something one would want to re-use anyway.&lt;/p&gt;

&lt;p&gt;What I do hope is that the experience I get from this makes it possible for me to assist with porting Elm to WASM in the future. I might even be able to write some modules which Elm can make use of when that happens, like a string library or even a basic garbage collector which can serve as a stop gap until WASM gets a GC of its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I try it out?
&lt;/h2&gt;

&lt;p&gt;Sure. The code, and instructions for trying it out, are available &lt;a href="https://github.com/els-lang/compiler"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>webassembly</category>
    </item>
    <item>
      <title>De-throning the List: Summary</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Tue, 08 May 2018 22:37:31 +0000</pubDate>
      <link>https://dev.to/robinheghan/de-throning-the-list-summary-3f3c</link>
      <guid>https://dev.to/robinheghan/de-throning-the-list-summary-3f3c</guid>
      <description>&lt;p&gt;I've written a total of five posts (or six, including this one) about why I would like to replace the &lt;code&gt;List&lt;/code&gt; with &lt;code&gt;Array&lt;/code&gt;. If you'd missed one, here they all are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/skinney/de-throning-the-list-2fjk"&gt;Introduction - the grand plan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/skinney/de-throning-the-list-part-deux-4idm"&gt;Part Deux - Improving the &lt;code&gt;Array&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/skinney/de-throning-the-list-part--44dl"&gt;Part π - stoppable fold operations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/skinney/de-throning-the-list-part-sc4k-4e3n"&gt;Part SC4K - API changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/skinney/de-throning-the-list-part-boron-185"&gt;Part Boron - literal representation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These posts lists a ton of work. First we need to alter the &lt;code&gt;Array&lt;/code&gt; implementation to improve performance in even more cases. Then we need to make it more extensible by introducing stoppable fold operations. Then we need to add functions that currently exists for &lt;code&gt;List&lt;/code&gt;, but not for &lt;code&gt;Array&lt;/code&gt;. Finally, we can make the Elm compiler output a literal representation of &lt;code&gt;Array&lt;/code&gt; directly in the javascript code.&lt;/p&gt;

&lt;p&gt;But why do all this work? Because I honestly believe Elm becomes easier to learn if the default collection type not only works similarly to the default collection type in other languages, but also provides decent performance for most cases you wish to use it with. I also believe Elm will become faster in the general case, if &lt;code&gt;Array&lt;/code&gt; is used in all the places &lt;code&gt;List&lt;/code&gt; is used today.&lt;/p&gt;

&lt;p&gt;I might not be right. But I do think it will be an undertaking worth taking. Or... Uh... You know what I mean.&lt;/p&gt;

&lt;p&gt;The next and first step of this journey will be to upgrade the &lt;code&gt;Array&lt;/code&gt; implementation from being a HAMT to an RRB-Tree. This process will probably take a while, but expect a new blog post with benchmark results when it happens.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>De-throning the List: Part Boron</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Tue, 08 May 2018 22:35:45 +0000</pubDate>
      <link>https://dev.to/robinheghan/de-throning-the-list-part-boron-185</link>
      <guid>https://dev.to/robinheghan/de-throning-the-list-part-boron-185</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/skinney/de-throning-the-list-part-sc4k-4e3n"&gt;last post&lt;/a&gt; of this series, we talked about extending the API for &lt;code&gt;Array&lt;/code&gt; to make it as usable as &lt;code&gt;List&lt;/code&gt;. In this post, we'll look at how making &lt;code&gt;Array&lt;/code&gt; the default collection could reduce overhead, and thus improve performance.&lt;/p&gt;

&lt;p&gt;In Elm 0.18, when the compiler sees an expression like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It compiles it into the following javascript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_some_namespace_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;ctor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;::&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;ctor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;::&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;ctor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;::&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;ctor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}}}};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is actually pretty nice, though it looks ugly, as it's theoretically the fastest way of creating a &lt;code&gt;List&lt;/code&gt;. Unfortunately, due to the way Chrome works it can also crash the browser if the &lt;code&gt;List&lt;/code&gt; literal is big enough. This has to do with the object literals being nested, the javascript engine can only support so much nesting before it crashes. You can read more about this in the following &lt;a href="https://github.com/elm-lang/elm-compiler/issues/1521"&gt;issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So in Elm 0.19, to avoid this problem, it will instead compile down to this javascript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_some_namespace_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_elm_core_fromArray&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but it does mean that every time you have a &lt;code&gt;List&lt;/code&gt; literal in your program, Elm will convert it from a javascript array at runtime. This extra conversion, could make your app a little slower.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much slower?
&lt;/h2&gt;

&lt;p&gt;I thought you'd never ask. It's benchmark time!&lt;/p&gt;

&lt;p&gt;This benchmark compares calling &lt;code&gt;List.foldl (\a b -&amp;gt; a + b) 0&lt;/code&gt; with &lt;code&gt;[1,2,3,4,5,6,7,8,9]&lt;/code&gt; using Elm 0.18's literal expression (nested objects) and 0.19 runtime conversion. By hand-editing the compiled output, we can get a benchmark of how the equivalent code with an &lt;code&gt;Array&lt;/code&gt; literal performs. You can read the benchmark code &lt;a href="https://github.com/Skinney/elm-array-exploration/blob/literals/bench/Main.elm"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The benchmark was run on the latest version of Chrome (v66), running the latest version of Mac OS X (High Sierra), on a Mid-2012 Macbook Air.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;List literal &lt;span class="nb"&gt;sum&lt;/span&gt;: 873,847 ops/sec
List runtime &lt;span class="nb"&gt;sum&lt;/span&gt;: 1,959,202 ops/sec &lt;span class="o"&gt;(&lt;/span&gt;124.2% faster than list literal&lt;span class="o"&gt;)&lt;/span&gt;
Array literal &lt;span class="nb"&gt;sum&lt;/span&gt;: 3,329,392 ops/sec &lt;span class="o"&gt;(&lt;/span&gt;40.61% faster than list runtime&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These results are pretty interesting. You'll see that runtime conversion is actually significantly faster than having a literal representation in Chrome. This is probably tied together with the runtime crashing issue described earlier. If we were to run this benchmark through Firefox and Safari, you'd see that runtime conversion is between 10-20% slower than literal representation.&lt;/p&gt;

&lt;p&gt;The more interesting thing is that an &lt;code&gt;Array&lt;/code&gt; literal would be faster still. From running this benchmark on different browsers with different sizes of &lt;code&gt;List&lt;/code&gt; literals, I think this has to do with the nesting of objects. Appearently, nested object literals are not good for performance. A &lt;code&gt;List&lt;/code&gt; is "just" nested objects, while &lt;code&gt;Array&lt;/code&gt; has a very flat structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What would an &lt;code&gt;Array&lt;/code&gt; literal look like?
&lt;/h2&gt;

&lt;p&gt;If &lt;code&gt;Array&lt;/code&gt; had been the default collection type, the compiler could've have turned it into the following javascript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_some_namespace_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;ctor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="na"&gt;_3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is shorter than the original literal representation for &lt;code&gt;List&lt;/code&gt;. It's also less nested. A &lt;code&gt;List&lt;/code&gt; with 1024 elements requires 1024 nested object literals when expressed as javascript, an &lt;code&gt;Array&lt;/code&gt; would require 3 nested literals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Although &lt;code&gt;List&lt;/code&gt; literals in Chrome is as slow as an asthmatic ant with heavy shopping, and might even crash the Elm application altogether, &lt;code&gt;Array&lt;/code&gt; literals are fast and safe.&lt;/p&gt;

&lt;p&gt;Literal syntax for &lt;code&gt;List&lt;/code&gt; is used heavily in Elm for stuff like Html nodes, so being able to construct such literals quickly is of huge value. By switching default collection type to &lt;code&gt;Array&lt;/code&gt; there is a clear performance win to be had.&lt;/p&gt;

&lt;p&gt;All my arguments and thoughts regarding making &lt;code&gt;Array&lt;/code&gt; the default collection type have now been made. Read this &lt;a href="https://dev.to/skinney/de-throning-the-list-summary-3f3c"&gt;next post&lt;/a&gt; for a summary of what I've written so far, and what I plan to do next.&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>De-throning the List: Part SC4K</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Mon, 23 Apr 2018 17:37:27 +0000</pubDate>
      <link>https://dev.to/robinheghan/de-throning-the-list-part-sc4k-4e3n</link>
      <guid>https://dev.to/robinheghan/de-throning-the-list-part-sc4k-4e3n</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/skinney/de-throning-the-list-part--44dl"&gt;last post&lt;/a&gt; we looked at how we could make &lt;code&gt;Array&lt;/code&gt; more expressive. By which I mean we added a way for people to extend the data structure to support more use cases. But while third parties now can add missing functionality, there are certain functions which should be supported out of the box, both for performance and convenience reasons.&lt;/p&gt;

&lt;p&gt;Elm has four built-in collection types: &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;Dict&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt;. With the exception of &lt;code&gt;Dict&lt;/code&gt;, these types look similar from a birds eye view. You can insert an item into the collection, get it back out, and even perform some task for every item stored. Of course, they do have different trade-offs which make them suitable for different situations.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;List&lt;/code&gt; is great when adding and retrieving items at the beginning (left side) of the collection. &lt;code&gt;Array&lt;/code&gt; is great when you need fast access to any element, and &lt;code&gt;Set&lt;/code&gt; is good when you need a sorted collection with no duplicates.&lt;/p&gt;

&lt;p&gt;The API for these collections are different as well. Sometimes this makes sense, but not always. For instance, there is no &lt;code&gt;sort&lt;/code&gt; function for &lt;code&gt;Set&lt;/code&gt;, which is reasonable as &lt;code&gt;Set&lt;/code&gt; is a sorted collection. However, there also isn't a &lt;code&gt;sort&lt;/code&gt; function for &lt;code&gt;Array&lt;/code&gt;, which means that you have to convert it to a &lt;code&gt;List&lt;/code&gt; or a &lt;code&gt;Set&lt;/code&gt; and then back again if you want it sorted.&lt;/p&gt;

&lt;p&gt;Converting from one collection type to another is a costly operation. If you use an &lt;code&gt;Array&lt;/code&gt; because it suits your use case most of the time, you don't want to convert to another collection just to perform that one operation.&lt;/p&gt;

&lt;p&gt;Let's look at how we can improve the API of &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt; to reduce the need for converting from one collection type to another to support the functionality you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differences which should remain
&lt;/h2&gt;

&lt;p&gt;Certain operations aren't supported on a collection type with good reason. For instance, there is not &lt;code&gt;get&lt;/code&gt; or &lt;code&gt;set&lt;/code&gt; operation on &lt;code&gt;List&lt;/code&gt; because the performance would be bad. If one need to &lt;code&gt;get&lt;/code&gt; or &lt;code&gt;set&lt;/code&gt; a random item in a collection, &lt;code&gt;Array&lt;/code&gt; should be used. Likewise, &lt;code&gt;union&lt;/code&gt;, &lt;code&gt;intersect&lt;/code&gt; and &lt;code&gt;diff&lt;/code&gt; should only be supported for &lt;code&gt;Set&lt;/code&gt;. Here are some functions that are not supported by all three collection types, which I believe shouldn't be supported either:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;insert&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, &lt;code&gt;::&lt;/code&gt; and &lt;code&gt;push&lt;/code&gt; can only be supported efficiently by their respective collections. If you're in need of one of these functions, it's a tell-tale sign of which collection you should use. However, with the improvements I've mentioned in earlier posts, &lt;code&gt;Array&lt;/code&gt; could support all of these functions efficiently, which is yet another reason as to why &lt;code&gt;Array&lt;/code&gt; should be the default collection type.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;indexedMap&lt;/code&gt; and &lt;code&gt;toIndexedList&lt;/code&gt; make no sense for &lt;code&gt;Set&lt;/code&gt;, as it doesn't operate by indexes and doesn't retain insertion order. &lt;code&gt;repeat&lt;/code&gt; doesn't make much sense for &lt;code&gt;Set&lt;/code&gt; either, as it cannot contain duplicates.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;union&lt;/code&gt;, &lt;code&gt;intersect&lt;/code&gt; and &lt;code&gt;diff&lt;/code&gt; can only be efficiently implemented by &lt;code&gt;Set&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head&lt;/code&gt; can be supported efficiently by the other collections, but the operation itself really only makes sense for &lt;code&gt;List&lt;/code&gt;. &lt;code&gt;Array&lt;/code&gt; would use &lt;code&gt;get 0&lt;/code&gt;, and it isn't quite clear what &lt;code&gt;head&lt;/code&gt; means in the case of &lt;code&gt;Sets&lt;/code&gt;, is it the first/lowest/minimal element or the root/middle element?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;sortBy&lt;/code&gt; and &lt;code&gt;sortWith&lt;/code&gt; doesn't make sense for &lt;code&gt;Set&lt;/code&gt;, but &lt;code&gt;Array&lt;/code&gt; should definitely get these functions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reverse&lt;/code&gt; can be implemented efficiently for &lt;code&gt;Array&lt;/code&gt;, but makes little sense for &lt;code&gt;Set&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where we could bridge the gap
&lt;/h2&gt;

&lt;p&gt;Below is a list of functions which can be easily supported across all three collections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;singleton&lt;/li&gt;
&lt;li&gt;initialize&lt;/li&gt;
&lt;li&gt;range&lt;/li&gt;
&lt;li&gt;concat&lt;/li&gt;
&lt;li&gt;intersperse&lt;/li&gt;
&lt;li&gt;member&lt;/li&gt;
&lt;li&gt;map2, map3, map4, map5&lt;/li&gt;
&lt;li&gt;concatMap&lt;/li&gt;
&lt;li&gt;filterMap&lt;/li&gt;
&lt;li&gt;partition&lt;/li&gt;
&lt;li&gt;take&lt;/li&gt;
&lt;li&gt;drop&lt;/li&gt;
&lt;li&gt;unzip&lt;/li&gt;
&lt;li&gt;slice&lt;/li&gt;
&lt;li&gt;sum&lt;/li&gt;
&lt;li&gt;product&lt;/li&gt;
&lt;li&gt;maximum&lt;/li&gt;
&lt;li&gt;minimum&lt;/li&gt;
&lt;li&gt;all&lt;/li&gt;
&lt;li&gt;any&lt;/li&gt;
&lt;li&gt;scanl&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While these functions could be supported across all three collections, does that mean they should? Since we're already messing about, let's ask ourselves if there are certain functions that shouldn't be in core to begin with.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sum&lt;/code&gt; and &lt;code&gt;product&lt;/code&gt; are essentially shortcuts for &lt;code&gt;List.foldl (+) 0&lt;/code&gt; and &lt;code&gt;List.foldl (*) 1&lt;/code&gt;. Are those operations common enough to grant them dedicated functions in the core library? If we introduce &lt;code&gt;slice&lt;/code&gt; for all three collections, do we need &lt;code&gt;take&lt;/code&gt; and &lt;code&gt;drop&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Do people actually use &lt;code&gt;map4&lt;/code&gt; and &lt;code&gt;map5&lt;/code&gt;? How about &lt;code&gt;scanl&lt;/code&gt; and &lt;code&gt;unzip&lt;/code&gt;? I mean, there probably are, but are those operations so common that one would expect to find them in core? Not that it necessarily does any harm, but there is something to be said of having a small, but powerful, package where you can read the entire documentation in a short sitting.&lt;/p&gt;

&lt;p&gt;Anyway, here's a list of which functions I, personally, see no reason for having in core. I expect people will tell me that these functions definitely belong, but I think it would be nice to at least have the discussion.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;intersperse&lt;/li&gt;
&lt;li&gt;map4&lt;/li&gt;
&lt;li&gt;map5&lt;/li&gt;
&lt;li&gt;concatMap&lt;/li&gt;
&lt;li&gt;unzip&lt;/li&gt;
&lt;li&gt;sum&lt;/li&gt;
&lt;li&gt;product&lt;/li&gt;
&lt;li&gt;scanl&lt;/li&gt;
&lt;li&gt;take&lt;/li&gt;
&lt;li&gt;drop&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Finishing touches
&lt;/h2&gt;

&lt;p&gt;Here are some minor things I think shouldn't be left out of a API renovation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;List&lt;/code&gt; and &lt;code&gt;Array&lt;/code&gt; has a &lt;code&gt;length&lt;/code&gt; function, &lt;code&gt;Set&lt;/code&gt; has &lt;code&gt;size&lt;/code&gt;. This is likely due to the fact that &lt;code&gt;Set&lt;/code&gt; is a thin abstraction on top of &lt;code&gt;Dict&lt;/code&gt; and so has just copied the name. I would rename &lt;code&gt;Set.size&lt;/code&gt; to &lt;code&gt;Set.length&lt;/code&gt; out of consistency if nothing else.&lt;/p&gt;

&lt;p&gt;Now that I'm on the topic, since &lt;code&gt;Set&lt;/code&gt; is  thin abstraction on top of &lt;code&gt;Dict&lt;/code&gt;, maybe everything discussed up til this point applies to &lt;code&gt;Dict&lt;/code&gt; as well?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;List&lt;/code&gt; has &lt;code&gt;::&lt;/code&gt; and &lt;code&gt;tail&lt;/code&gt;. The analogous for &lt;code&gt;Array&lt;/code&gt; is &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt;. &lt;code&gt;pop&lt;/code&gt; is missing from the API, so I would add it.&lt;/p&gt;

&lt;p&gt;I would add &lt;code&gt;find&lt;/code&gt; for all three collections. &lt;code&gt;List&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt; already supports &lt;code&gt;member&lt;/code&gt;, which is essentially &lt;code&gt;find&lt;/code&gt; except that it returns a boolean instead of the value for which the predicate function returns true. It's a more useful function in general, and so if &lt;code&gt;member&lt;/code&gt; should be a part of the API (which I believe it should) then &lt;code&gt;find&lt;/code&gt; belongs as well.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;Set&lt;/code&gt; and &lt;code&gt;Dict&lt;/code&gt; I would throw in &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; to retrieve the minimum/first and maximum/last element.&lt;/p&gt;

&lt;p&gt;I think &lt;code&gt;Stack&lt;/code&gt; is a better name than &lt;code&gt;List&lt;/code&gt; and so would rename that type. It's a name that more clearly explains what that collection type is good at.&lt;/p&gt;

&lt;p&gt;Finally, as mentioned in the previous post, I think &lt;code&gt;stoppableFoldl&lt;/code&gt; and &lt;code&gt;stoppableFoldr&lt;/code&gt;, or something with the same functionality but with better names, should be added to the API of &lt;code&gt;Array&lt;/code&gt;. I think &lt;code&gt;Dict&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt; could be well served with that functionality as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you think?
&lt;/h2&gt;

&lt;p&gt;The goal I'm trying to reach is to make the &lt;code&gt;Array&lt;/code&gt; type more general purpose, but when improving the &lt;code&gt;Array&lt;/code&gt; API, it makes sense to look at the other collection types as well. This article lays out what I believe those APIs should look like.&lt;/p&gt;

&lt;p&gt;First, I want to say that I'm not authority on what makes it into Elm. If I actually code up the suggestions in this article and submit it as a proposal, all of it could make it in, or none of it.&lt;/p&gt;

&lt;p&gt;Second, all these suggestions are based on my own experience. What I need is your experience. Does these suggestions make sense, or am I off my rockers? Let me know in the discussion thread on the &lt;a href="https://discourse.elm-lang.org/t/de-throning-the-list/997/32"&gt;Elm Discourse&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  And now, for something quite different
&lt;/h2&gt;

&lt;p&gt;So, is this the end of this series? Not quite. There's a summary left the be published, but that will have to wait until after we go over the top (you didn't think I'd forgot, did you?) in the &lt;a href="https://dev.to/skinney/de-throning-the-list-part-boron-185"&gt;next post&lt;/a&gt;, which is about the literal representation of &lt;code&gt;List&lt;/code&gt; and &lt;code&gt;Array&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>De-throning the List: Part π</title>
      <dc:creator>Robin Heggelund Hansen</dc:creator>
      <pubDate>Sun, 22 Apr 2018 11:49:11 +0000</pubDate>
      <link>https://dev.to/robinheghan/de-throning-the-list-part--44dl</link>
      <guid>https://dev.to/robinheghan/de-throning-the-list-part--44dl</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/skinney/de-throning-the-list-part-deux-4idm"&gt;last post&lt;/a&gt;, we looked at how we could alter the implementation of &lt;code&gt;Array&lt;/code&gt; to make it a more general purpose than it already is (like, five stars). In this post, we’ll see if we can make it more extensible.&lt;/p&gt;

&lt;p&gt;Extensible? What does that mean?&lt;/p&gt;

&lt;p&gt;Let’s see how we would implement a function like &lt;code&gt;find&lt;/code&gt; for &lt;code&gt;Array&lt;/code&gt;. &lt;code&gt;find&lt;/code&gt; takes a predicate function and a collection, and returns the first item in the collection for which the predicate returns true, or &lt;code&gt;Nothing&lt;/code&gt; if the predicate never returns true.&lt;/p&gt;

&lt;p&gt;The only way to implement this for &lt;code&gt;Array&lt;/code&gt; is by using &lt;code&gt;foldl&lt;/code&gt; or &lt;code&gt;foldr&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;foldl&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;result&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kt"&gt;Nothing&lt;/span&gt;
        &lt;span class="n"&gt;array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this implementation does what we want, it isn’t that efficient. When this implementation finds what we’re looking for, it will keep iterating through all the remaining items in the collection. Depending on the size of the array, this can be very slow.&lt;/p&gt;

&lt;p&gt;Is &lt;code&gt;List&lt;/code&gt; any better? Yes, yes it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="kt"&gt;Nothing&lt;/span&gt;

        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implementation does exactelly what we want. This is a benefit of &lt;code&gt;List&lt;/code&gt; being a simple data structure, it’s easy to pattern match on it to get the functionality we want. I explained briefly in my first post why the internal structure of &lt;code&gt;Array&lt;/code&gt; is not exposed like this, but I’ll say it again: it’s simply not simple, and it’s easy to make mistakes that can cause hard to find bugs. Now, before you go all «Off with &lt;code&gt;Array&lt;/code&gt;s head», let’s explore how we can get this same extensibility for &lt;code&gt;Array&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Looking at the &lt;code&gt;List&lt;/code&gt; version of &lt;code&gt;find&lt;/code&gt;, what we need is a way to iterate through the collection but be able to say «Hey! That’s my horse!» at any point and cut the iteration short. We could borrow an idea from Common Lisp and add a new function to the &lt;code&gt;Array&lt;/code&gt; API which allows us to signal that we’re done iterating. Such a function, called &lt;code&gt;stoppableFoldl&lt;/code&gt; in the example below, would allow us to implement &lt;code&gt;find&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stoppableFoldl&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="kt"&gt;Done&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="kt"&gt;Continue&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kt"&gt;Nothing&lt;/span&gt;
        &lt;span class="n"&gt;array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That doesn’t look so bad. Let’s see how these implementations stack up against each other, performance wise. The benchmarks below were run on a mid-2012 Macbook Air, using the latest version of Chrome. The benchmark creates a list and an array with 100 elements, and tries to find a value in the middle of the collection. The code can be found &lt;a href="https://github.com/Skinney/elm-array-exploration/blob/stoppable-foldl/bench/Main.elm"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;List:   402,870 ops/sec
Array:  227,745 ops/sec
% diff: &lt;span class="nt"&gt;-43&lt;/span&gt;.47% 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auch. It’s seems &lt;code&gt;List&lt;/code&gt; is still faster. It’s probably a combination of calling a function for every item in the &lt;code&gt;Array&lt;/code&gt;, as well as performing an extra allocation per item (Done/Continue).&lt;/p&gt;

&lt;p&gt;"But Robin," you say. "Doesn't this benchmark prove that &lt;code&gt;List&lt;/code&gt; is better than &lt;code&gt;Array&lt;/code&gt;? Is the reason behind this blog post taking so long to publish that you've been wandering around town soothing your bruised pride with alcohol?"&lt;/p&gt;

&lt;p&gt;Yes. I mean no! My argument in this series has been that &lt;code&gt;Array&lt;/code&gt; should be the default because it's a more general purpose data structure when compared to the &lt;code&gt;List&lt;/code&gt;. This doesn't mean that &lt;code&gt;Array&lt;/code&gt; will beat &lt;code&gt;List&lt;/code&gt; in all benchmarks, but that it will have decent performance for most operations.&lt;/p&gt;

&lt;p&gt;For instance, we can just as well provide a &lt;code&gt;stoppableFoldr&lt;/code&gt; function to make it possible to implement &lt;code&gt;findLast&lt;/code&gt;. The performance for &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;findLast&lt;/code&gt; would be about the same. This would not be the case for &lt;code&gt;List&lt;/code&gt;, which would have worse performance for &lt;code&gt;findLast&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That’s the point I’m trying to make: &lt;code&gt;List&lt;/code&gt; is very good at a few things, &lt;code&gt;Array&lt;/code&gt; is fine for most things. Even &lt;code&gt;Array&lt;/code&gt; makes use of &lt;code&gt;List&lt;/code&gt; in it’s internal implementation (take a look at how &lt;code&gt;Array.filter&lt;/code&gt; is implementated). For most applications, the &lt;code&gt;Array&lt;/code&gt; is a better default. So maybe &lt;code&gt;Array&lt;/code&gt; shouldn’t outright replace &lt;code&gt;List&lt;/code&gt;, but simply be the data type that is constructed when literal syntax is used (like &lt;code&gt;[1, 2, 3]&lt;/code&gt;). It might even be a good idea to rename &lt;code&gt;List&lt;/code&gt; to &lt;code&gt;Stack&lt;/code&gt; to signal what it really is good at.&lt;/p&gt;

&lt;h1&gt;
  
  
  What remains?
&lt;/h1&gt;

&lt;p&gt;There are still things you cannot do with &lt;code&gt;Array&lt;/code&gt; which are available with &lt;code&gt;List&lt;/code&gt;. In the &lt;a href="https://dev.to/skinney/de-throning-the-list-part-sc4k-4e3n"&gt;next part&lt;/a&gt; of this series, we’ll compare the API exposed by the &lt;code&gt;Array&lt;/code&gt; and &lt;code&gt;List&lt;/code&gt; module, and see where we need to bridge the gap, and perhaps even where the gap shouldn’t be bridged.&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
  </channel>
</rss>
