Notes from Compose 2017

Here are my take-away points from this year’s conference (I am pretty new to the FP world so excuse the oversimplification here):


Compose 2017 - NYC

http://www.composeconference.org/2017/

Day 1 (May 18)

KEYNOTE: A categorical view of computational effects

choose Your Own Derivative

Reactive Sheets: an intuitive approach to functional‑reactive computing

Typed-Tagless Final Bioinformatics

The Probability Monad

  • Presenter: Tikhon Jelvis
  • Modeling probability models as monads would simplify quite a lot of things:
    • Combining distributions to get joint distributions
    • Assigning weights, normalizing, and transformations
    • Sampling for joint expectations
    • Building more complex distribution combinations (e.g. decision tree like ones)
  • Paper: Functional Pearls - http://gallium.inria.fr/~huet/PUBLIC/zip.pdf
  • Implementation options:
    • Exhaustive: each possible element is listed with assigned weights
      • Makes it easy to transform
      • Not feasible for all distributions
  • Upsides: expressive, intuitive, and fits into Haskell
  • Downsides: slow and issues with normalization
  • Use case: basic examples implemented at Target to optimize distribution networks to reduce costs
  • Paper: Practical probabilistic programming with monads - http://mlg.eng.cam.ac.uk/pub/pdf/SciGhaGor15.pdf
  • Paper: Probabilistic Functional Programming in Haskell - https://web.engr.oregonstate.edu/~erwig/pfp/

Lock-step simulation is child’s play

  • Presenter: Joachim Breitner
  • Slides: https://github.com/nomeata/codeworld-talk
  • Case studies from https://code.world/
    • Interactive, fun, and gamified teaching platform for programming (e.g. Haskell)
    • Single-user player implementation is trivial but easily gets boring for the learner
    • Multi-user player implementation is challenging
      • Need to generalize for different types of games
      • Which user is responsible for computation and which for visualization
        • If all: redundancy, need to handle conflicts, delays, …
        • If one: hard to provide interactivity and engagement (if one cannot interact with the game, it gets boring)
      • Potential solution #1: everybody keeps track of their own local state but broadcast changes to others. This works fine with basic games (e.g. tic-tac-toe) but even minor network delays cause state divergences across clients when the game is more complex (e.g. pong)
      • Potential solution #2: use local states but broadcast more information that enable prediction of the next state on the other agent’s side

TUTORIAL: Learning F#: Case study with branch and bound

QuickFuzz Testing for Fun and Profit

Working with Monads in OCaml

Day 2 (May 19)

Teaching Haskell

Distrest - REST access to distributed services

  • Presenters: Hezekiah Carty and Chris Donaher
  • Motivation
    • Data science and malware research need to happen quick at Endgame
      • Limited time and resources for developers and researchers
    • People want to use already existing domain-specific tools and libraries spanning multiple languages and hardware requirements
  • Goal
    • Minimal intervention with the code to be used
    • Scale (in an easy way; e.g. adding a new computation node to the system)
    • Take tools and turn them into services
    • Ease experimentation
  • Distrest
    • Handles and routes RPC-like REST requests to tool services
    • Supports multiple languages via a broker/proxy implementation in OCaml
    • Implements basic workflow engine needs (e.g. dependency graph)
    • Facilitates parallelization of service runs
    • Soon to be open-sourced :frowning:
  • Use case
    • Collect information about the binary, extract features (via machine learning), and learn features to be used for classification of the binary (e.g. malware or not?)
    • Aggregate binaries and allow proxy requests for others interested in analyzing the archived binaries
  • Practical consideration
    • Versioning, deployment/scaling, and routing
    • Kubernetes to rescue!

Implementing an Event-Driven Microservices Architecture in F#: A case study of Jet.com

BuckleScript: Making functional programming accessible to JavaScript developers

  • Presenter: Hongbo Zhang
  • BuckleScript: A platform that features an optimizing OCaml compiler to readable JS. Optimization and readable JS code are the killer features.
  • Support all OCaml except C FFI and also Facebook’s ReasonML
  • Allows propagation of annotations on the OCaml level to the JS level
  • No way around using JS in web-technologies so BuckleScript addresses an important need for proper programming and is not meant to become yet-another-framework
  • Migration from JS to BuckleScript does not necessarily require a complete rewrite. Can be done in an incremental manner
  • Supports commonly used JS module systems; e.g. AmdJS, CommonJS, ES6, Google modules
  • MariOcaml comparison:
  • Adoption: React bindings/libraries/types, WebAssembly support, …

Android programming in Froid

  • Presenter: Michael Chavinda
  • Motivation
    • For a beginner, it is really hard to get started with developing GUIs
    • There are many GUI libraries but setting up the infrastructure takes much more time than the coding itself
    • Android GUI space was essentially lacking a reliable solution
    • Choice of language: Frege - because it provides a nice intermediate stepping stone for people who are making the transition from Java to Haskell or the other way around
  • Extensive documentation and guidelines are available on the Froid Wiki: https://github.com/mchav/froid/wiki
  • Basic setup to try Froid: https://github.com/mchav/try-frege-android

Data Driven UIs, Incrementally

  • Presenter: Yaron Minsky
  • When you are dealing with long lists or huge tables of data, UIs are the best; but how do you build a UI that is fast, reactive (responds to the data), and typed? Inspiration from React-* framework
    • Structure UIs as functions of a model, action, and virtual DOM
      • Apply: applies an action on the model
      • View: mutates the virtual dom based on the expected effect of the action on the UI
    • Consider UIs as online algorithms
    • Make use of diff and patch tools/ideas
      • Even if you are making use of a really good incremental computing framework, it is still hard to find/replace the elements that are changed for actual manipulation
      • Diff algorithms provide a nice way to reduce two versions of the model down to a minimal work to be done to convert one to another (e.g. Table.symmetric_diff in Incremental) and by making use of patch to fire methods required, the problem becomes easier to deal with
      • When the view itself is dynamic, the problem is a nested incremental problem.
  • Useful Incremental tricks to simplify the problem: filtering, partial rendering, and focus management
  • Upsides of using Incremental
    • The semantics of the code easier to understand
    • Significant performance boost
    • Sharing code is also made easy
    • Debugging becomes easier (thanks to JS)
  • Demo reactive table: https://github.com/janestreet/incr_dom

Sorry, had to leave at this point. No notes from now on :frowning:


Multiplying by 1 - an important form of computation and how it reveals distinctions between kleislis

  • Presenter: Edmund Cape

Smart Contracts and Formal Verification with Z3 with Pact

  • Presenter: Stuart Popejoy

New Hasql - a simpler, safer and faster Postgres client

  • Presenter: Nikita Volkov
15 Likes

Thanks for the really useful notes, @armish! I’ve bumped your trust level up so you should be able to edit and post as many links as you like, if you want to edit the markdown.

Thanks Amish, if we can have rendered markdown it would be better.

Thank you so much, @avsm and @Bob_fang. Thanks to the new trust level, I can now post the markdown version so I updated the post accordingly. Looks/reads much better now :tada:

1 Like

Thanks a lot for writing this up, armish! I couldn’t make Compose this year and it’s great to get pointers to what I missed.

1 Like

I just looked at the slides on Working with Monads in OCaml. Slide 15/17 mentions that “you can’t pass functors to functors”, and that this is an issue to implement

traverse :: Applicative f => (a -> f b) -> t a -> t (f b)

Would anyone know what exactly was being meant? Because you can in fact take functors are arguments to functors, and you can do traverse this way:

module type Functor = sig
  type 'a t
  val map : ('a -> 'b) -> 'a t -> 'b t
end

module type Applicative = sig
  type 'a t
  include Functor with type 'a t := 'a t
  val pure : 'a -> 'a t
  val app : ('a -> 'b) t -> 'a t -> 'b t
end

module type Monad = sig
  type 'a t
  include Functor with type 'a t := 'a t
  val return : 'a -> 'a t
  val bind : 'a t -> ('a -> 'b t) -> 'b t
end

module type Traversal = sig
  type 'a t
  module Traverse : functor (F : Applicative) -> sig
    val traverse : ('a -> 'b F.t) -> 'a t -> 'b t F.t
  end
end

module List = struct
  type 'a t = 'a list
  let map = List.map
  let pure x = [x]
  let rec app fs xs = match fs, xs with
    | [], [] -> []
    | f::fs, x::xs ->
      let y = f x in y :: app fs xs
    | (_::_), [] | [], (_::_) -> invalid_arg "List.app"
  let return = pure
  let join = List.flatten 
  let bind m f = List.map f m |> join
  module Traverse (F : Applicative) = struct
    let rec traverse f = function
      | [] -> F.pure []
      | x::xs ->
        let y = f x in
        let ys = traverse f xs in
        let ($) = F.app in
        F.pure (fun y ys -> y::ys) $ y $ ys
  end
end

module Option = struct
  type 'a t = 'a option

  let map f = function
    | None -> None
    | Some x -> Some (f x)

  let pure x = Some x
  let app f m = match f, m with
    | Some f, Some x -> Some (f x)
    | None, _ | _, None -> None

  let return = pure
  let bind m f = match m with
    | None -> None
    | Some x -> f x
end

let () =
  let module T = List.Traverse(Option) in
  let open T in
  assert
    (traverse (function true -> Some 1 | false -> Some 2) [true; false; true]
     = Some [1; 2; 1]);
  assert
    (traverse (function true -> Some 1 | false -> None) [true; false; true]
     = None);
  ()
3 Likes

@gasche In that case I was talking about, in terms of your example

module Twice(F : Traversal) = struct
  let twice a b =
    let module FO = F.Traverse(Option) in
    (FO.traverse (fun a -> Some a) a,
     FO.traverse (fun a -> Some a) b)
end

And hey! That works. Neat!

This is surprising to me because slide 65 of @chrisamaphone’s presentation from 2 years ago mentions that higher-order functors are disallowed. Does this just mean, then, that it is merely that functor types can’t be directly used as functor arguments, but if said functors are module members it’s always fine?

This is surprising to me because …

That talk was about SML.

The talk in general is about SML, but the part I pointed to refers to OCaml explicitly, comparing its functor behavior with SML and MoscowML.

No, it just means that slide 65 is wrong:

module AppApp
    (F : functor (X : Set.OrderedType) -> Set.S)
    (A : Set.OrderedType)
  = F (F (A))
module SetSet = AppApp (Set.Make)
module SetSetString = SetSet (String)

If you want a demonstration of high order functors in action, look at the internals of ocamlgraph and ctypes.