--- title: Functional Product Development with Elm tags: presentation slideOptions: theme: blood spotlight: enabled: true transition: 'convex' parallaxBackgroundImage: 'https://i.imgur.com/yQg1wtm.jpg' allottedMinutes: 30 --- #### Functional Product Development with Elm > Functional programming > solves many problems > facing developers > today --- ### About Søren Skovsbøll tech lead data visualization team Falcon LogScale (formerly Humio) @skovsboll on twitter --- ### Falcon LogScale Super fast · time series · data lake Record 1000 TB ingested in a single day "Log everything. Answer everything in real time" **312.000** lines of **Elm** 550.000 lines of Scala --- ![](https://i.imgur.com/ZlF1v53.png) --- ![](https://i.imgur.com/EFu6W40.png) --- ### Languages I've used professionally Turbo Pascal C# Objective-C Ruby Javascript Typescript Elm ...and a lot more, just for fun --- ### My journey through paradigms imperative object oriented functional --- ### Objection, your honor It's a toy language Only for scientists How can you get work done if side effects are forbidden? --- ### Elm * inspired by Haskell, written in Haskell * built for web development * a small language --- ```elm= update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (String.fromInt model) ] , button [ onClick Increment ] [ text "+" ] ] ``` --- ### Elm has most (important) functional language features algebraic types recursion with tail call optimization pattern matching side effects under control partial application --- ### But many Haskell / Elixir features are missing list comprehensions custom typeclasses & deriving guards macros --- ### Why choose Elm over more powerful languages? Built for web Friendly error messages Great tooling --- ### Why choose Elm over TypeScript? No runtime errors Reliable refactoring --- ### Why choose Elm over React or VueJS? Speed - beats the competition in render speed Managing state at scale - truly immutable data --- ### What does code look like in the industry? big messy many developers packages --- ### What does code look like in the industry? split teams with different focus deadlines bugs (15 - 50 bugs per 1000 lines) adversaries looking for attack surfaces --- ### Elm Fast feedback loop _Demo hot code reloading!_ --- ### Modelling with types ```elm type Authentication = LDAP | Auth0 Auth0Config | OAuth OAuthProviderConfig | NoAuth | ByProxy | SAML ``` --- ### Modelling with types ```typescript interface Authentication { type: 'LDAP' | 'Auth0' | 'OAuth' | 'NoAuth' | 'ByProxy' | 'SAML', oAuthConfig: OAuthProviderConfig | null, auth0Config: Auth0Config | null } ``` --- ### Elm Friendly Error Messages ```elm find : (a -> Bool) -> List a -> Maybe a find predicate l = case l of x :: xs -> if predicate x then x else find predicate xs [] -> Nothing ``` --- ### Elm Friendly Error Messages ![](https://i.imgur.com/6YemoIK.png) --- ### Elm Friendly Error Messages ```elm find : (a -> Bool) -> List a -> Maybe a find predicate l = case l of x :: xs -> if predicate x then Just x else find predicate xs [] -> Nothing ``` --- ### Elm Friendly Error Messages ![](https://i.imgur.com/rZzJBGT.png) --- ### Elm Safe Refactorings Code grows over time Price of changing increases --- ### Elm Safe Refactorings ![](https://i.imgur.com/zfaGPkD.png) --- ### Elm Security NPM injection attacks Can you read the code and find security holes? --- ### Functional makes it safer Side effects isolated to `Task`, `Sub` and `Cmd` --- ### Elm Security ```elm update : Msg -> Model -> ( Model, Cmd Msg ) ... ... ( model , updateOrganizationInfo apiClient model.newValues |> Task.attempt OrgDetailsSaved ) ``` --- ### Examples from LogScale source: Recursion Functors Monads --- ### Elm Recursion ![](https://i.imgur.com/ZlF1v53.png) --- ### Elm Recursion ![](https://i.imgur.com/Hm6TBxe.png) --- ### Elm Recursion ```elm guessWidgetType : QueryResult -> WidgetType guessWidgetType queryResult = WidgetView.widgetsInOrderOfSpecificToGeneral |> ListUtil.find (\widget -> canChoose widget queryResult ) |> Maybe.withDefault Viz.Table ``` --- ### Elm Recursion ```elm find : (a -> Bool) -> List a -> Maybe a find predicate l = case l of x :: xs -> if predicate x then Just x else find predicate xs [] -> Nothing ``` --- ### Recursion Used in everyday tasks Not scary Tooling will help keep it safe (tail call optimization) --- ### Elm Functors ![](https://i.imgur.com/Hm6TBxe.png) --- ### Elm Functors ```elm map : (a -> b) -> List a -> List b ``` --- ### Elm Functors ```elm ListBox.withItems (List.map (\widgetOption -> ListBox.initItemWithIcon { id = listBoxId widgetOption , value = widgetOption , label = listBoxText widgetOption , icon = toIcon widgetOption } |> ListBox.itemWithSubLabel (compatibilityString widgetOption) ) options ) ``` --- ### Elm Functors ```elm ListBox.withItems (List.map (\widgetOption -> ... ) options ) ``` --- ### Elm Functors Transform data elegantly every day Are not scary The type system makes it safe --- ### And now... ## A monad --- ### Scheduled Search ![](https://i.imgur.com/fsVy6NW.png) --- ### Crontab expressions :::info `* * * * *` _Every minute_ ::: :::info `0 12 * * *` _At the stroke of 12_ ::: --- ### Add Crazy :::info `*/15 12-18 * * *` _Every 15th minute past 12 through 18_ ::: :::info `30 * * * 6,7` _At 30 minutes past every hour, on Saturdays and Sundays_ ::: --- ### Parser Monad Can succeed, returning what you ask for – Or – Can fail, returning error details --- ### Parsing crontab atoms ```elm type Atom a = Particle a | Range a a ``` --- ```elm atom : Parser a -> Comparer a -> Parser (Atom a) atom parser comparer = Parser.oneOf [ rangeAtom parser , singleAtom parser ] |> Parser.andThen (checkRange comparer) ``` --- ### Parsing crontab atoms ```elm singleAtom : Parser a -> Parser (Atom a) singleAtom parser = Parser.map Particle parser rangeAtom : Parser a -> Parser (Atom a) rangeAtom parser = Parser.succeed Range |= backtrackable parser |. Parser.symbol "-" |= parser ``` --- ### Parsing is easier with functional languages Make impossible states impossible The parser is type checked --- ### Problems we look outside Elm for solving Boiler plate Understanding a large code base Super-optimizing performance --- > Functional programming > solves many problems > facing developers > today But which problems? --- ### Solving small problems Modelling with types Recursion Functors Monads --- ### Solving large scale problems Eliminating run time errors Increasing complexity over time Fast feedback Learnability --- While many modern languages try to be everything to everyone (multi-paradigm), Elm restrains us to a small subset. --- ### Thank you! More info https://elm-lang.org https://crowdstrike.com --- #### Functional Product Development with Elm > Function solves most problems with which developers struggle