Mini Workshop - Supercharged Web Development With Purescript

9d46cbdc3830248a0615f14ae4b7b33d?s=47 Anupam
November 15, 2019

Mini Workshop - Supercharged Web Development With Purescript

Mini Workshop presented at Functional Conf 2019 [https://functionalconf.com/].

Purescript is a purely functional, strongly typed language, that compiles to Javascript.

It provides several high quality libraries for frontend development, and comes with excellent tooling and editor support that makes writing code a snap!

In this talk I will provide a quick introduction to some basics of Purescript, and then dive into an interactive demonstration of building a non-trivial web application from scratch. I will show how to interface with React bindings, and how to interface with some existing Javascript libraries (a React UI component lib).

The presentation will be interactive and similar to an inpromptu talk I gave which is linked below. However, I will also demonstrate live coding of an actual purescript application which people can follow along.

Bring your laptop to follow along. Read up on Purescript and initialise a simple project via the template at https://github.com/ajnsit/purescript-react-starter.

9d46cbdc3830248a0615f14ae4b7b33d?s=128

Anupam

November 15, 2019
Tweet

Transcript

  1. Supercharged Web Development With Purescript Functional Conf 2019 Anupam Jain

  2. 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
  3. Prerequisite • git clone https://github.com/ajnsit/purescript-react-starter • npm install • npm

    run build • npm run start
  4. Purescript

  5. Modern FP • Pure, Strong Static Types • Type Classes

    • Higher Kinded Types • Row Types and Records • Effects • Syntactic Niceties • Granular Imports
  6. None
  7. Practical • Generates Readable Javascript Code • Excellent Community •

    Excellent Ecosystem and Tooling • “IDE” Integration • Compiles to Javascript, BEAM, Native • All of Javascript Ecosystem
  8. None
  9. None
  10. 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
  11. Tooling NPM Spago Parcel JS Deps PS Deps + Build

    JS Build
  12. 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
  13. 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!
  14. Dhall • Configuration Language for Spago • The programmable, non-repetitive,

    alternative to YAML • YAML + Functions + Types + Imports • NOT Turing Complete
  15. Spago.dhall • { name = “lib1" , dependencies = [

    "effect" , "console" , "prelude" ] , sources = [ "src/**/*.purs" ] , packages = ../packages.dhall }
  16. Packages.dhall { … , concur-react = { dependencies = [

    … ] , repo = "https://github.com/ajnsit/purescript-concur.git" , version = "v0.3.9" } … }
  17. 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
  18. Parcel - Optional • The Zero-Configuration Web Bundler • Dev

    Server • parcel index.html • Build • parcel build index.html
  19. Index.HTML <!doctype html> <html> <body> <div id="main"></div> <script src="index.js"></script> </body>

    </html>
  20. index.JS import Main from “./output/Main"; if (module.hot) { module.hot.accept(function ()

    { console.log('Reloaded, running main again'); main(); }); } main(); HMR Stuff
  21. 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
  22. Hello Purescript module Main where import Data.Unit (Unit) import Effect

    (Effect) import Effect.Console (log) main :: Effect Unit main = log “Hello World”
  23. 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
  24. 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)
  25. Live Code Demo

  26. React Element / Class • ReactElement -> DOM • ReactDOM.render

    <ReactElement> <DomElement> • ReactClass -> ReactElement • React.createLeafElement <ReactClass> <Props> • React.createElement <ReactClass> <Props> <Children>
  27. Creating New React Classes • React.component <Name> <Spec> • Spec

    = ReactThis -> Record { state :: Record State , render :: Effect ReactElement }
  28. Importing React Classes from JS • — Foo.js exports.classFoo =

    require(‘Foo’).default • — Foo.purs foreign import classFoo :: ReactClass { }
  29. Live Code With FFI

  30. Questions? Thank You!