<?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: John Pavlick</title>
    <description>The latest articles on DEV Community by John Pavlick (@jmpavlick).</description>
    <link>https://dev.to/jmpavlick</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%2F794094%2F4cb7dee8-e39d-4ae6-875c-73f31fe5923a.jpeg</url>
      <title>DEV Community: John Pavlick</title>
      <link>https://dev.to/jmpavlick</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jmpavlick"/>
    <language>en</language>
    <item>
      <title>For lack of a better name, I’m calling it “The Module Pattern”.</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Wed, 27 Mar 2024 02:24:49 +0000</pubDate>
      <link>https://dev.to/jmpavlick/for-lack-of-a-better-name-im-calling-it-the-module-pattern-5dfi</link>
      <guid>https://dev.to/jmpavlick/for-lack-of-a-better-name-im-calling-it-the-module-pattern-5dfi</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Module Pattern&lt;/strong&gt; is a pattern I've discovered in Elm for dealing with some of the inconveniences of nested TEA&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. As an added bonus, it can make component-type modules a little more straightforward to implement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I don’t recommend building an application entirely out of nested TEA. In fact, I recommend nesting TEA as infrequently as possible; but sometimes it seems to be inevitable - as much as again when you’re working on a large codebase that isn’t entirely yours. Handle with care, proceed with caution, terms and restrictions may apply, see store for details, something something California okay anyway moving on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People tend to nest TEA when they "want components"; a common scenario is that a codebase will include a form module - let's call it &lt;code&gt;Form&lt;/code&gt; - that has some parameterized types and is designed to be "hosted" within another module (usually a "page"). The intent of the author of the &lt;code&gt;Form&lt;/code&gt; module was that, while a form is inherently stateful, that state should be opaque, and any interactions with the form's state should be mediated through its own &lt;code&gt;view&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; functions, and then mapped back to the host module.&lt;/p&gt;

&lt;p&gt;So let's imagine that we have our &lt;code&gt;Form&lt;/code&gt; module, and let's imagine that we want to add a form to a module called &lt;code&gt;Signup&lt;/code&gt;, that describes a signup flow. You'd expect to run into something like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Form&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Form exposing (Model, Msg, view, update, init)

import Html exposing (Html)

type Model = Model ...

view : Model -&amp;gt; Html msg
view model =
    ...

init : ( Model, Cmd Msg )
init =
    ...

type Msg
    = ...

update : Msg -&amp;gt; Model -&amp;gt; ( Model, Cmd Msg )
update msg model =
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;Signup&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Signup exposing (Model, Msg, view, update, init)

import Html exposing (Html)

type Model =
    Model
        { formModel : Form.Model
        ...
        }

view : Model -&amp;gt; Html msg
view ( Model model ) =
    Html.div []
        [ Form.view model.formModel
            |&amp;gt; Html.map GotFormMsg
        ...
        ]

init : ( Model, Cmd Msg )
init =
    Form.init
        |&amp;gt; (\(formModel, formCmd) -&amp;gt;
                ( Model
                    { formModel = formModel
                    , ...
                    }
                , Cmd.batch
                    [ Cmd.map GotFormMsg formCmd
                    , ...
                    ]
                )
           )

type Msg
    = GotFormMsg Form.Msg

update : Msg -&amp;gt; Model -&amp;gt; ( Model, Cmd Msg )
update msg (Model model) =
    case msg of
        GotFormMsg formMsg -&amp;gt;
            Form.update formMsg model.formModel
                |&amp;gt; (\( formModel, formCmd ) -&amp;gt;
                    ( Model { model | formModel = formModel }  
                    , Cmd.map GotFormMsg formCmd
                   )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at all of the plates we just had to boil:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We had to call &lt;code&gt;Html.map&lt;/code&gt; once, and &lt;code&gt;Cmd.map&lt;/code&gt; twice&lt;/li&gt;
&lt;li&gt;We had to destructure the result of &lt;code&gt;Form.init&lt;/code&gt; and &lt;code&gt;Form.update&lt;/code&gt; and map them to our host module's &lt;code&gt;init&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When we mapped, we had to map to &lt;code&gt;GotFormMsg&lt;/code&gt; three times&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is a trivial example; what if we had to pass outside params to &lt;code&gt;Form.init&lt;/code&gt;, but not to &lt;code&gt;Form.update&lt;/code&gt;? What if &lt;code&gt;Form.view&lt;/code&gt; and &lt;code&gt;Form.update&lt;/code&gt; both needed access to a &lt;code&gt;Session&lt;/code&gt; that was defined outside of &lt;code&gt;Signup&lt;/code&gt;, that needed to be handed in? Bucket-brigading dependency params around to multiple callsites in the same module can quickly become exhausting.&lt;/p&gt;

&lt;p&gt;Moreover - what if &lt;code&gt;Form&lt;/code&gt; was one of those super-cool modules that had a &lt;code&gt;Config&lt;/code&gt; type that was constructed applicatively, with a dozen exposed functions to manage its various options - and then another score of exposed functions to actually implement bits and pieces of the module?&lt;/p&gt;

&lt;p&gt;And finally - for every module within which you choose to implement &lt;code&gt;Form&lt;/code&gt;, you have to do all of these mapping motions &lt;em&gt;over and over and over again&lt;/em&gt;. As &lt;code&gt;Form&lt;/code&gt; grows, if the parameters required to construct it and implement it change, you have to change &lt;em&gt;every single callsite&lt;/em&gt; where every MVU touchpoint is accessed, in &lt;em&gt;every single module&lt;/em&gt; that uses &lt;code&gt;Form&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Oh, and I know that I &lt;em&gt;just said&lt;/em&gt; “And finally -“ - but one more thing - maybe the worst thing? - there’s no clear delineation between “the parts of this module that are related to interop with another module”, and “the parts of this module that are actually dealing with business / domain logic”. In fact, it may be the case as this application grows, that your inter-module communication gets woven throughout the rest of your domain logic, sprinkled in haphazardly catch-as-catch-can - and it can become remarkably hard to disentangle, later on down the line.&lt;/p&gt;

&lt;p&gt;Now comes the Module Pattern. The idea is that you can create a type that represents your "module" - really, your model / view / update - and expose &lt;em&gt;that&lt;/em&gt;; by parameterizing a function that "initializes" your module, you can pass in all of those mapping params in one centralized place.&lt;/p&gt;

&lt;p&gt;Let's do it for &lt;code&gt;Form&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Form&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Form exposing (Model, Msg, Module, init)

import Html exposing (Html)

type alias Module msg model =
    { view : model -&amp;gt; Html msg
    , update : Msg -&amp;gt; model -&amp;gt; ( model, Cmd msg )
    , init : ( Model, Cmd msg )
    }

init :
    { toModel : model -&amp;gt; Model -&amp;gt; model
    , fromModel : model -&amp;gt; Model 
    , toMsg : Msg -&amp;gt; msg
    } -&amp;gt; Module msg model
init { toModel, fromModel, toMsg } =
    { view =
        \model -&amp;gt;
            view (fromModel model)
                |&amp;gt; Html.map toMsg
    , update =
        \msg model -&amp;gt;
            update msg (fromModel model)
                |&amp;gt; ( \( formModel, formCmd ) -&amp;gt;
                    ( toModel model formModel
                    , Cmd.map toMsg formCmd
                    )
    , init =
        Tuple.mapSecond GotFormMsg init_
    }


type Model = Model ...

view : Model -&amp;gt; Html msg
view model =
    ...

type Msg
    = ...

update : Msg -&amp;gt; Model -&amp;gt; ( Model, Cmd Msg )
update msg model =
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what does that do for our callsites in &lt;code&gt;Signup&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Signup&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Signup exposing (Model, Msg, view, update, init)

import Html exposing (Html)

type Model =
    Model
        { formModel : Form.Model
        ...
        }

formModule : Form.Module Msg Model
formModule =
    Form.init
        { toModel =
            \(Model model) formModel -&amp;gt;
                Model { model | formModel = formModel }
        , fromModel =
            \( Model { formModel } ) -&amp;gt; formModel
        , toMsg = GotFormMsg
        }

view : Model -&amp;gt; Html msg
view ( Model model ) =
    Html.div []
        [ formModule.view model
        ...
        ]

init : ( Model, Cmd Msg )
init =
    ( Model { formModel = Tuple.first formModule.init, ... }
    , Cmd.batch [ Tuple.second formModule.init, ... ]
    )


type Msg
    = GotFormMsg Form.Msg

update : Msg -&amp;gt; Model -&amp;gt; ( Model, Cmd Msg )
update msg (Model model) =
    case msg of
        GotFormMsg formMsg -&amp;gt;
            formModule.update formMsg (Model model)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's nice, it's simple, and it gives you some extra leverage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You know &lt;em&gt;for certain&lt;/em&gt; what interfaces you need to satisfy in order to successfully interop with &lt;code&gt;Form&lt;/code&gt; - if something is a parameter to &lt;code&gt;Form.init&lt;/code&gt;, now, you absolutely must have it in-scope to be able to create a &lt;code&gt;Form&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can think in terms of "the module that you're in" all of the time, unless you're implementing &lt;code&gt;init&lt;/code&gt; - your &lt;code&gt;Form&lt;/code&gt; module's &lt;code&gt;view&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; can be written in terms of &lt;code&gt;Form&lt;/code&gt;, and your &lt;code&gt;Signup&lt;/code&gt;'s &lt;code&gt;view&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; can be written in terms of &lt;code&gt;Signup&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can repeat this pattern virtually everywhere, so other developers in your codebase will always know that to implement a module, you always start at &lt;code&gt;init&lt;/code&gt; and expect a &lt;code&gt;Module msg model&lt;/code&gt; that they can use to represent that module's data and behaviors, without having to think too hard about how to map data into and out of it.&lt;/li&gt;
&lt;li&gt;You can centralize all of your module’s initialization, the definition of all of its required dependencies and interfaces, and its interop &lt;em&gt;all in one place&lt;/em&gt;; as your application grows, your &lt;code&gt;init&lt;/code&gt; will only change as requirements for inter-module communication change, and the rest of your module will only change as business / domain requirements change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note, too, that you don't &lt;em&gt;have&lt;/em&gt; to return a &lt;code&gt;view&lt;/code&gt; from your module initialization; you can return data - a function that takes an event and returns HTML, so that you can implement (for instance) form submission via any kind of &lt;code&gt;onClick&lt;/code&gt;-able element - or maybe just a list of values of a type that your module is creating, so that you can render them however you want.&lt;/p&gt;

&lt;p&gt;In my humble opinion, the less frequently you feel as though you need nested state in an Elm application, the better your life is going to be; but if you must do it, this seems to be the cleanest way to go about it.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;“Nested TEA” is a common pattern in Elm development, where “TEA” - The Elm Architecture, also known as Model-View-Update - is used as the primary abstraction for organizing the overall application. Nested TEA is so-called because most major parts of the application are segmented off into their own modules / module namespaces, with internal model / view / update types and functions that are “nested” inside of other models, other views, and other updates. Whether or not this is actually the best way to build Elm applications may be up for debate; but the fact remains that this is a popular style, and that if you’re a working Elm developer, you will likely get paid actual money to deal with it. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>elm</category>
      <category>functional</category>
    </item>
    <item>
      <title>Record Type Alias Combinators: A Public Service Announcement</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Mon, 18 Dec 2023 05:23:51 +0000</pubDate>
      <link>https://dev.to/jmpavlick/record-type-alias-combinators-a-public-service-announcement-58ce</link>
      <guid>https://dev.to/jmpavlick/record-type-alias-combinators-a-public-service-announcement-58ce</guid>
      <description>&lt;p&gt;I've been trying and failing to write this essay for well over a week, so I'm going to start by unburying the lede and we'll take it from there:&lt;/p&gt;

&lt;p&gt;I've figured out how to leverage Elm's type system in such a way so as to allow for the creation of record type aliases that create a constraint against the constructors that a given record type alias must expose. Sort of like... record type alias combinators.&lt;/p&gt;

&lt;p&gt;These record type aliases can be composed to expose a set of chained, nested "builders" for a type; and they can be implemented for any type.&lt;/p&gt;

&lt;p&gt;I'm doing my best here; perhaps a smarter and kinder soul than I, can explain my own discovery to me a little better, and if any of you can do that, please do - but here's what I'm getting at - you can generalize and combine &lt;em&gt;properties on record type aliases&lt;/em&gt;.&lt;/p&gt;




&lt;p&gt;Imagine that you're building a new design system. From scratch. You just finished reading Refactoring UI&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, and you're 100% ready to "limit your choices" and "define systems in advance" and "pick five colors that you like but don't call them by their names, call them some semantic thing like &lt;code&gt;Primary&lt;/code&gt; or &lt;code&gt;Danger&lt;/code&gt; or whatever".&lt;/p&gt;

&lt;p&gt;Color's easy. We'll start there. You know the drill: from the void, conjure a type; give it named constructors; map them to a value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Color
    = Primary
    | Secondary
    | Success
    | Danger
    | Warning
    | Info
    | Light
    | Dark


colorToAttr : Color -&amp;gt; Html.Attribute msg
colorToAttr color =
    Attr.style "background-color" &amp;lt;|
        case color of
            Primary -&amp;gt;
                "#0d6efd"

            Secondary -&amp;gt;
                "#6c757d"

            Success -&amp;gt;
                "#198754"

            Danger -&amp;gt;
                "#dc3545"

            Warning -&amp;gt;
                "#ffc107"

            Info -&amp;gt;
                "#0dcaf0"

            Light -&amp;gt;
                "#f8f9fa"

            Dark -&amp;gt;
                "#212529"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hey, alright - now we can just use our &lt;code&gt;Color&lt;/code&gt; type to create attrs. Easy.&lt;/p&gt;

&lt;p&gt;Wait, hold on - incoming Slack message - Product wants to know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You're building this design system around light mode and dark mode, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Okay okay, nothing we can't handle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type DisplayMode
    = LightMode
    | DarkMode


modedColorToAttr : DisplayMode -&amp;gt; Color -&amp;gt; Html.Attribute msg
modedColorToAttr displayMode color =
    case displayMode of
        LightMode -&amp;gt;
            colorToAttr color

        DarkMode -&amp;gt;
            Attr.style "background-color" &amp;lt;|
                case color of
                    Primary -&amp;gt;
                        "#0d6efd"

                    Secondary -&amp;gt;
                        "#6c757d"

                    Success -&amp;gt;
                        "#198754"

                    Danger -&amp;gt;
                        "#dc3545"

                    Warning -&amp;gt;
                        "#ffc107"

                    Info -&amp;gt;
                        "#0dcaf0"

                    Light -&amp;gt;
                        "#f8f9fa"

                    Dark -&amp;gt;
                        "#212529"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There we go. These colors will work for....... buttons.&lt;/p&gt;

&lt;p&gt;Definitely not for backgrounds. Or for lighter variants. Sigh. Time to start building up a bunch of types. With parameters. Zipping around everywhere.&lt;/p&gt;

&lt;p&gt;Drowning in a pile of types, again.&lt;/p&gt;

&lt;p&gt;I mean, I &lt;em&gt;guess&lt;/em&gt; we could just do it in CSS... right? CSS sucks, but it's a known quantity of suck, and the designers know it, and... I guess we'll never have a fully-specified design system.&lt;/p&gt;




&lt;p&gt;But what if there was another way? What if there was a way to create tighter constraints, that didn't require developers using a design system to pass around types?&lt;/p&gt;

&lt;p&gt;What if there was a way, as the gardener-in-chief of a design system, to create generic &lt;em&gt;kinds&lt;/em&gt; of specifications, and compose them together?&lt;/p&gt;

&lt;p&gt;What do I always say, on this website?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're better. And we can do better. &lt;em&gt;LFG.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Designing a System to Design Design Systems
&lt;/h2&gt;

&lt;p&gt;Here's the trick - we have to start thinking in terms of creating generic specifications for these design system elements.&lt;/p&gt;

&lt;p&gt;For instance - what if we could &lt;em&gt;generalize&lt;/em&gt; over the idea of a color palette - over the choices between &lt;code&gt;Primary&lt;/code&gt;, &lt;code&gt;Secondary&lt;/code&gt;, &lt;code&gt;Danger&lt;/code&gt;, etc - and then &lt;em&gt;generalize&lt;/em&gt; over the choices between &lt;code&gt;Background&lt;/code&gt; and &lt;code&gt;Font&lt;/code&gt; and &lt;code&gt;Border&lt;/code&gt; - and compose them together, and still have some type safety, and implement different things differently at each call site, while still leaning on the compiler?&lt;/p&gt;

&lt;p&gt;You people have got to check this out. Let's build a type. You wanna build a type? Let's build a type, let's do it.&lt;sup id="fnref2"&gt;2&lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Hue
    = Primary
    | Secondary
    | Danger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, nothing out of the ordinary, right? I mean, let's call it &lt;code&gt;Hue&lt;/code&gt; instead of &lt;code&gt;Color&lt;/code&gt; - &lt;code&gt;Color&lt;/code&gt; is a bigger idea - let's save it for something bigger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Target
    = Background
    | Font


type Opacity
    = Op100
    | Op70
    | Op30


type Accent
    = Normal
    | Subtle


type Color
    = Color Target Opacity Accent Hue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"John, it seems like we're drowning under a pile of types again--"&lt;/p&gt;

&lt;p&gt;Let me cook. I know you know how to make a type. This is all setup, and if you want to enable this kind of flexibility in your design system - you're going to have to specify it. And you're going to specify it eventually, regardless - but if you don't specify it on purpose, you'll specify it on accident. We have a word for that, but I can't remember what it's called.&lt;sup id="fnref3"&gt;3&lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias AllHues builder =
    { primary : builder
    , secondary : builder
    , danger : builder
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;A type alias? You're repeating the names of the constructors as properties? And assigning them to a type parameter?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am. And quickly now, I'm going to do it again for the others:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias AllTargets builder =
    { background : builder
    , font : builder
    }


type alias AllOpacities builder =
    { op100 : builder
    , op70 : builder
    , op30 : builder
    }


type alias AllAccents builder =
    { normal : builder
    , subtle : builder
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what did we just do, there?&lt;/p&gt;

&lt;p&gt;For every value in the constructor of the &lt;code&gt;Color&lt;/code&gt; type, we specified the possible constructors as a record type alias with a type parameter.&lt;/p&gt;

&lt;p&gt;And a type parameter can be anything. Even a function. But it truly can be &lt;em&gt;anything&lt;/em&gt; - what good is &lt;code&gt;AllHues&lt;/code&gt; if the values for &lt;code&gt;primary&lt;/code&gt;, &lt;code&gt;secondary&lt;/code&gt;, and &lt;code&gt;danger&lt;/code&gt; are open?&lt;/p&gt;

&lt;p&gt;Let's make them concrete by providing an implementation - a function that, for each record property, supplies a value that matches that property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allHues : (Hue -&amp;gt; builder) -&amp;gt; AllHues builder
allHues toBuilder =
    { primary = toBuilder Primary
    , secondary = toBuilder Secondary
    , danger = toBuilder Danger
    }


allTargets : (Target -&amp;gt; builder) -&amp;gt; AllTargets builder
allTargets toBuilder =
    { background = toBuilder Background
    , font = toBuilder Font
    }


allOpacities : (Opacity -&amp;gt; builder) -&amp;gt; AllOpacities builder
allOpacities toBuilder =
    { op100 = toBuilder Op100
    , op70 = toBuilder Op70
    , op30 = toBuilder Op30
    }


allAccents : (Accent -&amp;gt; builder) -&amp;gt; AllAccents builder
allAccents toBuilder =
    { normal = toBuilder Normal
    , subtle = toBuilder Subtle
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you see it, yet?&lt;/p&gt;

&lt;p&gt;Try this: what happens if we just call one of these functions?&lt;/p&gt;

&lt;p&gt;If we were going to do that, what kind of function would we pass in as the &lt;code&gt;(a -&amp;gt; builder)&lt;/code&gt; parameter?&lt;/p&gt;

&lt;p&gt;Let's try &lt;code&gt;identity&lt;/code&gt; - can't hurt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allHues_ =
    allHues identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let the compiler infer the type.&lt;/p&gt;

&lt;p&gt;What type is it?&lt;/p&gt;

&lt;p&gt;Oh, it's an &lt;code&gt;AllHues Hue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What happens if we access a property on that value?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;someHue =
    allHues_.primary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's... a &lt;code&gt;Hue&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;So, all of the props on &lt;code&gt;allHues_&lt;/code&gt; are &lt;code&gt;Hue&lt;/code&gt;s. That's not too surprising - but that was just with passing in &lt;code&gt;identity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could pass in... other functions... couldn't we? And then each property on &lt;code&gt;allHues_&lt;/code&gt; would be - a &lt;code&gt;Hue&lt;/code&gt;, applied to &lt;em&gt;some function&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Check this out - check out this type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias AllColors builder =
    AllTargets (AllOpacities (AllAccents (AllHues builder)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's.......&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;AllTargets builder&lt;/code&gt;, where &lt;code&gt;builder&lt;/code&gt; is

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;AllOpacities&lt;/code&gt; builder, where &lt;code&gt;builder&lt;/code&gt; is

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;AllAccents builder&lt;/code&gt;, where &lt;code&gt;builder&lt;/code&gt; is

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;AllHues builder&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;What if we made the final &lt;code&gt;builder&lt;/code&gt; concrete?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias ColorBuilder =
    AllColors Color
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And provided an implementation?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;colorBuilder : ColorBuilder
colorBuilder =
    allTargets
        (\target -&amp;gt;
            allOpacities
                (\opacity -&amp;gt;
                    allAccents
                        (\accent -&amp;gt;
                            allHues
                                (\hue -&amp;gt;
                                    Color target opacity accent hue
                                )
                        )
                )
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What... what is this thing?&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%2Fuploads%2Farticles%2F7jh1pp1q6694aat3t1rk.gif" 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%2Fuploads%2Farticles%2F7jh1pp1q6694aat3t1rk.gif" alt="GIF of  raw `Color` endraw  type construction from record type alias combinators, with autocomplete from the LSP"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a set of constraints with a concrete implementation that builds up successive, nested applications of values on a function.&lt;/p&gt;

&lt;p&gt;Now that you have a single, unambiguous implementation of a &lt;code&gt;Color&lt;/code&gt; type that describes all of the colors and their variations - you can build a renderer for that type; and &lt;em&gt;that renderer&lt;/em&gt; can be the single source-of-truth for all of the values that it supports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;colorToAttr : Color -&amp;gt; Html.Attribute msg
colorToAttr (Color target opacity accent hue) =
    let
        targetFragment : String
        targetFragment =
            case target of
                Background -&amp;gt;
                    "background-color"

                Font -&amp;gt;
                    "color"

        opacityFragment : String
        opacityFragment =
            case opacity of
                Op100 -&amp;gt;
                    String.fromFloat 1.0

                Op70 -&amp;gt;
                    String.fromFloat 0.7

                Op30 -&amp;gt;
                    String.fromFloat 0.3

        rgbFragment : String
        rgbFragment =
            case ( accent, hue ) of
                ( Normal, Primary ) -&amp;gt;
                    "13, 110, 253"

                ( Normal, Secondary ) -&amp;gt;
                    "108, 117, 125"

                ( Normal, Danger ) -&amp;gt;
                    "220, 53, 69"

                ( Subtle, Primary ) -&amp;gt;
                    "207, 226, 255"

                ( Subtle, Secondary ) -&amp;gt;
                    "226, 227, 229"

                ( Subtle, Danger ) -&amp;gt;
                    "241, 174, 181"
    in
    Attr.style targetFragment &amp;lt;| String.concat [ "rgba(", rgbFragment, ", ", opacityFragment, ")" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So that's all well and good and pretty cool - but you may be thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Won't typing out long dotted strings get sort of tiresome? Is there any value to having a call site that looks like &lt;code&gt;Html.div [ colorBuilder.background.op100.normal.secondary ] [...&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can go deeper. Check this out - let's create a type alias that makes the &lt;code&gt;builder&lt;/code&gt; parameter for &lt;code&gt;AllHues&lt;/code&gt; concrete to a function of type &lt;code&gt;String -&amp;gt; Html msg&lt;/code&gt;, which is incidentally the type signature of &lt;code&gt;Html.text&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias TextColorBuilder msg =
    AllHues (String -&amp;gt; Html msg)


textColorBuilder : TextColorBuilder msg
textColorBuilder =
    allHues
        (\hue string -&amp;gt;
            Html.span
                [ Color Font Op100 Normal hue
                    |&amp;gt; colorToAttr
                ]
                [ Html.text string ]
        )


type alias AllTexts msg =
    { unstyled : String -&amp;gt; Html msg
    , withColor : TextColorBuilder msg
    }


text : AllTexts msg
text =
    { unstyled = Html.text
    , withColor = textColorBuilder
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now we can:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dangerousHello : Html msg
dangerousHello =
    text.withColor.danger "Hello, dangerously!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well would you look at that!&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%2Fuploads%2Farticles%2F0d924mwfmsvoenaunlod.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%2Fuploads%2Farticles%2F0d924mwfmsvoenaunlod.png" alt="Sample of text rendered with our custom  raw `text` endraw  element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Guess what else - we can use the &lt;code&gt;builder&lt;/code&gt; type parameter to represent a "builder-pattern" function, so that we can use the output of one of our &lt;code&gt;All*s&lt;/code&gt; functions to apply a value to a wrapped configuration type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Button msg
    = Button { color : Color, onClick : Maybe msg, label : String }


type alias ButtonBuilder msg =
    Button msg -&amp;gt; Button msg


new : { onClick : Maybe msg, label : String } -&amp;gt; Button msg
new { onClick, label } =
    Button { color = colorBuilder.background.op100.normal.primary, onClick = onClick, label = label }


with :
    { opacity : AllOpacities (ButtonBuilder msg)
    , secondary : ButtonBuilder msg
    , danger : ButtonBuilder msg
    }
with =
    { opacity =
        allOpacities
            (\opacity (Button config) -&amp;gt;
                Button
                    { config
                        | color =
                            (\(Color target _ accent hue) -&amp;gt;
                                Color target opacity accent hue
                            )
                                config.color
                    }
            )
    , secondary =
        \(Button config) -&amp;gt;
            Button
                { config
                    | color =
                        (\(Color target opacity accent _) -&amp;gt;
                            Color target opacity accent Secondary
                        )
                            config.color
                }
    , danger =
        \(Button config) -&amp;gt;
            Button
                { config
                    | color =
                        (\(Color target opacity accent _) -&amp;gt;
                            Color target opacity accent Danger
                        )
                            config.color
                }
    }


view : Button msg -&amp;gt; Html msg
view (Button { color, onClick, label }) =
    Html.button
        [ Maybe.map Html.Events.onClick onClick
            |&amp;gt; Maybe.withDefault (Attr.class "")
        , colorToAttr color
        ]
        [ Html.text label ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see that? Did you see that?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We decided that one of our constraints for our &lt;code&gt;Button&lt;/code&gt; element in our design system was that we could adjust the opacity - so we exposed that via the &lt;code&gt;AllOpacities builder&lt;/code&gt; record type alias constraint, and made its &lt;code&gt;builder&lt;/code&gt; type parameter a &lt;code&gt;ButtonBuilder msg&lt;/code&gt; -&lt;/li&gt;
&lt;li&gt;Which gives us the flexibility to expose the record-alias dot-accessor "picker" for our opacity value - and then apply that value to a function that updates our &lt;code&gt;Button msg&lt;/code&gt; value!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out a call site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sortaTranslucentDangerButton : Html msg
sortaTranslucentDangerButton =
    new { onClick = Nothing, label = "If you push this button, nothing will happen" }
        |&amp;gt; with.opacity.op30
        |&amp;gt; with.danger
        |&amp;gt; view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fuploads%2Farticles%2Fme1bwtph0515fzj49ran.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%2Fuploads%2Farticles%2Fme1bwtph0515fzj49ran.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's still so, so much more that can be done with this paradigm - but let's talk about some things that I've found already:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can specify dot-accessor "builders" for constructors on types, for any type - and then compose them together&lt;/li&gt;
&lt;li&gt;If you're using the LSP, you get on-dot autocomplete - which makes for a great developer experience with nice call sites&lt;/li&gt;
&lt;li&gt;By leveraging record type aliases as a sort of "namespacing" - you can put more types and values into the same module without having to smurf&lt;sup id="fnref4"&gt;4&lt;/sup&gt;, or cut a new module to avoid smurfing&lt;/li&gt;
&lt;li&gt;You can defunctionalize core parts of an application - for instance, the design system - and separate the call site composition from the implementation - which allows you to colocate related behaviors&lt;/li&gt;
&lt;li&gt;You can expose &lt;code&gt;All*s builder&lt;/code&gt; record type aliases and &lt;code&gt;all*s builder&lt;/code&gt; functions from a module while keeping all constructors totally opaque - which gives you a finer degree of control over module opacity, especially since...&lt;/li&gt;
&lt;li&gt;Properties in a record type alias don't have to be 1:1 with constructors for a type that it's providing an implementation for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If anybody wants to play with this - there's an Ellie at this footnote&lt;sup id="fnref5"&gt;5&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;In closing: I'm over the moon about having figured out how to do this. I'm still struggling to explain it in the abstract, but I think that the biggest key to the question of "what exactly is this Thing" is that its implementation is isomorphic to the design of &lt;code&gt;elm/url&lt;/code&gt;&lt;sup id="fnref6"&gt;6&lt;/sup&gt;, which the main guy Wolfgang&lt;sup id="fnref7"&gt;7&lt;/sup&gt; pointed out while I was trying to explain it to him the other day.&lt;/p&gt;

&lt;p&gt;Un/fortunately, I think that I'm going to have more to say on this as I play with it more and get deeper into it. I'm not sure if anybody else has "discovered" this technique yet, but please @ me on X&lt;sup id="fnref8"&gt;8&lt;/sup&gt; or in Elm Slack if you'd like to discuss this further or if you have any additional insight.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://www.refactoringui.com/" rel="noopener noreferrer"&gt;https://www.refactoringui.com/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;NB: I'm going to shorten up these types so that my writing doesn't get buried in a fully-fledged design system - which don't get me wrong, I'd love to create - but I need to get this essay done &lt;em&gt;first&lt;/em&gt;. I've been putting it off for nearly two weeks now, and people are starting to Ask Questions. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;I just remembered: it's called &lt;em&gt;CSS&lt;/em&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;"Smurfing" is jargon for the practice of adding information to a name in order to disambiguate it from other "things" in a given namespace that have similar semantics but a different implementation. For instance - imagine that all of the code from &lt;code&gt;Html.Events&lt;/code&gt; was in the same module as &lt;code&gt;Html.Attributes&lt;/code&gt; - how would you know which was an event, and which was an attribute? You &lt;em&gt;could&lt;/em&gt; prefix all of the event attributes with &lt;code&gt;event&lt;/code&gt; - i.e., &lt;code&gt;eventOnClick&lt;/code&gt;, &lt;code&gt;eventOnInput&lt;/code&gt;, etc - but that would be noisy and repetitive, so it's best avoided when possible. ("Smurfing" is so-called after the popular cartoon "The Smurfs", wherein most characters have the word &lt;em&gt;Smurf&lt;/em&gt; in their names - i.e., "Papa Smurf", "Lazy Smurf", "Brainy Smurf", "AccursedUnutterablePerformIO Smurf".) ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://ellie-app.com/pMGzWB8GLjca1" rel="noopener noreferrer"&gt;https://ellie-app.com/pMGzWB8GLjca1&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://foldp.com/blog/elm-url.html" rel="noopener noreferrer"&gt;https://foldp.com/blog/elm-url.html&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/wolfadex" rel="noopener noreferrer"&gt;https://twitter.com/wolfadex&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/lambdapriest" rel="noopener noreferrer"&gt;https://twitter.com/lambdapriest&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>elm</category>
      <category>combinators</category>
      <category>designsystem</category>
      <category>functional</category>
    </item>
    <item>
      <title>On Ideology</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Sun, 12 Feb 2023 22:06:08 +0000</pubDate>
      <link>https://dev.to/jmpavlick/on-ideology-2bmp</link>
      <guid>https://dev.to/jmpavlick/on-ideology-2bmp</guid>
      <description>&lt;p&gt;Programming languages all implicity include an ideology - a set of core ideas and philosophies - that serve as a sort of conceptual framework for the choices that are made when one is using a given langauge to create a piece of software.&lt;/p&gt;

&lt;p&gt;An absence of a clearly-defined ideology is still an ideology; in that case, the ideology is, "anything goes". We have seen how this sort of ideology has worked out, over time and at scale; no examples need to be given. Ultimately, in a language community and ecosystem with no clearly-defined ideology, contributors tend to add their own ideas about "how things could work well" and create frameworks, tooling, scaffolding; in doing so, they are creating an ideology.&lt;/p&gt;

&lt;p&gt;For some programming language communities, the tools are an intentional byproduct of an ideology refined and followed to its logical conclusions. This is not always the case - and whether or not it is the case is certainly not some sort of value judgment. Some languages exist as an intersection of "what it was possible to do with computers at the time" and "what seemed most ergonomic, given the constraints".&lt;/p&gt;

&lt;p&gt;Elm is most certainly &lt;em&gt;not&lt;/em&gt; a member of the latter set. In my experience, and as evidenced most recently by the latest round of handwaving-freakoutery on the orange website&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, this results in surprise and dismay for those unaccustomed to confronting a programming language's ideology head-on; as much as again, when it is contra to their own ideals.&lt;/p&gt;

&lt;p&gt;The Elm ecosystem's design decisions - notoriously, the decision to disallow kernel code in 0.19 - function as a set of constraints to enforce the author's ideology on the system as a whole. Many have voiced an opinion that this was not only "wrong" - as in, "not technically correct", but also "wrong", as in "immoral".&lt;/p&gt;

&lt;p&gt;Some of Elm's promises and guarantees are literally impossible to realize without this sort of constraint. Should people, such as the author of Elm, be &lt;em&gt;explicity discouraged&lt;/em&gt; from creating these constraints, simply because "that's what the people and community want"?&lt;/p&gt;

&lt;p&gt;Was it morally wrong for the author of Elm to remove that functionality? Put another way: was there a moral imperative for him to continue to support a feature set that went against his ideology?&lt;/p&gt;

&lt;p&gt;What is the moral weight of public opinion?&lt;/p&gt;

&lt;p&gt;Is there ever a moral imperative for an Open Source engineer to "listen to the community", regardless of whether or not doing so goes against their personal convictions for how the thing that they've made should function?&lt;/p&gt;

&lt;p&gt;There are some types of systems that can only exist in a certain form when they are the product of one, or few minds. Should those systems not be permitted to exist?&lt;/p&gt;

&lt;p&gt;What do you value?&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://news.ycombinator.com/item?id=34746161" rel="noopener noreferrer"&gt;https://news.ycombinator.com/item?id=34746161&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>LETWW, Part 2: "Regular expressions are quite confusing and difficult to use."</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Tue, 19 Apr 2022 05:24:42 +0000</pubDate>
      <link>https://dev.to/jmpavlick/regular-expressions-are-quite-confusing-and-difficult-to-use-50l7</link>
      <guid>https://dev.to/jmpavlick/regular-expressions-are-quite-confusing-and-difficult-to-use-50l7</guid>
      <description>&lt;p&gt;Previously on Learning Elm The Wrong Way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/jmpavlick/learning-elm-the-wrong-way-a-series-probably-2ohp"&gt;Learning Elm the Wrong Way: A Series (Probably)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm back, everybody, and I've got more sins to atone for. Buckle up.&lt;/p&gt;




&lt;p&gt;The choice to use Elm was a decision made with the rationale that I've employed to make most major decisions in my life so far - by the seat of my pants, with hopes for the best. I'd never studied functional programming, and I'd never owned a whole product before end-to-end; but the client wanted what they wanted, and I was their best hope, so I did what I had to do.&lt;/p&gt;

&lt;p&gt;We were not happy, then; those were simpler times.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Anyway. I remember the first time I reached for Elm's regular expressions library. I remember reading Evan's helpful "nag screen" on the &lt;code&gt;elm/regex&lt;/code&gt; package docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generally speaking, it will be easier and nicer to use a parsing library like elm/parser instead of this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Hmm. Alright. I like 'nicer' and I like 'easier'." I clicked over to the docs for &lt;code&gt;elm/parser&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Regular expressions are quite confusing and difficult to use. This library provides a coherent alternative that handles more cases and produces clearer code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was sitting there, on my front porch, in the brutal, early-morning Michigan summer sun - all sixty-nine degrees of its feeble fury - and I thought: "Oh boy! If these people think that regex is hard... I'm gonna be so good at this. I'm the &lt;em&gt;God of regex&lt;/em&gt;." And it was true - early on in my career, I'd heard that programmers despised and struggled with regex, so I'd made it my business to use Vim only ever and study regex diligently. And, y'know, I was... not half-bad.&lt;/p&gt;

&lt;p&gt;Smash cut to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;point : Parser Point
point =
  succeed Point
    |. symbol "("
    |. spaces
    |= float
    |. spaces
    |. symbol ","
    |. spaces
    |= float
    |. spaces
    |. symbol ")"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and, &lt;em&gt;record-scratch&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;"Huh. Well, looks like I'll be using regex today, after all."&lt;/p&gt;




&lt;p&gt;Some time passed, and I "learned" how to use decoders; except, I didn't &lt;em&gt;really&lt;/em&gt; learn how to use decoders, I just fumbled around with them enough to get work done.&lt;sup id="fnref2"&gt;2&lt;/sup&gt; &lt;code&gt;Decode.Pipeline&lt;/code&gt; was particularly nice; I wasn't sure what it was doing with all of those &lt;code&gt;|&amp;gt;&lt;/code&gt;s, but it clicked on a visual level: "this is some sort of a pipeline, and every Thing that Happens in this pipeline goes into my value".&lt;/p&gt;

&lt;p&gt;One day, someone in Elm Slack said something along the lines of, "Yeah, &lt;code&gt;Parser&lt;/code&gt;'s just like &lt;code&gt;Decode.Pipeline&lt;/code&gt;". I looked at &lt;code&gt;Parser&lt;/code&gt; again. I read the docs again. My brain did that thing that it does when it &lt;em&gt;not only&lt;/em&gt; does not Understand, but &lt;em&gt;also&lt;/em&gt; does not Understand &lt;em&gt;why it does not Understand&lt;/em&gt; - and promptly powered down.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you've made it this far, here's a tip: Learn to identify the difference between "I don't understand this", and "I don't understand &lt;em&gt;why&lt;/em&gt; I don't understand this", and format your questions accordingly. You'll get further, faster.
&lt;/h3&gt;




&lt;p&gt;More time passed. Years, actually. I made a few more attempts at trying to learn how &lt;code&gt;Parser&lt;/code&gt; worked, but every time I made it around to the docs, I was seized by that same feeling of unfamiliarity and confusion. But along the way, I learned something that seemed, at the time, to be unrelated.&lt;/p&gt;

&lt;p&gt;I had finally decided to try &lt;code&gt;elm-review&lt;/code&gt;&lt;sup id="fnref3"&gt;3&lt;/sup&gt;, and I chose to use Elm Slack regular SiriusStarr's review config as a starting point for my own&lt;sup id="fnref4"&gt;4&lt;/sup&gt;. I was intrigued by some of the rules that were enforced; one of them yelled at me for the way that I was using &lt;code&gt;Decode.Pipeline&lt;/code&gt; to decode some JSON into a type alias. It turns out that there's a rule that prohibits you from using a type alias as a constructor!&lt;sup id="fnref5"&gt;5&lt;/sup&gt; This means that given a type alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias Point =
    { x : Int
    , y : Int
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're prohibited from ever calling it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin : Point
origin = Point 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, you must:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin : Point
origin = { x = 0, y = 0 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which meant that a decoder as follows, was invalid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pointDecoder : Decoder Point
pointDecoder =
    Decode.succeed Point
        |&amp;gt; Pipeline.required "x" Decode.int
        |&amp;gt; Pipeline.required "y" Decode.int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that instead, you must:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pointDecoder : Decoder Point
pointDecoder =
    Decode.succeed (\x y -&amp;gt; { x = x, y = y }) 
        |&amp;gt; Pipeline.required "x" Decode.int
        |&amp;gt; Pipeline.required "y" Decode.int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Well that's pretty verbose, but I get it. Since the type alias is a positional constructor, you could get yourself out of whack if you passed in multiple same-typed arguments out of order, so this forces you to be a little more explicit about what goes where."&lt;/p&gt;

&lt;p&gt;"Oh. And I guess that means that I can put any function after the &lt;code&gt;Decode.succeed&lt;/code&gt; in a pipeline, and that the &lt;code&gt;Decoder&lt;/code&gt; will be a &lt;code&gt;Decoder&lt;/code&gt; for whatever type that function outputs; this follows from knowing that a type alias is just a positional constructor for a record."&lt;/p&gt;

&lt;p&gt;I didn't realize it, but I was getting closer to unlocking the mysteries of the &lt;code&gt;Parser&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Earlier this week, I was refactoring some code from the project that I mentioned at the beginning of this post. It's been through a lot over the years, as have I, but the client still loves it - and I've learned a lot from stubbornly fixing things over the years, rather than throwing everything out and starting over. I found a branch of my main &lt;code&gt;update&lt;/code&gt; function where I was taking a string value, using regex to split it based on a delimiter, and doing a bunch of nonsense to verify that the string contained two and only two pieces after splitting; that they were both integers; etc.&lt;/p&gt;

&lt;p&gt;"Man. This looks like a great place to stick a &lt;code&gt;Parser&lt;/code&gt;. If only I understood them."&lt;/p&gt;

&lt;p&gt;"Maybe this time will be different." &lt;em&gt;You said that the last time.&lt;/em&gt; "Yeah, but I'm a little smarter now." &lt;em&gt;We'll see about that, won't we?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I pulled up the docs. I saw the &lt;code&gt;|.&lt;/code&gt; and the &lt;code&gt;|=&lt;/code&gt;, and I panicked and froze. But this time, I tried something new.&lt;/p&gt;

&lt;p&gt;I pulled up Martin Janiczek's Ellie Catalog&lt;sup id="fnref6"&gt;6&lt;/sup&gt;, and typed in &lt;code&gt;parser&lt;/code&gt;. Bingo: &lt;a href="https://ellie-app.com/f2smkjHfN26a1"&gt;https://ellie-app.com/f2smkjHfN26a1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as I saw the code in the Ellie, without even running it - I recognized what had kept me from ever understanding before, and then I immediately understood the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My prior lack of understanding was due to a mental disconnect between the two true sentences, "record type aliases come with implicit constructors"&lt;sup id="fnref7"&gt;7&lt;/sup&gt; and "all constructors are functions".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You see, most of my application development experience has been in csharp. In csharp, we don't have type aliases or anything like that, but we do have classes. Classes have a type, and &lt;em&gt;types&lt;/em&gt; have a type (and the type of a type is a type called &lt;code&gt;Type&lt;/code&gt;, &lt;em&gt;obviously&lt;/em&gt;). After marinating for over a decade in a type system where type names are "special" and have to be invoked only in certain special-case contexts (with operators like &lt;code&gt;typeof()&lt;/code&gt;, or as function signatures) - I couldn't see what was literally right in front of my eyes:&lt;/p&gt;

&lt;h3&gt;
  
  
  Type names, just like everything else in Elm, are Not Special. They're constructors for a value.
&lt;/h3&gt;

&lt;p&gt;And this was obscured for so long, because when I saw&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parser.succeed Point
    |= ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I didn't see "a function (&lt;code&gt;Parser.succeed&lt;/code&gt;) taking another function as an argument (&lt;code&gt;Point&lt;/code&gt;) and then passing it values collected from a parsing operation" - I saw "&lt;code&gt;Parser.succeed for a Special Type Name&lt;/code&gt;".&lt;/p&gt;

&lt;p&gt;So from this spiraling diatribe (spiral-tribe?&lt;sup id="fnref8"&gt;8&lt;/sup&gt;), three lessons:&lt;/p&gt;

&lt;h3&gt;
  
  
  Great pains have been taken to ensure that everything with Elm is internally consistent; if you don't understand one Thing, that's based on another Thing - there's a good chance that you don't understand the "another Thing" as well as you think you do.
&lt;/h3&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;h3&gt;
  
  
  Never be afraid to re-visit ideas that you didn't understand the first time around. You're smarter now.
&lt;/h3&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;h3&gt;
  
  
  Nothing in this language is special; everything is a function with zero or more arguments. If you don't understand something, try to think about how it could be a function with zero or more arguments, and what that might mean.
&lt;/h3&gt;




&lt;p&gt;Never did hear back about the yacht job&lt;sup id="fnref9"&gt;9&lt;/sup&gt;. Oh well. More yachts in the sea, I suppose.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=BO_ZmDETR98"&gt;https://www.youtube.com/watch?v=BO_ZmDETR98&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;To everyone in Elm Slack that's ever explained decoders to me - had to have been upwards of 20 times until y'all wore a groove in my smooth brain to give the information a place to live - &lt;em&gt;thank you so much&lt;/em&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Spreading the gospel of how and why &lt;code&gt;elm-review&lt;/code&gt; is important falls outside of the scope of this post; but for the love of God, if you don't know about &lt;code&gt;elm-review&lt;/code&gt;, learn about &lt;code&gt;elm-review&lt;/code&gt;. All hail Jeroen. &lt;a href="https://github.com/jfmengels/elm-review"&gt;https://github.com/jfmengels/elm-review&lt;/a&gt;  ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://github.com/SiriusStarr/elm-review-rules"&gt;https://github.com/SiriusStarr/elm-review-rules&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://elm.dmy.fr/packages/lue-bird/elm-no-record-type-alias-constructor-function/latest/"&gt;https://elm.dmy.fr/packages/lue-bird/elm-no-record-type-alias-constructor-function/latest/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://janiczek-ellies.builtwithdark.com/"&gt;https://janiczek-ellies.builtwithdark.com/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;After I posted this, lue helpfully pointed out some instances where a type alias is &lt;em&gt;not&lt;/em&gt; actually a constructor for a value - you can read more about this here: &lt;a href="https://elm.dmy.fr/packages/lue-bird/elm-no-record-type-alias-constructor-function/latest/"&gt;https://elm.dmy.fr/packages/lue-bird/elm-no-record-type-alias-constructor-function/latest/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;&lt;a href="https://sp23.org/"&gt;https://sp23.org/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;&lt;a href="https://dev.to/jmpavlick/hungary-for-the-power-a-closer-look-at-hungarian-notation-282d"&gt;https://dev.to/jmpavlick/hungary-for-the-power-a-closer-look-at-hungarian-notation-282d&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>elm</category>
    </item>
    <item>
      <title>Hungary for the Power: A Closer Look at Hungarian Notation</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Sun, 13 Feb 2022 07:33:04 +0000</pubDate>
      <link>https://dev.to/jmpavlick/hungary-for-the-power-a-closer-look-at-hungarian-notation-282d</link>
      <guid>https://dev.to/jmpavlick/hungary-for-the-power-a-closer-look-at-hungarian-notation-282d</guid>
      <description>&lt;p&gt;Few concepts within the Global Programming Mindshare are as universally-reviled as Hungarian notation. Everybody Knows that it's completely unnecessary, aesthetically displeasing, and considered harmful&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. If you're not familiar, the idea is generally interpreted as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hungarian notation is a naming convention that adds a prefix to each variable name, so as to encode its type in its name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it's generally accepted that examples look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string str_firstName;

int i_ageInYears;

bool b_enabled;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most people are happy to dismiss this immediately; to consign it to the trashbin of Universally Acknowledged Bad Programming Thoughts, right along with &lt;code&gt;GOTO&lt;/code&gt; and Internet Explorer 8. And at first glance, it's not hard to see why; programmers are, by virtue, lazy. There's no compelling reason to annotate a variable's type by encoding it in its name - that's what we have compilers for! If you're dumb enough to type &lt;code&gt;int result = firstName + ageInYears;&lt;/code&gt;, you deserve whatever abuse you get from your compiler. It should be &lt;em&gt;obvious&lt;/em&gt; that those two things are probably not the Same Kind of Thing. Right?&lt;/p&gt;

&lt;p&gt;You'd probably think so, but I'm nothing if not the sworn enemy of "What Everyone Knows"; so come now, let us reason together.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm going to start by quoting the whitepaper, because it doesn't seem like anybody else has read it.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;...the concept of "type" in this context is determined by the set of operations that can be applied to a quantity. The test for type equivalence is simple: could the same set of operations be meaningfully applied to the quantities in questions? If so, the types are thought to be the same. If there are operations that apply to a quantity in exclusion of others, the type of the quantity is different.&lt;/p&gt;

&lt;p&gt;Note that the above definition of type (which, incidentally, is suggested by languages such as SIMULA and Smalltalk) is a superset of the more common definition, which takes only the quantity's representation into account. Naturally, if the representations of x and y are different, there will exist some operations that could be applied to x but not y, or the reverse.&lt;sup id="fnref2"&gt;2&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"&lt;a href="https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa260976(v=vs.60)"&gt;The whitepaper&lt;/a&gt;", as it happens, was written by one Charles Simonyi. You may not have heard of him, but you're no doubt familiar with his work; he is the mind behind Microsoft Word and Microsoft Excel&lt;sup id="fnref3"&gt;3&lt;/sup&gt;. He's probably on a yacht right now&lt;sup id="fnref4"&gt;4&lt;/sup&gt;, and he is almost &lt;em&gt;definitely&lt;/em&gt; smarter than you are.&lt;/p&gt;

&lt;p&gt;Regardless, I'm hard-pressed to think of a more correct definition for a type. Most software developers I've talked to think that a "type" is a "thing" like an &lt;code&gt;int&lt;/code&gt;, a &lt;code&gt;string&lt;/code&gt;, or a &lt;code&gt;bool&lt;/code&gt;, that defines a set of operations over a given category of values; and while they're not wrong&lt;sup id="fnref5"&gt;5&lt;/sup&gt;, I can't say that they're right, either - because that's too broad a definition. "What's an ocean?" "Oh, it's a thing you can drown in." Sure, it's not a false statement; but by that reasoning, I have an ocean in my bathroom.&lt;/p&gt;

&lt;p&gt;If you don't understand why this is a big deal, let's outline a simple example. There's a difference, you know, between an &lt;code&gt;int&lt;/code&gt; value storing someone's age, and an &lt;code&gt;int&lt;/code&gt; value storing a &lt;code&gt;for&lt;/code&gt; loop's index value. The compiler doesn't know about it, because if you try to multiply someone's age by an iterator's index, as long as they're both &lt;code&gt;int&lt;/code&gt;s, the compiler will be happy; but will your program be correct?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just because an operation is possible, that doesn't mean that it's correct.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So anyway - Simonyi goes on to suggest some naming conventions to give programmers the tools to help themselves avoid this footgun - to make the representations of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; different, so as to discourage performing valid-but-nonsensical operations to them.&lt;/p&gt;

&lt;p&gt;Let's look at another example - let's think about Microsoft Excel for a moment. In a spreadsheet, your two most important primitives are "Row" and "Column". If you needed to implement a spreadsheet in C, you'd probably start by defining a multi-dimensional array - rows of columns - to hold your data, with a cell represented by the the data stored at the coordinate of the indices for the row and the column. Since you can access an item in an array by its index, this means that you can write a function with a signature like &lt;code&gt;void clearCellData(int rowIndex, int columnIndex)&lt;/code&gt;. And it's great - but what happens when you transpose your inputs for the row and column? What happens when you write a function &lt;code&gt;void clearRow(int rowIndex)&lt;/code&gt; but you accidentally pass in a column index? The compiler is as pleased as ever, and you won't even get an error at runtime (unless it's for a null reference) - but you've deleted every cell in the wrong row.&lt;sup id="fnref6"&gt;6&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;If you'd been careful to follow Hungarian Notation as outlined in the whitepaper, you'd be much less likely to make that mistake; if every &lt;code&gt;int&lt;/code&gt; representing a "Row" was prefixed with &lt;code&gt;row_&lt;/code&gt;, and if every &lt;code&gt;int&lt;/code&gt; representing a "Column" was prefixed with &lt;code&gt;col_&lt;/code&gt;, you'd be much less likely to call &lt;code&gt;clearRow(col_selected)&lt;/code&gt;. And that, my friends, is the pragmatism behind the reasoning for Hungarian Notation. Nowhere in the whitepaper will you find mention of prefixing &lt;code&gt;string&lt;/code&gt;s with &lt;code&gt;str_&lt;/code&gt; and &lt;code&gt;int&lt;/code&gt;s with &lt;code&gt;i_&lt;/code&gt;, solely on the basis that they're &lt;code&gt;string&lt;/code&gt;s and &lt;code&gt;int&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Well now, that certainly doesn't sound so bad, does it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The trouble, it seems, is that everybody else got it wrong.
&lt;/h2&gt;

&lt;p&gt;Spend enough time&lt;sup id="fnref7"&gt;7&lt;/sup&gt; researching Hungarian Notation, and you'll come across the name Charles Petzold. This particular Charles was &lt;em&gt;also&lt;/em&gt; an Important Programmer at Microsoft, and in his book "Programming Windows", he explains it thusly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Many Windows programmers use a variable-naming convention known as "Hungarian Notation," in honor of the&lt;br&gt;
legendary Microsoft programmer Charles Simonyi. Very simply, the variable name begins with a lowercase letter or letters that denote the data type of the variable. For example, the &lt;code&gt;sz&lt;/code&gt; prefix in &lt;code&gt;szCmdLine&lt;/code&gt; stands for "string terminated by zero." The &lt;code&gt;h&lt;/code&gt; prefix in &lt;code&gt;hInstance&lt;/code&gt; and &lt;code&gt;hPrevInstance&lt;/code&gt; stands for "handle;" the &lt;code&gt;i&lt;/code&gt; prefix in &lt;code&gt;iCmdShow&lt;/code&gt; stands for "integer."&lt;sup id="fnref8"&gt;8&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that's it! That's his whole statement on the topic. Huh. I guess Other Charles didn't read the whitepaper. Unfortunately, this is the version of the idea that has found widespread adoption. The important difference here is that the idea behind Hungarian Notation concerns itself with &lt;em&gt;semantics&lt;/em&gt;, not with the way that the data is handled by the compiler or its output.&lt;/p&gt;

&lt;p&gt;If you've been following along, you'll note that earlier, I didn't say, "The naming convention was &lt;em&gt;the reasoning&lt;/em&gt; behind Hungarian Notation"; that was merely the pragmatism that drove it. The &lt;em&gt;reasoning behind&lt;/em&gt; Hungarian notation should be familiar to every Elm developer that's ever been force-fed Richard Feldman talks in the Elm Slack: &lt;strong&gt;making impossible states impossible&lt;/strong&gt;&lt;sup id="fnref9"&gt;9&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The goal was never to make sure that you knew that an &lt;code&gt;int&lt;/code&gt; was an &lt;code&gt;int&lt;/code&gt;; it was to give you better tools to &lt;em&gt;restrict your program in such a way that it only ever performed computations that were semantically valid&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, so you're certainly not suggesting...
&lt;/h2&gt;

&lt;p&gt;... that you go out and prefix all of your program's values with semantic information? Well, it certainly couldn't &lt;em&gt;hurt&lt;/em&gt; - but in the forty-plus years that have passed since these ideas were introduced, we've built better tools and thought about these problems a lot more. We're better, and we can do better.&lt;/p&gt;

&lt;p&gt;We have Elm, and Elm has custom types, and with custom types we can implement domain-specific types as easily as we can breathe. The Elm Patterns book briefly outlines this in the section about Type Blindness&lt;sup id="fnref10"&gt;10&lt;/sup&gt;, and Joel Quenneville has an excellent demonstration of the pattern applied at this footnote's link&lt;sup id="fnref11"&gt;11&lt;/sup&gt;, but I'll summarize it here.&lt;/p&gt;

&lt;p&gt;In the context of our earlier example - given that we had a two-dimensional array that we needed to access by its indices&lt;sup id="fnref12"&gt;12&lt;/sup&gt;, we could &lt;em&gt;wrap&lt;/em&gt; the &lt;code&gt;Int&lt;/code&gt; values with custom types, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type RowIndex = RowIndex Int

type ColIndex = ColIndex Int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of a sudden, we have &lt;em&gt;compile-time verification for our program's &lt;strong&gt;semantics&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We can keep going! Wrapping primitives means that we have to unwrap them (i.e., some form of &lt;code&gt;(\(RowIndex index) -&amp;gt; index)&lt;/code&gt;) when we need to use the primitive value, which is a &lt;em&gt;little&lt;/em&gt; extra work - but it's worth it, because now we have to think a little harder about what kinds of operations we're going to need to perform on our values. We have now shifted into the realm of considering our program's &lt;em&gt;semantics&lt;/em&gt;, which means that we are now motivated to write functions to use our values. Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nextRowIndex : RowIndex -&amp;gt; RowIndex
nextRowIndex (RowIndex index) =
    RowIndex (index + 1)

prevRowIndex : RowIndex -&amp;gt; RowIndex
prevRowIndex (RowIndex index)
    RowIndex (index - 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we accidentally pass a &lt;code&gt;ColIndex&lt;/code&gt; to &lt;code&gt;nextRowIndex&lt;/code&gt; - we won't get back a semantically-incorrect value - &lt;em&gt;our code won't compile&lt;/em&gt;. You won't get that with a function signature that uses all primitives, such as &lt;code&gt;nextRowIndex : Int -&amp;gt; Int&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is powerful. &lt;strong&gt;By including a value's semantics in the definition of the type used to store and refer to that value, we can use our compiler to verify our program's correctness&lt;/strong&gt; - and with Elm, we have the tools to do just that. This, truly, is the spirit in which Hungarian Notation was developed and presented; and that spirit lives on, every time an Elm developer writes &lt;code&gt;type Dollar = Dollar Int&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion, Elm is Hungarian Notation. Thank you for your time. No - stop - where are you going? I thought we were FRIENDS
&lt;/h2&gt;

&lt;p&gt;Oh, and Mr. Simonyi, if you need an Elm developer on that yacht, Microsoft has my number on file from the number of times they've coerced me into giving it to them; call me anytime.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="http://catb.org/jargon/html/C/considered-harmful.html"&gt;http://catb.org/jargon/html/C/considered-harmful.html&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa260976(v=vs.60)#type-calculus"&gt;https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa260976(v=vs.60)#type-calculus&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Charles_Simonyi#Microsoft"&gt;https://en.wikipedia.org/wiki/Charles_Simonyi#Microsoft&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Charles_Simonyi#Personal_life"&gt;https://en.wikipedia.org/wiki/Charles_Simonyi#Personal_life&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://rationalwiki.org/wiki/Not_even_wrong"&gt;https://rationalwiki.org/wiki/Not_even_wrong&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;The Joel talks about this, here, and his prose is much nicer than mine: &lt;a href="https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/"&gt;https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/&lt;/a&gt; - but he &lt;em&gt;still&lt;/em&gt; misses the point that I intend to make in this essay. I'm getting close to it, I promise. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;Five minutes, max ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;The top search result for "charles petzold programming windows online" was this sketchy public Google Drive Link, which you may download at your own risk and peril: &lt;a href="https://docs.google.com/file/d/0B73JwvIHVHaiSFdpekJCOUdoeE0/view?resourcekey=0-JFez95uS9jETJQdFGKY_1w"&gt;https://docs.google.com/file/d/0B73JwvIHVHaiSFdpekJCOUdoeE0/view?resourcekey=0-JFez95uS9jETJQdFGKY_1w&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=IcgmSRJHu_8"&gt;https://www.youtube.com/watch?v=IcgmSRJHu_8&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn10"&gt;
&lt;p&gt;&lt;a href="https://sporto.github.io/elm-patterns/basic/type-blindness.html"&gt;https://sporto.github.io/elm-patterns/basic/type-blindness.html&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn11"&gt;
&lt;p&gt;&lt;a href="https://thoughtbot.com/upcase/videos/domain-specific-types-in-elm"&gt;https://thoughtbot.com/upcase/videos/domain-specific-types-in-elm&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn12"&gt;
&lt;p&gt;I know that accessing an array's value by index isn't very Elm-y, but it fits the illustration; assume that it's for interop with some dirty old Javascript, if that makes you feel better ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>elm</category>
      <category>programming</category>
      <category>functional</category>
    </item>
    <item>
      <title>"You can't do nested record updates in Elm."</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Fri, 28 Jan 2022 05:08:39 +0000</pubDate>
      <link>https://dev.to/jmpavlick/you-cant-do-nested-record-updates-in-elm-hjh</link>
      <guid>https://dev.to/jmpavlick/you-cant-do-nested-record-updates-in-elm-hjh</guid>
      <description>&lt;p&gt;At least, not in an intuitive way. It's one of the first pain-points that a new developer runs into when getting started with the language.&lt;/p&gt;

&lt;p&gt;Given:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type alias Model =
    { person : Person
    }

type alias Person =
    { firstName : String
    , lastName : String
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... the natural thing to try when writing an &lt;code&gt;update&lt;/code&gt; function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update msg model =
    case msg of
        UpdatedFirstName firstName -&amp;gt;
            { model | person =
              { model.person |
                  firstName = firstName
              }
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler won't like it, and neither will you; this is not The Way.&lt;/p&gt;

&lt;p&gt;The natural next step always looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update msg model =
    case msg of
        UpdatedFirstName firstName -&amp;gt;
            let
                currentPerson = model.person

                updatedPerson =
                    { currentPerson | firstName = firstName }
            in
            { model | person = updatedPerson }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we're better. We can do better. Follow me.&lt;/p&gt;




&lt;p&gt;Elm is a really, &lt;em&gt;really&lt;/em&gt; simple language. Everything in the language follows a set of internally-consistent semantics; I find that when something does &lt;em&gt;not&lt;/em&gt; work as I'd expect it to, it means that my expectations are wrong, which means that my mental model of the language is incomplete or wrong. (NB: people that claim to design systems that "work just like you'd expect them to" - how can they make that claim? Who is this subset of people for whom these things work exactly as they'd expect them to; and are they even the right subset of people to optimize for?&lt;sup id="fnref1"&gt;1&lt;/sup&gt;)&lt;/p&gt;

&lt;p&gt;A few weeks ago, one of those Elm Lightbulbs fell neatly into its socket and I noticed one of Elm's guiding principles:&lt;/p&gt;

&lt;h2&gt;
  
  
  Functions go on the left. Parameters go on the right.
&lt;/h2&gt;

&lt;p&gt;(Yes, I'm aware of &lt;code&gt;|&amp;gt;&lt;/code&gt;; do you know how a mirror works?)&lt;/p&gt;

&lt;p&gt;This seems obvious enough, but it has interesting implications, not all of which are immediately apparent. Everybody knows that if you have an &lt;code&gt;a&lt;/code&gt; and you want to turn it into a &lt;code&gt;b&lt;/code&gt;, all you have to do is put a function to the left of &lt;code&gt;a&lt;/code&gt; that turns it into &lt;code&gt;b&lt;/code&gt; - so you write a function, and call it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aToB : a -&amp;gt; b

aToB valueA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if you only need to use it once? Why not just write a lambda?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(\a -&amp;gt; b) valueA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;But you already knew that, and I still haven't addressed the elephant in the room. You probably knew, too, that you can write a lambda that takes a value and returns a record.&lt;/p&gt;

&lt;p&gt;So why haven't I seen this before?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update msg model =
    case msg of
        UpdatedFirstName firstName -&amp;gt;
            { model |
                person =
                    (\p -&amp;gt;
                        { p | firstName = firstName }
                    ) model.person
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  "Wow, John. Neat party trick. But -"
&lt;/h2&gt;

&lt;p&gt;You're right. This isn't a silver bullet. Sometimes, you should just write a function that does this for you. Some people use a builder pattern&lt;sup id="fnref2"&gt;2&lt;/sup&gt;, so they can do neat stuff like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;update msg model =
    case msg of
        UpdatedFirstName firstName -&amp;gt;
            { model | person =
                model.person
                    |&amp;gt; withUpdatedFirstName firstName
            }

withUpdatedFirstName : String -&amp;gt; Person -&amp;gt; Person
withUpdatedFirstName firstName =
    (\person -&amp;gt; { person | firstName = firstName } )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But you don't always need to reach for a builder pattern, when all you need to do is update a nested record once in your &lt;code&gt;update&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Besides, that's really not even what this little essay was about, in the first place:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a beginner or intermediate Elm developer, if you get the sense that "there must be a better way to do this" - there probably is. Go look for it, and don't stop looking until you find it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's all. Good night, take care.&lt;/p&gt;




&lt;p&gt;Update / edit: I posted this on the Elm Slack&lt;sup id="fnref3"&gt;3&lt;/sup&gt; last night, and Jeroen Engels was kind enough to read though this, detail some errata, and suggest some improvements. I'm just going to quote him, here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I think one of the options I end up going for in the end, is to have a separate function to update Person, in a separate Person module where the Person type is opaque. That's I think usually where you get the most benefits and it feels least cumbersome (if you already have the opaque type), and I think it would be valuable to mention it here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Opaque types are beyond the scope of this post&lt;sup id="fnref4"&gt;4&lt;/sup&gt;, but &lt;a href="https://ckoster22.medium.com/advanced-types-in-elm-opaque-types-ec5ec3b84ed2"&gt;Charlie Koster does a great job of explaining them, here, for anyone interested.&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Love or hate DHH, this document is still relevant: &lt;a href="https://rubyonrails.org/doctrine"&gt;https://rubyonrails.org/doctrine&lt;/a&gt; - &lt;code&gt;Ctrl+F "surprise"&lt;/code&gt; to get to the relevant section. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://sporto.github.io/elm-patterns/basic/builder-pattern.html"&gt;https://sporto.github.io/elm-patterns/basic/builder-pattern.html&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="http://elmlang.herokuapp.com/"&gt;http://elmlang.herokuapp.com/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;Because I don't feel qualified to explain them, and because my schtick is "saving beginners from themselves" and "atoning for my sins"; I still have much to learn. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>elm</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Elm the Wrong Way: A Series (Probably)</title>
      <dc:creator>John Pavlick</dc:creator>
      <pubDate>Sat, 15 Jan 2022 07:33:19 +0000</pubDate>
      <link>https://dev.to/jmpavlick/learning-elm-the-wrong-way-a-series-probably-2ohp</link>
      <guid>https://dev.to/jmpavlick/learning-elm-the-wrong-way-a-series-probably-2ohp</guid>
      <description>&lt;p&gt;Hi, I'm John, and a few months ago I decided that &lt;em&gt;I've been doing this for too long to be this bad at it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I've been an Elm developer since 2018, and the story is really only important to me&lt;sup id="fnref1"&gt;1&lt;/sup&gt; (there's enough self-aggrandizing on the Internet&lt;sup id="fnref2"&gt;2&lt;/sup&gt; these days) so I'll leave it out - but it's taken me a remarkably long time to feel as if I have any real command of the language and its tooling / ecosystem.&lt;/p&gt;

&lt;p&gt;Some of the Best &amp;amp; Brightest on &lt;a href="https://elmlang.herokuapp.com/"&gt;the Elm Slack&lt;/a&gt; have been kindly tolerating my ineptitude for some years now, and now that I know about &lt;a href="https://package.elm-lang.org/packages/elm/html/latest/Html-Attributes#classList"&gt;classList&lt;/a&gt; and can hang out in &lt;code&gt;#beginners&lt;/code&gt; and field easy questions, it's time to take the next logical step: start a dev blog.&lt;/p&gt;

&lt;p&gt;Learning by example is well and good, but most of the truly important things I've learned have been by &lt;em&gt;counter-example&lt;/em&gt;. What-to-do is nowhere near as poignant on its own, as it is when contrasted with what-not-to-do. And I'm an expert at what-not-to-do. Unfortunately, I've had to find these poignant counter-examples on my own. I'm here today to 1) confess my sins, and 2) show you how not to be like me. I've got enough sins for which to seek absolution that this will likely be a series, but let's dive in now. If you want to learn Elm the wrong way, start by following the headline-sized point below, don't read anything else, and... I'll see you in &lt;code&gt;#beginners&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignore / Fear The Runtime
&lt;/h3&gt;

&lt;p&gt;So you did &lt;a href="https://guide.elm-lang.org/"&gt;https://guide.elm-lang.org/&lt;/a&gt;, and you're aware that "Elm is a functional language that transpiles to Javascript and has its own runtime". Great! Now, if you want to do things the wrong way: &lt;em&gt;never ever think about the runtime, ever again&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To be fair, this isn't wholly advice without merit; the runtime stays out of your way. My background is in data / reporting - I thought, "Oh, good. A runtime. Like when I smash &lt;code&gt;F5&lt;/code&gt; on SQL Server and it runs my query. Like dotnet. Like the JVM."&lt;/p&gt;

&lt;p&gt;But there's a difference that wasn't apparent to me when I got started - since Elm is event-driven, you don't call the runtime; &lt;em&gt;the runtime calls YOU&lt;/em&gt;. I'll say it again:&lt;/p&gt;

&lt;h4&gt;
  
  
  The runtime calls you!
&lt;/h4&gt;

&lt;p&gt;Remember when you copied and pasted this block of code into &lt;code&gt;elm reactor&lt;/code&gt; and fiddled with everything around it until your app compiled? I do!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main : Program () Model Msg
main =
    Browser.sandbox
        { init = initialModel
        , view = view
        , update = update
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Ah. A &lt;code&gt;main&lt;/code&gt; function. Seems right."&lt;/p&gt;

&lt;p&gt;The problem with &lt;code&gt;main&lt;/code&gt; is that by the numbers, it's not a function that you write often; you set it up, and it's good. The Code is Good, and you don't touch the Code when it is Good; and so you proceed to not think very hard about it for a few years.&lt;/p&gt;

&lt;p&gt;At a high level, the difference between &lt;code&gt;public static void main()&lt;/code&gt; and &lt;code&gt;main : Program () Model Msg&lt;/code&gt; is that, in the case of the latter, you are telling a program that already exists which three specific functions it's going to call, to handle very specific parts of your application domain. &lt;/p&gt;

&lt;p&gt;Elm's &lt;code&gt;main&lt;/code&gt; function has more in common with dependency injection - with &lt;code&gt;services.AddSingleton&amp;lt;IEmailProxy, EmailProxy&amp;gt;();&lt;/code&gt;, than it does with &lt;code&gt;public static void main()&lt;/code&gt;. Our old friend &lt;code&gt;psvm()&lt;/code&gt; will execute any old code that we sling in there; in contrast, Elm's runtime only knows that it's going to get messages (from the DOM, from ports, and from HTTP responses); that it's going to render HTML; and that it's going to have to start up your application for the first time. The particulars of what it does in those situations are what the code that you are writing &lt;em&gt;actually does&lt;/em&gt;, and do those things and those things only it must (no side effects, remember?). And this brings me to my next point:&lt;/p&gt;

&lt;h4&gt;
  
  
  Msgs happened in the past; getting their names right is important.
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Hardest two problems, cache invalidation, naming, blah blah blah&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You've already heard the quote, you already &lt;em&gt;know that&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But you need to realize that when you declare the variants for your &lt;code&gt;Msg&lt;/code&gt; type, that every time you process a &lt;code&gt;Msg&lt;/code&gt; in &lt;code&gt;update&lt;/code&gt;, you are processing the output of an action that &lt;em&gt;already happened&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Since I came from an OO / imperative / procedural background, I brought what I had with me when I started learning this language. If I was writing a Windows Forms application, and I wanted &lt;code&gt;btn_DoSomething&lt;/code&gt; to do something, I'd wire its click event-handler to a function &lt;code&gt;DoSomething&lt;/code&gt;, and something would be done&lt;sup id="fnref3"&gt;3&lt;/sup&gt;. So in Elm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;button [ onClick DoSomething ] [ text "Do Something" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Msg
    = DoSomething
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case msg of
    DoSomething -&amp;gt;
        ( model, doSomething )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I regret to inform you that this is not the Way.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DoSomething&lt;/code&gt; means, "perform an action", and tells you nothing about how you got to the point in your program's execution where something was done. So if you choose to &lt;code&gt;DoSomething&lt;/code&gt;, and something was done, what do you name your variant "for when something was done"?&lt;/p&gt;

&lt;p&gt;Probably &lt;code&gt;DoSomethingResult&lt;/code&gt;. But this is a function, in a functional language! "DoSomethingResult" is a name, a &lt;em&gt;noun&lt;/em&gt;; and their kind are not welcome here&lt;sup id="fnref4"&gt;4&lt;/sup&gt;. Banish from your mind any thoughts that this is a silly hill to die on; we are programmers, we are talking about a programming language, and if you don't spend quite a bit of time thinking about the structure and interpretation&lt;sup id="fnref5"&gt;5&lt;/sup&gt; of the language that you speak &lt;em&gt;every day&lt;/em&gt; - you're going to have a bad time. Get interested in linguistics.&lt;/p&gt;

&lt;p&gt;I digress. This is a functional language; custom type variants are functions that are a constructor for their custom type; we need to give them names that are verbs. What's a good verb for receiving a result from a function yclept &lt;code&gt;doSomething&lt;/code&gt;? I don't know, how about, &lt;code&gt;GetDoSomethingResult&lt;/code&gt;? Close, but computer says "no"&lt;sup id="fnref6"&gt;6&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The act of receiving a &lt;code&gt;Msg&lt;/code&gt; is not something that will be done by your program; it is something that &lt;em&gt;was done&lt;/em&gt;, in the &lt;em&gt;past&lt;/em&gt;, by the  runtime. Your &lt;code&gt;Msg&lt;/code&gt; variants are event handlers for the return value of events that come &lt;em&gt;from the runtime&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Who clicked that button? You did! (Who's a good doggy?) But the only way that the event "clicked a button" is any different from any of the other thousand events per second that you emit while using a web browser (scrolling, moving your mouse, clicking on a blank space) is that you told Elm's runtime to listen for that event, and that you could handle whatever result the runtime generated from processing that event.&lt;/p&gt;

&lt;p&gt;So since the event that you want to handle happened in the past, and since it was done by somebody else - what should you call it? In this instance, I would call my variant &lt;code&gt;GotDoSomethingResult&lt;/code&gt;. It's perfect! It tells us that the runtime already received our result from the &lt;code&gt;doSomething&lt;/code&gt; function, and is ready to hand it over to us for further processing. Once you start reading packages, or other open-source projects, you'll see these patterns pop up - lots of &lt;code&gt;Got&lt;/code&gt;s and &lt;code&gt;Clicked&lt;/code&gt;s and &lt;code&gt;Changed&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Let's take what we've learned, and selectively refactor our application that we wrote earlier to use our new knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;button [ onClick ClickedBtnDoSomething ] [ text "Do Something" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Msg
    = ClickedBtnDoSomething
    | GotDoSomethingResult Result (Http.Error ())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case msg of
    ClickedBtnDoSomething -&amp;gt;
        ...

    GotDoSomethingResult result -&amp;gt;
        ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you talk about "getting" something, the Thing that you will Get is not yet in your possession, no matter how near the future may be wherein you have that Thing; but when you "Got" something, you can only ever speak of the action of your coming into its possession, in the past-tense. I brought up linguistics because when you start naming your &lt;code&gt;Msg&lt;/code&gt;s (etc) in this way, it allows you to shift your thinking ever-so-slightly in a way that makes it a &lt;em&gt;lot&lt;/em&gt; easier to reason about your application, its state, and why its behavior may or may not be as expected.&lt;/p&gt;

&lt;p&gt;In conclusion, conclusions are hard and I could spill another thousand more keystrokes without actually adding anything else of substance to this post, so I'll stop now. If you're still here: thanks for reading along. If this helped you: there's lots more where this came from. Be sure to tune in next time (probably) for (a lot) more&lt;sup id="fnref7"&gt;7&lt;/sup&gt;.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;The short version is, "I needed to learn Javascript but &lt;em&gt;I really didn't want to do that thing&lt;/em&gt;" ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Are you supposed to capitalize "Internet"? I tried it both ways. Both feel weird. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Politician%27s_syllogism"&gt;https://en.wikipedia.org/wiki/Politician%27s_syllogism&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html"&gt;https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html&lt;/a&gt; (talk about an evergreen blogpost) ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;The structure and interpretation of computer programs is, at its core, the structure and interpretation of &lt;em&gt;a bunch of thoughts&lt;/em&gt;, both yours and those of others. Language enables thought and gives rise to consciousness; the structure and interpretation of computer programs is the structure and interpretation of &lt;em&gt;thought&lt;/em&gt;, which is the structure and interpretation of &lt;em&gt;language&lt;/em&gt;. Mind that I'm above my pay grade talking about these things, so whether you agree with me or not, go learn about them for yourself; and then it won't matter if I'm right - &lt;em&gt;you&lt;/em&gt; will know. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=zFl6p4D59AA"&gt;https://www.youtube.com/watch?v=zFl6p4D59AA&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;And if this made you mad, @ me in the Elm Slack. Maybe calm down a little first, though. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

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