nie poznasz, że to javascript! [zobacz slajdy]namekdev.net/elm-talk/elm-talk.pdf · 1. angularjs,...

Post on 28-Jun-2020

7 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Funkcyjny frontendNie poznasz, że to JavaScript!

[ZOBACZ SLAJDY]

rg-dev #12

Who I amKamil Dąbrowski 

prog-polyglot

questioner

www.NamekDev.net

@NamekDev

currently working on ANTS Pro lers (.NET)

rg-dev #12

elm‐lang.orgA delightful language for reliable webapps.“ “

Generate JavaScript with great performanceand no run蠈�me excep蠈�ons.

rg-dev #12

What is Elm?umm

rg-dev #12

What is   ?umm

rg-dev #12

What is   ?

rg-dev #12

What is   ?

rg-dev #12

What is   ?language

rg-dev #12

What is Elm?programming language

designed for web: front-end

pattern / architecture

technology?

React + Redux ‐ JavaScript +   = Elm... so is a part of Elm?

rg-dev #12

a bit of (sad) story

rg-dev #12

no   story this 蠈�me

rg-dev #12

 Played with1. AngularJS, Angular 2

2. Vue.js + Vuex

3. Cycle.js

4. Meteor

 ... and disliked(implementations of) declarativity was a lie

components were a lie

things would crash on run蠈�me(yeah, JS)

rg-dev #12

Failing Run蠈�me? New language!Let's go with something that compiles.

TypeScript - a miserable failure

Dart - small traction

ClojureScript - not really attractive to most people

PureScript - sounds interesting but looks like...Haskell

EVE - too experimental, not stable feature-wise

rg-dev #12

React + Redux is almost like Elmdeclarative

model projected on view

whole model should be global

great feature: run蠈�me errors

because nothing stops your nasty colleagues fromproviding hacks, right? Screw them. Let's use somethingreliable.

Elm rg-dev #12

Elm is more than React + Reduxdeclarative

model projected on view

whole model is global

great feature: no run蠈�me errors

now you're safe, phew!

Why? Because it's strongly-typed and has no null.

rg-dev #12

Who needs JS?

How it feels to learn JavaScript in 2016rg-dev #12

Who needs JS?thing state (psst, what is it?)npm/yarn built in package system

Webpack built in bundler

React built in components + VDOM

Redux built in state mangling

Flux built in architecture

TypeScript or Flow built in types, compiler

Immutable.JS built in feature

rg-dev #12

Who needs JS?thing state (psst, what is it?)

JSDoc built incomment docs ->HTML

ReduxDevTools

built in time travel

JSX just functions HTML-like syntax

undefined unsupported* errors

*Elm has type Maybe = Just value | Nothing

rg-dev #12

rg-dev #12

But hey! About JavaScript...it's OK for prototyping things

rg-dev #12

and...

rg-dev #12

But if you're going to developmodern front‐end webSingle Page Applica蠈�on

then consider using Elm.

rg-dev #12

Hello Worldmodule Main exposing (..)

import Html exposing (Html, text)

main = text "Hello World!!"

"strongly-typed" doesn't mean you need to de ne typeseverywhere.

rg-dev #12

Hello Worldmodule Main exposing (..)

import Html exposing (Html, text)

main : Html msgmain = text "Hello World!!"

"strongly-typed" doesn't mean you need to de ne typeseverywhere.

Compiler will guess that ("type inference").

rg-dev #12

Hello Worldmodule Main exposing (..)

import Html exposing (Html, text)

main : Html msgmain = text "Hello World!!"

text : String -> Html msgtext = VirtualDom.text

rg-dev #12

HTMLdiv [] [ text "hey" ]

or with styling:

div [ style -- style : List (String, String) -> Attribute msg [ ("color", "red") , ("margin", "7px") ] ] [ text "hey" ]

where div is a function!

div : List (Attribute msg) -> List (Html msg) -> Html msgdiv = node "div"

rg-dev #12

attrs : List (Attribute msg)attrs = [ id (cellInputId ref) , classList [ "wowz" => isFocused ] , style [ "background-color" => (isFocused |> either "#ccf" "") ] , onFocus (FocusCell ref) , onBlur (LostCell ref) , onInput (SubmitCell ref) ]

# infix operator(=>) : a -> b -> ( a, b )(=>) = (,)

either : a -> a -> Bool -> aeither valIf valElse cond = if cond then valIf else valElse

rg-dev #12

TEA ‐ The Elm Architecture

input [ onInput SetSearchText ] []

type Msg = SetSearchText String

input [ onInput SetSearchText ] []button [ onClick GoogleIt ] [ "Google it!" ]

type Msg = SetSearchText String | GoogleIt

rg-dev #12

input [ onInput SetSearchText ] []button [ onClick GoogleIt ] [ "Google it!" ]

type Msg = SetSearchText String | GoogleIt

update : Msg -> Model -> Modelupdate msg model = case msg of SetSearchText text -> { model | searchText = text } GoogleIt -> # TODO

rg-dev #12

main = Html.beginnerProgram { init = init , view = view , update = update , subscriptions = subscriptions }

type alias Model = { ... }

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

type Msg = SubmitForm | ClearForm | ...

update : Msg -> Model -> (Model, Cmd Msg)update msg model = ...

view : Model -> Html Msgview model = ...

subscriptions : Model -> Sub Msgsubscriptions model = ...

rg-dev #12

main = Html.beginnerProgram { init = init , view = view , update = update

}

type alias Model = { ... }

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

type Msg = SubmitForm | ClearForm | ...

update : Msg -> Model -> (Model, Cmd Msg)update msg model = ...

view : Model -> Html Msgview model = ...

rg-dev #12

main = Html.beginnerProgram { init = { name = "World" } , view = view , update = update }

view model = div [] [ text ("Hello " ++ model.name) , input [ value model.name, onChange SetName ] [] ]

update msg model = case msg of SetName newName -> { model | name = newName }

type Msg = SetName String

rg-dev #12

DebuggingDebug.log , Debug.crash

message history

Event Sourcing

sadly, no sourcemaps for breakpoints

rg-dev #12

Debugging

rg-dev #12

package.elm‐lang.org

rg-dev #12

Package systempackage.elm-lang.org

elm-package does NOT allow publishing of:

lack of documentation for "exposed functions"

"native" code - JavaScript

But if you don't agree then there are alterna蠈�ves:

elm-github-install

elm-grove - pretty new

rg-dev #12

Enforced Seman蠈�c VersioningNo more surprises in PATCH releases!

rg-dev #12

Documenta蠈�on{-| Represent values that may or may not exist. It can be useful if you have arecord field that is only filled in sometimes. Or if a function takes a valuesometimes, but does not absolutely need it.

-- A person, but maybe we do not know their age. type alias Person = { name : String , age : Maybe Int }

tom = { name = "Tom", age = Just 42 } sue = { name = "Sue", age = Nothing }-}type Maybe a = Just a | Nothing

rg-dev #12

Documenta蠈�on

rg-dev #12

Helpful compiler

rg-dev #12

rg-dev #12

rg-dev #12

Func蠈�onal Paradigm

rg-dev #12

Pure Func蠈�onsrelation between sets

where each input is related to exactly one output.

rg-dev #12

DeterminismStatement vs Expression

Elm does not allow Statements

if someCondition then 10else 14

You won't compile this:

if someCondition then if someCondition2 then 10 else 14-- `if someCondition` is not a full -> if/else expression <-

rg-dev #12

No null, no undefined, no nothing

rg-dev #12

No null?We have some helpful types built into the core library:

type Maybe a = Just a | Nothing model = { name = Just "Jason" , surname = Nothing }

type Result error value = Ok value | Err error -- you may return one of theseret1 = Err "incorrect input expression"ret2 = Ok 42

rg-dev #12

repackTokenToEvalOperation : Token -> EvalOperationrepackTokenToEvalOperation token = case token of TOperator rpnOp -> DoMath rpnOp

TNumber val -> JustValue val

TVariable varName -> GetValue varName

_ -> Debug.crash "sorry, nope, doesn't make sense"

Let's transform it to use Result .

rg-dev #12

repackTokenToEvalOperation : Token -> Result String EvalOperationrepackTokenToEvalOperation token = case token of TOperator rpnOp -> Ok <| DoMath rpnOp

TNumber val -> Ok (JustValue val)

TVariable varName -> GetValue varName |> Ok

_ -> Err "sorry, nope, doesn't make sense"

No runtime errors because we have to match against it:

case repackTokenToEvalOperation token of Ok operation -> -- TODO: ...

Err errorStr -> -- TODO: display it to user

rg-dev #12

Lambda

rg-dev #12

Lambda calculusa function can be a value itself...

also lambda function takes one argument (by default)

add : Int -> Int -> Intadd = \x -> \y -> (+) x y -- more readable form:add = \x -> (\y -> ((+) x y))

or it can be uncurried

add x y = x + y

rg-dev #12

Lambda calculusFunction without an argument looks like a constant!

We can apply only some arguments to a function...

which gives us par蠈�al applica蠈�on

add : Int -> Int -> Intadd x y = x + y

addTo5 : Int -> IntaddTo5 = add 5

-- this evaluates to 12ourResult : IntourResult = addTo5 7

rg-dev #12

OK, Elm, let JavaScript talk to you.Native ("native" LOL )

Ports

For determinism use Ports - send and receive messages.

Native is for stuff which can be deterministic on theJavaScript side.

However, those two kinds of determinism are different:

port may not respond, it's not a callback

Native call is evaluated in the place as it was purefunction

rg-dev #12

 Types 

rg-dev #12

TypesBuilt-in types:

String , Int , Float , Char , Bool

comparable , number

List , Array , Dict

Everything you can de ne is:

records

alias type for record

union type

rg-dev #12

Record{ name = "John", surname = Just "Doe", age = 27, hobbies : ["programming"]}

Elm will gure out it's type:

{ name: String, surname: Maybe String, age: Int, hobbies: List String}

rg-dev #12

Record aliasmodel : { name : String , surname : Maybe String , age : Int , hobbies : List String }model = { name = "John" , surname = Just "Doe" , age = 27 , hobbies = [ "programming" ] }

model : Modelmodel = { name = "John" , surname = Just "Doe" , age = 27 , hobbies = [ "programming" ] }

rg-dev #12

Record aliastype alias Model = { name : String , surname : Maybe String , age : Int , hobbies : List String }

model : Modelmodel = { name = "John" , surname = Just "Doe" , age = 27 , hobbies = [ "programming" ] }

rg-dev #12

We can't add anything into already de ned type

newModel = { model | phone = "+00123456789", address = Nothing }

rg-dev #12

Union Type ‐ more than enumHow Google Search would work:

type Msg = SetSearchText (Maybe String) | SwitchMode SearchMode | GoogleIt | ClearInput type SearchMode = Websites | Images | Maps

Note: union types also behave as func蠈�ons!

SetSearchText takes 1 argument: Maybe String

SwitchMode takes 1 argument: SearchMode (another type)rg-dev #12

Union Type ‐ more than enumupdate : Msg -> Model -> ( Model, Cmd Msg )update msg model = let { grid } = model in case msg of FocusCell cell -> { model | grid = { grid | focusedCell = Just cell } } ! []

LostCell cell -> { model | grid = { grid | focusedCell = Nothing } } ! []

SubmitCell cell text -> model ! []

type Msg = Omg | FocusCell CellRef | LostCell CellRef | SubmitCell CellRef String

rg-dev #12

rg-dev #12

we can use it same way as always: pure CSS, PostCSS,Webpack Sass, w/e

some people use Elm for styling

rg-dev #12

Alterna蠈�ves to default styling1. elm-css by Richard Feldman

2. style-elements by Matthew Grif th

3. elm-stylesheet by Daniel Narey

Addi蠈�onally:

elm-transit - transitions (animations)

elm-css-normalize - normalize.css ported to elm-css

many more

rg-dev #12

default: Elm-Html

button [ style [ ("backgroundColor", "rgb(200,128,64)") , ("position", "absolute") , ("left", "5px") ] ] [ text "Whee!" ]

vs elm‐css

button [ styles [ backgroundColor (rgb 200 128 64) , position absolute , left (px 5) ] ] [ text "Whee!" ]

rg-dev #12

elm‐csstype CssClasses = NavBar | BeautifulText

type CssIds = Page | Header | Footer primaryAccentColor = hex "ccffaa"

removing code causes compilation errors

rg-dev #12

css = (stylesheet << namespace "dreamwriter") [ body [ overflowX auto , minWidth (px 1280) ] , id Page [ backgroundColor (rgb 200 128 64) , color (hex "CCFFFF") , width (pct 100) , height (pct 100) , boxSizing borderBox , padding (px 8) , margin zero ] , class NavBar [ margin zero , padding zero , children [ li [ (display inlineBlock) |> important , color primaryAccentColor ] ] ] ]

rg-dev #12

elm‐css ‐ usageApproach 1: Inline Styles

Approach 2: Generating CSS les

rg-dev #12

Style ElementsLayout vs Styling

type MyStyles = Header

stylesheet = Style.styleSheet [ Style.style Header [ Color.text darkGrey , Color.background white , Font.size 5 ] ]

view = Element.layout stylesheet <| el Title [] (text "Welcome to My Website") -- An `el` is the most basic element, like a <div>

rg-dev #12

elm‐testwipSuite : TestwipSuite = describe "skip, only, and todo" [ only <| describe "`only`this one test will be run!" [ test "This test will be run" <| \_ -> 1 + 1 |> Expect.equal 2 , skip <| test "This test will be skipped" <| \_ -> 2 + 3 |> Expect.equal 4 ] , test "This test will be skipped because it has no only" <| \_ -> "left" |> Expect.equal "right" , todo "Make sure all splines are reticulated" , fuzz string "restores the original string" <| \randomlyGeneratedString -> randomlyGeneratedString |> String.reverse |> String.reverse |> Expect.equal randomlyGeneratedString ]

rg-dev #12

Community http://elm-lang.org/community

Elm Town Podcast

elm-slack

Elm Discuss

elm-dev - people work on Elm

r/elm - reddit

http://elm-news.com/ - reddit + HN + elm-discuss +elm-dev

rg-dev #12

Experimentselchemy backends, Elm -> Elixir

tangram - backends, Elm compiled to Go

take-home - all written in Elm, including database

elm-serverless - HTTP API @ AWS Lambda

elm-electron-todomvc

elm-native-ui - React Native UI

elmx - JSX for Elm

rg-dev #12

Coolness of Elm"when it compiles, it works" aka "no runtime errors"

small amount of syntax

helpful compiler

truly semantic versioning

package diff (wowz)

documentation is so important

seems to be pretty ef cient

Community!

rg-dev #12

Startersdefault elm-make and elm-reactor

create-elm-app with Hot Reloading

elm‐spa‐example - Single Page Apps how-to

elm‐hipster‐stack (I recommend this PR)

Phoenix 1.3 (Elixir)

Elm 0.18

GraphQL

PostgreSQL

webpackrg-dev #12

Startersdrupal-elm-starter

https://github.com/gkubisa/elm-app-boilerplate

https://github.com/elm-community/elm-webpack-starter

https://github.com/simonh1000/elm-fullstack-starter

https://github.com/simonh1000/elm-webpack-starter

rg-dev #12

LearnElmseeds - videos

dwyl/learn elm

elmprogramming.com

Exercism Elm Track

Elm in action - book by Richard Feldman

Tame the frontend with Elm - Fluent Conf 2017 -talks more about syntax

TodoMVC

rg-dev #12

   www.namekdev.net/elm‐talk

rg-dev #12

Ques蠈�ons / comments / sugges蠈�ons

about   ?

link

rg-dev #12

Ques蠈�ons / comments / sugges蠈�ons

about Elm ?

link

rg-dev #12

top related