Slide 1

Slide 1 text

Supercharged Web Development With Purescript Functional Conf 2019 Anupam Jain

Slide 2

Slide 2 text

Hi, I’m Anupam Jain.. Functional Programming Web Development User Interfaces! • Work at S&PGlobal on Financial Web Applications • Organise FPNCR Meetup Group https://fpncr.github.io • Wrote Concur UI Library in Purescript (+ Haskell and JS) https://github.com/purescript-concur

Slide 3

Slide 3 text

Prerequisite • git clone https://github.com/ajnsit/purescript-react-starter • npm install • npm run build • npm run start

Slide 4

Slide 4 text

Purescript

Slide 5

Slide 5 text

Modern FP • Pure, Strong Static Types • Type Classes • Higher Kinded Types • Row Types and Records • Effects • Syntactic Niceties • Granular Imports

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Practical • Generates Readable Javascript Code • Excellent Community • Excellent Ecosystem and Tooling • “IDE” Integration • Compiles to Javascript, BEAM, Native • All of Javascript Ecosystem

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Setup From Scratch • npm init • npm install —save-dev purescript spago parcel-bundler • npm install —save react react-dom • npx spago init • npx spago install react react-dom web-html web-dom

Slide 11

Slide 11 text

Tooling NPM Spago Parcel JS Deps PS Deps + Build JS Build

Slide 12

Slide 12 text

NPM - Optional • Installing Purescript Tools • npm install —save-dev purescript spago parcel- bundler • Installing Javascript dependencies • npm install —save react react-dom • Build scripts • npm run start

Slide 13

Slide 13 text

Spago • Purescript Package Manager and Build Tool • spago list-packages • spago install react react-dom • spago repl • spago build --purs-args '-g sourcemaps’ • spago bundle-app —main Main —to bundle.js • spago test SourceMaps!

Slide 14

Slide 14 text

Dhall • Configuration Language for Spago • The programmable, non-repetitive, alternative to YAML • YAML + Functions + Types + Imports • NOT Turing Complete

Slide 15

Slide 15 text

Spago.dhall • { name = “lib1" , dependencies = [ "effect" , "console" , "prelude" ] , sources = [ "src/**/*.purs" ] , packages = ../packages.dhall }

Slide 16

Slide 16 text

Packages.dhall { … , concur-react = { dependencies = [ … ] , repo = "https://github.com/ajnsit/purescript-concur.git" , version = "v0.3.9" } … }

Slide 17

Slide 17 text

Packages.dhall • Specify the package-set (Curated set of Packages that build together) • let upstream = https://.../packages.dhall sha256:f9eb600e5… • Specify package additions and overrides • let overrides = { lib1 = ./lib1/spago.dhall as Location , lib2 = ./lib2/spago.dhall as Location } in upstream // overrides

Slide 18

Slide 18 text

Parcel - Optional • The Zero-Configuration Web Bundler • Dev Server • parcel index.html • Build • parcel build index.html

Slide 19

Slide 19 text

Index.HTML

Slide 20

Slide 20 text

index.JS import Main from “./output/Main"; if (module.hot) { module.hot.accept(function () { console.log('Reloaded, running main again'); main(); }); } main(); HMR Stuff

Slide 21

Slide 21 text

Clojure Compiler - Optional • spago bundle-app --to temp.js • java -jar closure-compiler-v20190301.jar --js temp.js -- js_output_file index.js • parcel build index.html • Only modest improvements with SIMPLE optimisations • Errors with ADVANCED optimisations

Slide 22

Slide 22 text

Hello Purescript module Main where import Data.Unit (Unit) import Effect (Effect) import Effect.Console (log) main :: Effect Unit main = log “Hello World”

Slide 23

Slide 23 text

Hello React import Render (renderComponent) import React (ReactElement) import React.DOM as D mainComponent :: ReactElement mainComponent = D.h1 [ ] [ D.text "Hello world!” ] main :: Effect Unit main = renderComponent mainComponent

Slide 24

Slide 24 text

RenderComponent renderComponent :: ReactElement -> Effect Unit renderComponent component = do window <- DOM.window document <- DOM.document window let node = DOM.toNonElementParentNode document mroot <- DOM.getElementById "main" node case mroot of Nothing -> pure unit Just root -> void (ReactDOM.render component root)

Slide 25

Slide 25 text

Live Code Demo

Slide 26

Slide 26 text

React Element / Class • ReactElement -> DOM • ReactDOM.render • ReactClass -> ReactElement • React.createLeafElement • React.createElement

Slide 27

Slide 27 text

Creating New React Classes • React.component • Spec = ReactThis -> Record { state :: Record State , render :: Effect ReactElement }

Slide 28

Slide 28 text

Importing React Classes from JS • — Foo.js exports.classFoo = require(‘Foo’).default • — Foo.purs foreign import classFoo :: ReactClass { }

Slide 29

Slide 29 text

Live Code With FFI

Slide 30

Slide 30 text

Questions? Thank You!