<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Richard Wood</title>
    <description>The latest articles on DEV Community by Richard Wood (@rwoodnz).</description>
    <link>https://dev.to/rwoodnz</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%2F64322%2Fafdcb5ea-eaa1-41cb-8b68-33210a61c137.jpeg</url>
      <title>DEV Community: Richard Wood</title>
      <link>https://dev.to/rwoodnz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rwoodnz"/>
    <language>en</language>
    <item>
      <title>Playing with "with" in Elm </title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Wed, 04 Sep 2019 11:55:35 +0000</pubDate>
      <link>https://dev.to/elmupdate/playing-with-with-in-elm-3p9m</link>
      <guid>https://dev.to/elmupdate/playing-with-with-in-elm-3p9m</guid>
      <description>&lt;p&gt;Inspired by &lt;a href="https://medium.com/@ckoster22/with-functions-in-elm-a88dc0e1f851"&gt;With* Functions in Elm&lt;/a&gt; by Charlie Koster I determined to bring in a set of 'with' functions into a recent work project.&lt;/p&gt;

&lt;p&gt;Koster's example allows you to create a default button and then pipe to one or more modifiers rather than define the full record of modifiers each time.&lt;/p&gt;

&lt;p&gt;From his code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Small Call to Action"&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="n"&gt;makeSolid&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;makeDisabled&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;My code was in a worse state. For my calling functions I had unnamed parameters rather than an options record as a single parameter. These had grown as the application grew, to a point where it was wasn't always obvious what a parameter might be for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;singleCheckBox&lt;/span&gt; 
    &lt;span class="n"&gt;editingUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blocked&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ToUsers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="kt"&gt;ChangeBlock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login blocked"&lt;/span&gt; 
    &lt;span class="kt"&gt;False&lt;/span&gt;

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



&lt;p&gt;Rather than separate out required parameters and retain them as regular parameters I decided for simplicity to put everything in the option parameter, to benefit from them all being named. &lt;/p&gt;

&lt;p&gt;Then when I started to create the "with" statements I soon realised the number of "with" modifiers would blow out, yet a lot of what is needed is the same concept between input types. &lt;/p&gt;

&lt;p&gt;So I decided to use the record modifying syntax that allows us to be generic. Now I can use the one "with" modifier for title, for example, across the different buttons and inputs that I have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;withTitle&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="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;title&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;title&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;withTitle&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;You may realise I do not have as much type safety going on as Koster did. His is a module just for a button and tied down to it. I have a module for a collection of different inputs. I'm not clear yet if I can retain the generic approach if I lock it down further.&lt;/p&gt;

&lt;p&gt;I also read this exchange started by &lt;a href="https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/7"&gt;Thomas Kagan&lt;/a&gt; where the pros and cons of pipelines vs list of attributes are discussed.&lt;/p&gt;

&lt;p&gt;I decided the list of attributes approach was more consistent with rest of my code. I also placed the options type definitions and default values in the context of each.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;InputOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;textContent&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;changeMsg&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;Msg&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;placeholderText&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;title&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;titleNote&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;disable&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;inputBox&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;InputOptions&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;InputOptions&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;Element&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;inputBox&lt;/span&gt; &lt;span class="n"&gt;optionModifiers&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;defaults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;textContent&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;changeMsg&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;Noop&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;placeholderText&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;title&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;titleNote&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;disable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;options&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;foldl&lt;/span&gt;
                &lt;span class="n"&gt;identity&lt;/span&gt;
                &lt;span class="n"&gt;defaults&lt;/span&gt;
                &lt;span class="n"&gt;optionModifiers&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I applied this approach to all of input views that I have - both inputs as well as views that present collections of inputs. I've ended up with a list of 20 "with" modififiers I can use generically.&lt;/p&gt;

&lt;p&gt;Now my calls to inputs look great&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;standardButton&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;withButtonMsg&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ToUsers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ConfirmDeleteUser&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;withTitle&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Delete Permanently"&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;withColor&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;red&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

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



&lt;p&gt;I can tick off that the code is more readable  excepting the addition of the foldl statements. And above all now only the parameters beyond default values are passed and they are all named. &lt;/p&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>Type Wars, TDD and Elm</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Tue, 03 Sep 2019 10:23:53 +0000</pubDate>
      <link>https://dev.to/elmupdate/type-wars-tdd-and-elm-4893</link>
      <guid>https://dev.to/elmupdate/type-wars-tdd-and-elm-4893</guid>
      <description>&lt;p&gt;Should we TDD in statically typed languages, even in Elm?&lt;/p&gt;

&lt;p&gt;Yesterday I offered an &lt;a href="https://dev.to/rwoodnz/the-future-of-programming-rejected-1mb3"&gt;opinion&lt;/a&gt; on Bob Martin's video &lt;a href="https://www.youtube.com/watch?v=ecIWPzGEbFc"&gt;The Future of Programming&lt;/a&gt;. The comments went off on a tangent and ended up with the attention of a moderator. In amongst that I learned there had been a kerfluffle online earlier about another Bob Martin missive - &lt;a href="https://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html"&gt;Type Wars&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Ok, so bear with me.&lt;/p&gt;

&lt;p&gt;The crux of that debate is the characterisaton of innovation in language as a battle of ideas that began between those that want no types and liked C and those that want types and perhaps if they are old enough liked Pascal, or more lately Java and C#. It seems in his world you had to choose your camp and defend it ... unless you switched sides.&lt;/p&gt;

&lt;h4&gt;
  
  
  Back to reality
&lt;/h4&gt;

&lt;p&gt;What I do like in the article is what matches my experience, that in the Ruby world with dynamic typing the ultimate is to do TDD. Unit tests rule and drive you crazy. However over in the static typing C# world people seem happy with a lot of after-the-fact unit test creation. Although that can then become a drudgry task for some and risks not being done well.&lt;/p&gt;

&lt;p&gt;I don't see a battlefront at all. It simply makes sense that if you are not getting help from a compiler and perhaps write all your software in a code editor, as many Ruby folk do, then you you need to have as comprehensive as possible unit tests. Hence TDD, which by definition gives you a certain amount of unit tests for every function.&lt;/p&gt;

&lt;p&gt;If you are getting shit loads of help from your compiler and your IDE, as you do in C# and Visual Studio, and even more so in Elm, then you will need less from your unit tests. &lt;/p&gt;

&lt;p&gt;I still admire those that TDD in languages such as C# but the reality I have seen is that very few judge it necessary to acquire those skills.&lt;/p&gt;

&lt;p&gt;That said I came across &lt;a href="https://discourse.elm-lang.org/t/elmer-an-elm-testing-tool/232"&gt;this debate&lt;/a&gt; about a library in strictly typed Elm targetted at TDD. And &lt;a href="https://medium.com/@brian.watkins/test-driving-elm-with-elmer-649e2e7e02a8"&gt;this&lt;/a&gt; also.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sidetrack
&lt;/h4&gt;

&lt;p&gt;For those outside of the Elm community the contents of that debate might seem odd. Someone who loves TDD wants to have a testing library focused on it and puts in his own efforts to create it. The supporters of an existing testing library aren't happy it seems because it breaks a community desire to focus efforts for maximum impact.&lt;/p&gt;

&lt;p&gt;I have long been bemused by those in the Elm community that push that there should only be one library per language function. Nothing wrong though with throwing some good questions in to really test if someone knows what is around and is committed!&lt;/p&gt;

&lt;p&gt;The bottom line though is that if someone wants to go and write a library that overlaps another then that's their perogative. If it gets community support then let it be on the library's merits. You can just imagine whose sides people would have been on when Einstein came up with his reletavity ideas.&lt;/p&gt;

&lt;p&gt;I hope what I saw at Elm Europe 2019 heralds a more open thinking future. Two groups forking the compiler and a leader of the community kicking off his own language development. &lt;/p&gt;

&lt;p&gt;Create a whole new thing - Great! You may cause a revolution or you may influence evolution of the existing dominant tool.&lt;/p&gt;

&lt;h4&gt;
  
  
  Back to TDD
&lt;/h4&gt;

&lt;p&gt;Now, looking at the idea of a testing library for Elm focused on TDD. As someone who has only dabbled in TDD in Ruby, the question of the value of TDD in Elm is what I am left with. &lt;/p&gt;

&lt;p&gt;Elm, like Ruby, is a language that can just be loads of fun to program in, in quite a playful way. As well as being a solid choice for bigger projects, it is great for your own startup and for experiemental greenfield projects. A function may only last 10 minutes before you refactor things and it disappears. Elm also has the bonus of a compiler that really helps you along to write your code and refactor.&lt;/p&gt;

&lt;p&gt;TDD would seem to be more suitable when the thing you are building is well defined. You can nail down at the outset what you intend to create. Then it's quite a mechanical thing to write the code to meet the tests.&lt;/p&gt;

&lt;p&gt;Is TDD though just the articulation of the process you are doing in your head anyway, slowed down? You have identified a need for a function, you have in your head what you want out of that function and you write the function. &lt;/p&gt;

&lt;p&gt;Some people advocate writing code incrementally, which is a form of transitory testing as you create using dummy values and function calls. Is that the same process again from an other view?&lt;/p&gt;

&lt;p&gt;Let's assume you end up writing all your tests anyway. What I want to know is. Does doing TDD, particularly with statically typed languages, take some of the immediacy and fun out of the process? Or once you are good at it, is it a seamless experience with the same level of enjoyment?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tdd</category>
      <category>elm</category>
    </item>
    <item>
      <title>The Future of Programming - Rejected!</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Mon, 02 Sep 2019 08:08:52 +0000</pubDate>
      <link>https://dev.to/rwoodnz/the-future-of-programming-rejected-1mb3</link>
      <guid>https://dev.to/rwoodnz/the-future-of-programming-rejected-1mb3</guid>
      <description>&lt;p&gt;Much admired software guru "Uncle" Bob Martin wants to take away all our fun and make us into responsible "disciplined" programmers.&lt;/p&gt;

&lt;p&gt;I watched his talk &lt;a href="https://www.youtube.com/watch?v=ecIWPzGEbFc"&gt;The Future of Programming&lt;/a&gt; recently. His beef is that, if we carry on as we are, the authorities will regulate us. So we need to regulate ourselves, make software programming a profession, create and enforce standards, etc etc.&lt;/p&gt;

&lt;p&gt;Coming from the 70s dark ages where perhaps most projects were for military, space exploration, or some big industry project you can speculate why he may think this way.&lt;/p&gt;

&lt;p&gt;In essense coding requires mathematical nous, and a high level of discipline that older programmers had because they became programmers later in life. Now there are lots of youngsters who don't have the discipline yet and what we do can kill people.&lt;/p&gt;

&lt;p&gt;Lol what low percentage of us actually work on software that could end up killing someone. FFS. &lt;/p&gt;

&lt;p&gt;Of course there are airplane systems, factory controls, social media tools that encourage suicides and terrorism, etc etc.&lt;/p&gt;

&lt;p&gt;However, most of us work in website development helping businesses look good and be more efficient. Even a fintech solution shuffling large amounts of money around needs to be kept in perspective. There are critical parts to the code where errors could make people bankcrupt and there are soft parts that are just about winning and keeping customers with a great UI.&lt;/p&gt;

&lt;p&gt;On the other hand a modern take on coding is that it is like writing and should be taught as such in primary school. Some people literally think anyone can do it and everyone should be able to. The bootcamp I went through - New Zealand's Dev Academy - pretty much had this attitude. In retrospect I think they overstate it.&lt;/p&gt;

&lt;p&gt;So we have two extremes and the problem is not that we all need to be regulated. Would you force a poet to use a particular style? Does every novel have to have 3 dramatic stages? No. Should an aircraft manual be structured, detailed and constantly updated? Yes.&lt;/p&gt;

&lt;p&gt;The issue is that some software development needs more rigor and oversight than others. Where there is development of critical systems for likes of spacecraft and airlines then bring on the regulation. Even if it means people there have to program in last decades' languages when a modern language would be better. There are plenty of people who like the old languages and have the experience to make that code bulletproof.&lt;/p&gt;

&lt;p&gt;Segregate that lot and leave the rest of us in peace. We are having fun creatively developing frameworks, languages and solutions at dramatic pace.&lt;/p&gt;

&lt;p&gt;There's this idea that young developers are reinventing the wheel all the time because they dont understand enough yet. Is this a case of aging developers who may want to maintain their position in a fantasy heirachy. News flash - very few people care, they are having a ball.&lt;/p&gt;

&lt;p&gt;Young people are experimenting, having fun, finding multitudes of ways to express themselves and solve problems with code. The best learning happens through play!&lt;/p&gt;

&lt;p&gt;Ok. Let's face it, the amount of effort put into JS in recent years was stupid and unproductive. We ended up with the dueling nightmares of React and Angular. Node was like the warm up performance. We also got a crazy amount of other backend language options. It's all driven a hugely inefficent industy in learning and recruitment.&lt;/p&gt;

&lt;p&gt;But for all that, this creative surge got people excited, interested and in my view it's all very healthy. The ease with which people could and can pump out libraries, frameworks and languages has democratised language development. &lt;/p&gt;

&lt;p&gt;The lead has been well and truely wrested from the cohort who kicked off this industry so many years ago. Yes they should be respected for it, despite writing huge boring books about subjects such has how to keep your code clean and overcome the defiencies of OO. :)&lt;/p&gt;

&lt;p&gt;Out of an apparently ridiculous situation will come better things and like many I'm putting a lot of faith in functional programming. Go on, check out Elm and Elixir if you haven't already. There is huge opportunty for evolution and revolution. Enough to keep young programmers excited for decades to come, and with a lot of the discipline built in!&lt;/p&gt;

&lt;p&gt;Otherwise, the populace don't need nostalga buffs telling us what to do, warning that the sky is falling, and taking away our fun. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>functional</category>
      <category>future</category>
    </item>
    <item>
      <title>Keeping it simple beyond a basic Elm app </title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Thu, 18 Jul 2019 21:11:38 +0000</pubDate>
      <link>https://dev.to/elmupdate/keeping-it-simple-beyond-a-basic-elm-app-569m</link>
      <guid>https://dev.to/elmupdate/keeping-it-simple-beyond-a-basic-elm-app-569m</guid>
      <description>&lt;p&gt;When you want to go beyond a basic Elm code base people will usually point you to Richard Feldman’s &lt;a href="https://github.com/rtfeldman/elm-spa-example"&gt;elm-spa-example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unless you are confident you are heading for a multipage, feature-rich extravaganza then this is overkill. &lt;/p&gt;

&lt;p&gt;Yes, it proves that in Elm you actually can break things into subcomponents, delegating models, messages and subscriptions, which in no way means you should.&lt;/p&gt;

&lt;p&gt;On the other hand, it's also been said that you can just put everything in one file with a huge update function with hundreds of lines. Um. Seriously, you probably don’t want to be waiting for that to scroll or end up jumping to specific meaningless line numbers.&lt;/p&gt;

&lt;p&gt;Recently I had a mid-size web app to start building so I sought to navigate a middle path. Starting with some basic principles.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep it simple - future maintenance depends on it.&lt;/li&gt;
&lt;li&gt;Minimise meaningless abstractions and patterns - code that doesn't do what the app is trying to do wastes everyone's time.&lt;/li&gt;
&lt;li&gt;Don't fight The Elm Architecture - update function changes model is changed and calls commands. Model changes are reflected in views. View events, command results, and subscriptions lead to more updates. It's a virtuous and relatively tidy one-way circle. &lt;/li&gt;
&lt;li&gt;Avoid nesting. Keep the single source of truth model as flat as possible. Remember that all events flow through the main update even if delegated. &lt;/li&gt;
&lt;li&gt;Don't make it difficult for components to interact. A web app will generate events in one corner that lead to model changes and commands affecting other parts of the app. Subviews will need access to the top level and other component's data.&lt;/li&gt;
&lt;li&gt;Make it easy to find relevant code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I began with &lt;a href="https://github.com/halfzebra/create-elm-app"&gt;create-elm-app&lt;/a&gt; with a one file solution, then upgraded to Browser.application when I needed access to the Url. &lt;/p&gt;

&lt;p&gt;When I felt the update function was getting a bit scrolly and I had a user editing section that was burgeoning I moved that into its own file. It was at this point that I had to decide how far to go with delegation.&lt;/p&gt;

&lt;p&gt;Interestingly, and something I’ve found previously, is that it is pretty easy to get into a situation where you need to call back and forth to your main file for type and message definitions - leading to circular references. &lt;/p&gt;

&lt;p&gt;I’ve found in the past that this can be knocked on the head by putting all types in a file called Types, all msgs in a file called Msgs and common functions in a file called Helpers or a file called CommonViews accordingly. &lt;/p&gt;

&lt;p&gt;So I went ahead with this refactor. This worked in tune with not going crazy on delegation. What we are trying to avoid is stuff that makes you think too hard, like this from elm-spa-example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;updateWith : (subModel -&amp;gt; Model) -&amp;gt; (subMsg -&amp;gt; Msg) -&amp;gt; Model -&amp;gt; ( subModel, Cmd subMsg ) -&amp;gt; ( Model, Cmd Msg )
updateWith toModel toMsg model ( subModel, subCmd ) =
    ( toModel subModel
    , Cmd.map toMsg subCmd
    )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Noone should have to read that! &lt;/p&gt;

&lt;p&gt;In a nutshell I went with a delagation for the update function but not for anything else.&lt;/p&gt;

&lt;p&gt;So in the main update:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case msg of
    ----COMPONENT MESSAGES----
    ToEnv envMsg -&amp;gt;
        Env.update envMsg model

    ToUsers userMsg -&amp;gt;
        Users.update userMsg model
        ...

    ----TOP LEVEL MESSAGES----
        ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The wrapped messages for the components do often mean I am doing component composition (&amp;lt;&amp;lt;) to reference them.&lt;/p&gt;

&lt;p&gt;In the Types file the main model definition is broken into component sections by using comment separators. &lt;/p&gt;

&lt;p&gt;This helps keeps a lid on nesting and keeps the single source of truth reality front-of-mind. &lt;/p&gt;

&lt;p&gt;It means also one equivalent init function, albeit referencing empty component-specific records, which for now I am holding in their respective component files.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias Model =
    { window : Window
    , messageToUser : Maybe String
    , env : Env
    , initialUrl : Url
    , navKey : Key
    ...

    -- User
    , users : List User
    , userSearchQuery : String
    ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For the Msgs file there is a main message type for the main file that includes the component wrappers, and separate message types for each of the components.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Msg
    = ResizeDevice Int Int
    | ToEnv EnvMsg
    | ToUsers UserMsg
    ...

type EnvMsg
    = GetEnv
    | EnvResult (Result Http.Error ConfigEnv)
    ...

type UserMsg
    = ClearSearchUsers
    | SearchUsers
    ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I could have put component messages in with the rest of the component. However it has been useful to keep all possible messages in one view as far as possible.&lt;/p&gt;

&lt;p&gt;The net effect of this is that the main has a very clean update function showing the structure of the application, without meaningless absractions. &lt;/p&gt;

&lt;p&gt;The component file have their own update function that works off their own message type and comes back to the single source of truth model either through top level of any component messages.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update : UserMsg -&amp;gt; Model -&amp;gt; ( Model, Cmd Msg )
update userMsg model =
    case userMsg of
        SearchUsers -&amp;gt;
        ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There is a little bit of nesting access needed in the component but only to one level so it’s manageable.&lt;/p&gt;

&lt;p&gt;The component files also hold the related views for those components.&lt;/p&gt;

&lt;p&gt;I haven’t found a reason yet in my app for delegating subscriptions, perhaps because I don’t have many yet. I also am not doing much with routing yet.&lt;/p&gt;

&lt;p&gt;Otherwise, overall I am very pleased with the result for a small to mid-size app. There is a minimisation of scaffolding. It has been very easy to be able to find, add to and refactor code.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>elmlang</category>
    </item>
    <item>
      <title>Elm Europe 2019 - Elm and GraphQL heavenly match</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Wed, 26 Jun 2019 19:11:33 +0000</pubDate>
      <link>https://dev.to/elmupdate/elm-and-graphql-heavenly-match-586n</link>
      <guid>https://dev.to/elmupdate/elm-and-graphql-heavenly-match-586n</guid>
      <description>&lt;p&gt;Today I attended a full day workshop on Elm-GraphQL at Elm Europe lead by the package’s author Dillon Kearns.  &lt;/p&gt;

&lt;p&gt;There were 10 attendees, all with a variety of interests ranging from learning more about the Elm ecosystem generally to adding to their skills for work or home projects. A few including myself were working or had worked in environments with GraphQL but not Elm, so a great opportunity to bring two worlds together.&lt;/p&gt;

&lt;p&gt;And what music these two worlds together bring. GraphQL is effectively an enhanced type system that sits between your client front end and your back end data. It allows you to send nested queries without having to set up or distort a REST endpoint for every variation. It’s easy to be specific with what you want from the backend and not ‘overfetch’ or ‘underfetch’ as is easy to do using REST. &lt;/p&gt;

&lt;p&gt;Instead you query using object style definitions and set up ‘resolvers’ for every type of data you may want to call. If a type of data has another type of data within it then a resolver is called for the inner data and so on. On the flip side this may mean more individual calls to your database, which may be a problem depending on your application needs and the sophistication of the back end GraphQL server in generating SQL calls.&lt;/p&gt;

&lt;p&gt;This whole GraphQL thing came out of Facebook and you can intuitively see how it would have solved a lot of their 'graph' access challenges in pulling together data in different views from different people and types of records. These days GraphQL is used by many companies including GitHub, Shopify and Twitter.&lt;/p&gt;

&lt;p&gt;Having a declared schema, introspection, and documentation in whatever GraphQL implementation is server-side gave the opportunity for Dillon to create a code generation tool that gives you the equivalent types and decoders in Elm. That is paired with the Elm package to give a seamless way to retrieve data. So no more doing your own decoders. Dillon also has a related tool for Typescript and Elm.&lt;/p&gt;

&lt;p&gt;What this means is you are getting pre-made Elm modules that allow you to build queries that are fully typed and you know will work if they compile (if your GraphQL backend is full-proof of course). All the benefits of the Elm Compiler, edged into the back end.&lt;/p&gt;

&lt;p&gt;So, a graphql query just looks like a JS or JSON object but just the keys of the data you want, nested as far as you want. A get query returns the object with the values included.&lt;/p&gt;

&lt;p&gt;A graphql mutation query can also return a query but the main point of course is to change particular fields. There is also a subscription query for setting up data change notifications that may typically feedback through web sockets. GraphQL is a transport agnostic spec.&lt;/p&gt;

&lt;p&gt;We covered a lot of detail around nullable fields, scalar fields, ENUMs, lists and more. Then we got onto exercises that introduced us to how this all looks in Elm. If you compare side-to-side it’s a little bit verbose and daunting, but once you start playing with it you can see the power.&lt;/p&gt;

&lt;p&gt;Elm-GraphQL doesn’t just imitate what you can do in a regular GraphQl client. Dillon described it as operating at a higher abstraction level, because of what Elm itself adds to the equation. &lt;/p&gt;

&lt;p&gt;And there's what can be brought back to the compiler from the introspection of the GraphQL server implementation. Being able to get Elm compile errors for invalid queries at compile time is a boon. Having docs in your editor, just being able to write your queries as Elm language not as magic strings.&lt;/p&gt;

&lt;p&gt;Dillon also had a focus on the process of writing code that was like a bonus gift in the workshop. For example writing small pieces at a time that compile and work and using dummy values along the way to reduce cognitive load. &lt;/p&gt;

&lt;p&gt;Also encouraging us to experiment with pipeline patterns and see how it affected error messages. In Elm-GraphQL you build up your query ‘selection set’ by specifying fields in a SelectionSet.mapN function call or by building a pipeline starting with SelectionSet.succeed. This approach and the tradeoffs will be familiar to some.&lt;/p&gt;

&lt;p&gt;I’ve purposefully left code out of this blog post as it would get deep very quickly. I don’t want you to think it’s all a walk in the park. There is a learning curve and it helps if you are confident in the range of Elm language features at the outset.&lt;/p&gt;

&lt;p&gt;Even with the smooth code generation in Elm-GraphQL the reality is that two worlds are coming together. You can still find yourself staring at something blankly not sure how it relates to the simplicity of an Graph-QL object. You will import the code that is generated and you need to understand what is in those files. The compiler will help you a lot but sometimes the error messages will flummox.&lt;/p&gt;

&lt;p&gt;Nevertheless we could see with the fluidity that Dillon moved around his examples that it is just practice - and in parallel you should get fully up to speed on things like opaque and phantom types as these can help to understand things.&lt;/p&gt;

&lt;p&gt;The ability to remove uncertainty is what this is all about, as Dillon has spent much time talking about previously. With the contracts that GraphQL enforces passed over to Elm you are able to have confidence that your queries if they compile will get you the data you want.&lt;/p&gt;

&lt;p&gt;It is a pretty good feeling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/"&gt;https://package.elm-lang.org/packages/dillonkearns/elm-graphql/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elm</category>
      <category>elmeurope</category>
      <category>graphql</category>
      <category>elmlang</category>
    </item>
    <item>
      <title>Immutability - something worth striving for</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Fri, 30 Nov 2018 09:29:56 +0000</pubDate>
      <link>https://dev.to/rwoodnz/immutability---something-worth-striving-for-3ppp</link>
      <guid>https://dev.to/rwoodnz/immutability---something-worth-striving-for-3ppp</guid>
      <description>&lt;p&gt;When I worked in C# at PartsTrader I started to see the similarities between what Domain Driven Design is looking for and what Functional Programming does. Or rather what FP has to do to be able to be useful in the real world.&lt;/p&gt;

&lt;p&gt;I currently develop in Javascript for one client and functional language Elm for another. I've previously worked for two .Net companies. One of them - PartsTrader - was dead keen on DDD.&lt;/p&gt;

&lt;p&gt;So I'm talking about separating out pure functions from side effects. In DDD the idea is to circumscribe business logic, keeping all the IO and external interfaces outside the circle.&lt;/p&gt;

&lt;p&gt;Whamo, when you look at a functional environment such as Elm, you have all the pure functions segregated away from the messy IO and external javascript functions.&lt;/p&gt;

&lt;p&gt;The difference is that in Elm this split is mandatory. In DDD and object oriented languages it's a voluntary design decision with some serious book reading available to convince you that you are doing the right thing lol.&lt;/p&gt;

&lt;p&gt;However, it still comes back to immutability. Functional programming gives you this off the bat. In non-functional languages it is still a great idea, but you have to choose to do it. The benefits are that your code is easier to debug as what goes in and comes out remains constant at every level.&lt;/p&gt;

&lt;p&gt;In Elm the entire code is immutable - think of it as one big function that is called as needed. Anything side-effecty will be done by the runtime and then the function called again. &lt;/p&gt;

&lt;p&gt;This has some interesting benefits. If you want to see what your programme is doing, just look at the big 'update' function that is at the bottom of this tree and anything it delegates it to. With the strict typing on top of that, if you make any changes that disrupt things you find out very quickly on compile, and the error messages just 'know' so much about what you are doing.&lt;/p&gt;

&lt;p&gt;Which is not to disparage .Net's Visual Studio when using C#. It 'knows' a hell of a lot before you even get to compile thanks to the work that has gone into it over the years from some very smart people.&lt;/p&gt;

&lt;p&gt;In non-functional languages it is also good practice to pass in any values that may change randomly so that you still have unit-testable functions - dependency injection. In Elm, functions that call side effects don't return things back into the code and so don't impact the return value. They go off to the runtime, which then returns values through the message update channel as if some magic fairy generated them.&lt;/p&gt;

&lt;p&gt;Anyway, developing in Javascript is where the rubber hits the road for this discussion. On the one hand it is a functional language in that functions are first class and references to them can be passed around. On the other hand it is so loose that you can have side effects wherever you like. You really don't know with some functions what might come out the other end. Tightening that up requires a fair bit of overhead construction.&lt;/p&gt;

&lt;p&gt;I am working on an old JS code base that I've largely converted to ES6. While I've brought in Webpack, I've shied away from introducing any of the new frameworks like React and Angular - both of which I have used before. I use a bit of native JSX as a short cut for templating forms and menus, but that's another story.&lt;/p&gt;

&lt;p&gt;With ordinary JS you can still take a strategy of making things as immutable as possible. Again it means segregating out anything that is a side effect until your functions become pure. &lt;/p&gt;

&lt;p&gt;In my case I'd like to start to reorganise the codebase so that, well, it looks more like an Elm structure with a tree of update logic updating a model and a set of view functions that simply reflect the changes in the model - all as pure as possible. I'm still working through how best to do that in combination with the heavy use of Mapbox and Leaflet in the app.&lt;/p&gt;

&lt;p&gt;There are also times in the nitty gritty when imperative code in Javascript is just easier to understand and quicker to achieve, and being pragmatic is certainly a good quality. Perhaps best to leave a comment in such functions that they should not be extended into incorporating side effects and make sure not to pass anything external in.&lt;/p&gt;

&lt;p&gt;I believe that immutability and segregation of side effects is one of the core goals worth striving for in software design. If it can't be achieved immediately it should at least be regarded as the preferred direction.&lt;/p&gt;

&lt;p&gt;I am confident that by taking this approach something easier to read, maintain and add to will come of it.&lt;/p&gt;

</description>
      <category>immutability</category>
      <category>elm</category>
      <category>javascript</category>
      <category>ddd</category>
    </item>
    <item>
      <title>Is coding easy? </title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Fri, 12 Oct 2018 08:10:09 +0000</pubDate>
      <link>https://dev.to/rwoodnz/is-coding-easy--33g6</link>
      <guid>https://dev.to/rwoodnz/is-coding-easy--33g6</guid>
      <description>&lt;p&gt;My eldest son asked me - is coding easy?&lt;/p&gt;

&lt;p&gt;Where do you start. At the Dev Academy bootcamp they were adamant that just about anyone can give it a go. Yet I still think an ability to think logically, some mathematical nous and basic communication skills are essential. &lt;/p&gt;

&lt;p&gt;I suspect their message was mainly to get people who had self-doubts over the sign-up line. Some people just don't realise what they can do and some of this can certainly also be taught.&lt;/p&gt;

&lt;p&gt;If you can think logically and have a lot of patience then you can work through the hard-to-read documentation. If you can sit at a computer for hours. If you can create the right search online. If you can generalise off the examples that don't always match the difficult problem you face. Intuition helps immensely there too.&lt;/p&gt;

&lt;p&gt;It can be easy if you don't have a constant need to interact with your colleagues - although working remotely mitigates this for me. If you enjoy that fully focused in-the-zone time when everything else disappears. If you enjoy solving puzzles and problems that you know must have a solution even if you just can't see it. That's part of the answer.&lt;/p&gt;

&lt;p&gt;It can be easy. If it's something you've done a few times before. It's all relative to the difficulty of the problem you face and your familiarity with the tools you need to use. New and unknown have to be treated like exploring rather than doing.&lt;/p&gt;

&lt;p&gt;It also depends on how tired you are and whether you are really doing in life what you want to do.&lt;/p&gt;

&lt;p&gt;It will be easier if you surround yourself with people who are better at it than you. If you work in companies with big teams. With people who want to help you. If you love to hang out on technical forums and don't mind posting dumb questions. If you are a good person and look after your relationships with the people who are answering your questions.&lt;/p&gt;

&lt;p&gt;It will be easier if you are immune to the sort of technical criticism that suggests you are the dumbest person in the room because you don't quite get something yet, when that is more about the other person's lack of communications skills or dumb ego. The reality is everyone is always learning.&lt;/p&gt;

&lt;p&gt;It will be easier if you like to go to meet-ups with like-minded people and like pizza. If you like to go to conferences and can actually absorb what is being said. Or you love to watch tech videos or work through tutorials online in your spare time.&lt;/p&gt;

&lt;p&gt;It will be easier if what you are working on actually inspires, your team is fun, and your boss doesn't suck.&lt;/p&gt;

&lt;p&gt;And over time yes the technical side gets easier as you learn the tools. As you come across the same concepts in different guises and odd things you learnt on one job become useful in another.&lt;/p&gt;

&lt;p&gt;It gets easier as you come to understand the parts of the job you are good at. When you learn to recognise when you need to go for help vs banging you head against a wall of unknowns.&lt;/p&gt;

&lt;p&gt;So yes for me, after four years, while there is the occasional day when it seems impossible, it is otherwise easy. &lt;/p&gt;

&lt;p&gt;For you I don't know.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>jobs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Elm Europe 2018 - attending Richard Feldman’s workshop </title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Mon, 09 Jul 2018 11:11:14 +0000</pubDate>
      <link>https://dev.to/elmupdate/elm-europe-2018---attending-richard-feldmans-workshop--j37</link>
      <guid>https://dev.to/elmupdate/elm-europe-2018---attending-richard-feldmans-workshop--j37</guid>
      <description>

&lt;p&gt;When I booked for Elm Europe I gave myself a day to recover from the early morning flights - Cyprus to Belgrade, Belgrade to Paris. Then a day for sightseeing before the conference began...&lt;/p&gt;

&lt;p&gt;Then, dammit, Richard Feldman offered a workshop on my sightseeing day! It wasn’t exactly cheap and it got me thinking about the value of workshops vs conference presentations. It must differ for different people. For a start, it would depend on how best you learn, as well as how much the cost eats into your income for the year. &lt;/p&gt;

&lt;p&gt;It’s important as a web developer to hone in on how you learn. We are faced with continuous change. You may for example learn on the job, through tutorials, books, from colleagues, workshops or combinations.&lt;/p&gt;

&lt;p&gt;Some may be able to sit through two days of presentations and learn a lot from them. Personally, I am easily put to sleep. I need to engage and workshops provide exactly that, as do tutorials.&lt;/p&gt;

&lt;p&gt;It’s also about how important learning is for you at a conference. Is meeting people more important? Is hearing a diversity of ideas more valuable? I love to meet people and am also very aware that both friendships and work opportunities may come from such contacts. &lt;/p&gt;

&lt;p&gt;However, as a remote worker I find learning is top priority. Without colleagues to learn off face-to-face in the office, you have to take the opportunity to pick up whatever you can. Workshops may provide the friendships and learning.&lt;/p&gt;

&lt;p&gt;Half a dozen people attended this workshop, which was good for me, not so good I suspect for the presenter and organizers. I recommend fine tuning the price to increase numbers. The sweat spot was probably at a lower price with more people and up to a dozen would still be very manageable.&lt;/p&gt;

&lt;p&gt;The content was targeted beyond beginner level. This is where a lot of people would now be looking and was perfect for me. The direction was informal and fluid according to attendees needs. In the morning it was more of a review of things I already new. Even that is valuable, as it reinforces. &lt;/p&gt;

&lt;p&gt;The afternoon was full of things I didn’t know about and hence I came out of the workshop suspecting I had received long term value and may well have got my money’s worth. I’d like to see more workshops, altering the balance of what is regarded as the main event. &lt;/p&gt;

&lt;p&gt;The rest of the Elm Europe was also good though. There were a number of presentations that educated and/or entertained. I’d rate Feldman’s presentation on the second day as the best as yet again it was practical applicable material. &lt;/p&gt;

&lt;p&gt;So what did I learn about at the workshop?&lt;/p&gt;

&lt;p&gt;Some notes:&lt;br&gt;
Better to decode initial data coming through flags rather than let it be automatically turned into records - I guess this is about type safety.&lt;/p&gt;

&lt;p&gt;Use intermediate representations rather than change your model to match incoming JSON records - you don’t want your code determined by something in JS or other land not designed necessarily for your situation.&lt;/p&gt;

&lt;p&gt;Nested model updates are a sign that something is wrong - split it out and work with something smaller. Although it’s not nested vs flat, it’s situational for when there is something you can work with.&lt;/p&gt;

&lt;p&gt;Move functions to the top level rather than in a let-in block - this is about being explicit about the dependencies. In a let-in block you have access to all the parameters of the enclosing function. The exception is when you are actually going to use most of those parameters.&lt;/p&gt;

&lt;p&gt;Phantom types - adding a type definition you don’t use - can be useful for catching certain compile time errors - I’d need to review this again to recall what that looks like in practice.&lt;/p&gt;

&lt;p&gt;Trick for unwrapping - avoid case statements for single option union types by using pattern match:&lt;br&gt;
e.g.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Style&lt;/span&gt;
&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="n"&gt;makeStyle&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There was something about how when making a union of types the more open type results. This was a little above my understanding so I’ll just file it away until I come across it next. Lol.&lt;/p&gt;

&lt;p&gt;When parameters appear at the end of both sides of a function definition you can remove them, but don’t, as it affects readability.&lt;/p&gt;

&lt;p&gt;Ports - use one set of ports for everything;&lt;br&gt;
e.g.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;port&lt;/span&gt; &lt;span class="n"&gt;sendToD3&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Value&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;receiveFromD3&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Value&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a concept that has gained traction but not with everyone. I had some side conversations about it and there is concern that it is less type safe for example.&lt;/p&gt;

&lt;p&gt;Ports - who should own the state of a library? JS should. Elm doesn’t change it. If you want to change it, send a msg out to JS to change it, and it can send a message back to Elm to change it’s model. If choosing where to draw the line between JS and Elm, default to a minimum interface between them.&lt;/p&gt;

&lt;p&gt;Then we got onto some meaty stuff around JS interop - getting beyond using ports:&lt;/p&gt;

&lt;p&gt;One way is Custom Elements, which is very useful when wanting to manipulate stuff in the DOM - think View as the interface rather than Update. Basically a custom element can be produced by putting a ‘-’ in a node name: Html.node “rtfeldman-div” [] []&lt;br&gt;
generates &lt;br&gt;
Custom Elements need polyfills for non-Chrome browsers.&lt;br&gt;
Another way is to use custom events on their own. Register the event in JS and pick up from Elm using ‘on’ under Html.Events.&lt;/p&gt;

&lt;p&gt;Then there was a review of Html.Keyed and Html.Lazy. I hadn’t used these before so it was all good stuff. Keyed is uniquely identifying rows for for when you want to make adjustments without Elm redrawing significant portions of the DOM. React has something similiar. Lazy should apparently only be used when you experience a runtime performance issue. It prevents reevaluating view functions where the parameters and result have already been calculated. &lt;/p&gt;

&lt;p&gt;Finally we had a look at parsing. This a pretty powerful tool for validation or other applications and worth knowing about.&lt;/p&gt;

&lt;p&gt;Note that Feldman is preparing a new course for Front End Masters that will go beyond beginner level and incorporate some of the stuff we talked about at the workshop. I’ve no doubt I’ll take that as well.&lt;/p&gt;


</description>
      <category>elmeurope</category>
      <category>elm</category>
    </item>
    <item>
      <title>Cloudinary uploads direct from Elm </title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Fri, 04 May 2018 11:37:34 +0000</pubDate>
      <link>https://dev.to/elmupdate/cloudinary-uploads-direct-from-elm--50j1</link>
      <guid>https://dev.to/elmupdate/cloudinary-uploads-direct-from-elm--50j1</guid>
      <description>

&lt;p&gt;If you need to store your images on a third party server, you may well have considered Cloudinary - &lt;a href="https://cloudinary.com/"&gt;https://cloudinary.com/&lt;/a&gt; . It has a raft of cool image management features that take away a lot of the hassles of dealing with images in your application.&lt;/p&gt;

&lt;p&gt;Cloudinary has support for a variety of languages but as anticipated nothing explicit for Elm.&lt;/p&gt;

&lt;p&gt;But no problem as there is elm-cloudinary - &lt;a href="http://package.elm-lang.org/packages/ghivert/elm-cloudinary/latest"&gt;http://package.elm-lang.org/packages/ghivert/elm-cloudinary/latest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the good news is it appears to work out-of-the-box. There is some JS code you need to put into your index.js and then follow the example to include the necessary fields, msgs and update handling.&lt;/p&gt;

&lt;p&gt;Now, I didn't actually have it working at that point, since our requirement is to upload unsigned uploads direct from the browser. This is a feature that Cloudinary supports but it looks like it came out after elm-cloudinary being released.&lt;/p&gt;

&lt;p&gt;So, time to hack the cloudinary.elm file. What I discovered was that simply a different settings file was needed.&lt;/p&gt;

&lt;p&gt;The existing settings file is:&lt;/p&gt;



&lt;div class="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;Settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;username&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;apiKey&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;timestamp&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;signature&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For unsigned calls these need to be replaced with:&lt;/p&gt;



&lt;div class="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;SettingsUnsigned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;username&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;uploadPreset&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You get the uploadPreset string from the Cloudinary management portal.&lt;/p&gt;

&lt;p&gt;Rather than have one overall settings record and fill in different fields, the settings have to change because if we continue to include the authorisation fields in the original settings then Cloudinary won't accept the upload.&lt;/p&gt;

&lt;p&gt;What I did is take each of the features - uploadPhoto and trackUploadPhoto - and create unsigned alternatives using the unsigned settings. This is a cheap approach that means I haven't disrupted the signed features if I need to use them later. Intention will be that when I am confident this is working I'll file a pull request back to the original elm-cloudinary author.&lt;/p&gt;

&lt;p&gt;I have tried experimenting with whether union types or some other construct might provide for the original function set and just vary the settings. Haven't been able to do that yet without breaking changes to the API. Keen to hear if anyone has ideas for this.&lt;/p&gt;

&lt;h1&gt;
  
  
  Attempt to track progress
&lt;/h1&gt;

&lt;p&gt;In the meantime the other obstacle I came across was in the trackUploadPhoto feature, or in my case I created trackUploadPhotoUnsigned. This arose because we were uploading a Cloudinary image but without a progress indicator.&lt;/p&gt;

&lt;p&gt;The elm-cloudinary uses Elm's Http.Progress and looking in the console at the network responses showed that the Progress.track subscription was only responding that it is done, but not sending 'Some' notifications along the way.&lt;/p&gt;

&lt;p&gt;Exploring this I found the following very helpful post request example: &lt;a href="https://github.com/gdotdesign/elm-ui-examples/blob/master/file-upload-progress/source/Main.elm"&gt;https://github.com/gdotdesign/elm-ui-examples/blob/master/file-upload-progress/source/Main.elm&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I tried implementing a bit of this, even making my own custom request and to cut a long story short I found that if I sent the file to a dead drop such as "&lt;a href="https://httpbin.org/post"&gt;https://httpbin.org/post&lt;/a&gt;" instead of Cloudinary's url then I got back the Progress Some notifications.&lt;/p&gt;

&lt;p&gt;Further seeking help online I have so far concluded that this is to do in the Cloudinary case with the request using 'chunking' in transfer-encoding, which results in content-length not being returned in the request response. Without that, progress cannot be determined.&lt;/p&gt;

&lt;p&gt;Cloudinary provides progress capability in its JS widgets and I've asked them if there is another way to get this information. Any suggestions in this area are welcome as I'm clearly still learning about the intricacies of http requests and responses.&lt;/p&gt;


</description>
      <category>elm</category>
      <category>elmlang</category>
      <category>cloudinary</category>
      <category>elmcloudinary</category>
    </item>
    <item>
      <title>Geolocation in an Elm web application</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Mon, 30 Apr 2018 07:20:09 +0000</pubDate>
      <link>https://dev.to/elmupdate/geolocation-in-an-elm-web-app-4n9i</link>
      <guid>https://dev.to/elmupdate/geolocation-in-an-elm-web-app-4n9i</guid>
      <description>&lt;p&gt;Getting location for your web application comes down to basing it on an IP address or using the HTML5 geolocation provided through your browser.&lt;/p&gt;

&lt;p&gt;In the IP address case the location information may come from the registration addresses of the IP addresses amongst other sources.&lt;/p&gt;

&lt;p&gt;With the browser approach it will depend whether your device has GPS or not. If so then it can use that system, otherwise it may also look up third party databases of IP addresses. One example is the data collected by Google's StreetView surveys.&lt;/p&gt;

&lt;p&gt;Getting IP address sourced location data using Elm is easy-as. First find a source by googling for IP address location data. I found this list to be very useful: (&lt;a href="https://ahmadawais.com/best-api-geolocating-an-ip-address/"&gt;https://ahmadawais.com/best-api-geolocating-an-ip-address/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Then you want to send off an Http.get request. For example:&lt;/p&gt;

&lt;p&gt;Set up the get, where decodeData uses the original method or the pipeline decoder style and YourData is a type alias reflecting the format of the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;getData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="kt"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.ipdata.co/?format=json"&lt;/span&gt; &lt;span class="n"&gt;decodeData&lt;/span&gt;

&lt;span class="n"&gt;decodeData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;decode&lt;/span&gt; &lt;span class="kt"&gt;YourData&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;latitude"&lt;/span&gt; &lt;span class="kt"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Decode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;longitude"&lt;/span&gt; &lt;span class="kt"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Decode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Do the send using the Http.send or RemoteData.send approach. In this case LoadData is a Msg &lt;code&gt;(Result Http.Error YourData)&lt;/code&gt; you've defined to handle the response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;sendData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="kt"&gt;LoadData&lt;/span&gt; &lt;span class="n"&gt;getData&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you want to use the HTML5 solution built into your browser then there is an Elm module for that - Geolocation.elm -&lt;a href="http://package.elm-lang.org/packages/elm-lang/geolocation/1.0.2/Geolocation"&gt;http://package.elm-lang.org/packages/elm-lang/geolocation/1.0.2/Geolocation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the simplest case you may fire off the Cmd msg from an Update function where FoundLocation will be another update function that interprets the results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="kt"&gt;GetLocation&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;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="kt"&gt;FoundLocation&lt;/span&gt; &lt;span class="kt"&gt;Geolocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kt"&gt;FoundLocation&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;location&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;error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
               &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;do&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;various&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;

           &lt;span class="kt"&gt;Ok&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
               &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;longitude&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;need&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note the user will be asked to confirm that it is okay to share location information.&lt;/p&gt;

&lt;p&gt;You may also want your app to be told when the user moves. You can set up an Elm subscription, which will call a specified update function - eg MoveLocation - when there is a change, with a Location type parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Location&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;location&lt;/span&gt; &lt;span class="o"&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;batch&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;Geolocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;changes&lt;/span&gt; &lt;span class="kt"&gt;MoveLocation&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Whether you need to store state on your model will depend on your application. If so then at the beginning you won't know location so you will need to store location as a Maybe field and incorporate handling for this.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>location</category>
      <category>geolocation</category>
      <category>ipaddress</category>
    </item>
    <item>
      <title>Into remote software development</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Tue, 24 Apr 2018 08:50:11 +0000</pubDate>
      <link>https://dev.to/rwoodnz/into-remote-software-development-3455</link>
      <guid>https://dev.to/rwoodnz/into-remote-software-development-3455</guid>
      <description>&lt;p&gt;It's almost a year since I decided to remain in Europe and I left one of the best jobs I ever had, as a software developer at PartsTrader Markets in New Zealand. If you live in Wellington or want to move there and are a software developer then check them out.&lt;/p&gt;

&lt;p&gt;I've always hated corporate culture (aka 'preferred a high level of autonomy') and one of the drivers for me to get back into software development was the opportunity to work in the flatter structure of agile teams or go remote working.&lt;/p&gt;

&lt;p&gt;So then the shift from a great agile environment to working from home/coffee shops may seem a big jump on the surface, but behind the scenes both deliver to me a feeling that you can get on with the work intensely and so long as you are delivering progress at the end of the day then it's a good feeling all round.&lt;/p&gt;

&lt;p&gt;That's a pun by the way, because as a remote contractor I literally do tend to deliver code at the end of the day. I find that's best for communication, ensuring that you are on the right track and keeping your code on track with others.&lt;/p&gt;

&lt;p&gt;The first few months looking for work were hard. I had three years full stack experience in C# and JS but what you really need is about five and JS frameworks are what is in demand.&lt;/p&gt;

&lt;p&gt;In Europe also companies got burned with outsourcing and are very careful about remote workers. In the UK especially the term usually just means you can work somewhere else in the UK and they want you to come to the office regularly.&lt;/p&gt;

&lt;p&gt;So I've had more luck from New Zealand and the US and the time difference can actually be a positive.&lt;/p&gt;

&lt;p&gt;My first contract I did 40 hours a week for a US startup and it went for five months. It was originally going to be an Elm contract but it turned to Javascript. I learned React and GraphQL along the way and gained a lot of confidence in what I could solve on my own.&lt;/p&gt;

&lt;p&gt;Unfortunately that work dried up and I needed to get back out looking. Since then I've picked up a Javascript contract from New Zealand and an Elm contract from the US. As I've gone along I've adjusted my rates but keeping them very reasonable as I regard myself as very much still learning the remote ropes. I've found having two part time contracts is also good.&lt;/p&gt;

&lt;p&gt;I've seen companies trying to do the full agile team work virtually. I'm yet to be convinced that the structures that work in an office are appropriate or necessary remotely. If you want to work remotely you probably don't want to wake up at 3am to attend stand-ups and retros. Perhaps at some point I'll get some experience with one of those firms and see first hand.&lt;/p&gt;

&lt;p&gt;In the meantime my focus is on balancing learning with earning. If I can see I will need particular knowledge then I make sure I have reading to do and tutorials where it is a bigger challenge. Part of getting back into blogging for me is to improve the learning I do by writing tech blog posts, which I've started under the banner ElmUpdate - &lt;a href="https://dev.to/elmupdate"&gt;https://dev.to/elmupdate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On top of that is avoiding isolation. Getting more engaged with the online community and getting to conferences - but making sure they are the right relevant ones. There's a lot of fluff being presented at tech conferences these days so it can be better to go to the workshops even if it is a big cost.&lt;/p&gt;

&lt;p&gt;Final thought is around hours. 8 hour days in an office is fine. However, when you work remotely with no distractions that is an intense day. The cliche that 8 hours in an office is really 6 at best comes to mind. &lt;/p&gt;

&lt;p&gt;I find software development addictive so doing 8 or 10 hours is not uncommon and I don't think that will change. However by that point you are suffering from a certain type of stress, not thinking straight, and you are probably not going to make the most of the evening non-work time as you will be mentally recovering. &lt;/p&gt;

&lt;p&gt;Better to break up the day. Start with some learning, take a decent lunch break, do a blog post. Then you can do some quality coding - build your self-worth and reputation and not your sleep deprivation. &lt;/p&gt;

&lt;p&gt;That's me for today. Until next time...&lt;/p&gt;

</description>
      <category>remote</category>
      <category>development</category>
      <category>contracting</category>
    </item>
    <item>
      <title>Implementing Elm Toasts</title>
      <dc:creator>Richard Wood</dc:creator>
      <pubDate>Tue, 24 Apr 2018 07:29:19 +0000</pubDate>
      <link>https://dev.to/elmupdate/implementing-elm-toasts-3p7k</link>
      <guid>https://dev.to/elmupdate/implementing-elm-toasts-3p7k</guid>
      <description>&lt;p&gt;When you want to send briefly displayed messages to the user of your web application, Toasts are a cool way to do it. You know those little boxes that show up on the side and disappear after a while.&lt;/p&gt;

&lt;p&gt;Without anything in place so far to display errors or confirm activity I went hunting for what Elm had to offer.&lt;/p&gt;

&lt;p&gt;There weren't a lot of offerings, but Toasty (&lt;a href="http://package.elm-lang.org/packages/pablen/toasty/1.0.4/Toasty" rel="noopener noreferrer"&gt;http://package.elm-lang.org/packages/pablen/toasty/1.0.4/Toasty&lt;/a&gt;) looked like it had some good customisation capability and the demo certainly looked the part.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ff2g15g3fhk4r6fqtcv0r.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ff2g15g3fhk4r6fqtcv0r.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my ideal world I'd install the package, edit a config file and start calling the module. Oops, that sounds like Javascript...&lt;/p&gt;

&lt;p&gt;In this case there was stuff to add to the Model, initial model, a type alias, an update branch, and view stuff. I don't know if this is the price of type safety, or how possible it is to make Elm modules more independent. I'm just grateful people are writing these libraries at all.&lt;/p&gt;

&lt;p&gt;AS STEP 1 - I recommend just following the instructions on that part of it.&lt;/p&gt;

&lt;p&gt;At about this point and after playing around with Toasty.config things weren't working for me in that I was getting text showing on the screen that disappeared -  good - but no box around it - bad. &lt;/p&gt;

&lt;p&gt;Usually I skim read things and assume a 'work-out-of-the-box' mentality. Then when I hit problems I go back. In this case I re-read the opening bit which mentioned Toasty.Defaults.  This gave me a starter Toast definition, which was handy but I wasn't otherwise much the wiser.&lt;/p&gt;

&lt;p&gt;So time to read or at least look at the source code. Whamo there's an example App.elm in there that appears to be the code for the demo. I also found there  Defaults.css and Toasty.Defaults, which you can customise. I needed to reposition my Toasts and change the widths for example.&lt;/p&gt;

&lt;p&gt;AS STEP 2 - Bring Defaults.css and Toasty.Defaults into the app and customize to your needs. Then make sure all your references to myConfig are to Toasty.Defaults.config&lt;/p&gt;

&lt;p&gt;This provided the missing pieces I needed to get it up and running.&lt;/p&gt;

&lt;p&gt;Now I only had one issue remaining. I really wanted a minimum calling api. The site was suggesting putting this on the end of update functions:&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addToast&lt;/span&gt; &lt;span class="n"&gt;myConfig&lt;/span&gt; &lt;span class="kt"&gt;ToastyMsg&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;MyToast&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Entity successfully created!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I liked the idea of feeding from update functions but there is no way I'm going to litter the code with lots of those.&lt;/p&gt;

&lt;p&gt;The App.elm example had another version of addToast that simplified things to:&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;addToast&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Allright!"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thing successfully updated"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I really just wanted to cover 90% of usage with something like:&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doToast&lt;/span&gt; &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You did it"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be achieved by adding a helper function that assumes the config file and Update message names:&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;doToast&lt;/span&gt; &lt;span class="n"&gt;toast&lt;/span&gt; &lt;span class="n"&gt;title&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;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addToast&lt;/span&gt; 
        &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; 
        &lt;span class="kt"&gt;ToastyMsg&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toast&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or what I really wanted was:&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doToast&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You did it!"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So (purists please avert your eyes):&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;doToast&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="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="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;doToast&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;message&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;toast&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;title&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; 
            &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
                &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
            &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
                &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
            &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Warning"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
                &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Warning&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;message&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;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;

    &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addToast&lt;/span&gt; 
        &lt;span class="kt"&gt;Toasty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; 
        &lt;span class="kt"&gt;ToastyMsg&lt;/span&gt; &lt;span class="n"&gt;toast&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AS STEP 3. Make your own helper(s) that keep it simple and flexible for you. For example you may want to specify the length of time each toast displays for. That's just one of the config options you have with Toasty that I haven't covered here.&lt;/p&gt;

&lt;p&gt;In summary: A very useful and flexible module that in the scheme of things did not take long to get up and running.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>notifications</category>
      <category>toasty</category>
      <category>toasts</category>
    </item>
  </channel>
</rss>
