<?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>Forem: Kristian Pedersen</title>
    <description>The latest articles on Forem by Kristian Pedersen (@kristianpedersen).</description>
    <link>https://forem.com/kristianpedersen</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%2F383155%2F4f4d19f6-8c66-4ea2-a914-6db26365ce91.png</url>
      <title>Forem: Kristian Pedersen</title>
      <link>https://forem.com/kristianpedersen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kristianpedersen"/>
    <language>en</language>
    <item>
      <title>#30daysofelm Day 30: Closing thoughts</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Fri, 15 Jan 2021 15:00:18 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-30-closing-thoughts-2oka</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-30-closing-thoughts-2oka</guid>
      <description>&lt;p&gt;This is the last day of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Today is less about code, and more about how this whole project went.&lt;/p&gt;

&lt;p&gt;In short, the 30 days have been successful. I'm now at a place where I know enough basics to make something, and be able to ask good questions when I get stuck.&lt;/p&gt;

&lt;p&gt;Writing these posts takes a lot of time, so I'm looking forward to putting more energy into some personal projects that I want to to re-make and improve. &lt;/p&gt;

&lt;p&gt;Looking at all the comments and help I've gotten, I can safely say that the Elm community is extremely helpful and beginner-friendly. Hopefully I can thank some of the commenters in person at a conference or meetup in the future! :)&lt;/p&gt;

&lt;p&gt;I still think it would be nice to write occasionally to keep the momentum going, and get the benefits in terms of deeper thinking and great feedback. I'll think about how to approach this during the weekend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Why Elm?&lt;/li&gt;
&lt;li&gt;
2. Personal top 5 projects from these 30 days

&lt;ul&gt;
&lt;li&gt;2.1. Day 5: "Lights Out" game&lt;/li&gt;
&lt;li&gt;2.2. Day 6: Accessible background colors&lt;/li&gt;
&lt;li&gt;2.3. Day 9: Deploying a Python backend + Elm frontend&lt;/li&gt;
&lt;li&gt;2.4. Day 15 to 19: From struggling with JSON to decoding JSON from Python&lt;/li&gt;
&lt;li&gt;2.5. Day 24: Html Msg vs Html msg&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

3. Things that I like about Elm

&lt;ul&gt;
&lt;li&gt;3.1. If it compiles, it works&lt;/li&gt;
&lt;li&gt;3.2. Types&lt;/li&gt;
&lt;li&gt;3.3. elm-format&lt;/li&gt;
&lt;li&gt;3.4. Syntax&lt;/li&gt;
&lt;li&gt;3.5. Immutability&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

4. Things I don't like about Elm

&lt;ul&gt;
&lt;li&gt;4.1. Some parts of the documentation lack examples&lt;/li&gt;
&lt;li&gt;4.2. Can't mix Floats and Ints&lt;/li&gt;
&lt;li&gt;4.3. Some things are harder than expected&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

5. Learning strategy

&lt;ul&gt;
&lt;li&gt;
5.1. Things that worked really well

&lt;ul&gt;
&lt;li&gt;5.1.1. Setting the bar low&lt;/li&gt;
&lt;li&gt;5.1.2. Writing&lt;/li&gt;
&lt;li&gt;5.1.3. Not following a set structure was mostly really good&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

5.2. Things that could have been better

&lt;ul&gt;
&lt;li&gt;5.2.1. Not taking enough breaks&lt;/li&gt;
&lt;li&gt;5.2.2. Writing too much&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;6. What's next?&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Why Elm?
&lt;/h1&gt;

&lt;p&gt;I first learned JavaScript in 2016, thanks to &lt;a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6ZiZxtDDRCi6uhfTH4FilpH" rel="noopener noreferrer"&gt;Daniel Shiffman's p5.js videos&lt;/a&gt; about visualizing mathematics and physics, and making cool animations.&lt;/p&gt;

&lt;p&gt;Already back then, I saw some Elm code, but it looked weird to me: &lt;code&gt;case msg of&lt;/code&gt;, square brackets instead of HTML templates, commas at the &lt;em&gt;beginning&lt;/em&gt; of each line, no side effects. All that code just to increment a counter? No, thanks.&lt;/p&gt;

&lt;p&gt;Then in late 2020, after having learned React for a month or so, I found myself struggling with my 100th runtime exception that day. &lt;/p&gt;

&lt;p&gt;I'm not smart enough to write complex JavaScript without shooting myself in the foot, and I remembered Elm's promise of 0 runtime exceptions, and here I am now.&lt;/p&gt;

&lt;p&gt;Sure, it would have made sense to learn TypeScript, and maybe incorporate immutable.js and some other libraries, but this diagram helped convince me:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxcciqld4r9t8xi2dy7gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxcciqld4r9t8xi2dy7gf.png" alt="Screenshot showing Elm's ecosystem compared to JavaScript"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Screenshot from &lt;a href="https://www.youtube.com/watch?v=kEitFAY7Gc8" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=kEitFAY7Gc8&lt;/a&gt; (slightly outdated)&lt;/p&gt;

&lt;p&gt;Somehow that same day, I stumbled upon &lt;a href="https://twitter.com/larsparsfromage" rel="noopener noreferrer"&gt;@larsparsfromage&lt;/a&gt;'s #100daysofhaskell challenge, and decided to do a 30 day Elm challenge with detailed write-ups.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Personal top 5 projects from these 30 days
&lt;/h1&gt;

&lt;p&gt;I'm happy with all of them, as they were all part of the journey.&lt;/p&gt;

&lt;p&gt;Here's the full list: &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that said, some were a bit more entertaining or educational than others:&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1. Day 5: "Lights Out" game
&lt;/h2&gt;

&lt;p&gt;This was my first Elm project where I was both happy with my code, and found myself having fun with the end result.&lt;/p&gt;

&lt;p&gt;You have a 5x5 grid of checkboxes. When you toggle one, its neighbors also get toggled. The goal is to clear the board.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-5-lights-out-game-4b16"&gt;https://dev.to/kristianpedersen/30daysofelm-day-5-lights-out-game-4b16&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.2. Day 6: Accessible background colors
&lt;/h2&gt;

&lt;p&gt;I was happy about how accessible this topic was (shouldn't come as a surprise, I guess).&lt;/p&gt;

&lt;p&gt;A slider generates a color palette, which is represented as squares. Each square then gets its text colored white or black text, depending on which accessibility standard you choose.&lt;/p&gt;

&lt;p&gt;There's just something about moving a slider and have so many things happen!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-6-accessible-background-colors-29ao"&gt;https://dev.to/kristianpedersen/30daysofelm-day-6-accessible-background-colors-29ao&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.3. Day 9: Deploying a Python backend + Elm frontend
&lt;/h2&gt;

&lt;p&gt;I had previously made a small Python backend, which fetches astronomy data.&lt;/p&gt;

&lt;p&gt;Getting this up and running, and have Elm display the data was amazing!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-9-astronomy-data-from-python-in-elm-deployment-difficulties-2i47"&gt;https://dev.to/kristianpedersen/30daysofelm-day-9-astronomy-data-from-python-in-elm-deployment-difficulties-2i47&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.4. Day 15 to 19: From struggling with JSON to decoding JSON from Python
&lt;/h2&gt;

&lt;p&gt;Decoding JSON was tough, but by asking for help and not giving up, I got it working!&lt;/p&gt;

&lt;p&gt;I also learned some lessons about making things as simple as possible, which I'm very happy about.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-15-struggling-with-json-4hhm"&gt;15: Struggling with JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-16-struggling-slightly-less-with-json-38g7"&gt;16: Struggling slightly less with JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-17-i-decoded-some-json-4na5"&gt;17: I decoded some JSON!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/kristianpedersen/day-18-decoding-json-from-a-python-backend-4010"&gt;18: Decoding JSON from a Python backend&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2.5. Day 24: Html Msg vs Html msg
&lt;/h2&gt;

&lt;p&gt;Finally decided to get to the bottom of this mystery, and also got a sense of types vs type aliases.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Html msg&lt;/code&gt;: There no event.&lt;br&gt;
&lt;code&gt;Html Msg&lt;/code&gt;: There's an event, and it might have some data associated with it.&lt;/p&gt;

&lt;p&gt;I still don't like how similar these two look, so I prefer using &lt;code&gt;Html a&lt;/code&gt; instead of &lt;code&gt;Html msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-24-msg-vs-msg-2n1h"&gt;https://dev.to/kristianpedersen/30daysofelm-day-24-msg-vs-msg-2n1h&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  3. Things that I like about Elm
&lt;/h1&gt;

&lt;p&gt;I'm sure there are things that I've forgotten or taken from granted, but here are some things that I've really liked.&lt;/p&gt;
&lt;h2&gt;
  
  
  3.1. If it compiles, it works
&lt;/h2&gt;

&lt;p&gt;I've had 0 runtime exceptions, which is obviously one of the biggest benefits. In my last React project, everything compiled fine, I clicked around to test everything, and suddenly got a runtime exception out of nowhere.&lt;/p&gt;

&lt;p&gt;In Elm, I still get lots of compile-time errors, but I really don't mind. They make it feel like I'm doing pair programming with someone more experienced, and actually getting help.&lt;/p&gt;

&lt;p&gt;That feeling when it finally compiles and you know everything is going to work: 10/10&lt;/p&gt;
&lt;h2&gt;
  
  
  3.2. Types
&lt;/h2&gt;

&lt;p&gt;Coming from JavaScript and some Python, the static typing was weird at first, but they've forced me to think more deeply about what I'm trying to do. Also, types result in better error messages.&lt;/p&gt;

&lt;p&gt;Type aliases are very convenient, and types is something I've only recently started to understand the power of.&lt;/p&gt;

&lt;p&gt;I really like how the &lt;code&gt;Msg&lt;/code&gt; type provides a great overview of an application's possible actions, and I can imagine this benefit holds true with other custom types as well.&lt;/p&gt;

&lt;p&gt;I'm very excited by the thought of &lt;a href="https://www.youtube.com/watch?v=IcgmSRJHu_8" rel="noopener noreferrer"&gt;making impossible states impossible&lt;/a&gt;, so I'm looking forward to working more with types.&lt;/p&gt;
&lt;h2&gt;
  
  
  3.3. elm-format
&lt;/h2&gt;

&lt;p&gt;At first, some of the formatting threw me off, but now I mostly like it.&lt;/p&gt;

&lt;p&gt;Practially all Elm code uses &lt;code&gt;elm-format&lt;/code&gt;, which sounds restrictive at first, but it's one less thing to worry about, and reading other people's code is made easier.&lt;/p&gt;

&lt;p&gt;Things can get a bit messy when doing anonymous functions with &lt;code&gt;let&lt;/code&gt; blocks, but in those cases I prefer extracting things into separate functions anyway.&lt;/p&gt;

&lt;p&gt;Reading code is quicker with equal signs being followed by a newline, and I now believe that commas do indeed belong at the beginning of the line.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: I forgot one of the most important ones! &lt;code&gt;elm-format&lt;/code&gt; automatically sorts all imports and their exposed functions alphabetically!&lt;/em&gt; 😍&lt;/p&gt;
&lt;h2&gt;
  
  
  3.4. Syntax
&lt;/h2&gt;

&lt;p&gt;At first, the view functions in Elm looked insane. All those empty square bracket pairs nearly made me cry.&lt;/p&gt;

&lt;p&gt;Then you learn that attributes go in the first one, and content goes in the other one. Not bad after all!&lt;/p&gt;

&lt;p&gt;The pipeline operator &lt;code&gt;|&amp;gt;&lt;/code&gt; feels nice and familiar, coming from JavaScript's chained function calls.&lt;/p&gt;

&lt;p&gt;I like how function definitions have less "noise", along with the fact that all functions return something.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function double(x) {return x * 2}&lt;/code&gt; &lt;br&gt;
or &lt;br&gt;
&lt;code&gt;const double = x =&amp;gt; x * 2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elm:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;double x = x * 2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's read these out loud:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"function double parenthesis x closing parenthesis curly brace return x times two closing curly brace"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"const double equals x equals is greater than x times two"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"double x equals x times two"&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  3.5. Immutability
&lt;/h2&gt;

&lt;p&gt;In JavaScript, I have to remember to explicitly make copies of things, and make sure I'm &lt;a href="https://www.freecodecamp.org/news/copying-stuff-in-javascript-how-to-differentiate-between-deep-and-shallow-copies-b6d8c1ef09cd/#:~:text=shallow%20copying.,into%20how%20JavaScript%20stores%20values." rel="noopener noreferrer"&gt;not just doing shallow copies&lt;/a&gt;, especially of nested objects. &lt;/p&gt;

&lt;p&gt;Having immutability built-in is a relief. Making copies is not a problem, as I'm already used to map, filter and reduce from JavaScript.&lt;/p&gt;

&lt;p&gt;I like knowing that nothing external can make my functions do unexpected things.&lt;/p&gt;
&lt;h1&gt;
  
  
  4. Things I don't like about Elm
&lt;/h1&gt;
&lt;h2&gt;
  
  
  4.1. Some parts of the documentation lack examples
&lt;/h2&gt;

&lt;p&gt;I know that &lt;code&gt;OnClick&lt;/code&gt; is explained in the Elm Guide, but why not include a basic event example directly in the &lt;a href="https://package.elm-lang.org/packages/elm/html/latest/Html-Events" rel="noopener noreferrer"&gt;&lt;code&gt;Html.Events&lt;/code&gt; documentation&lt;/a&gt;? Switching to another tab feels unnecessary.&lt;/p&gt;

&lt;p&gt;(The link to TodoMVC on that page doesn't work any longer, by the way.)&lt;/p&gt;

&lt;p&gt;One example would be enough to get beginners going with events more easily:&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="o"&gt;..&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;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&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;button&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&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;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Events&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;onClick&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;onInput&lt;/span&gt;&lt;span class="p"&gt;)&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;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sandbox&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;number&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;userInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Increment&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;ReceivedInput&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&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;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Increment&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;ReceivedInput&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;Increment&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number&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;input&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onInput&lt;/span&gt; &lt;span class="kt"&gt;ReceivedInput&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;p&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The model is: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, if I want to create a &lt;code&gt;canvas&lt;/code&gt; element, how do I actually use it? How can I get its context? Is it supported in Elm? This is all I'm getting from the documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;canvas : List (Attribute msg) -&amp;gt; List (Html msg) -&amp;gt; Html msg&lt;br&gt;
Represents a bitmap area for graphics rendering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Scrolling through &lt;a href="https://package.elm-lang.org/packages/elm/html/latest/Html#h1" rel="noopener noreferrer"&gt;elm/html&lt;/a&gt;, I would have expected to see examples when clicking on an entry.&lt;/p&gt;

&lt;p&gt;Maybe experienced Elm devs prefer type annotations over examples, but I just want to know how to make something.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.2. Can't mix Floats and Ints
&lt;/h2&gt;

&lt;p&gt;Let's say some function returns an &lt;code&gt;Int&lt;/code&gt;, and you want to add 0.1 to it:&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;doesntWork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;

&lt;span class="n"&gt;works&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Error message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I need both sides of (+) to be the exact same type. Both Int or both Float.&lt;br&gt;
3|   (floor 1.1) + 0.1&lt;br&gt;
     ^^^^^^^^^^^^^^^^^&lt;br&gt;
But I see an Int on the left and a Float on the right.&lt;br&gt;
Use toFloat on the left (or round on the right) to make both sides match!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/elm/compiler/blob/master/hints/implicit-casts.md" rel="noopener noreferrer"&gt;There are reasons for this&lt;/a&gt;, but it's still a bit annoying.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.3. Some things are harder than expected
&lt;/h2&gt;

&lt;p&gt;This is just a consequence of how Elm is structured, so I'm not mad about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-10-mouse-coordinates-1llo"&gt;On day 10&lt;/a&gt;, I was puzzled by how much code was needed just to get mouse coordinates.&lt;/p&gt;

&lt;p&gt;Then again, Elm is better suited for applications of a certain complexity. If I want to make a very quick prototype, I'll just use &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Learning strategy
&lt;/h1&gt;

&lt;p&gt;Next up, I want to examine my methodology for learning Elm. What worked, and what could have been done differently?&lt;/p&gt;

&lt;h2&gt;
  
  
  5.1. Things that worked really well
&lt;/h2&gt;

&lt;p&gt;I'm happy to report that many things went well during this challenge! :D&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1.1. Setting the bar low
&lt;/h3&gt;

&lt;p&gt;This was a very successful hypothesis. 30 days of varying productivity is better than a week of divine hustle and blissful inspiration.&lt;/p&gt;

&lt;p&gt;If I'm unmotivated or something comes up, I can still succeed by doing the absolute minimum imaginable.&lt;/p&gt;

&lt;p&gt;If I'm motivated, I'll keep going because I want to, and end up raising the bar anyway.&lt;/p&gt;

&lt;p&gt;Looking back, there were definitely some frustrating days, or days where I really didn't want to do anything.&lt;/p&gt;

&lt;p&gt;Almost every time that happened, I told myself that 5 minutes of any Elm code or knowledge was okay, and I usually ended up spending an hour anyway.&lt;/p&gt;

&lt;p&gt;Another effect of this was preserving momentum. Some of my most productive or insightful days were preceded by one or more difficult days.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1.2. Writing
&lt;/h3&gt;

&lt;p&gt;There were two purposes behind the blogging:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Documenting what it's like to learn Elm, for someone with my experience. Maybe it could help other beginners?&lt;/li&gt;
&lt;li&gt;Setting up a situation where I have to think more deeply about concepts and problems. I had several great a-ha moments and blind spot revelations while writing these blog posts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The third consequence was unintended - amazing help and feedback.&lt;/p&gt;

&lt;p&gt;The comments I've gotten on some of my posts have been astoundingly good. I wouldn't have gotten such good help by just asking.&lt;/p&gt;

&lt;p&gt;I think people get motivated to help when they see someone really trying, who provides detailed information, thoughts and reflections.&lt;/p&gt;

&lt;p&gt;Also, I think many programmers have this instinct of "by the way, you can also do it this much better way". For this reason, beginners shouldn't be shy about sharing their code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cunningham's Law states "the best way to get the right answer on the internet is not to ask a question; it's to post the wrong answer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://meta.wikimedia.org/wiki/Cunningham%27s_Law" rel="noopener noreferrer"&gt;https://meta.wikimedia.org/wiki/Cunningham%27s_Law&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.1.3. Not following a set structure was mostly really good
&lt;/h3&gt;

&lt;p&gt;I think some of the project ideas in the 30 day list are really cool, and I wouldn't be surprised if I end up working more on them. These wouldn't have been part of a pre-determined learning roadmap.&lt;/p&gt;

&lt;p&gt;Not having to do a ton of stuff on low-motivation days was really beneficial. It meant that if I had a bad day, I wouldn't fall behind, which I think was crucial for motivation.&lt;/p&gt;

&lt;p&gt;I do have this feeling that I should now learn how to make more "useful" stuff, along the traditional path. Knowing how &lt;code&gt;elm-spa&lt;/code&gt; works, making a todo list, doing something with a database, etc.&lt;/p&gt;

&lt;p&gt;However, I mostly think many of those things will emerge naturally as I work on increasingly complex projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  5.2. Things that could have been better
&lt;/h2&gt;

&lt;p&gt;Of course I did some things wrong - or as I like to say, I learned something.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2.1. Not taking enough breaks
&lt;/h3&gt;

&lt;p&gt;At my previous job, I was often the one who said "Hey, let's go outside for 5 minutes and stretch!".&lt;/p&gt;

&lt;p&gt;Now that I'm on my own, I'm a lot worse at taking regular breaks. I do go for a 1-2 hour walk every day, and I cook proper meals, but I often end up just grinding through lots of computer time, which often ends up not being that efficient anyway.&lt;/p&gt;

&lt;p&gt;Unsurprisingly, I often have a-ha moments after I've been outside, talked with someone, or done something completely unrelated.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2.2. Coding and writing in one day is a lot of work
&lt;/h3&gt;

&lt;p&gt;The writing has definitely helped a lot, and introduced me to some great people.&lt;/p&gt;

&lt;p&gt;However, it does take a lot of time, and I found it a bit stressful. I'm the kind of person who can spend 10-15 minutes on just one sentence.&lt;/p&gt;

&lt;p&gt;Sometimes, I would get into a nice flow with the coding, only to realize I needed to start writing soon.&lt;/p&gt;

&lt;p&gt;Some 100 day challenges I've seen around just involve a paragraph or two, which sounds a lot more sustainable.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. What's next?
&lt;/h1&gt;

&lt;p&gt;My primary focus is on implementing a few hobby projects in Elm, and improving them. Other than that, some potential areas of interest are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;. What are the different assistive technologies out there? What kinds of tests have to be passed? How do you avoid overloading users' working memory? The web should be for everyone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Making flexible designs that look good&lt;/strong&gt;. I just want to know how to make designs that look modern, are easy to change, and users don't even think about. I'm still stuck at using too many borders and computer colors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data visualization&lt;/strong&gt;. Elm has some good tools for this, but &lt;a href="https://observablehq.com/@observablehq/user-manual" rel="noopener noreferrer"&gt;Observable&lt;/a&gt; seems like a really nice environment for experimentation. For interactive installations, I now know how to &lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-27-using-websockets-ports-to-control-a-desktop-app-4b00"&gt;control TouchDesigner from Elm&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend/cloud/IOT&lt;/strong&gt;: It would be cool to deploy a web page that displays serial port data from my Arduino, or some other external data. Elixir+Phoenix+LiveView seems really interesting, but I'm open to other options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting a job&lt;/strong&gt;. I've been to several interviews the past couple of months, and they've been positive regarding background, projects, personality, willingness to learn, etc.However, I lack experience (and probably certain skills aren't useful enough to employers yet). I'm waiting to hear back from many applications, but any advice is helpful. :)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Right now, I'm taking my first weekend off since mid-december. If you have any questions, comments, feedback or anything, I'm here. &lt;/p&gt;

&lt;p&gt;Thanks for joining me, and see you around!&lt;br&gt;
- Kristian&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 29: Basic map, filter and reduce/foldl</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Thu, 14 Jan 2021 21:51:52 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-29-basic-map-filter-and-reduce-366l</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-29-basic-map-filter-and-reduce-366l</guid>
      <description>&lt;p&gt;This is day 29 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yesterday was fun, but I'm really exhausted today. Maybe it's because I'm almost done with the 30 days, and I need a break. &lt;/p&gt;

&lt;p&gt;I sure am glad I didn't commit to 100 days. :D&lt;/p&gt;

&lt;p&gt;This is the most unmotivated I've felt since starting this challenge, so today I decided to write about map, filter and reduce. &lt;/p&gt;

&lt;p&gt;Going from for loops to these functions really improved my JavaScript code and my experience, and I was happy to see them in Elm too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. In depth documentation&lt;/li&gt;
&lt;li&gt;
2. Array.map / List.map

&lt;ul&gt;
&lt;li&gt;2.1. JavaScript&lt;/li&gt;
&lt;li&gt;2.2. Elm&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
3. Array.map / List.indexedMap

&lt;ul&gt;
&lt;li&gt;3.1. JavaScript&lt;/li&gt;
&lt;li&gt;3.2. Elm&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
4. Array.filter / List.filter

&lt;ul&gt;
&lt;li&gt;4.1. JavaScript&lt;/li&gt;
&lt;li&gt;4.2. Elm&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
5. Array.reduce / List.foldl

&lt;ul&gt;
&lt;li&gt;5.1. JavaScript&lt;/li&gt;
&lt;li&gt;5.2. Elm&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;6. Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. In depth documentation
&lt;/h1&gt;

&lt;p&gt;I'm only going to explain some simple use cases. Afterwards, make yourself some hot beverage, and read these:&lt;/p&gt;

&lt;p&gt;JavaScript array methods: &lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elm list functions:&lt;br&gt;
&lt;a href="https://package.elm-lang.org/packages/elm/core/latest/List"&gt;https://package.elm-lang.org/packages/elm/core/latest/List&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  2. Array.map / List.map
&lt;/h1&gt;

&lt;p&gt;Applies a function to each element in a list.&lt;/p&gt;
&lt;h2&gt;
  
  
  2.1. JavaScript
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2.2. Elm
&lt;/h2&gt;

&lt;p&gt;In Elm, the list usually comes last.&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="kt"&gt;List&lt;/span&gt;&lt;span class="o"&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;number&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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="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;span class="c1"&gt;-- [2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, there's a nicer way to do this.&lt;/p&gt;

&lt;p&gt;Using the pipeline &lt;code&gt;|&amp;gt;&lt;/code&gt;, the result to its left gets passed as the last argument to the function that comes after it:&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;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;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&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;number&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- [2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think this syntax is intuitive, and very nice to look at.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Array.map / List.indexedMap
&lt;/h1&gt;

&lt;p&gt;This is just how the standard JavaScript map function works.&lt;/p&gt;

&lt;p&gt;Elm has two map functions: &lt;code&gt;List.map&lt;/code&gt; with no index, and &lt;code&gt;List.indexedMap&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.1. JavaScript
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JavaScript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Scratch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Using parentheses to get implicit return on its own line&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;// ["0: JavaScript", "1: Elm", "2: Scratch"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3.2. Elm
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;languages&lt;/span&gt; &lt;span class="o"&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;JavaScript"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elm"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Scratch"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;withIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;languages&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexedMap&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;language&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 order of index and element are the other way around in Elm.&lt;/p&gt;

&lt;p&gt;Also, Elm doesn't have very nice string interpolation, and you have to explicitly convert other types to a string.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Array.filter / List.filter
&lt;/h1&gt;

&lt;p&gt;Keeps the items that return true. &lt;/p&gt;

&lt;p&gt;The name "filter" is kind of ambiguous to me, so think of it as &lt;code&gt;keepIfTrue&lt;/code&gt; instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.1. JavaScript
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;=&amp;gt; number &amp;lt;=&lt;/code&gt; part looks weird, so I added a second option that looks nicer to me.&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="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;span class="mi"&gt;4&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="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 3]&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;span class="mi"&gt;4&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="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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;h2&gt;
  
  
  4.2. Elm
&lt;/h2&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;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="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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;Note that Elm's filter function doesn't provide an index.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Array.reduce / List.foldl
&lt;/h1&gt;

&lt;p&gt;Reduces an array into one single variable. &lt;/p&gt;

&lt;p&gt;JavaScript has &lt;code&gt;reduce&lt;/code&gt; and &lt;code&gt;reduceRight&lt;/code&gt;, while Elm has &lt;code&gt;foldl&lt;/code&gt; and &lt;code&gt;foldr&lt;/code&gt;. Left and right just specify if we're looping from the beginning or the end of the list.&lt;/p&gt;

&lt;p&gt;In the beginning, I just thought of &lt;code&gt;reduce&lt;/code&gt; as the way you get a sum, but now I want to use it for everything. &lt;/p&gt;

&lt;p&gt;It's not a replacement for more readable standard functions, although that can be very fun. Anyway:&lt;/p&gt;

&lt;h2&gt;
  
  
  5.1. JavaScript
&lt;/h2&gt;

&lt;p&gt;We have a variable &lt;code&gt;total&lt;/code&gt;, which will be updated from inside a loop that's going through an array.&lt;/p&gt;

&lt;p&gt;Many people use the term &lt;code&gt;accumulator&lt;/code&gt;, which sounds more fancy than &lt;code&gt;total&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's an example &lt;em&gt;without&lt;/em&gt; &lt;code&gt;reduce&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;let&lt;/span&gt; &lt;span class="nx"&gt;array&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="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;span class="mi"&gt;4&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// Could also be a string, array, object, etc.&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, other parts of the code might use the accumulator, so it's safer to let &lt;code&gt;reduce&lt;/code&gt; handle it:&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;const&lt;/span&gt; &lt;span class="nx"&gt;sumOf1to5&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="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;span class="mi"&gt;4&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="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sumOf1to5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;total&lt;/code&gt; refers to &lt;code&gt;0&lt;/code&gt;, which is the initial value, and &lt;code&gt;item&lt;/code&gt; is each separate value in the array.&lt;/p&gt;

&lt;p&gt;Also, the really cool people don't use variable names that make sense:&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;const&lt;/span&gt; &lt;span class="nx"&gt;sumOf1to5&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="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;span class="mi"&gt;4&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="nx"&gt;reduce&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="o"&gt;=&amp;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;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5.2. Elm
&lt;/h2&gt;

&lt;p&gt;Firstly, Elm has its own sum and product functions, so you don't need to implement these with &lt;code&gt;List.foldl&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="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&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="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;-- 15&lt;/span&gt;

&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- 5050&lt;/span&gt;

&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- 120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;List.foldl&lt;/code&gt; works the same way if you want:&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;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="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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="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;total&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond that, you can do a bunch of crazy stuff, but I'm not in the mood for that now.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope this helped, or maybe even steered you away from for loops.&lt;/p&gt;

&lt;p&gt;map, filter and reduce are a lot of fun, and they really improved my JavaScript code and experience when I learned them.&lt;/p&gt;

&lt;p&gt;See you tomorrow!&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 28: Chess board + intro to Knight's Tour</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Wed, 13 Jan 2021 19:55:22 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-28-chess-board-intro-to-knight-s-tour-1eb4</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-28-chess-board-intro-to-knight-s-tour-1eb4</guid>
      <description>&lt;p&gt;This is day 28 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today we're generating a chess board, and dipping our toes in the &lt;a href="https://en.wikipedia.org/wiki/Knight%27s_tour"&gt;Knight's Tour problem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Demo/code: &lt;a href="https://ellie-app.com/c59zGwgPN3Ha1"&gt;https://ellie-app.com/c59zGwgPN3Ha1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table of contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Creating a basic chessboard, and calculating a few moves&lt;/li&gt;
&lt;li&gt;2. Create a chess board&lt;/li&gt;
&lt;li&gt;3. index -&amp;gt; (Int, Int) and index -&amp;gt; letter ++ number&lt;/li&gt;
&lt;li&gt;4. Get valid destinations&lt;/li&gt;
&lt;li&gt;5. Get the destinations' destionations&lt;/li&gt;
&lt;li&gt;6. Things that need fixing&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Creating a basic chessboard, and calculating a few moves
&lt;/h1&gt;

&lt;p&gt;Eventually, I really want to improve my old React project for solving the Knight's Tour problem, and maybe even compare my home-made algorithm with existing ones.&lt;/p&gt;

&lt;p&gt;It's fun to use and I like some of the ideas, but it doesn't look good: &lt;a href="https://kristianpedersen.github.io/knights-tour-react/"&gt;https://kristianpedersen.github.io/knights-tour-react/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today I've just set up some basics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a chess board&lt;/li&gt;
&lt;li&gt;Set up two possible representation of the positions on the board: 

&lt;ol&gt;
&lt;li&gt;A record with coordinates and various info&lt;/li&gt;
&lt;li&gt;A human-readable form: "A1".."H8"&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;For a given position, get the valid destinations on the board.&lt;/li&gt;
&lt;li&gt;Later, I will sort those destinations by &lt;em&gt;their&lt;/em&gt; number of possible destinations, and move to the one with the fewest destinations. This is known as &lt;a href="https://en.wikipedia.org/wiki/Knight%27s_tour#Warnsdorff's_rule"&gt;Warnsdorff's rule&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  2. Create a chess board
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;squareWithCoordinates&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;BoardPosition&lt;/span&gt;
&lt;span class="n"&gt;squareWithCoordinates&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&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;modBy&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destinations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;createBoard&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;List&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&lt;/span&gt;
&lt;span class="n"&gt;createBoard&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;boardSize&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="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;squareWithCoordinates&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;chessBoard&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&lt;/span&gt;
&lt;span class="n"&gt;chessBoard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;createBoard&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way of generating X and Y coordinates seems simpler than dealing with a two-dimensional list.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;visited&lt;/code&gt; and &lt;code&gt;destinations&lt;/code&gt; don't do anything yet. I think I might need them, although maybe it's easier to just build up a new chessboard, move by move?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;createBoard&lt;/code&gt; relies on partial application. We're not directly passing in &lt;code&gt;index&lt;/code&gt;, but the pipeline &lt;code&gt;|&amp;gt;&lt;/code&gt; adds the &lt;code&gt;List.range&lt;/code&gt; result as the last argument to &lt;code&gt;List.map&lt;/code&gt;. These two functions do the same thing:&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;createBoard1&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;boardSize&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="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;squareWithCoordinates&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;createBoard2&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;boardSize&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="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&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;index&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;squareWithCoordinates&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some might prefer the explicitness of &lt;code&gt;createBoard2&lt;/code&gt;. Partial application is very useful and very cool, but I can see how it might demand some extra mental capacity when read by others or my future forgetful self.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. index -&amp;gt; (Int, Int) and index -&amp;gt; letter ++ number
&lt;/h1&gt;

&lt;p&gt;When showing the squares, they should say "A1" up to "H8".&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;squareView&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;NamedPosition&lt;/span&gt;
&lt;span class="n"&gt;squareView&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;sliceStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;modBy&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;

        &lt;span class="n"&gt;sliceEnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;sliceStart&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt; &lt;span class="n"&gt;sliceStart&lt;/span&gt; &lt;span class="n"&gt;sliceEnd&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZ"&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&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;I know the board only goes up to 8, but later I want to be able to select other board sizes.&lt;/p&gt;

&lt;p&gt;To get the X index of the alphabet string, we use &lt;code&gt;modBy&lt;/code&gt;, which takes &lt;code&gt;index / boardSize&lt;/code&gt; and returns the remainder.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;//&lt;/code&gt; just means integer division, which works just like &lt;code&gt;Math.floor(index / boardSize)&lt;/code&gt; if you're coming from JavaScript.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Get valid destinations
&lt;/h1&gt;

&lt;p&gt;This one is easier. From a given position, return the pieces that have an XY distance of (1, 2) or (2, 1).&lt;/p&gt;

&lt;p&gt;Later on, this will also only include squares that have not been visited.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;elm-format&lt;/code&gt; looks crazy sometimes when there are no parentheses! :D&lt;/p&gt;

&lt;p&gt;Before:&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;getValidDestinations&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&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="kt"&gt;BoardPosition&lt;/span&gt;
&lt;span class="n"&gt;getValidDestinations&lt;/span&gt; &lt;span class="n"&gt;board&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;board&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&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;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
                    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
                    &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&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;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
                    &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
                    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still looks kind of messy:&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;getValidDestinations&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&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="kt"&gt;BoardPosition&lt;/span&gt;
&lt;span class="n"&gt;getValidDestinations&lt;/span&gt; &lt;span class="n"&gt;board&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;board&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&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;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&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="n"&gt;abs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&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;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&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;getValidDestinations&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;BoardPosition&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="kt"&gt;BoardPosition&lt;/span&gt;
&lt;span class="n"&gt;getValidDestinations&lt;/span&gt; &lt;span class="n"&gt;board&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;board&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;xDistance&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yDistance&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="n"&gt;abs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&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;current&lt;/span&gt;&lt;span class="o"&gt;.&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;abs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
                        &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;in&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xDistance&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;yDistance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&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="n"&gt;xDistance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;yDistance&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="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prefer this one by far. The &lt;code&gt;in&lt;/code&gt; part explains what we're filtering (keeping).&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Get the destinations' destionations
&lt;/h1&gt;

&lt;p&gt;Now that we've gotten a list of valid destinations, let's get &lt;em&gt;their&lt;/em&gt; valid destinations.&lt;/p&gt;

&lt;p&gt;We're just going with a hardcoded starting position of (0, 0). The unused record attributes have been removed for readability.&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;makeMove&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Position&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="kt"&gt;Position&lt;/span&gt;
&lt;span class="n"&gt;makeMove&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;getValidDestinations&lt;/span&gt; &lt;span class="n"&gt;chessBoard&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;


&lt;span class="n"&gt;nextDestinations&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Position&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="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;nextDestinations&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;makeMove&lt;/span&gt; &lt;span class="n"&gt;position&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getValidDestinations&lt;/span&gt; &lt;span class="n"&gt;chessBoard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's some REPL output from testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; makeMove {x=4,y=4} |&amp;gt; List.length
8 : Int

&amp;gt; nextDestinations {x=4,y=4} |&amp;gt; List.map List.length
[8,8,8,6,8,6,6,6]
    : List Int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  6. Things that need fixing
&lt;/h1&gt;

&lt;p&gt;If I log out &lt;code&gt;nextDestinations {x=4,y=4}&lt;/code&gt;, I will get (4,4) as one of the valid destinations, which won't work.&lt;/p&gt;

&lt;p&gt;Some places in the code, I'm passing the board (8x8 grid) as a parameter, and other places I'm referring to a function that just returns the initial version.&lt;/p&gt;

&lt;p&gt;I'll need to think about this, but maybe my model could consist of two boards? One with the unvisited squares, and another one with the visited ones?&lt;/p&gt;

&lt;p&gt;Then of course, there's the part where we've done a few moves, this particular sequence wasn't successful, and we need to rewind. In my JavaScript implementation, each square had an array of its valid moves, so I might need to implement that here too.&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 27: Using WebSockets+ports to control TouchDesigner</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Tue, 12 Jan 2021 19:42:10 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-27-using-websockets-ports-to-control-a-desktop-app-4b00</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-27-using-websockets-ports-to-control-a-desktop-app-4b00</guid>
      <description>&lt;p&gt;This is day 27 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today we're sending data back and forth between JavaScript and TouchDesigner, using web sockets and ports! We'll compile &lt;code&gt;Main.elm&lt;/code&gt; to &lt;code&gt;main.js&lt;/code&gt;, and add a few additional lines of JavaScript in &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;TouchDesigner might be the coolest programming environment out there. It's like having a mix of After Effects, basic 3D software, Python, and have all changes being reflected instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://derivative.ca/download"&gt;https://derivative.ca/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what today's project looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--th7_7TZX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2jzmvci7eadoq4ticm99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--th7_7TZX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2jzmvci7eadoq4ticm99.png" alt="Screenshot of browser and TouchDesigner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The top row is a 1x1 grayscale noise texture (0-1). We then get its red channel &lt;code&gt;r&lt;/code&gt; and convert it to a number. Any value changes trigger the code inside &lt;code&gt;chopexec1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The other important part here are the two &lt;code&gt;webserver&lt;/code&gt; nodes. The bottom one has Python code in it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;constant1&lt;/code&gt; receives our Elm app's slider value! &lt;code&gt;lag1&lt;/code&gt; applies smoothing to it, which is very useful for inputs like mouse movements, or sensor data from an Arduino.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The slider value is one step behind in TD, but it's good enough for me!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to learn TouchDesigner, I highly recommend going through &lt;a href="https://www.youtube.com/playlist?list=PLFrhecWXVn5862cxJgysq9PYSjLdfNiHz"&gt;Bileam Tschepe's fantastic beginner videos on YouTube&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A lot of the TouchDesigner setup today is taken from this tutorial: &lt;a href="https://thenodeinstitute.org/courses/webserver-dat-level-1/lessons/setting-up-the-webserverdat/topic/create-a-webserverdat/"&gt;https://thenodeinstitute.org/courses/webserver-dat-level-1/lessons/setting-up-the-webserverdat/topic/create-a-webserverdat/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm still a TouchDesigner beginner, so if you have any improvement suggestions, I would be very happy to hear those!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Main.elm&lt;/li&gt;
&lt;li&gt;2. index.html / Compiling Main.elm with live reload&lt;/li&gt;
&lt;li&gt;3. Very brief introduction to TouchDesigner / project screenshot&lt;/li&gt;
&lt;li&gt;4. TouchDesigner server&lt;/li&gt;
&lt;li&gt;5. Sending data from TouchDesign on value change&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Main.elm
&lt;/h1&gt;

&lt;p&gt;Today's Elm program is a simpler version of the &lt;a href="https://guide.elm-lang.org/interop/ports.html"&gt;Ports example in the guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's some stuff in the code I wouldn't have remembered by heart, so I might have to revisit it later on. I find it fairly easy to read though, so I'm not worried:&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;port&lt;/span&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="o"&gt;..&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;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&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="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&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="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Events&lt;/span&gt; &lt;span class="k"&gt;exposing&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="c1"&gt;-- MAIN&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;Model&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;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;



&lt;span class="c1"&gt;-- PORTS&lt;/span&gt;


&lt;span class="k"&gt;port&lt;/span&gt; &lt;span class="n"&gt;sendMessage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;


&lt;span class="k"&gt;port&lt;/span&gt; &lt;span class="n"&gt;messageReceiver&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;msg&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;Sub&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;



&lt;span class="c1"&gt;-- MODEL&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;sliderValue&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;noiseValueFromTD&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;flags&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="n"&gt;sliderValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;noiseValueFromTD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;



&lt;span class="c1"&gt;-- UPDATE&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ReceivedNoise&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;NewSliderValue&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&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;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;ReceivedNoise&lt;/span&gt; &lt;span class="n"&gt;noiseValue&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;noiseValueFromTD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;noiseValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kt"&gt;NewSliderValue&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sliderValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sendMessage&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sliderValue&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Sub&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;messageReceiver&lt;/span&gt; &lt;span class="kt"&gt;ReceivedNoise&lt;/span&gt;



&lt;span class="c1"&gt;-- VIEW&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;From TouchDesigner: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;noiseValueFromTD&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;type_&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;range"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;onInput&lt;/span&gt; &lt;span class="kt"&gt;NewSliderValue&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100"&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;p&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Slider value is "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sliderValue&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;h1&gt;
  
  
  2. index.html / Compiling Main.elm with live reload
&lt;/h1&gt;

&lt;p&gt;Basically, &lt;code&gt;Main.elm&lt;/code&gt; will be compiled to &lt;code&gt;main.js&lt;/code&gt;, which is referenced inside &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Some of the HTML is copied from the &lt;a href="https://guide.elm-lang.org/interop/ports.html"&gt;Ports guide&lt;/a&gt;, and some of it is taken from the &lt;a href="https://thenodeinstitute.org/courses/webserver-dat-level-1/lessons/setting-up-the-webserverdat/topic/create-a-webserverdat/"&gt;NODE Institute tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the project root, I set up two terminals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;nodemon --exec elm make --output=main.js&lt;/code&gt;, which re-compiles the Elm file when I hit &lt;code&gt;CMD+S&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;live-server&lt;/code&gt; - reload browser on file change&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you don't have &lt;code&gt;nodemon&lt;/code&gt; or &lt;code&gt;live-server&lt;/code&gt;, get &lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; and run &lt;code&gt;npm install -g nodemon live-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At first I tried running &lt;code&gt;elm-live src/Main.elm&lt;/code&gt;, which is usually great for other Elm projects, but it overwrote my &lt;code&gt;index.html&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;One important thing I've changed here is the WebSocket URL, which in our case is now &lt;code&gt;ws://localhost:9980&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Elm + Websockets&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"myapp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myapp&lt;/span&gt;&lt;span class="dl"&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;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ws://localhost:9980&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&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;sendToTD&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&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;receiveFromTD&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageReceiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;app&lt;/code&gt; constant is just standard boilerplate. &lt;code&gt;app.ports.sendMessage.subscribe&lt;/code&gt; is quite a mouthful, which is why I named the function &lt;code&gt;sendToTD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Currently, we're just sending one value. I guess if we wanted to be specific, we would have to set up Elm to send something like this: &lt;code&gt;{ op = "constant1", value = sliderValue }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we have everything we need in the browser - let's head over to TouchDesigner!&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Brief explanation of TouchDesigner data types (CHOP/DAT/TOP)
&lt;/h1&gt;

&lt;p&gt;TouchDesigner is a node-based programming tool for Windows and MacOS, which feels like a realtime version of After Effects + Python, with some 3D capabilities.&lt;/p&gt;

&lt;p&gt;Only boxes of the same data type can be connected, although they can be converted.&lt;/p&gt;

&lt;p&gt;There are a couple of other data types in TD, but these are the ones I'll mention today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CHOP (Channel Operators): Numbers&lt;/li&gt;
&lt;li&gt;DAT (Data operators): Strings/tables/code/text&lt;/li&gt;
&lt;li&gt;TOP (Texture operators): Image data (computed on the GPU)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These all have separate menus, which are accessed by double-clicking anywhere, and hitting &lt;code&gt;Tab&lt;/code&gt; to cycle between the different menus.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. TouchDesigner server
&lt;/h1&gt;

&lt;p&gt;Add a &lt;code&gt;Web Server&lt;/code&gt; DAT, and set its active status to &lt;code&gt;on&lt;/code&gt;. Hit &lt;code&gt;p&lt;/code&gt; if its parameters are hidden.&lt;/p&gt;

&lt;p&gt;This will set up a web socket server on localhost:9980.&lt;/p&gt;

&lt;p&gt;Expand Web Server by pressing the pink arrow on its bottom right, and edit the code by hitting &lt;code&gt;CTRL+E&lt;/code&gt;. A lot of this code is not needed, so I replaced it with a simplified version of the Node Academy tutorial code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This code goes in webserver1_callbacks
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;onHTTPRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webServerDAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;target_operator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'uri'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;target_operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isDAT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target_operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s"&gt;'data'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'statusCode'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;  &lt;span class="c1"&gt;# OK
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'statusReason'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'OK'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;

&lt;span class="c1"&gt;# Slider value from Elm comes in here (gets converted from String to Int automatically - yikes! :D)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;onWebSocketReceiveText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webServerDAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'constant1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;par&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;onWebSocketOpen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webServerDAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'table1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;appendRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Adds connected address to our list
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;onWebSocketClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webServerDAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'table1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;deleteRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this code to work, we need a &lt;code&gt;Constant&lt;/code&gt; CHOP with name "constant1", and a &lt;code&gt;Table&lt;/code&gt; DAT with name "table1". Both of these names are automatic when you create a node.&lt;/p&gt;

&lt;p&gt;We can now receive web socket messages from the browser, but how about sending messages?&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Sending data from TouchDesign on value change
&lt;/h1&gt;

&lt;p&gt;To send continuous data, we can use a &lt;code&gt;CHOP Execute&lt;/code&gt; DAT. &lt;/p&gt;

&lt;p&gt;Make sure &lt;code&gt;Value Change&lt;/code&gt; is set to &lt;code&gt;On&lt;/code&gt;, enter the name of the CHOP you want to toggle data sending (&lt;code&gt;topto1&lt;/code&gt; in my case), and add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;onValueChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sampleIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"topto1"&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="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'table1'&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;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'webserver1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;webSocketSendText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's pretty much it, as far as I can see. You can actually also get images from TouchDesigner into the browser, but given the data amount, I guess still images are the best choice for this.&lt;/p&gt;

&lt;p&gt;Very cool! :D&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 26: Debug.log, Debug.toString and the REPL</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Mon, 11 Jan 2021 17:08:57 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-26-inspecting-values-with-debug-log-debug-tostring-and-the-repl-3k4k</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-26-inspecting-values-with-debug-log-debug-tostring-and-the-repl-3k4k</guid>
      <description>&lt;p&gt;This is day 26 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today I learned how to test my functions in the REPL, instead of logging them with &lt;code&gt;Debug.log&lt;/code&gt; or displaying them in the view function with &lt;code&gt;text (myVariable |&amp;gt; Debug.toString)&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Debug.log: Like console.log(), but only in the browser&lt;/li&gt;
&lt;li&gt;2. text (variableOfAnyType |&amp;gt; Debug.toString)&lt;/li&gt;
&lt;li&gt;3. My Main.elm code&lt;/li&gt;
&lt;li&gt;4. Starting and using the REPL&lt;/li&gt;
&lt;li&gt;5. Screenshot&lt;/li&gt;
&lt;li&gt;6. Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My project is just a new directory where I've entered &lt;code&gt;elm init&lt;/code&gt; and created a &lt;code&gt;src/Main.elm&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;The REPL can be launched from the project root if there's an &lt;code&gt;elm.json&lt;/code&gt; file, by entering &lt;code&gt;elm repl&lt;/code&gt;. Note how it says &lt;code&gt;Say :help for help and :exit to exit! More at https://elm-lang.org/0.19.1/repl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;CTRL+C didn't work on my Mac, but &lt;code&gt;:exit&lt;/code&gt; did.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Debug.log: Like console.log(), but only in the browser
&lt;/h1&gt;

&lt;p&gt;This one had me confused at first. In JavaScript, you can just put &lt;code&gt;console.log()&lt;/code&gt; wherever you want.&lt;/p&gt;

&lt;p&gt;In Elm, &lt;code&gt;Debug.log&lt;/code&gt; has to be within a &lt;code&gt;let&lt;/code&gt; block (&lt;em&gt;edit: not accurate - see comments&lt;/em&gt;). Most code I've seen just refer to it with an underscore &lt;code&gt;_&lt;/code&gt; since its value isn't important (does it even have a value?):&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;rangeEcho&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;5&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="o"&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;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt;
                    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The number is: "&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
                &lt;span class="k"&gt;in&lt;/span&gt;
                &lt;span class="n"&gt;n&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lonely &lt;code&gt;n&lt;/code&gt; is there because we have to return something.&lt;/p&gt;

&lt;p&gt;Interestingly, the numbers come out backwards! I'd love to know why this is.&lt;/p&gt;

&lt;p&gt;Keep in mind, this only displays in the browser dev tools, not in the terminal.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. text (variableOfAnyType |&amp;gt; Debug.toString)
&lt;/h1&gt;

&lt;p&gt;The above function can also be displayed in the DOM, 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;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rangeEcho&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;-- [1,2,3,4,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a bit nicer than &lt;code&gt;Debug.log&lt;/code&gt;, but I've found the REPL to be the far most engaging and flexible experience.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. My Main.elm code
&lt;/h1&gt;

&lt;p&gt;If you're using VS Code with the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Elmtooling.elm-ls-vscode"&gt;Elm Tooling extension&lt;/a&gt;, it will probably add a line like this to the top:&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="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, you can test anything you want from your file, try passing it different parameters, or try combining functions.&lt;/p&gt;

&lt;p&gt;Here's the file I was working on: &lt;a href="https://ellie-app.com/c4cRdN4y4Pta1"&gt;https://ellie-app.com/c4cRdN4y4Pta1&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Starting and using the REPL
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Open a terminal and enter &lt;code&gt;elm repl&lt;/code&gt; in your project root. There has to be an &lt;code&gt;elm.json&lt;/code&gt; file there.&lt;/li&gt;
&lt;li&gt;Enter &lt;code&gt;import Main exposing (..)&lt;/code&gt; (or whatever your filename is)&lt;/li&gt;
&lt;li&gt;Now you can just type function names from your project.&lt;/li&gt;
&lt;li&gt;You can even modify or create new functions in Main.elm, and the REPL will automatically have access to them without needing to restart!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I gotta say, this is a much nicer way of working than what I've done up until now.&lt;/p&gt;

&lt;p&gt;To learn more, here's the REPL documentation: &lt;a href="https://github.com/elm/compiler/blob/master/hints/repl.md"&gt;https://github.com/elm/compiler/blob/master/hints/repl.md&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Screenshot
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6XW1Jre_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/alegfgiadobddx5yg5dz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6XW1Jre_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/alegfgiadobddx5yg5dz.png" alt="Screenshot of code and REPL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, you can see that &lt;code&gt;test&lt;/code&gt; results in an error, but works after I've entered &lt;code&gt;import Main exposing (..)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That last line with &lt;code&gt;grid |&amp;gt; List.filter (\xy -&amp;gt; ...))&lt;/code&gt; was particularly nice. Testing stuff interactively like this feels better than regular logging, although they all have their place, I suppose.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Conclusion
&lt;/h1&gt;

&lt;p&gt;This was a fun thing to learn! I just wish I could get tab completion for &lt;code&gt;Main.elm&lt;/code&gt; functions, not just for the ones that are created during the REPL runtime.&lt;/p&gt;

&lt;p&gt;Happy logging, and see you tomorrow!&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 25: Displaying a List (List String)</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Sun, 10 Jan 2021 20:44:26 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-25-displaying-a-list-list-string-5bf4</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-25-displaying-a-list-list-string-5bf4</guid>
      <description>&lt;p&gt;This is day 25 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today we'll create a very basic chess board view from a 8x8 &lt;code&gt;List&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the final result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A8B8C8D8E8F8G8H8
A7B7C7D7E7F7G7H7
A6B6C6D6E6F6G6H6
A5B5C5D5E5F5G5H5
A4B4C4D4E4F4G4H4
A3B3C3D3E3F3G3H3
A2B2C2D2E2F2G2H2
A1B1C1D1E1F1G1H1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Demo/code: &lt;a href="https://ellie-app.com/c3QTnvkpn7ha1"&gt;https://ellie-app.com/c3QTnvkpn7ha1&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Creating a single row&lt;/li&gt;
&lt;li&gt;2. Creating a grid (list of rows)&lt;/li&gt;
&lt;li&gt;3. Creating a grid with chess position names (A1, A2, .. H8)&lt;/li&gt;
&lt;li&gt;4. Refactoring: Named functions look nicer than long anonymous ones&lt;/li&gt;
&lt;li&gt;5. Creating the view&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Creating a single row
&lt;/h1&gt;

&lt;p&gt;This is easy in Elm:&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="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;-- [1, 2, 3, 4, 5, 6, 7, 8]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want the list to contain something else, you can use &lt;code&gt;List.map&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="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&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="o"&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;item&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lol"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- ["lol", "lol", "lol", "lol", "lol", "lol", "lol", "lol", ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Creating a grid (list of rows)
&lt;/h1&gt;

&lt;p&gt;Instead of having a list of numbers, we can imagine each number being replaced with a &lt;code&gt;List&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;verySimpleGrid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;verySimpleGrid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;-- [1, 2, 3, 4, 5, 6, 7, 8]&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="o"&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;number&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;-- Each individual number in the previous list is replaced with [1, 2, 3, 4, 5, 6, 7, 8]&lt;/span&gt;
        &lt;span class="c1"&gt;-- [[1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8], etc]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3. Creating a grid with chess position names (A1, A2, .. H8)
&lt;/h1&gt;

&lt;p&gt;This was my initial approach:&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;letters&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZ"&lt;/span&gt;


&lt;span class="n"&gt;grid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;grid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&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="o"&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;row&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexedMap&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;row&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="o"&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;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                        &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;row&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;letters&lt;/code&gt; is one of my favorite hardcoded things I've done. Very nice!&lt;/p&gt;

&lt;p&gt;The first two lines of the grid function are the same as before.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;List.indexedMap&lt;/code&gt; works the same way as JavaScript's regular &lt;code&gt;Array.map&lt;/code&gt;, except it's index first, and then element.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we're getting the Y index and its row (&lt;code&gt;List String&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Then, using &lt;code&gt;List.map&lt;/code&gt; on &lt;code&gt;row&lt;/code&gt;, we get each X value.&lt;/li&gt;
&lt;li&gt;The X coordinates should go from A to H. This is done with String.slice, which cuts from index1 up to (not including) index2.&lt;/li&gt;
&lt;li&gt;The Y coordinates work as usual, except chess board have 1-based indexing.&lt;/li&gt;
&lt;li&gt;The rows are reversed, so that A1 isn't at the top of the board.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  4. Refactoring: Named functions look nicer than long anonymous ones
&lt;/h1&gt;

&lt;p&gt;Looking at the code above, all that indentation is awkward to read, and none of the functions passed to &lt;code&gt;List.map&lt;/code&gt; or &lt;code&gt;List.indexedMap&lt;/code&gt; are reusable. &lt;/p&gt;

&lt;p&gt;I get shivers from anonymous functions that span more than one line. I'm feeling lazy today, but I'm doing this just so I can sleep well at night.&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;letters&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZ"&lt;/span&gt;


&lt;span class="n"&gt;singleCell&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;String&lt;/span&gt;
&lt;span class="n"&gt;singleCell&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;chessRow&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;List&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;List&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;chessRow&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;row&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="o"&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;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;singleCell&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;grid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;grid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&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="o"&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;row&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;8&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexedMap&lt;/span&gt; &lt;span class="n"&gt;chessRow&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think that is so much nicer to read, I'm actually a bit impressed at how much of a difference that makes.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Creating the view
&lt;/h1&gt;

&lt;p&gt;All that's left is getting the grid displayed in the browser. I guess I could have done nested &lt;code&gt;List.map&lt;/code&gt;s, but again, I think separate functions look nicer.&lt;/p&gt;

&lt;p&gt;First, we need to put each row into one div. &lt;/p&gt;

&lt;p&gt;Then those divs all get put into one main div.&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;rowDiv&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;rowDiv&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&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="o"&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;boardPosition&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="n"&gt;boardPosition&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="kt"&gt;Html&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grid&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;rowDiv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking good. See you tomorrow!&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 24: msg vs. Msg</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Sat, 09 Jan 2021 21:53:55 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-24-msg-vs-msg-2n1h</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-24-msg-vs-msg-2n1h</guid>
      <description>&lt;p&gt;This is day 24 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My original intention was to work further on yesterday's UI, but I kept getting weird errors about &lt;code&gt;Msg&lt;/code&gt; and &lt;code&gt;msg&lt;/code&gt; and weird type annotations.&lt;/p&gt;

&lt;p&gt;Today's project is just me finally trying to get my head around &lt;code&gt;Msg&lt;/code&gt; and &lt;code&gt;msg&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
1. msg vs Msg

&lt;ul&gt;
&lt;li&gt;1.1. &lt;code&gt;Msg&lt;/code&gt; vs &lt;code&gt;Msg Float&lt;/code&gt;, &lt;code&gt;Msg String&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;1.2. &lt;code&gt;Float -&amp;gt; Msg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;1.3. msg is just a placeholder&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;2. Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. &lt;code&gt;msg&lt;/code&gt; vs &lt;code&gt;Msg&lt;/code&gt; (you can choose your own names, too)
&lt;/h1&gt;

&lt;p&gt;I've seen &lt;code&gt;msg&lt;/code&gt; and &lt;code&gt;Msg&lt;/code&gt; all over the place, and I've always thought this ambiguous convention was really confusing and annoying as a beginner. &lt;/p&gt;

&lt;p&gt;You can of course name these whatever you want. I took &lt;a href="https://elm-lang.org/examples/clock"&gt;elm-lang.org's clock example&lt;/a&gt; and mofified it, by changing &lt;code&gt;Msg&lt;/code&gt; to &lt;code&gt;MsgForYouMyDude&lt;/code&gt; and &lt;code&gt;Svg msg&lt;/code&gt; to &lt;code&gt;Svg abc&lt;/code&gt;. In the update function, I changed &lt;code&gt;msg model&lt;/code&gt; to &lt;code&gt;massage supermodel&lt;/code&gt;: &lt;a href="https://ellie-app.com/c3r3mdDh3YRa1"&gt;https://ellie-app.com/c3r3mdDh3YRa1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, I see these exact names everywhere, so I think it's probably a good idea to just learn them, so what's going on?&lt;/p&gt;

&lt;p&gt;Rupert's example made me get a feel for it: &lt;a href="https://discourse.elm-lang.org/t/html-msg-vs-html-msg/2758/2"&gt;https://discourse.elm-lang.org/t/html-msg-vs-html-msg/2758/2&lt;/a&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;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;div&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;vs.&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;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Click&lt;/span&gt;

&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;Click&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 first one (&lt;code&gt;msg&lt;/code&gt;) has no event. It could if it wanted to, but it's too busy vaping, watching documentaries about ancient civilizations and UFOs, and listening to 432 Hz music.&lt;/p&gt;

&lt;p&gt;The last one (&lt;code&gt;Msg&lt;/code&gt;) deals with an important message that I've defined, which will get sent to the &lt;code&gt;update&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.1. &lt;code&gt;Msg&lt;/code&gt; vs &lt;code&gt;Msg Float&lt;/code&gt;, &lt;code&gt;Msg String&lt;/code&gt;, etc.
&lt;/h2&gt;

&lt;p&gt;The simplest one to understand for me is &lt;code&gt;Msg&lt;/code&gt;. The one with the capital letter is the one you make yourself. This describes different messages that can be picked up by your update 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="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NewBoardSize&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;NewAnimationSpeed&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now how do we get the &lt;code&gt;Float&lt;/code&gt; value?&lt;/p&gt;

&lt;p&gt;My current understanding is that this is how you deal with continuous events in Elm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous events, like input&lt;/strong&gt;: Get MyMessage (uppercase) and a value of a certain type. Input events return a string (&lt;code&gt;event.target.value&lt;/code&gt; in JavaScript terms).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Momentary events, like click:&lt;/strong&gt; Something happened. No value required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can however have extra values along with your click events as well, Joel told me.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.2. &lt;code&gt;Float -&amp;gt; Msg&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;I hadn't seen this before that I could remember, but I was getting an error about how my slider was receiving an &lt;code&gt;Msg&lt;/code&gt; instead of a &lt;code&gt;Float -&amp;gt; Msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Normally, I think this would have been caught by Elm's type inference, but my slider attribute type annotation was causing problems.&lt;/p&gt;

&lt;p&gt;joelq was kind enough to help me out on Slack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before: &lt;a href="https://ellie-app.com/c3mJCmb9Mqta1"&gt;https://ellie-app.com/c3mJCmb9Mqta1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;After: &lt;a href="https://ellie-app.com/c3nw4rHyftKa1"&gt;https://ellie-app.com/c3nw4rHyftKa1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be fair, I could have found it right there in the &lt;a href="https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/Element-Input#slider"&gt;elm-ui slider documentation&lt;/a&gt;. :)&lt;/p&gt;

&lt;p&gt;The only two changes were as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;SliderAttribute&lt;/code&gt;'s message field was changed from &lt;code&gt;message : Msg&lt;/code&gt; to &lt;code&gt;message: Float -&amp;gt; Msg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The createSlider function was changed from &lt;code&gt;createSlider : Model -&amp;gt; SliderAttributes -&amp;gt; Element msg&lt;/code&gt; to &lt;code&gt;createSlider : Model -&amp;gt; SliderAttributes -&amp;gt; Element Msg&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The compiler highlights the last error pretty well, but even after reading up on this subject and getting help, my brain just sees &lt;code&gt;Msg&lt;/code&gt; and &lt;code&gt;msg&lt;/code&gt; and thinks they're the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.3. &lt;code&gt;msg&lt;/code&gt; is just a placeholder
&lt;/h2&gt;

&lt;p&gt;My conclusion is that &lt;code&gt;msg&lt;/code&gt; can basically just be anything. So why isn't the convention just &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;value&lt;/code&gt;, &lt;code&gt;yourTypeHere&lt;/code&gt; or something similar? I don't know.&lt;/p&gt;

&lt;p&gt;Again, here's from Joel in the thread I linked to above:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While the lowercase msg variable name has good intentions of communicating “the type that would go here fills the role of a message (definition 1)”, my experience is that many people read it as “the type that would go here is going to be a Msg (definition 2)”.&lt;/p&gt;

&lt;p&gt;Personally, I’ve started using Html a in my own code rather than Html msg to avoid this confusion&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://discourse.elm-lang.org/t/html-msg-vs-html-msg/2758/4"&gt;https://discourse.elm-lang.org/t/html-msg-vs-html-msg/2758/4&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Summary
&lt;/h1&gt;

&lt;p&gt;I realize &lt;code&gt;Msg&lt;/code&gt; and &lt;code&gt;msg&lt;/code&gt; have pretty much become standards in Elm, and you &lt;em&gt;will&lt;/em&gt; see them in most Elm code, so I don't know if it's a good idea to change at this stage.&lt;/p&gt;

&lt;p&gt;As a beginner, it would have been helpful to have a separate &lt;code&gt;Msg&lt;/code&gt; vs. &lt;code&gt;msg&lt;/code&gt; section in the guide. &lt;/p&gt;

&lt;p&gt;By the way, you also have things 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;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;msg&lt;/code&gt; is a reference to &lt;code&gt;Msg&lt;/code&gt;, but it's just a local variable name, so it could have been a reference to any type. It's not a &lt;code&gt;msg&lt;/code&gt; like &lt;code&gt;Html msg&lt;/code&gt;, but I guess it would refer to the &lt;code&gt;Msg&lt;/code&gt; in &lt;code&gt;Html Msg&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;See you tomorrow! :D&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 23: Simple layout with elm-ui</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Fri, 08 Jan 2021 20:29:07 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-23-simple-layout-with-elm-ui-274l</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-23-simple-layout-with-elm-ui-274l</guid>
      <description>&lt;p&gt;This is day 23 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try + view source: &lt;a href="https://ellie-app.com/c2WWjMTM4ZLa1" rel="noopener noreferrer"&gt;https://ellie-app.com/c2WWjMTM4ZLa1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmshosehxpcd71a13t5u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmshosehxpcd71a13t5u8.png" alt="Screenshow of three part layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  About today's project
&lt;/h1&gt;

&lt;p&gt;I made a React project a few months back that I eventually want to remake in Elm: &lt;a href="https://kristianpedersen.github.io/knights-tour-react/" rel="noopener noreferrer"&gt;https://kristianpedersen.github.io/knights-tour-react/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, you click a chess board position, and the program finds a valid sequence of moves where the knight visits every position on the board.&lt;/p&gt;

&lt;p&gt;I'm happy with the concept and interactions, but the visuals need a lot of work.&lt;/p&gt;

&lt;p&gt;Especially the board being positioned all the way to the left looks weird, and somehow in my caffeine-crazed coding bonanza, I managed to get the SVG lines to resize, but a "fix" stopped the board from resizing. :D&lt;/p&gt;

&lt;p&gt;Also, the colors and borders make it look like it was made 15 years ago.&lt;/p&gt;

&lt;h1&gt;
  
  
  Elm-ui is much nicer to read
&lt;/h1&gt;

&lt;p&gt;I touched upon this in &lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-7-centered-div-and-content-hfa"&gt;my previous quick elm-ui encounter&lt;/a&gt;, but CSS can be difficult. &lt;/p&gt;

&lt;p&gt;In my case, struggling with CSS is mostly my own fault for not bothering to learn it properly.&lt;/p&gt;

&lt;p&gt;Still though, here's a centered div:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nc"&gt;.center-screen&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"center-screen"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            I'm in the center
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From &lt;a href="https://stackoverflow.com/questions/31217268/center-div-on-the-middle-of-screen" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/31217268/center-div-on-the-middle-of-screen&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's my elm-ui program from day 7:&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;import&lt;/span&gt; &lt;span class="kt"&gt;Element&lt;/span&gt; &lt;span class="k"&gt;exposing&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="n"&gt;centeredDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;column&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I am centered"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;centeredDiv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's just a lot less noise in the second example. Now, if this is true in such a small example, imagine how this adds up.&lt;/p&gt;

&lt;h1&gt;
  
  
  Today's code
&lt;/h1&gt;

&lt;p&gt;I'm still an &lt;code&gt;elm-ui&lt;/code&gt; beginner. I had some problems initially that happened because I provided the wrong type annotations. &lt;/p&gt;

&lt;p&gt;Once I removed them, the errors went away too, so today is an automatic type inference day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic slider function
&lt;/h2&gt;

&lt;p&gt;The code for making a slider in &lt;code&gt;elm-ui&lt;/code&gt; is kind of long, to be honest.&lt;/p&gt;

&lt;p&gt;My project needed two sliders, but I didn't want two huge slider functions, so I made one generalized slider 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;slider&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slider&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;behindContent&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;el&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Background&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgb255&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Border&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rounded&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;none&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="n"&gt;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="kt"&gt;Input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;labelAbove&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thumb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="kt"&gt;Input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultThumb&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;attributes&lt;/code&gt; is a record that contains the info I would want in a smaller slider function.&lt;/p&gt;

&lt;p&gt;The sliders for the board size and animation speed now look nicer, instead of repeating the whole mess above twice:&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;sliderBoardSize&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;el&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;alignLeft&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slider&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boardSize&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Board size"&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UpdateBoardSize&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;sliderAnimationRate&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;el&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;alignRight&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slider&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;animationSpeed&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Animation speed"&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UpdateAnimationSpeed&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;h2&gt;
  
  
  Panel for the controls
&lt;/h2&gt;

&lt;p&gt;The two sliders then get included in a "nav bar", which looks 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;controls&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spacing&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Background&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgb255&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="mi"&gt;100&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="n"&gt;sliderBoardSize&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sliderAnimationRate&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's there to say? It's a full-width row with two sliders in it. &lt;code&gt;elm-ui&lt;/code&gt; code is just so nice to look at! &amp;lt;3&lt;/p&gt;

&lt;h2&gt;
  
  
  Info text
&lt;/h2&gt;

&lt;p&gt;Then underneath the controls, I wanted some info text to be displayed:&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;infoText&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spacing&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Background&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgb255&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgb255&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="mi"&gt;200&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="n"&gt;el&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The board size is "&lt;/span&gt;
                    &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, and the animation interval is "&lt;/span&gt;
                    &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;animationSpeed&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; ms"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  "Board"
&lt;/h2&gt;

&lt;p&gt;Honestly, I just want to watch some Netflix right now, so I didn't bother doing the board properly with the letters and numbers. I'll do that tomorrow.&lt;/p&gt;

&lt;p&gt;For now, it expands and contracts along with the board size slider, which I think is pretty cool. :)&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;showRow&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boardSize&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="o"&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;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hi there"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;showBoard&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boardSize&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="o"&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;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;showRow&lt;/span&gt; &lt;span class="n"&gt;model&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;First, we create a row of 8 cells: ********&lt;br&gt;
Then, we create a column with 8 of those:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;********
********
********
********
********
********
********
********
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The main fullscreen container, and the view function
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullscreenContainer&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;fullscreenContainer&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spacing&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;padding&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;
        &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&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;elmUiSection&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;elmUiSection&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;-- I want to add the "buttons" function to this list, but Elm won't let me because of a type mismatch&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;controls&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;infoText&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;showBoard&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Element.layout&lt;/code&gt; is the topmost level in this &lt;code&gt;elm-ui&lt;/code&gt; application. In my case, it just takes a &lt;code&gt;column&lt;/code&gt; that contains everything.&lt;/p&gt;

&lt;p&gt;I'm using map, because each of the &lt;code&gt;elmUiSection&lt;/code&gt;s, ([controls, infoText, showBoard]) take the model as their argument.&lt;/p&gt;

&lt;p&gt;I could have also written 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;column&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spacing&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;padding&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;controls&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;infoText&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;showBoard&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that kind of needless repetition just puts me asleep.&lt;/p&gt;

&lt;p&gt;The "buttons" function didn't work in this list. Lists can only consist of items of the same type, and the button is a different type because of its &lt;code&gt;onPress&lt;/code&gt; message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main, model, update, the usual stuff
&lt;/h2&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="o"&gt;..&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;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Element&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;Element&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alignLeft&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alignRight&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;behindContent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&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="n"&gt;none&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rgb255&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&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;Element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Background&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Background&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Border&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Border&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Font&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Font&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Input&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Input&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;Model&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;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sandbox&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;animationSpeed&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;animationSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UpdateBoardSize&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;UpdateAnimationSpeed&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;BoardSizeFromButton&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&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;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;UpdateBoardSize&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;UpdateAnimationSpeed&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;animationSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;BoardSizeFromButton&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;boardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;v&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 a very standard Elm setup. I'd definitely change the Msg names, as they're not really clear. &lt;code&gt;SliderBoardSize&lt;/code&gt;, &lt;code&gt;SliderAnimationSpeed&lt;/code&gt; and &lt;code&gt;ButtonBoardSize&lt;/code&gt; would be better names for me.&lt;/p&gt;

&lt;p&gt;Also, almost at the top, rather than exposing so many individual things from Element, I think I would just expose all.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This was my 2nd time using &lt;code&gt;elm-ui&lt;/code&gt;. Type annotations gave me some trouble to begin with, but other than that, I must say that it feels really intuitive.&lt;/p&gt;

&lt;p&gt;I'm just going to be honest and say that it would have taken me a lot more effort to make today's project in CSS.&lt;/p&gt;

&lt;p&gt;My CSS skills aren't good, so I use &lt;code&gt;elm-ui&lt;/code&gt;, and my React code gives me runtime errors, so I use &lt;code&gt;elm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I'll definitely look more into elm-ui for future projects - it's really nice.&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 22: Simple codewars.com challenges</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Thu, 07 Jan 2021 11:28:32 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-22-simple-codewars-com-challenges-557c</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-22-simple-codewars-com-challenges-557c</guid>
      <description>&lt;p&gt;This is day 22 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code+demo: &lt;a href="https://ellie-app.com/c2kXwQbnFbja1"&gt;https://ellie-app.com/c2kXwQbnFbja1&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. About today's project&lt;/li&gt;
&lt;li&gt;2. Can number A be divided to get number B?&lt;/li&gt;
&lt;li&gt;3. Get the sum of all numbers from 1 to n&lt;/li&gt;
&lt;li&gt;4. Get a list of 1 to n (also with partial application example)&lt;/li&gt;
&lt;li&gt;5. Time since midnight in milliseconds&lt;/li&gt;
&lt;li&gt;6. Formatting large numbers&lt;/li&gt;
&lt;li&gt;7. Remove all spaces from a string&lt;/li&gt;
&lt;li&gt;8. Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. About today's project
&lt;/h1&gt;

&lt;p&gt;I like doing small &lt;a href="http://codewars.com/"&gt;CodeWars&lt;/a&gt; challenges sometimes, just to practice some basics. &lt;/p&gt;

&lt;p&gt;They're often quite simple, but sometimes the simplicity can be deceiving, and occasionally I find myself not having read the requirements well enough.&lt;/p&gt;

&lt;p&gt;My "&lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-11-next-binary-number-with-same-number-of-1-s-34gg"&gt;next binary number with same number of 1's&lt;/a&gt;" was a CodeWars challenge. I also wrote about &lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-14-four-codewars-katas-3nck"&gt;4 CodeWars challenges&lt;/a&gt; on day 14.&lt;/p&gt;

&lt;p&gt;While it's very good to push yourself like I've done lately, it can also be good to get some easy wins, while also picking up a new thing or two.&lt;/p&gt;

&lt;p&gt;I hope today's writedown can be a nice resource for other beginners. Some Elm beginners immediately want to decode JSON and get into complex types, while others just want to know how to make an array of numbers from 1 to 100 (that's me).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I usually skip a few CodeWars challenges, usually because they're poorly written, or they don't interest me.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Can number A be divided to get number B?
&lt;/h1&gt;

&lt;p&gt;All we have to do is check if there's a remainder or not.&lt;/p&gt;

&lt;p&gt;The remainder of 10 / 2 is 0, while the remainder of 9 / 2 is 1.&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;checkIfFactor&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;Bool&lt;/span&gt;
&lt;span class="n"&gt;checkIfFactor&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;remainderBy&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="n"&gt;checkIfFactor&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;-- True&lt;/span&gt;
&lt;span class="n"&gt;checkIfFactor&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;-- False&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A slightly shorter solution would be 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;checkForFactor&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;Bool&lt;/span&gt;
&lt;span class="n"&gt;checkForFactor&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;modBy&lt;/span&gt; &lt;span class="n"&gt;b&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;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference between modBy and remainderBy has to do with negative numbers: &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy"&gt;https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Get the sum of all numbers from 1 to n
&lt;/h1&gt;

&lt;p&gt;I'm sure I can solve this one easily, but it's still good to practice the very basics, and there might be solutions I haven't thought of.&lt;/p&gt;

&lt;p&gt;Here's what I came up with, which is very easy to read:&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;summation&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;summation&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;n&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I saw some other interesting ones. I know which approach I prefer.&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;summation&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;summation&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;modBy&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="n"&gt;n&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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="n"&gt;n&lt;/span&gt;  &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;summation&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;summation&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&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;h1&gt;
  
  
  4. Get a list of 1 to n (also with partial application example)
&lt;/h1&gt;

&lt;p&gt;The next one seemed even simpler one than the previous, but I decided to try it anyway. I was confident my solution would be the shortest and simplest.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Count the monkeys!&lt;br&gt;
You take your son to the forest to see the monkeys. You know that there are a certain number there (n), but your son is too young to just appreciate the full number, he has to start counting them from 1.&lt;/p&gt;

&lt;p&gt;As a good parent, you will sit and count with him. Given the number (n), populate an array with all numbers up to and including that number, but excluding zero.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
monkeyCount(10) // --&amp;gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br&gt;
monkeyCount(1) // --&amp;gt; [1]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And here's my solution. Easy!&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;monkeyCount&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;List&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;monkeyCount&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But then to my surprise and delight, I found an even shorter solution! You can use partial application:&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;monkeyCount2&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;List&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;monkeyCount2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand what's going on, let's look at the type annotation for &lt;code&gt;List.range&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;range : Int -&amp;gt; Int -&amp;gt; List Int&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So when we store &lt;code&gt;List.range 1&lt;/code&gt;, we've supplied 1 argument, and another one remains. What we get is a function that looks like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;monkeyCount2 : Int -&amp;gt; List Int&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I still think my solution is easier to read, but it's a good example of partial application.&lt;/p&gt;

&lt;p&gt;Then you have examples that go the other way. No comment:&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;monkeyCount&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;List&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;monkeyCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;monkeyCountHelper&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;monkeyCountHelper&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Int&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;Int&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="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;monkeyCountHelper&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;x&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;x&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;c&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;monkeyCountHelper&lt;/span&gt; &lt;span class="p"&gt;(&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;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&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;h1&gt;
  
  
  5. Time since midnight in milliseconds
&lt;/h1&gt;

&lt;p&gt;I eventually want to deal with time in my astronomy project. I've already written the most important functions, but it's good to just get this stuff into my head.&lt;/p&gt;

&lt;p&gt;Given a number of hours, minutes and seconds, return the number of milliseconds that have passed since midnight.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seconds to milliseconds = seconds * 1000&lt;/li&gt;
&lt;li&gt;Minutes to milliseconds = minutes * 1000 * 60&lt;/li&gt;
&lt;li&gt;Hours to milliseconds = hours * 1000 * 60 * 60&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Going by this, I decided to submit this solution:&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;past&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;past&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&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="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could have written 60000 and 3600000, but again, I think that affects readability.&lt;/p&gt;

&lt;p&gt;By far the most interesting solution was this one:&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;expand&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;expand&lt;/span&gt; &lt;span class="o"&gt;=&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;60&lt;/span&gt;

&lt;span class="n"&gt;past&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;past&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;h&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&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="n"&gt;m&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&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="n"&gt;s&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&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;1000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;:D&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Formatting large numbers
&lt;/h1&gt;

&lt;p&gt;The resulting number of milliseconds since midnight is a big number. These are hard to read, so it's nice to add some formatting, 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;const&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1234567890&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "1 234 567 890"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found &lt;a href="https://package.elm-lang.org/packages/cuducos/elm-format-number/latest/"&gt;cuducos/elm-format-number&lt;/a&gt; and included it in my project.&lt;/p&gt;

&lt;p&gt;First I did &lt;code&gt;elm install cuducos/elm-format-number&lt;/code&gt;, and then these were the imports I used:&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;import&lt;/span&gt; &lt;span class="kt"&gt;FormatNumber&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;format&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;FormatNumber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Locales&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;Decimals&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="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usLocale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, I was disappointed that it adds &lt;code&gt;.00&lt;/code&gt; to the end by default, but that's easy to fix:&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="c1"&gt;-- 49,062,000.00&lt;/span&gt;
&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;millisecondsSinceMidnight&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="n"&gt;usLocale&lt;/span&gt;


&lt;span class="c1"&gt;-- 49,062,000&lt;/span&gt;
&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;millisecondsSinceMidnight&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="n"&gt;usLocale&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  7. Remove all spaces from a string
&lt;/h1&gt;

&lt;p&gt;In advance, I think this should just be &lt;code&gt;split " " |&amp;gt; join ""&lt;/code&gt; or something like that.&lt;/p&gt;

&lt;p&gt;Here's what these two functions do:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;split " "&lt;/code&gt; will add a new list item for every space it comes across.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"cat dog human"&lt;/code&gt; becomes &lt;code&gt;["cat", "dog", "human"]&lt;/code&gt;. The spaces aren't included - they're used as delimiters.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;String.split "***" "a***b***c"&lt;/code&gt; becomes &lt;code&gt;["a", "b", "c"]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;String.join&lt;/code&gt; turns an array of strings into one string, and adds a character (or none) between each item. &lt;code&gt;String.join "-" ["o", "m", "g"]&lt;/code&gt; becomes &lt;code&gt;"o-m-g"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Instead of the dash, you can also pass an empty string, like I did:&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;noSpace&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;noSpace&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After submitting my solution, I saw a more elegant approach:&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;noSpace2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;noSpace2&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript has this functionality as well, but I keep forgetting about it. :)&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a b c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// a-b-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  8. Conclusion
&lt;/h1&gt;

&lt;p&gt;I really enjoyed practicing some basics, and I was excited to discover a couple of solutions I wouldn't have thought of.&lt;/p&gt;

&lt;p&gt;See you tomorrow!&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 21: Planet list -&gt; SVG drawings</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Wed, 06 Jan 2021 21:38:56 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-21-planet-list-svg-drawings-3n96</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-21-planet-list-svg-drawings-3n96</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VNLGwsVI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bkn7guq71lfs0vg2eosq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VNLGwsVI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bkn7guq71lfs0vg2eosq.png" alt="The planets and their orbits"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://ellie-app.com/c25wRvWCppXa1"&gt;https://ellie-app.com/c25wRvWCppXa1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is day 21 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today I had some fun with &lt;a href="https://package.elm-lang.org/packages/elm/svg/latest/"&gt;elm/svg&lt;/a&gt;, using hardcoded data to draw some fake orbits and planets.&lt;/p&gt;

&lt;p&gt;The reason I got into JavaScript in the first place was Daniel Shiffman's visualizations of mathematics, fractals, physics and animations. You're guaranteed to find something cool in his &lt;a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6ZiZxtDDRCi6uhfTH4FilpH"&gt;Coding Challenge playlist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In other words, I had a great time drawing circles and lines with code again. :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. About the project&lt;/li&gt;
&lt;li&gt;2. Imports, Model and Msg&lt;/li&gt;
&lt;li&gt;3. The data&lt;/li&gt;
&lt;li&gt;4. Displaying individual planets and orbits&lt;/li&gt;
&lt;li&gt;5. Displaying multiple planets and orbits&lt;/li&gt;
&lt;li&gt;6. View&lt;/li&gt;
&lt;li&gt;7. Main function with what's needed to get the browser width and height&lt;/li&gt;
&lt;li&gt;8. Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. About the project
&lt;/h1&gt;

&lt;p&gt;I want to draw something, based on a data source.&lt;/p&gt;

&lt;p&gt;Orbits: Transparent circles with black strokes. &lt;code&gt;radius = index * someNumber&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Planets: Filled circles. Index lets us calculate X and Y coordinates, by doing something 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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;middleOfScreen&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt; &lt;span class="n"&gt;angle&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;middleOfScreen&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cos&lt;/span&gt; &lt;span class="n"&gt;angle&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Imports, Model and Msg
&lt;/h1&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;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Dom&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;Viewport&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;Html&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;Html&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;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&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;attribute&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;Svg&lt;/span&gt; &lt;span class="k"&gt;exposing&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="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Svg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&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="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Task&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;initialModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;span class="n"&gt;initialModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&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;0&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;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NoOp&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;ReceivedViewport&lt;/span&gt; &lt;span class="kt"&gt;Viewport&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Viewport&lt;/code&gt; and &lt;code&gt;Task&lt;/code&gt; are used to get the browser's dimensions. &lt;a href="https://github.com/kristianpedersen/30-days-of-elm/blob/main/008-data-from-js-and-autoreload/src/Main.elm"&gt;Looking at my code from day 8&lt;/a&gt;, I'm wondering if just getting those from JavaScript using &lt;code&gt;innerWidth&lt;/code&gt; and &lt;code&gt;innerHeight&lt;/code&gt; would be a cleaner solution. Maybe it has some drawbacks.&lt;/p&gt;

&lt;p&gt;Yesterday, I used &lt;code&gt;Task&lt;/code&gt; to get the browser size, but I also implemented a resize solution. Today, I decided not to bother with that, just to keep it simple.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NoOp&lt;/code&gt; is just "don't do any commands", while &lt;code&gt;ReceivedViewport&lt;/code&gt; will be used to update the model.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. The data
&lt;/h1&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="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Planet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&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;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;WindowDimensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerX&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;hardcodedPlanets&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Planet&lt;/span&gt;
&lt;span class="n"&gt;hardcodedPlanets&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mercury"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Venus"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Earth"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&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;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mars"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturn"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orange"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jupiter"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&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;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gold"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Uranus"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lightblue"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Neptune"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue"&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pluto"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;beige"&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;I'm appreciating type aliases and the resulting type annotations more and more. &lt;/p&gt;

&lt;p&gt;Seeing actual words instead of just &lt;code&gt;Float&lt;/code&gt; and &lt;code&gt;List String&lt;/code&gt; is really nice, and we'll see some examples of this later in the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Displaying individual planets and orbits
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;viewOrbit&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WindowDimensions&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
&lt;span class="n"&gt;viewOrbit&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;circle&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;centerX&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;centerY&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none"&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stroke&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;black"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[]&lt;/span&gt;


&lt;span class="n"&gt;viewPlanet&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WindowDimensions&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Planet&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
&lt;span class="n"&gt;viewPlanet&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;planet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;circle&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;centerX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&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;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;centerY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&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;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;planet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt; &lt;span class="n"&gt;planet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stroke&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;black"&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;Looking at this code, the &lt;code&gt;index&lt;/code&gt; should have been part of the &lt;code&gt;Planet&lt;/code&gt; instead. Oh well.&lt;/p&gt;

&lt;p&gt;Because we're dealing with SVGs, the numbers need to be converted to strings. It's mildly annoying, but I can live with it.&lt;/p&gt;

&lt;p&gt;As we can see, the orbits' radiuses will increase by the same number of pixels. It's not accurate, but visualizing the real orbits would have been silly.&lt;/p&gt;

&lt;p&gt;The planet positions are calculated this way: centerOfScreen + (angle * radius). &lt;/p&gt;

&lt;p&gt;Using the index for angles is a bit silly, but I like doing silly things sometimes. Later on, my goal is to get accurate angles from my Python backend.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Displaying multiple planets and orbits
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;viewOrbits&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WindowDimensions&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="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Svg&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;viewOrbits&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;hardcodedPlanets&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexedMap&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;planet&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;viewOrbit&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="n"&gt;viewPlanets&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WindowDimensions&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="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Svg&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;viewPlanets&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;hardcodedPlanets&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexedMap&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;planet&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;viewPlanet&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;planet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are almost identical, but I figured there might be scenarios where you might wish to toggle just one of them.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;window&lt;/code&gt; is just being passed to the individual &lt;code&gt;viewOrbit&lt;/code&gt; and &lt;code&gt;viewPlanet&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;List.indexedMap&lt;/code&gt; gives us access to both the index and element, just like JavaScript does natively: &lt;code&gt;array.map((e, i) =&amp;gt; ...)&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. View
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&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="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&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="n"&gt;centerX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&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;2&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;centerY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&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;2&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;svg&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&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;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&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;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;viewBox&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 0 "&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&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;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&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;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&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="o"&gt;&amp;lt;|&lt;/span&gt;
        &lt;span class="n"&gt;viewOrbits&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;
            &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;viewPlanets&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;let&lt;/code&gt; statement isn't strictly necessary, but I just think &lt;code&gt;window.width&lt;/code&gt; sounds a lot better than &lt;code&gt;model.width&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There's a lot of &lt;code&gt;String.fromFloat&lt;/code&gt; going on here. On one hand, I want to write a very short function to make things less verbose, but then everyone else would have to learn about my spcial snowflake function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;++&lt;/code&gt; works for converting multiple lists into one, which is pretty cool. I almost created two separate SVG elements here!&lt;/p&gt;

&lt;h1&gt;
  
  
  7. Main function with what's needed to get the browser width and height
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&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;Model&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="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;handleResult&lt;/span&gt; &lt;span class="n"&gt;v&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;v&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="kt"&gt;Err&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="kt"&gt;NoOp&lt;/span&gt;

                &lt;span class="kt"&gt;Ok&lt;/span&gt; &lt;span class="n"&gt;vp&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="kt"&gt;ReceivedViewport&lt;/span&gt; &lt;span class="n"&gt;vp&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;initialModel&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="n"&gt;handleResult&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Dom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getViewport&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&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="kt"&gt;Sub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your read the let statement first, this may look confusing. Things look better if we start with &lt;code&gt;Browser.element&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Init equals an anonymous function which returns a tuple, consisting of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The inital model&lt;/li&gt;
&lt;li&gt;A function called &lt;code&gt;Task.attempt&lt;/code&gt;, which sends a message &lt;code&gt;handleResult&lt;/code&gt;, depending on the outcome of &lt;code&gt;Browser.Dom.getViewport&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you &lt;em&gt;then&lt;/em&gt; read the let statement, things make a bit more sense. &lt;code&gt;NoOp&lt;/code&gt; or &lt;code&gt;ReceivedViewport&lt;/code&gt; get sent to the update function, I believe.&lt;/p&gt;

&lt;h1&gt;
  
  
  8. Conclusion
&lt;/h1&gt;

&lt;p&gt;Drawing stuff with code is still fun.&lt;/p&gt;

&lt;p&gt;It was good to have a more relaxing kind of project today. The last days have been challenging.&lt;/p&gt;

&lt;p&gt;I went for two walks today, which was a very good idea. &lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 20: Getting the browser's width and height</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Tue, 05 Jan 2021 21:31:23 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-20-getting-browser-width-and-height-1nf9</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-20-getting-browser-width-and-height-1nf9</guid>
      <description>&lt;p&gt;This is day 20 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today I wanted to do something visual, but I wanted the SVG to fill up the available space. &lt;/p&gt;

&lt;p&gt;Instead, this turned out to be a day where we learn about getting information about the browser's width and height.&lt;/p&gt;

&lt;p&gt;In JavaScript, I can just ask for &lt;code&gt;innerWidth&lt;/code&gt; and &lt;code&gt;innerHeight&lt;/code&gt;. In Elm, it's more difficult.&lt;/p&gt;

&lt;p&gt;This post is written with confusion and poor sleep. :)&lt;/p&gt;

&lt;p&gt;Code/demo: &lt;a href="https://ellie-app.com/bZDy65SqXXFa1"&gt;https://ellie-app.com/bZDy65SqXXFa1&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;1. Getting the browser's width and height&lt;/li&gt;
&lt;li&gt;2. Responding to window resize events&lt;/li&gt;
&lt;li&gt;
3. The code

&lt;ul&gt;
&lt;li&gt;3.1. Model and Msg&lt;/li&gt;
&lt;li&gt;3.2. Main and subscription&lt;/li&gt;
&lt;li&gt;3.3. Update&lt;/li&gt;
&lt;li&gt;3.4. View&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;4. Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Getting the browser's width and height
&lt;/h1&gt;

&lt;p&gt;My experience with Elm documentation has been a bit frustrating. The descriptions are often good, and the type annotations help, but there have been a few occasions where just one or two code examples would have helped a lot.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href="https://package.elm-lang.org/packages/elm/browser/latest/Browser-Dom#getViewport"&gt;Browser.Dom.getViewport&lt;/a&gt; sounds good, but how do I use it? Its type annotation says &lt;code&gt;Task x Viewport&lt;/code&gt;. I've seen &lt;code&gt;Task&lt;/code&gt; mentioned before, and &lt;code&gt;Viewport&lt;/code&gt; is explained very well, but what on earth is an &lt;code&gt;x&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Of course, I should have read the documentation more thoroughly, but just having a practical example would have been nice for developers at any level.&lt;/p&gt;

&lt;p&gt;The type alias is easy to understand:&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="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Viewport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;scene&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
          &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;viewport&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
          &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
          &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
          &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&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;However, when trying to return &lt;code&gt;Browser.Dom.getViewport.scene&lt;/code&gt; in a function, I get this error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is not a record, so it has no fields to access!&lt;br&gt;
23|     Browser.Dom.getViewport.scene&lt;br&gt;
        ^^^^^^^^^^^^^^^^^^^^^^^&lt;br&gt;
This &lt;code&gt;getViewport&lt;/code&gt; value is a:&lt;br&gt;
Task.Task x Browser.Dom.Viewport&lt;br&gt;
But I need a record with a scene field!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well excuse me for reading the type alias and thinking curly braces equal a record. ;)&lt;/p&gt;

&lt;p&gt;So I read up on the &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/Task"&gt;Task documentation&lt;/a&gt;, and revisit the time example, and try &lt;code&gt;Task.perform GetBrowserDimensions Browser.Dom.getViewport&lt;/code&gt;, with 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;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;GetBrowserDimensions&lt;/span&gt;


&lt;span class="n"&gt;dimensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="kt"&gt;GetBrowserDimensions&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Dom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getViewport&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This resulted in a type of error message I've seen before, but I still struggle a bit with. &lt;code&gt;Msg&lt;/code&gt; and &lt;code&gt;msg&lt;/code&gt; - not a good choice of convention. :/&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;28|     Task.perform GetBrowserDimensions Browser.Dom.getViewport&lt;br&gt;
                    ^^^^^^^^^^^^^^^^^^^^&lt;br&gt;
This &lt;code&gt;GetBrowserDimensions&lt;/code&gt; value is a:&lt;br&gt;
    Msg&lt;br&gt;
But &lt;code&gt;perform&lt;/code&gt; needs the 1st argument to be:&lt;br&gt;
    a -&amp;gt; msg&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I asked at the Elm Slack channel, and got help very quickly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Samuel Kacer  28 minutes ago&lt;br&gt;
The first argument to Task.perform needs to be a function that will take the result from the Task and wrap it in some kind of message. so for the case of getViewPort, the argument needs to be of type Viewport -&amp;gt; Msg.&lt;br&gt;
the first argument you are providing, &lt;code&gt;GetBrowserDimensions&lt;/code&gt;, is of type Msg, so I assume it doesn't contain anything and has a definition something like this:&lt;br&gt;
type Msg =&lt;br&gt;
  ...&lt;br&gt;
  | GetBrowserDimensions&lt;br&gt;
but instead needs to be something like&lt;br&gt;
  | GetBrowserDimensions Viewport&lt;br&gt;
that way the constructor for that message variant will have a type of Viewport -&amp;gt; Msg, which would fit for the Task you are wanting to perform&lt;/p&gt;

&lt;p&gt;arkham  27 minutes ago&lt;br&gt;
you can check out this ellie &lt;a href="https://ellie-app.com/bZvHnKqpPrCa1"&gt;https://ellie-app.com/bZvHnKqpPrCa1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, I decided I needed it to respond to window resize events, which was also confusing, since the &lt;a href="https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize"&gt;onResize documentation&lt;/a&gt; uses &lt;code&gt;Cmd Msg&lt;/code&gt; as its type, but apparently I needed to use a &lt;code&gt;Sub Msg&lt;/code&gt; in my case:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kristian Pedersen  2 hours ago&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  2. Responding to window resize events
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Actually, I realized I wanted it to update on window resize. Again, I think I’m almost there, but it’s telling me I need a sub msg, not a cmd msg:&lt;br&gt;
&lt;a href="https://ellie-app.com/bZBqjmgPS9pa1"&gt;https://ellie-app.com/bZBqjmgPS9pa1&lt;/a&gt;&lt;br&gt;
What also confuses me is that going by the documentation, the subscriptions function returns a cmd msg, but in my example, it need to be a sub msg: &lt;a href="https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize"&gt;https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;arkham  1 hour ago&lt;br&gt;
hey &lt;a class="comment-mentioned-user" href="https://dev.to/kristian"&gt;@kristian&lt;/a&gt;
 Pedersen, it’s just the type of the subscription is a Sub Msg instead of a Cmd Msg , so your subscriptions function should be a Sub Msg, here’s a working ellie &lt;a href="https://ellie-app.com/bZC6k6dv9wna1"&gt;https://ellie-app.com/bZC6k6dv9wna1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;arkham  1 hour ago&lt;br&gt;
I also converted the Ints to Floats to get the type checker to be happy&lt;/p&gt;

&lt;p&gt;arkham  1 hour ago&lt;br&gt;
and here’s a very simple example of a subscription: &lt;a href="https://guide.elm-lang.org/effects/time.html"&gt;https://guide.elm-lang.org/effects/time.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;arkham  1 hour ago&lt;br&gt;
oh, and to be clear: the documentation is saying that onResize returns a Sub msg &lt;a href="https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize"&gt;https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for the help and patience, Arkham! You're a legend.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. The code
&lt;/h1&gt;

&lt;p&gt;Once all the confusion and going back and forth had settled, my resulting code mostly looks pretty nice, to be honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.1. Model and Msg
&lt;/h2&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="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;initialModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;
&lt;span class="n"&gt;initialModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&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;0&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;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NoOp&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;GotInitialViewport&lt;/span&gt; &lt;span class="kt"&gt;Viewport&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Resize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model is straight forward. Although &lt;code&gt;GotInitialViewport&lt;/code&gt; and &lt;code&gt;Resize&lt;/code&gt; look different, they both involve dealing with two &lt;code&gt;Float&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;I don't really like how this looks. Maybe it would have been cleaner to just do it through &lt;a href="https://dev.to/kristianpedersen/30daysofelm-day-8-data-from-js-and-auto-reload-1o4h"&gt;JavaScript interop&lt;/a&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  3.2. Main and subscription
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&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;Model&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="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;handleResult&lt;/span&gt; &lt;span class="n"&gt;v&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;v&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="kt"&gt;Err&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="kt"&gt;NoOp&lt;/span&gt;

                &lt;span class="kt"&gt;Ok&lt;/span&gt; &lt;span class="n"&gt;vp&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="kt"&gt;GotInitialViewport&lt;/span&gt; &lt;span class="n"&gt;vp&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;initialModel&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="n"&gt;handleResult&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Dom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getViewport&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Sub&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;E&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onResize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Resize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a pretty chunky main function compared to what I've seen before.&lt;/p&gt;

&lt;p&gt;When the task &lt;code&gt;handleResult&lt;/code&gt; is done, it will return one of those two &lt;code&gt;Cmd Msg&lt;/code&gt;s in the &lt;code&gt;let&lt;/code&gt; statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.3. Update
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;setCurrentDimensions&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&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="n"&gt;model&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="n"&gt;w&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="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&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;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;GotInitialViewport&lt;/span&gt; &lt;span class="n"&gt;vp&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;setCurrentDimensions&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;vp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scene&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="n"&gt;vp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scene&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kt"&gt;Resize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;setCurrentDimensions&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kt"&gt;NoOp&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Cmd.none&lt;/code&gt; just seems like it could be implicit instead, although I guess Elm favors explicitness a lot more than I'm used to. &lt;/p&gt;

&lt;p&gt;It adds a bit extra overhead to me as a beginner, but I guess it can be nice to see &lt;code&gt;Cmd.none&lt;/code&gt; at a glance.&lt;/p&gt;

&lt;p&gt;Again, I don't like my double approach, where I get the width and height two different ways: through a &lt;code&gt;vp&lt;/code&gt; variable, and through a &lt;code&gt;( w, h )&lt;/code&gt; tuple. It just feels wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.4. View
&lt;/h2&gt;

&lt;p&gt;Just displaying some data. A nice ending to a confusing day:&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;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The width is "&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&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;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;px, and the height is "&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&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;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;px"&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;h1&gt;
  
  
  4. Conclusion
&lt;/h1&gt;

&lt;p&gt;This is one case where I don't immediately see the benefit in doing it the Elm way, rather than just doing it through JavaScript interop, using &lt;code&gt;window.eventListener&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I definitely need to re-read the &lt;a href="https://package.elm-lang.org/packages/elm/browser/latest/Browser-Dom"&gt;Browser.Dom&lt;/a&gt; and &lt;a href="https://package.elm-lang.org/packages/elm/core/latest/Task"&gt;Task&lt;/a&gt; documentation.&lt;/p&gt;

&lt;p&gt;What I also need is a good night's sleep. (I highly recommend &lt;a href="https://www.amazon.com/Why-We-Sleep-Unlocking-Dreams/dp/1501144316"&gt;"Why We Sleep" by Matthew Walker&lt;/a&gt;) &lt;/p&gt;

&lt;p&gt;I woke up way too early, didn't have a siesta, and I'm noticing the negative effects on my thinking and mood. I've been through frustrating learning moments before, so I'll get through this one as well.&lt;/p&gt;

&lt;p&gt;Get a good night's sleep you too, and see you tomorrow!&lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>#30daysofelm Day 19: Basic time</title>
      <dc:creator>Kristian Pedersen</dc:creator>
      <pubDate>Mon, 04 Jan 2021 22:21:07 +0000</pubDate>
      <link>https://forem.com/kristianpedersen/30daysofelm-day-19-basic-time-ac</link>
      <guid>https://forem.com/kristianpedersen/30daysofelm-day-19-basic-time-ac</guid>
      <description>&lt;p&gt;This is day 19 of my &lt;a href="https://dev.to/kristianpedersen/30-days-of-elm-intro-2lo2"&gt;30 day Elm challenge&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Table of contents&lt;/li&gt;
&lt;li&gt;1. About today's project&lt;/li&gt;
&lt;li&gt;2. Time in Elm&lt;/li&gt;
&lt;li&gt;
3. What is different from the example code?

&lt;ul&gt;
&lt;li&gt;3.1 View&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;4. Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. About today's project
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://ellie-app.com/bZcnMkJZvrVa1"&gt;https://ellie-app.com/bZcnMkJZvrVa1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main piece of information I want to convey in this project is distance and time.&lt;/p&gt;

&lt;p&gt;Building on the astronomy project, the main thing we're working with is light minutes, which tells us how far light travels in a certain number of minutes.&lt;/p&gt;

&lt;p&gt;Light years sound a bit weird, but we're already using time for distance. The nearest city from my parents' place is one -hour- away.&lt;/p&gt;

&lt;p&gt;What I want to display in this project is &lt;code&gt;users_current_time - lightMinutes&lt;/code&gt;. If you were observing your house from a given solar system body, how far back in time would you see?&lt;/p&gt;

&lt;p&gt;I don't feel like doing much today, so I'll focus on getting a hardcoded proof of concept working first.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Time in Elm
&lt;/h1&gt;

&lt;p&gt;As a starting point, I just copied and pasted this code: &lt;a href="https://guide.elm-lang.org/effects/time.html"&gt;https://guide.elm-lang.org/effects/time.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In JavaScript, I'm used to the &lt;code&gt;Date&lt;/code&gt; object, which has some weird quirks:&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;const&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// Checking if it's the 24th day of the 12th month&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isXmas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="c1"&gt;// lol wtf&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getYear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="c1"&gt;// Returns 121! You need to use d.getFullYear() to get 2021 :D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Elm on the other hand uses Posix time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With POSIX time, it does not matter where you live or what time of year it is. It is just the number of seconds elapsed since some arbitrary moment (in 1970). Everywhere you go on Earth, POSIX time is the same.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  3. What is different from the example code?
&lt;/h1&gt;

&lt;p&gt;Except from the view, I haven't added anything. I just want to subtract X minutes from the time, so there's no need in over-complicating things.&lt;/p&gt;

&lt;p&gt;I could have chosen to update the time less frequently. We're only displaying the hours and minutes, so updating it every second means that only one of 60 ticks will result in a view update.&lt;/p&gt;

&lt;p&gt;However, I kept everything as is. I wouldn't like it if the GUI and the user's computer didn't change the minutes at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.1 View
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;lightMinutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="mi"&gt;75&lt;/span&gt;

        &lt;span class="n"&gt;currentHour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="kt"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toHour&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;

        &lt;span class="n"&gt;currentMinute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="kt"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toMinute&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;

        &lt;span class="n"&gt;newMinutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentHour&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;currentMinute&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lightMinutes&lt;/span&gt;

        &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="n"&gt;newMinutes&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;60&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;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;padLeft&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;

        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;remainderBy&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="n"&gt;newMinutes&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;padLeft&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;currentHour&lt;/code&gt; and &lt;code&gt;currentMinute&lt;/code&gt; look different from JavaScript, but I think it's pretty clear what they do.&lt;/p&gt;

&lt;p&gt;As I'm writing this, the time is 17:50. A time difference of 75 minutes means we should get &lt;code&gt;16&lt;/code&gt; for the hours and &lt;code&gt;35&lt;/code&gt; for the minutes.&lt;/p&gt;

&lt;p&gt;To get the new time, we can first find out how many minutes have passed today since midnight. &lt;/p&gt;

&lt;p&gt;If we're sticking with 17:50, the total number of minutes would be ((17 * 60) + 50). We then subtract the lightminutes from that number.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;17 * 60 + 50 = 1070&lt;/li&gt;
&lt;li&gt;We subtract 75 minutes, which is 995.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;floor 995 / 60&lt;/code&gt; = 16&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remainderBy 60 995&lt;/code&gt; = 35&lt;/li&gt;
&lt;li&gt;The new time is 16:35&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the number is less than 10, we use &lt;code&gt;String.padLeft&lt;/code&gt; to add a 0. Make sure to wrap the 0 character in single quotes, or Elm will think it's a character, not a string.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: I didn't include 00:00 - 1 = 23:59. Here's what that would look like:&lt;/em&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;getNewHour&lt;/span&gt; &lt;span class="n"&gt;currentHour&lt;/span&gt; &lt;span class="n"&gt;hoursToSubtract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;timeDifference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;currentHour&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;hoursToSubtract&lt;/span&gt;

        &lt;span class="n"&gt;newHour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;timeDifference&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="n"&gt;timeDifference&lt;/span&gt;

            &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;timeDifference&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;newHour&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  4. Summary
&lt;/h1&gt;

&lt;p&gt;I had hoped this would be a simple exercise, and I was right. This will be very useful later on. &lt;/p&gt;

&lt;p&gt;Some funky numbers are displayed the first second, but I'm too tired to fix that now.&lt;/p&gt;

&lt;p&gt;See you tomorrow!&lt;/p&gt;

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