{"id":17856,"date":"2019-07-24T10:30:05","date_gmt":"2019-07-24T15:30:05","guid":{"rendered":"https:\/\/keyholesoftware.com\/?p=17856"},"modified":"2025-01-28T12:56:15","modified_gmt":"2025-01-28T18:56:15","slug":"elm-language","status":"publish","type":"post","link":"https:\/\/keyholesoftware.com\/elm-language\/","title":{"rendered":"Elm Language"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_81 ez-toc-wrap-left counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title ez-toc-toggle\" style=\"cursor:pointer\">Page Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Why\" >Why<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Elm\" >Elm<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Development_Environment\" >Development Environment<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Modules\" >Modules<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Type_Information\" >Type Information<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Function_Signature\" >Function Signature<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#HTML_View\" >HTML View<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Reduced_Example\" >Reduced Example<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Interoperating_with_JavaScript\" >Interoperating with JavaScript<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Realistic_Example\" >Realistic Example<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Impressions\" >Impressions<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Cons\" >Cons<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Pros\" >Pros<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#Wrap\" >Wrap<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/keyholesoftware.com\/elm-language\/#References\" >References<\/a><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<div class=\"juiz-outdated-message jodpm-top\">Attention: This article was published over 7 years ago, and the information provided may be aged or outdated. While some topics are evergreen, technology moves fast, so please keep that in mind as you read the post.<\/div><p>This blog is about my dalliance with Elm; a purely functional, statically-typed language that has type inference. It compiles to JavaScript. Functional programming is compelling, but heretofore, I\u2019d only woven cherry-picked techniques into large object-oriented projects. In Functional Programming parlance, I\u2019m partially applied! The times, they are a-changin\u2019.<\/p>\n<p>In this article, I\u2019ll:<\/p>\n<ul>\n<li>touch on the reasoning for giving a nod to functional languages and data immutability;<\/li>\n<li>move on to Elm; a blazing-fast, statically typed, purely functional browser-side language that compiles to JavaScript and follows the principles of functional reactive programming;<\/li>\n<li>survey background items and the Elm environment;<\/li>\n<li>show a simple type-and-click application, followed by a more realistic To-do application;<\/li>\n<li>end with my impressions from functional-programming semi-outsider point-of-view.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Why\"><\/span>Why<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Nowadays, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Moore%27s_law\" target=\"_blank\" rel=\"noopener noreferrer\">Moore\u2019s Law<\/a> manifests by increasing CPU cores, not by doubling core speed. That compels us to exploit increased hardware potential via an altered coding approach. Immutable data combined with pure first-class functions help us to manage fragile state across multiple CPU cores.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Elm\"><\/span>Elm<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Enter <a href=\"https:\/\/elm-lang.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Elm<\/a>, a browser client language. It resembles a subset of Haskell, a pure functional language: really, really pure. Haskell compiles to a native executable. Elm compiles to JavaScript that targets a browser. Previous Haskell play helped me learn Elm, while Elm, in turn, increased my Haskell knowledge.<\/p>\n<p>Elm\u2019s application space is a single-page application. This is the realm of React, Vue, or Angular. Elm can call or be called by JavaScript as well. We could restrict the use of Elm to a part of a page, a project, or a migration. Like Haskell, Elm code, when compiled error-free, cannot cause runtime exceptions. Sure, that does not guarantee that program logic is correct, but sane typing mitigates issues in seeking correct logic. To aid in diagnosing compilation issues, Elm produces the most-helpful error messages that I\u2019ve seen in any language.<\/p>\n<p>DOM manipulation is a cycle-eating hotspot in SPA code. Elm minimizes DOM manipulation as does React, and modern Vue or Angular. These ignore unnecessary DOM changes by means of shadow DOM diffing. Surprisingly, Elm renders significantly faster than that competition. See <a href=\"https:\/\/elm-lang.org\/blog\/blazing-fast-html-round-two\">https:\/\/elm-lang.org\/blog\/blazing-fast-html-round-two<\/a>.<\/p>\n<p>Older SPAs often maintained state in the DOM: \u201cdisable that input field if this radio button is set.\u201d That approach is bad due to the DOM performance issue, and worse, because it mixes concerns of rendering with state.<\/p>\n<p>Instead, Elm reacts to model changes, rendering DOM elements accordingly.<\/p>\n<p>An Elm application\u2019s state resides in an immutable model record. When view code emits an event (e.g. user clicks a button), the Elm runtime fields the event, passing it to a stipulated update function. The update function may construct a new model from the current model using information from the event. The new model is the return value to the runtime.<\/p>\n<p>The runtime internally carries out any model replacement by limiting replacement to isolated structural parts of the input model. This structural mode of replacement is the usual approach in immutability implementations.<\/p>\n<p>At this point, the runtime calls a configured view function. The view renders a new DOM based upon model state, by using the DOM delta approach mentioned earlier. Elm does not use a template language for rendering but instead uses a composition of pure functions to create HTML elements, attributes, text, and contained elements.<\/p>\n<p>After rendering, the runtime sleeps, awaiting another external event. At each event, a new generation of the application model circulates at each interaction between view code and update code, as shown in this figure below:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-17859\" src=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/image2-4.png\" alt=\"\" width=\"372\" height=\"276\" srcset=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/image2-4.png 372w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image2-4-300x223.png 300w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image2-4-100x74.png 100w\" sizes=\"(max-width: 372px) 100vw, 372px\" \/><\/p>\n<p>That is the Elm run cycle.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Development_Environment\"><\/span>Development Environment<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You can develop for Elm on Linux, Mac OS, or Windows \u2013 anywhere you can edit a text file and execute the development commands:<\/p>\n<ul>\n<li><code>elm repl<\/code> \u2013 interact with Elm expressions on a command line<\/li>\n<li><code>elm make<\/code> \u2013 most-general way to compile an Elm project to either JavaScript or to HTML<\/li>\n<li><code>elm reactor<\/code> \u2013 browser-based development environment, doc, and test server<\/li>\n<li><code>elm install<\/code> \u2013 adds https:\/\/package.elm-lang.org\/ dependencies to elm.json (think: npm and package.json)<\/li>\n<\/ul>\n<p>Run <code>elm help<\/code> to receive help that is amazingly helpful.<\/p>\n<p>The <code>elm.json<\/code> project file declares the location of test and application source files, the version of the Elm environment, and any included library dependencies.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{\r\n    &quot;type&quot;: &quot;application&quot;,\r\n    &quot;source-directories&quot;: &#x5B;\r\n        &quot;src&quot;\r\n    ],\r\n    &quot;elm-version&quot;: &quot;0.19.0&quot;,\r\n    &quot;dependencies&quot;: {\r\n        &quot;direct&quot;: {\r\n            &quot;elm\/browser&quot;: &quot;1.0.1&quot;,\r\n            &quot;elm\/core&quot;: &quot;1.0.2&quot;,\r\n            &quot;elm\/html&quot;: &quot;1.0.0&quot;\r\n        },\r\n        &quot;indirect&quot;: {\r\n            &quot;elm\/json&quot;: &quot;1.1.3&quot;,\r\n            &quot;elm\/time&quot;: &quot;1.0.0&quot;,\r\n            &quot;elm\/url&quot;: &quot;1.0.0&quot;,\r\n            &quot;elm\/virtual-dom&quot;: &quot;1.0.2&quot;\r\n        }\r\n    },\r\n    &quot;test-dependencies&quot;: {\r\n        &quot;direct&quot;: {},\r\n        &quot;indirect&quot;: {}\r\n    }\r\n}\r\n<\/pre>\n<p>I used WebStorm IDE with an Elm plugin because I already had WebStorm. Any type violations received red underlines, and when I repaired a type flow, the red lines disappeared. Successfully compiled code will never throw an exception; code having type issues refuses to execute.<\/p>\n<p>A good text editor, such as Sublime 3 or Atom, along with an Elm plugin, is an alternative to an IDE. Issue Elm commands to carry out compilation instantly.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Modules\"><\/span>Modules<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Elm is a functional language having pure first-class functions. A first-class function can take a function as input data or return a function in result data.<\/p>\n<p>An object can hold state, but a pure function cannot. Elm has no objects. An Elm module\u2019s state resides in that immutable model we showed earlier, never in any function. At each external event, the designated Elm update function creates a new model from the old model and message data. If we wanted to make a component-like entity per page in Elm, we could use an Elm module per page.<\/p>\n<p>Elm application developers use such modules to help grow a program in a sane manner. An idiomatic page module\u2019s non-library code resides in a single text file. We segregate consecutive init, update, and view sections under header comments in the file. For an accepted source layout, see <a href=\"https:\/\/guide.elm-lang.org\/webapps\/structure.html\">https:\/\/guide.elm-lang.org\/webapps\/structure.html<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Type_Information\"><\/span>Type Information<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Refer to <a href=\"https:\/\/guide.elm-lang.org\/core_language.html\">https:\/\/guide.elm-lang.org\/core_language.html<\/a> to learn about basic Elm syntax. Notice that type information appears last in a definition, not first, contrary to Java, JavaScript, or C. This allows trailing explicit type information to possibly be omitted. Elm is strongly typed, but Elm\u2019s type analysis can often infer the type from flow analysis. I\u2019ve found that designing code for Elm is first about getting a type flow arranged.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Function_Signature\"><\/span>Function Signature<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A function declaration consists of a function name (think verb) followed by zero or more arguments (think nouns). The arguments\u2019 separator is -&gt;. The final item is the required return type.<\/p>\n<p>Elm functions actually take only one argument internally! Elm internally composes a source function by applying arguments one-by-one, returning a new function at each application except the final step. This single-argument partial application is called currying. A call to a multi-argument Elm function compiles to a composition of curried functions. Reference: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Currying\">https:\/\/en.wikipedia.org\/wiki\/Currying<\/a>.<\/p>\n<p>Here\u2019s a contrived double-argument Elm function declaration:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nconcatenate: String -&gt; String -&gt; String\r\n<\/pre>\n<p>Its corresponding function definition has an = that delimits the body that creates the functional result. An Elm function\u2019s result is the value of its final expression.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nconcatenate stringA stringB = stringA ++ stringB\r\n<\/pre>\n<p>The optional type declaration normally precedes the declaration on a line above the declaration. Here\u2019s an operational function signature and definition from my TODO application:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngenerateKey : Seq -&gt; TodoKey\r\ngenerateKey seq =\r\n    &quot;td&quot; ++ String.fromInt seq\r\n<\/pre>\n<p>The function returns a string that is a function of an input sequence integer.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"HTML_View\"><\/span>HTML View<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Elm carries out View rendering through an HTML library that creates each desired element from a function taking parameters for attributes, events, and content. A render function for an HTML element expects an attribute array parameter and a content array parameter. For example, the following represents an HTML <code>div<\/code> that has no attributes, signified by the empty array first argument.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndiv &#x5B;] &#x5B; text (renderText model) ]\r\n<\/pre>\n<p>It has a content array second argument consisting of a text function that takes a <code>renderText<\/code> function argument that takes a model argument. This shows first-class functions in practice. Note that content could have been another render element function instead.<\/p>\n<p>The following is a button having an <code>onClick<\/code> attribute that sends a reset message:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbutton &#x5B; onClick Reset ] &#x5B; text &quot;Reset&quot; ]\r\n<\/pre>\n<p>See the <strong>simple example<\/strong> source in the next section, for a small complete view rendering example.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Reduced_Example\"><\/span>Reduced Example<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This typical Elm Hello World echoes a field input to text and can reset the input via a button click. This is a screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-17858\" src=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/image3-3.png\" alt=\"\" width=\"744\" height=\"680\" srcset=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/image3-3.png 744w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image3-3-300x274.png 300w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image3-3-100x91.png 100w\" sizes=\"(max-width: 744px) 100vw, 744px\" \/><\/p>\n<p>Refer to the source below. The main is the entry function that declares defines the names of the <code>init<\/code>, <code>update<\/code>, and <code>view<\/code> functions that handle the model in the runtime cycle. I used an Elm custom type to define a <code>Model<\/code> custom type. It is simply a <code>String<\/code> in this case. A <code>Msg<\/code> type defines the type of message used to communicate model change requests.<\/p>\n<h6>Simple Example Source<\/h6>\n<p>To run it:<\/p>\n<ol>\n<li>Ensure that Elm infrastructure is installed: <a href=\"https:\/\/guide.elm-lang.org\/install.html\">https:\/\/guide.elm-lang.org\/install.html<\/a><\/li>\n<li>clone the project repo <a href=\"https:\/\/guide.elm-lang.org\/install.html\">https:\/\/guide.elm-lang.org\/install.html<\/a><\/li>\n<li>build <code>.\/index.html<\/code> using the elm command: <code>elm make src\/Main.elm<\/code><\/li>\n<li><code><\/code>open <code>.\/index.html<\/code> in a browser.<\/li>\n<\/ol>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nmodule Main exposing (..)\r\n\r\nimport Browser\r\nimport Html exposing (Html, Attribute, div, input, text, button, br)\r\nimport Html.Attributes exposing (..)\r\nimport Html.Events exposing (onInput, onClick)\r\n\r\n-- MAIN\r\n\r\n\r\nmain =\r\n  Browser.sandbox { init = init, update = update, view = view }\r\n\r\n\r\n-- MODEL\r\n\r\n\r\ntype alias Model =\r\n  { content : String\r\n  }\r\n\r\n\r\ninit : Model\r\ninit =\r\n  { content = &quot;&quot; }\r\n\r\n\r\n-- UPDATE\r\n\r\n\r\ntype Msg\r\n  = Change String\r\n  | Reset\r\n\r\n\r\nupdate : Msg -&gt; Model -&gt; Model\r\nupdate msg model =\r\n  case msg of\r\n\r\n    Change newContent -&gt;\r\n        { model | content = newContent }\r\n\r\n    Reset  -&gt;\r\n        { model | content = &quot;&quot; }\r\n\r\n\r\n\r\n-- VIEW\r\n\r\nrenderText : Model -&gt; String\r\nrenderText model =\r\n    if String.isEmpty model.content\r\n    then &quot;&quot;\r\n    else &quot;Hello, &quot; ++ model.content ++ &quot;!&quot;\r\n\r\n\r\nrootStyle : Attribute msg\r\nrootStyle =\r\n    attribute\r\n        &quot;style&quot;\r\n        &quot;background-color: #eeeeee; width: 10rem; padding: 2rem; margin: 4rem; border: solid 1px black&quot;\r\n\r\n\r\nview : Model -&gt; Html Msg\r\nview model =\r\n  div &#x5B; rootStyle ]\r\n    &#x5B; div &#x5B;] &#x5B; text (renderText model) ]\r\n    , br &#x5B;] &#x5B;]\r\n    , input &#x5B; placeholder &quot;Enter text&quot;, value model.content, onInput Change, size 13, maxlength 12, autofocus True] &#x5B;]\r\n    , br &#x5B;] &#x5B;]\r\n    , br &#x5B;] &#x5B;]\r\n    , button &#x5B; onClick Reset ] &#x5B; text &quot;Reset&quot; ]\r\n    ]\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Interoperating_with_JavaScript\"><\/span>Interoperating with JavaScript<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We invoke compiled Elm via a native JavaScript calling routine. For example, the <code>&lt; script &gt; <\/code> block below calls Elm-compiled JavaScript that was loaded in a previous <code> &lt; script &gt; <\/code> block. The example entry function is <code>Elm.Main.init<\/code> because I named the source Elm module <code>Main<\/code> and I named its entry function <code>init<\/code>. Look at the init function\u2019s object parameter. Its <code>node<\/code> key names a DOM element that receives the Elm view rendered DOM subtree. But what is that <code>flags<\/code> key?<\/p>\n<h6>JavaScript Elm invoker<\/h6>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&lt; script &gt;\r\n    const storeName = 'cache';\r\n    const cache = JSON.parse(localStorage.getItem(storeName));\r\n\r\n    const app = Elm.Main.init({\r\n        node: document.getElementById('app'),\r\n        flags: cache\r\n    });\r\n\r\n    app.ports.cache.subscribe(function(data) {\r\n        localStorage.setItem(storeName, JSON.stringify(data));\r\n    });\r\n\r\n&lt; \/ script &gt;\r\n<\/pre>\n<p>Elm has two optional points of integration with its invoking JavaScript: <code>flags<\/code> and <code>ports<\/code>. The <code>flags<\/code> are a means to pass a value to the Elm program during its initialization. The <code>ports<\/code> are a single-direction asynchronous message-passing mechanism between JavaScript and Elm. To pass messages in both directions, use two ports. Refer to <a href=\"https:\/\/guide.elm-lang.org\/interop\/ports.html\">https:\/\/guide.elm-lang.org\/interop\/ports.html<\/a> for flags and ports. The asynchronous message-passing nature of ports provides a barrier to external JavaScript code causing a runtime exception in Elm code.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Realistic_Example\"><\/span>Realistic Example<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If you expected an example TODO application as a realistic CRUD example, then here it is: <a href=\"https:\/\/github.com\/mauget\/elm-todo.git\">https:\/\/github.com\/mauget\/elm-todo.git<\/a>.<\/p>\n<p>It uses browser local storage to cache the model. I used flags and an inbound port to cache the model under the direction of my Elm code. The signature of the Elm side of the port looks like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\tport cache : Maybe Model -&gt; Cmd msg\r\n<\/pre>\n<p>Recall the JavaScript Elm <code>init<\/code> call shown previously? When Elm code invokes that cache function, the result is a <code>Cmd<\/code> message that causes a call to that JavaScript subscribe listener repeated here:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\napp.ports.cache.subscribe(function(data) {\r\n    localStorage.setItem(storeName, JSON.stringify(data));\r\n});\r\n<\/pre>\n<p>The remainder of the TODO program is an idiomatic Elm module that runs the Elm update\/view loop we discussed. A bit of page-loaded CSS provides layout and gingerbread. Refer to the source on GitHub, along with the Elm official guide <a href=\"https:\/\/guide.elm-lang.org\/\">https:\/\/guide.elm-lang.org\/<\/a>.<\/p>\n<p>To run:<\/p>\n<ol>\n<li>Ensure that Elm infrastructure is installed: <a href=\"https:\/\/guide.elm-lang.org\/install.html\">https:\/\/guide.elm-lang.org\/install.html<\/a><\/li>\n<li>Clone the repo from <a href=\"https:\/\/github.com\/mauget\/elm-todo.git\">https:\/\/github.com\/mauget\/elm-todo.git <\/a><\/li>\n<li>Compile <code>Main.elm<\/code> to elm.js using a command from the project root:<code>elm make src\/Main.elm --output=elm.js<\/code><\/li>\n<li><code><\/code>Open <code>.\/index.html<\/code> in a browser; no server needed for this application<\/li>\n<\/ol>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-17857\" src=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2.png\" alt=\"\" width=\"1600\" height=\"843\" srcset=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2.png 1600w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2-300x158.png 300w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2-768x405.png 768w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2-1024x540.png 1024w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2-100x53.png 100w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2-862x454.png 862w, https:\/\/keyholesoftware.com\/wp-content\/uploads\/image4-2-1200x632.png 1200w\" sizes=\"(max-width: 1600px) 100vw, 1600px\" \/><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Impressions\"><\/span>Impressions<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The following are my takeaways from playing with Elm. Notice that some cons and pros are at odds, like opposing sides of that old double-sided sword&#8230;<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Cons\"><\/span>Cons<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<ul>\n<li>Strong typing feels like interference at times<\/li>\n<li>Elm community and ecosystem is thin<\/li>\n<li>Talent hiring pool seems small<\/li>\n<li>Coding HTML from functions feels like coding HTML from servlets<\/li>\n<li>New features seem slow to emerge due to the slow pace of releases<\/li>\n<li>Elm is a SPA language only<\/li>\n<\/ul>\n<h4><span class=\"ez-toc-section\" id=\"Pros\"><\/span>Pros<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<ul>\n<li>Strong typing reduces unit test numbers<\/li>\n<li>Immutability + Strong typing + pure first-class functions == crash-proof<\/li>\n<li>Pure functions are easy to confidently test<\/li>\n<li>Newbie-friendly<\/li>\n<li>Fast compiler<\/li>\n<li>The most-helpful compiler messages ever<\/li>\n<li>Workable for a small part of an application or page<\/li>\n<li>Asynchronous JavaScript ports are a crash barrier<\/li>\n<li>Slow thoughtful pace of releases with few breaking changes (compare Node.js)<\/li>\n<li>Blazing fast DOM updates<\/li>\n<li>Elm community is warm and welcoming<\/li>\n<li>Immutable collection contents are also immutable (compare Immutable.js)<\/li>\n<li>Elm is a SPA language only<\/li>\n<\/ul>\n<p>Would I pick Elm if I were an architect who had to choose a language or framework for a SPA application? I would, provided that I could find Elm talent for the project. I\u2019d have to consider both development and future maintenance. I reason that maintenance would consist more of features and less of defects because the compiler and ease of unit testing could short-circuit many future bugs.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Wrap\"><\/span>Wrap<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We\u2026<\/p>\n<ul>\n<li>looked at Elm, a fast, statically typed, purely functional browser-side language that compiles to JavaScript;<\/li>\n<li>reasoned about the need for a language having characteristics of immutability, strong typing, and first-class pure functions;<\/li>\n<li>carried out a coarse overview of the characteristics of Elm, providing references for a deeper dive;<\/li>\n<li>showed a minimal interactive application that exercises the Elm model flow, followed by a more realistic TODO application;<\/li>\n<li>presented subjective impressions of Elm.<\/li>\n<\/ul>\n<h4><span class=\"ez-toc-section\" id=\"References\"><\/span>References<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Elm Official Guide: <a href=\"https:\/\/guide.elm-lang.org\/\">https:\/\/guide.elm-lang.org\/<\/a><br \/>\nElm Packages: <a href=\"https:\/\/package.elm-lang.org\">https:\/\/package.elm-lang.org<\/a><br \/>\nPublic Domain Logo: <a href=\"https:\/\/commons.wikimedia.org\/w\/index.php?curid=51314022\">https:\/\/commons.wikimedia.org\/w\/index.php?curid=51314022<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog is about my dalliance with Elm; a purely functional, statically typed language that has type inference. It compiles to JavaScript. Functional programming is compelling, but heretofore, I\u2019d only woven cherry-picked techniques into large object-oriented projects. In FP parlance, I\u2019m partially applied! The times, they are a-changin\u2019.<\/p>\n<p>In this article, I\u2019ll:<br \/>\n&#8211; touch on the reasoning for giving a nod to functional languages and data immutability;<br \/>\n&#8211; move on to Elm; a blazing-fast, statically typed, purely functional browser-side language that compiles to JavaScript and follows the principles of functional reactive programming;<br \/>\n&#8211; survey background items and the Elm environment;<br \/>\n&#8211; show a simple type-and-click application, followed by a more realistic To-do application;<br \/>\n&#8211; end with my impressions from functional-programming semi-outsider point-of-view.<\/p>\n","protected":false},"author":16,"featured_media":17959,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[2241,13,118,247,624],"tags":[1221,586,176,357],"class_list":["post-17856","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-articles","category-dev-tools","category-javascript","category-general-programming","category-single-page-application","tag-elm","tag-javascript","tag-programming","tag-spa"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.1 (Yoast SEO v27.1.1) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Elm Language<\/title>\n<meta name=\"description\" content=\"Overview of Elm, a purely functional, statically typed language that has type inference and compiles to JavaScript.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/keyholesoftware.com\/elm-language\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Elm Language\" \/>\n<meta property=\"og:description\" content=\"This blog is about my dalliance with Elm; a purely functional, statically typed language that has type inference. It compiles to JavaScript. Functional programming is compelling, but heretofore, I\u2019d only woven cherry-picked techniques into large object-oriented projects. In FP parlance, I\u2019m partially applied! The times, they are a-changin\u2019.  In this article, I\u2019ll: - touch on the reasoning for giving a nod to functional languages and data immutability; - move on to Elm; a blazing-fast, statically typed, purely functional browser-side language that compiles to JavaScript and follows the principles of functional reactive programming; - survey background items and the Elm environment; - show a simple type-and-click application, followed by a more realistic To-do application; - end with my impressions from functional-programming semi-outsider point-of-view.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/keyholesoftware.com\/elm-language\/\" \/>\n<meta property=\"og:site_name\" content=\"Keyhole Software\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/KeyholeSoftware\/\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-24T15:30:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-28T18:56:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lou Mauget\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@KeyholeSoftware\" \/>\n<meta name=\"twitter:site\" content=\"@KeyholeSoftware\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lou Mauget\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/\"},\"author\":{\"name\":\"Lou Mauget\",\"@id\":\"https:\/\/keyholesoftware.com\/#\/schema\/person\/c39f813353ffbd4102e56df719a5b6b7\"},\"headline\":\"Elm Language\",\"datePublished\":\"2019-07-24T15:30:05+00:00\",\"dateModified\":\"2025-01-28T18:56:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/\"},\"wordCount\":2438,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/keyholesoftware.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png\",\"keywords\":[\"Elm\",\"JavaScript\",\"Programming\",\"SPA\"],\"articleSection\":[\"Articles\",\"Development Technologies &amp; Tools\",\"JavaScript\",\"Programming\",\"Single-Page Application\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/keyholesoftware.com\/elm-language\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/\",\"url\":\"https:\/\/keyholesoftware.com\/elm-language\/\",\"name\":\"Elm Language\",\"isPartOf\":{\"@id\":\"https:\/\/keyholesoftware.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png\",\"datePublished\":\"2019-07-24T15:30:05+00:00\",\"dateModified\":\"2025-01-28T18:56:15+00:00\",\"description\":\"Overview of Elm, a purely functional, statically typed language that has type inference and compiles to JavaScript.\",\"breadcrumb\":{\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/keyholesoftware.com\/elm-language\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage\",\"url\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png\",\"contentUrl\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png\",\"width\":1024,\"height\":512},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/keyholesoftware.com\/elm-language\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/keyholesoftware.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Elm Language\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/keyholesoftware.com\/#website\",\"url\":\"https:\/\/keyholesoftware.com\/\",\"name\":\"Keyhole Software\",\"description\":\"Quality Consulting. Knowledge Transfer.\",\"publisher\":{\"@id\":\"https:\/\/keyholesoftware.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/keyholesoftware.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/keyholesoftware.com\/#organization\",\"name\":\"Keyhole Software\",\"url\":\"https:\/\/keyholesoftware.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/keyholesoftware.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/2011\/12\/keyholelogo.png\",\"contentUrl\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/2011\/12\/keyholelogo.png\",\"width\":300,\"height\":108,\"caption\":\"Keyhole Software\"},\"image\":{\"@id\":\"https:\/\/keyholesoftware.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/KeyholeSoftware\/\",\"https:\/\/x.com\/KeyholeSoftware\",\"https:\/\/www.instagram.com\/keyholesoftware\/\",\"https:\/\/www.linkedin.com\/company\/keyhole-software\/\",\"https:\/\/www.youtube.com\/c\/Keyholesoftware\"],\"email\":\"info@keyholesoftware.com\",\"telephone\":\"877-521-7769\",\"legalName\":\"Keyhole Software LLC\",\"foundingDate\":\"2008-07-01\",\"duns\":\"878190391\",\"naics\":\"541511\",\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"minValue\":\"51\",\"maxValue\":\"200\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/keyholesoftware.com\/#\/schema\/person\/c39f813353ffbd4102e56df719a5b6b7\",\"name\":\"Lou Mauget\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/keyholesoftware.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/loumauget-96x96.jpg\",\"contentUrl\":\"https:\/\/keyholesoftware.com\/wp-content\/uploads\/loumauget-96x96.jpg\",\"caption\":\"Lou Mauget\"},\"description\":\"Known as Ed Mauget in civilian life. Lou is a name imposed by IBM in 1966. Newly infatuated with Microservices Architecture. In 2015 I coded MockOla, a wire-framing tool for Keyhole Software. Have coded in Java since it was conceived. Also worked with C\/C++. Current interests include microservices, Docker, Node JS, NoSQL databases, functional programming, single-page web applications ... any new software languages\/frameworks.\",\"url\":\"https:\/\/keyholesoftware.com\/author\/lmauget\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Elm Language","description":"Overview of Elm, a purely functional, statically typed language that has type inference and compiles to JavaScript.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/keyholesoftware.com\/elm-language\/","og_locale":"en_US","og_type":"article","og_title":"Elm Language","og_description":"This blog is about my dalliance with Elm; a purely functional, statically typed language that has type inference. It compiles to JavaScript. Functional programming is compelling, but heretofore, I\u2019d only woven cherry-picked techniques into large object-oriented projects. In FP parlance, I\u2019m partially applied! The times, they are a-changin\u2019.  In this article, I\u2019ll: - touch on the reasoning for giving a nod to functional languages and data immutability; - move on to Elm; a blazing-fast, statically typed, purely functional browser-side language that compiles to JavaScript and follows the principles of functional reactive programming; - survey background items and the Elm environment; - show a simple type-and-click application, followed by a more realistic To-do application; - end with my impressions from functional-programming semi-outsider point-of-view.","og_url":"https:\/\/keyholesoftware.com\/elm-language\/","og_site_name":"Keyhole Software","article_publisher":"https:\/\/www.facebook.com\/KeyholeSoftware\/","article_published_time":"2019-07-24T15:30:05+00:00","article_modified_time":"2025-01-28T18:56:15+00:00","og_image":[{"width":1024,"height":512,"url":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png","type":"image\/png"}],"author":"Lou Mauget","twitter_card":"summary_large_image","twitter_creator":"@KeyholeSoftware","twitter_site":"@KeyholeSoftware","twitter_misc":{"Written by":"Lou Mauget","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/keyholesoftware.com\/elm-language\/#article","isPartOf":{"@id":"https:\/\/keyholesoftware.com\/elm-language\/"},"author":{"name":"Lou Mauget","@id":"https:\/\/keyholesoftware.com\/#\/schema\/person\/c39f813353ffbd4102e56df719a5b6b7"},"headline":"Elm Language","datePublished":"2019-07-24T15:30:05+00:00","dateModified":"2025-01-28T18:56:15+00:00","mainEntityOfPage":{"@id":"https:\/\/keyholesoftware.com\/elm-language\/"},"wordCount":2438,"commentCount":0,"publisher":{"@id":"https:\/\/keyholesoftware.com\/#organization"},"image":{"@id":"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage"},"thumbnailUrl":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png","keywords":["Elm","JavaScript","Programming","SPA"],"articleSection":["Articles","Development Technologies &amp; Tools","JavaScript","Programming","Single-Page Application"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/keyholesoftware.com\/elm-language\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/keyholesoftware.com\/elm-language\/","url":"https:\/\/keyholesoftware.com\/elm-language\/","name":"Elm Language","isPartOf":{"@id":"https:\/\/keyholesoftware.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage"},"image":{"@id":"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage"},"thumbnailUrl":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png","datePublished":"2019-07-24T15:30:05+00:00","dateModified":"2025-01-28T18:56:15+00:00","description":"Overview of Elm, a purely functional, statically typed language that has type inference and compiles to JavaScript.","breadcrumb":{"@id":"https:\/\/keyholesoftware.com\/elm-language\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/keyholesoftware.com\/elm-language\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/keyholesoftware.com\/elm-language\/#primaryimage","url":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png","contentUrl":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/Add-a-heading.png","width":1024,"height":512},{"@type":"BreadcrumbList","@id":"https:\/\/keyholesoftware.com\/elm-language\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/keyholesoftware.com\/"},{"@type":"ListItem","position":2,"name":"Elm Language"}]},{"@type":"WebSite","@id":"https:\/\/keyholesoftware.com\/#website","url":"https:\/\/keyholesoftware.com\/","name":"Keyhole Software","description":"Quality Consulting. Knowledge Transfer.","publisher":{"@id":"https:\/\/keyholesoftware.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/keyholesoftware.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/keyholesoftware.com\/#organization","name":"Keyhole Software","url":"https:\/\/keyholesoftware.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/keyholesoftware.com\/#\/schema\/logo\/image\/","url":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/2011\/12\/keyholelogo.png","contentUrl":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/2011\/12\/keyholelogo.png","width":300,"height":108,"caption":"Keyhole Software"},"image":{"@id":"https:\/\/keyholesoftware.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/KeyholeSoftware\/","https:\/\/x.com\/KeyholeSoftware","https:\/\/www.instagram.com\/keyholesoftware\/","https:\/\/www.linkedin.com\/company\/keyhole-software\/","https:\/\/www.youtube.com\/c\/Keyholesoftware"],"email":"info@keyholesoftware.com","telephone":"877-521-7769","legalName":"Keyhole Software LLC","foundingDate":"2008-07-01","duns":"878190391","naics":"541511","numberOfEmployees":{"@type":"QuantitativeValue","minValue":"51","maxValue":"200"}},{"@type":"Person","@id":"https:\/\/keyholesoftware.com\/#\/schema\/person\/c39f813353ffbd4102e56df719a5b6b7","name":"Lou Mauget","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/keyholesoftware.com\/#\/schema\/person\/image\/","url":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/loumauget-96x96.jpg","contentUrl":"https:\/\/keyholesoftware.com\/wp-content\/uploads\/loumauget-96x96.jpg","caption":"Lou Mauget"},"description":"Known as Ed Mauget in civilian life. Lou is a name imposed by IBM in 1966. Newly infatuated with Microservices Architecture. In 2015 I coded MockOla, a wire-framing tool for Keyhole Software. Have coded in Java since it was conceived. Also worked with C\/C++. Current interests include microservices, Docker, Node JS, NoSQL databases, functional programming, single-page web applications ... any new software languages\/frameworks.","url":"https:\/\/keyholesoftware.com\/author\/lmauget\/"}]}},"_links":{"self":[{"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/posts\/17856","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/comments?post=17856"}],"version-history":[{"count":0,"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/posts\/17856\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/media\/17959"}],"wp:attachment":[{"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/media?parent=17856"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/categories?post=17856"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/keyholesoftware.com\/wp-json\/wp\/v2\/tags?post=17856"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}