Nie poznasz, że to JavaScript! [ZOBACZ SLAJDY]namekdev.net/elm-talk/elm-talk.pdf · 1. AngularJS,...
Transcript of Nie poznasz, że to JavaScript! [ZOBACZ SLAJDY]namekdev.net/elm-talk/elm-talk.pdf · 1. AngularJS,...
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 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
Play
Ellie - play with Elm online
runelm.io -
Work
elm-format
atom-elmjutsu
Hardcore
elm-test + elm-html-test
elm-benchmark
elm-oraclerg-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
Community Libsjahweson/elm-graphql
jamesmacaulay/elm-graphql
elm-webgl
elm-plot
elm-ui
elm-mdl - Material Design, mini
dive - Prezi-like (animated) presentations
elm-maps
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
Ques蠈�ons / comments / sugges蠈�ons
about ?
link
rg-dev #12
Ques蠈�ons / comments / sugges蠈�ons
about Elm ?
link
rg-dev #12