Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mini Workshop - Supercharged Web Development With Purescript

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.

Anupam

November 15, 2019
Tweet

More Decks by Anupam

Other Decks in Technology

Transcript

  1. 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
  2. Modern FP • Pure, Strong Static Types • Type Classes

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

    Excellent Ecosystem and Tooling • “IDE” Integration • Compiles to Javascript, BEAM, Native • All of Javascript Ecosystem
  4. 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
  5. 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
  6. 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!
  7. Dhall • Configuration Language for Spago • The programmable, non-repetitive,

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

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

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

    Server • parcel index.html • Build • parcel build index.html
  12. index.JS import Main from “./output/Main"; if (module.hot) { module.hot.accept(function ()

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

    (Effect) import Effect.Console (log) main :: Effect Unit main = log “Hello World”
  15. 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
  16. 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)
  17. React Element / Class • ReactElement -> DOM • ReactDOM.render

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

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

    require(‘Foo’).default • — Foo.purs foreign import classFoo :: ReactClass { }