Many submissions this year so a few had to be squeezed into "short talk" slots.
Session 1: Runtime system
Multicore OCaml, by Stephen Dolan (presenting), Leo White, Anil Madhavapeddy (University of Cambridge)
Still work in progresss. Concurrency v. parallelism. Concurrency: for writing programs (e.g. handle 10000 connections at once). Parallelism is for performance (e.g. making use of 8 cores).
LWT and Async give good support for concurrency (monads are a bit awkward).
Direct-style threading library: vmthreads and systhreads are not very efficient.
Parallelism: sad story. Can use multiple processes with manual copying ...
Unifying the two? -- concurrent programs are easily parallelized: should we use the same primitives?Java, C# and others do but it's a bad idea. At scale, death by context-switching.
Fibers for concurrency (cheap! -- have millions) and Domains for parallelism (expensive! -- have ~#core ones)
Concurrency primitives that are proposed are non-monadic. MVar: a blocking variable. Can use MVars to define an "async" function.
Demo using a Fibonacci function: One recursive call is done using "async". Parallelize it to 48 cores -- get diminishing returns as expected, but the speedup is impressive.
Q: Do you keep spawning even when no domains are free?
A: Yes. Spawning creates a new fiber which is extremely cheap (minor allocation of 30 words).
Q: Can you manipulate domains from within the program?
Multiple domains run in parallel; fibers are balanced between domains. Creating domains is heavyweight.
OCaml is very fast for immutable data and functional programs -- try to keep this unchanged. Mutability is more complicated in a multithreaded system! Use a descendant of Doligez-Leroy.
Each domain has a private minor heap; no pointers exist between minor heaps. The major heap is shared. The major heap can point into minor heaps. Can do completely independent minor collections. Shared heap: mostly-concurrent, inspired by VCGC.
C API -- some minor changes required (sed can fix most!), e.g.
caml_modify(&Field(x,i), y) becomes
caml_modify_field(x, i, y). Atomicity guarantees of current GC are preserved.
Status: bootstraps, but GC needs more testing, tuning and benchmarking. Bytecode only at the moment. Weak references, finalizers etc. are still missing.
Q: Are you exposing a raw memory model?
A: We'll probably settle on enforcing an ordering of stores by using a memory fence on platforms which don't support this natively.
Q: Your collector stops all of the mutator sets. Is there any way of doing collection in parallel with mutators?
A: Have collection in parallel, then stop the world to verify (?)
Q: If fiber does a blocking system call, does that block the entire domain?
A: Yes at the moment, but there are plans to change that.
Q: Can what you are doing be used in monadic libraries in LWT or Async?
A: Yes but that would probably not a good idea because users of these libraries don't assume that their code is running concurrently.
Q: Is it possible to make sure that a particular fiber is in the same or is not in the same domain as other fibers?
A: Priorities, affinities to domains etc. are very interesting and we are just starting to provide these.
Ephemerons meet OCaml GC, by François Bobot (CEA)
Memoization -- computing a function with a cache while avoiding memory leaks: if a key is not needed anymore, we want to remove the entry from the cache. Particular case: heap-allocated keys not needed anymore means not reachable (apart from the cache).
Naive solution: use traditional dictionary data structure (has table, balanced tree etc.) -- problem: no key-value combination is ever released until the function is released!
Weak pointers -- a value not yet reclaimed can be accessed via a weak pointer. GC can release a value that is only pointed to by weak pointers.
Finalizers: can attach one or several to a value. So next idea; don't use K directly to index in K. But what if K and V are the same? Gives circular dependency, and nothing ever gets released.
Next idea: keep table in key! (Haskell: can do something like that with System.Mem.Weak) But we can still get cycles.
Ephemerons (Hayes 1997): value v can be reclaimed if its key k or the ephemeron can be reclaimed.
Implementation: OCaml runtime modified (Github pull request 22). Adds a new phase, cleaning, between mark and sweep.
Can use ephemerons to implement weak tables.
Session 2: Tools and libraries
Introduction to 0install, by Thomas Leonard (University of Cambridge)
Converted 0install from Python to OCaml. Will give intro to 0install -- decentralized, cross-platform package manager -- and report his experience porting Python code to OCaml code.
0install (www.0install.net) created in 2003. Make one package that works everywhere. Packages can come directly from upstream (or from distribution); switch to latest version easily.
Example: 0install add opam http://tools.ocaml.org/opam.xml
Q: How does it deal with libraries?
A: Libraries are shared.
Porting to OCaml.
Python problems -- too slow (mobile platforms), too unreliable -- no static type checking, Python 3 trouble, PyGTK breakage...
Idea to port to a different language -- lots of languages compared (for 0install, only startup time matters)
OCaml: Bad -- top-level no readline support, syntax errors hard to find, unhelpful errors; Good -- fast!, stable, reliable.
Suggestion: OCaml for Python, Java, ... users on the website.
Porting process: used old Python and new OCaml parts together; communication via JSON. Literal translation first; refactor later in OCaml.
Results: similar LOC, 10x faster, reliable, great community!
Q: Can 0install deal with multiple versions of the same package?
A: For OCaml packages, use OPAM.
Q: How often did you run into type errors when porting to OCaml?
A: Porting the SAT solver was a little tricky. None and null are handled better in the OCaml code and all kinds of network errors are handled now.
Q: Are you still using objects?
A: Currently getting rid of objects and making things more immutable.
Transport Layer Security purely in OCaml (*), by Hannes Mehnert (presenting, University of Cambridge), David Kaloper MerÅ¡injak (University of Nottingham)
Current state: Mirage OS -- memory safe, abstract, modular. But for security call unsafe insecure C code??
Motivation: protocol logic encapsulated in declarative functional core; side effects isolated in frontends; concise, useful, well-designed API (should be easy in comparison to OpenSSL!)
TLS: secure channel between two nodes. Most widely used security protocol family. Flexible algorithm: negotiation of key exchange, cipher and hash.
Detailed properties: authentication, secrecy, integrity, confidentiality, forward secrecy. Divided into protocol layers: handshake, change cipher spec, alert, application data, heartbeat subprotocol.
Authentication (X.509): client has set of trust anchors (CA certificates); server has certificate signed by a CA; during handshake client receivers server certificate chain; client verifies that server certificate is signed by a trust anchor.
Handshake demo using the OCaml TLS implementation.
Stats: 10kloc (compare OpenSSL 350kloc); interoperable. Missing features: client authentication, session resumption, ECC ciphersuites. Roughly 5x slower than OpenSSL. Took ~3 months to implement.
Future: implement missing features, improve performance, test suites, integration with Mirage.
More at http://openmirage.org/blog/introducing-ocaml-tls
Q: Who will use this?
A: The University of Cambridge.
C: The team that discovered the Heartbleed bug ran their test framework against this library, and found five bugs in Linux but none in this library.
Q: What about timing and interaction with GC?
A: Best practice is not to use and data-dependent branches and to use the same memory access patterns. No data dependent allocations. But the preferred way is to do this in the language.
Q: How about tests?
A: We have a test suite but we'd like to automatically generate tests and run them against other implementations to be able to do comparisons.
OCamlOScope: a New OCaml API Search (*), by Jun Furuse (Standard Chartered Bank, Singapore)
Haskell has type classes, purity, laziness where OCaml is different. But what's really different is library search: Hoogle. Can search by name, by type, or both.
OCamlBrowser, OCaml API Search are very limited so Jun built OCamlScope.
OCamlBrowser works only for locally compiled code, uses OCaml typing code. OCaml API search was based on OCamlBrowser but has been discontinued.
Previously there were many problems with trying to build an OCaml API search. Now cmt/cmti files give compiled AST with locations, and OPAM gives unified installations; compiler-libs make it easier to access OCaml internals.
OCaml Scope: remote (hosted); search by edit distance.
525k entries (values, types, constructors) -- 115 OPAM packages, 185 OCamlFind packages. Note: need to deal with two different package systems! Scraping cmt/cmti with OPAM, create module hierarchy with OCamlFind; must detect OPAM - OCamlFind package relationships.
Future work: real alias analysis (instead of ad-hoc grouping).
Find it at https://ocamloscope.herokuapp.com
Q: Do you plan to integrate this with an editor?
A: That would be nice, sure.
C: Could use something like your edit distance approach to improve error message and have the compiler give suggestions.
Session 3: OCaml News
The State of OCaml (invited), Xavier Leroy (INRIA Paris-Rocquencourt).
Today: What's new in OCaml 4.02 (September 2014)? Many new features; 66 bugs fixed, 18 feature wishes.
1. Unified matching on values and exceptions
Classic programming problem: in
let x = a in b, we want to catch exceptions raised by a but not those raised by b. In OCaml 4.02, the match .. with .. construct is extended to analyse both the value of a and exceptions raised during a's evaluation.
let rec readfile ic accu = match input_line ic with | "" -> readfile ic accu | l -> readfile ic (l :: accu) | exception End_of_file -> List.rev accu
Compilation preserve tail-call optimization.
2. Module aliases
Common practice: bind an existing module to another name.
module A = struct module M = AnotherModule ... end
This binding is traditionally treated like any other definition. This can cause subtle type errors with applicative functors; accesses sometimes go through more indirections; linking problems.
In OCaml 4.02, these constructs are treated specially during type-checking, compilation and linking.
Discussion of the application of this to libraries.
3. Mutability of strings
For historical reasons, the string type is mutable in place and has two broad uses. It can be used to represent text, or as an I/O buffer (mutable). OCaml programmers usually keep these two uses distinct. But mistakes happen, and user code may be malicious.
In the Lafosec study (ANSSI), there are a few examples of OCaml code where one can mutate someone else's string literals, or make a Hashtable key disappear.
New solution by Damien Doligez: in 4.02, there are two base types -- string for text, and bytes for byte arrays. By default, the two are synonymous but incompatible if option -safe-string is given.
In default mode, all existing code compiles but get warnings when using String functions that mutate in place.
-safe-string mode, the values of type string are immutable (unless unsafe coercions are used); I/O code and imperative constructions of strings need to be rewritten to use type bytes and library functions from Bytes.
Other novelties: explicitly generative functors; annotations over OCaml terms; external preprocessers that rewrite the typed AST (-ppx option); open datatypes, extensible a posteriori with additional constructors.
Performance improvements: more aggressive constant propagation, dead code elimination, common subexpression elimination, pattern-matching, printf (based on GADTs); representation of exceptions without arguments
New toplevel directives to query the environment; new port to 64-bit ARM; source reorganization: Camlp4 and Labltk split off the core distribution and now live as independent projects.
What's next? Bug fix release 4.02.1, then various language experiments in progress; more optimizations, ephemerons, GDB support, tweaks to support OPAM better.
Q: Safe Haskell is starting to catch on in the Haskell community.
A: "Safe strings" are a first step in this direction. Safe OCaml is definitely something we're thinking about.
The OCaml Platform v1.0, by Anil Madhavapeddy (presenting, C), Amir Chaudhry (C), Jeremie Diminio (JS), Thomas Gazagnaire (C), Louis Gesbert (OCamlPro), Thomas Leonard (C), David Sheets (C), Mark Shinwell (JS), Leo White (C), Jeremy Yallop (C); (C = University of Cambridge, JS = Jane Street)
The platform: tooling, quantitative metrics, agility to judge the impact of language changes. Ultimate goal: grow a sustainable open source community.
OPAM 1.2: "The Platform Release" -- solver errors are explained in plain English rather than boolean formulae, more expressive queries (reverse dependencies and recursive); can clone the source code and repo file for any OPAM package.
Steady growth in the number of released OPAM packages. Growth in number of contributors is much slower.
New workflow in OPAM 1.2 (See http://opam.ocaml.org/blog/opam-1-2-pin/) -- flexible clone, pin, configuration, sharing.
OCaml Platform? OPAM Platform! Tools built around OPAM that provide a modular workflow for developing, publishing and maintaining OCaml source code, both online and offline.
OPAM = OCaml PlAtformM!
OPAM 1.2 restructured: everything built on OpamLib. On top of that library, have "opam", "opam-publish", "opam-doc" (with opam-units) tools.
OPAM documentation -- goal: documentation unified across packages that handles cross-referencing and module inclusion well. It's hard!
Use only the Typed AST; comments are transformed into attributes in the typed AST; these are used by external tools.
Preview: http://ocaml.github.io/platform-dev a working prototype.
Timeline: Sept online release, Nov use it locally, Dec build custom website for other repositories.
Tooling: OCamlJS now supports complete compiler REPL in JS; GDB integration.
Polish: easier to package and install; binary releases on lots of platforms; documentation rewritten.
One More Thing: Assemblage -- an very alpha eDSL to describe OCaml projects. OCaml as host language with Merlin auto-completion. Can introspect the project description to generate build rules. Very lightweight, integrates easily.
Q: Do you have anything to help with ARM cross-compilation?
A: Global build "glue" still required to support cross-compilation (Assemblage will help with this)
Q: Any platform is a (false?) promise to define a set of supported libraries. What's OPAM's take on this?
A: We as the developers of the platform don't want to be the people who define what the current set of packages considered as "stable" is. We just build the tools.
Session 4: Language
A Proposal for Non-Intrusive Namespaces in OCaml, by Pierrick Couderc (I), Fabrice Le Fessant (I+O), Benjamin Canou (O), Pierre Chambart (O); (I = INRIA, O = OCamlPro)
In OCaml, we cannot use multiple modules that have the same name.
Common practice: use long names, e.g. LibA (Misc, Map) as LibA (LibA_Misc, LibA_Map).
Packs: for the developer -- no code change, simply a matter of options; user -- use path to distinguish modules. Cons: too many recompilations, dependencies, large executables!
In 4.02, we can use module aliases. Option
Advantages: can deceive ocamldep for better dependencies and namespaces can be used transparently.
Proposed solution: namespaces and "as" imports. Can import specific modules, or all modules, or all modules except certain ones from a namespace.
Namespaces are not closed -- adding a module a posteriori is possible.
Comparison with module aliases: +extensibility, +simple build system, +better dependencies, +expressivity. But -new syntax.
Work in progress: big functors -- using packs to generate functors.
Conclusion: mechanism of namespaces integrated in the language, solves compilation issues. Working prototype for 4.02: github.com/pcouderc/ocaml_namespaces
C: Openness vs. functorization.
A: With big functors, one idea would be to close namespaces but that would not be ideal.
C: There are already module aliases and then there will be namespaces. Mixing the idea of big functors with namespaces does not seem like a good idea.
Q: How about qualified imports?
A: Interesting idea.
Q: Why do you need "in namespace" if you're already separating by directory structure?
A: It's not enough. We need to separate compilation units.
C: But directory names could be used a link time.
C: The benefits must be very clear because there already are lots of ways of importing "stuff".
Improving Type Error Messages in OCaml (*), by Arthur CharguÃ©raud (INRIA & Université Paris Sud)
Type errors: dozens of papers, no implementation. For beginners and experts, type errors can be very frustrating.
Result: a patch to the type-checker, providing alternative error messages for ill-typed toplevel definitions.
Example: missing unit argument to
read_int -- report "You probably forgot to provide '()' somewhere"; refs and bangs; missing "rec" -- report "You are probably missing the 'rec' keyword".
Example: missing else branch -- laughs from the audience about the terrible type error message.
Other common errors where the error messages were improved: subexpressions, ill-typed applications, binary operators, incompatible branches, higher-order function application, occurs check errors.
Also works for optional and named arguments.
Not included GADTs, module type checking.
Try it online: tinyurl.com/ocamleasy
Q: Why can't we have this today??
A: Need more testing, especially with higher order functions.
Github Pull Requests for OCaml development: a field report (*), by Gabriel Scherer (INRIA).
Experiment of using Github pull requests for 8 months.
Old way: Mantis.
users report bugs, request features, propose patches
sometimes a developer works on a PR
a release each year, with some bugs fixed and some new features
Serious bugs get fixed, features are mostly ignored. Patches got ignore too!
Results of the experiment: 18 new contributions (patches) from people who probably wouldn't have sent their patches in the old system, 18 new reviews! So Github attracted a new crowd of contributors.
Some Github pull requests were handled very quickly (small fixes and changes). Developer meetings help taking decisions. Pull requests are most effective during initial development: before the feature freeze (after that the team is busy with getting the release out).
Negative results: to be effective, external users should be told more about the development cycle. Github was used mostly by people used to git.
Q: Reviews and contributions?
A: 0 reviews on Mantis, 18 on Github; ~40 patches on Mantis, 18 on Github.
Q: How about switching to git?
A: Don't believe that is going to happen. There is so much information on Mantis right now! Continuous integration is nice though.
Joint Poster Session (with ML Family workshop)
Irminsule; a branch-consistent distributed library database, by Thomas Gazagnaire (C), Amir Chaudhry (C), Anil Madhavapeddy (C), Richard Mortier (University of Nottingham), David Scott (Citrix System), David Sheets (C), Gregory Tsipenyuk (C), Jon Crowcroft (C); (C = University of Cambridge)
What if you had a distributed database with git-like semantics? -- E.g. commit history
Have an Obj and a Git backend. Implementations of various persistent data structures with merge function: prefix trees, mergeable queues, mergeable ropes.
A Case for Multi-Switch Constraints in OPAM, by Fabrice Le Fessant (INRIA)
OPAM: the official way to install OCaml packages. Builds a CUDF universe with packages available for the switch, and the dependency constraints between these packages. Send the universe to the CUDF solver, then apply the solution to the switch.
Multi-switch constraints: add a switch prefix to each package name. allow dependency constraints between packages with different switch prefixes
Use cases: cross-compilation (build and host switches), multi-switch packages, all-switch commands, per-switch repositories, external dependencies, applications-specific switches.
No implementation yet -- just an idea for discussion.
LibreS3: design, challenges, and steps toward reusable libraries, by Edwin Török (Skylable Ltd.)Slides Poster.
Concepts: monads, S3 server -- proprietary Amazon service; FOSS replacements exist.
Architecture: don't choose one particular library/framework; be careful with acquiring resources: with_resource; some code in LibreS3 has been generalized (any-cache, any-http)
Found some interesting bugs in OCaml and libraries while developing LibreS3. Debugging monadic code is hard! Stack traces from monadic concurrency are incomplete.
Nullable Type Inference (#), by Michel Mauny and Benoit Vaugon (ENSTA-ParisTech)
Nullable type t? includes NULL and values of type t. Provide type inference algorithm featuring HM polymorphism that statically guarantees that NULL cannot be used as a regular value (algorithm's soundness has been proved).
Nullable types are used in practice: Hack (Facebook), Swift (Apple)
Coq of OCaml, by Guillaume Claret (Université Paris Diderot)
OCaml: FP with imperative features, many libraries and programs.
Coq: mainly used as a proof language, purely functional (only terminating programs!), dependent types, limited number of libraries.
Coq to OCaml: extraction mechanism developed by Pierre Letouzey -- removes proof terms, complete.
OCaml to Coq: CFML: deep embedding -- how to do shallow embedding? How to import imperative programs? How to keep the resulting code small?
Use a monadic translation to represent imperative features in Coq.
Usage: prove formal properties on OCaml programs, augment number of Coq libraries for programming.
Effects descriptor: a set of atomic effects. Inference: infer types using the OCaml compiler, then bottom-up analysis; fixpoint for mutually recursive definitions. Then represent effects as monads in Coq.
There is one monad per descriptor of effects -- how do we compose them? Impossible in general, but doable when we restrict the shape of the monads.
Monads exist to model global references, exceptions, i/o, non-termination.
Supported language fragment: pure lambda-calculus kernel, mutually recursive functions, inductive types, records, ADTs, ...
Compilation passes: 1. import the syntax tree typed by the OCaml compiler; 2. infer effects; 3. do monadic transformation; 4. pretty-print to Coq syntax.
Challenges: generate human-readable code, support real OCaml programs, import basic libraries, support functors (not currently implemented).
Conclusions: hard to make compiler work on real examples; functors are complex!
Q: The granularity of effects matters a lot when you use this to prove properties of your OCaml code.
Q: How can I use this to prove properties about recursion -- e.g. whether they are tail-recursive?
Q: Do you handle local references?
A: Not at this moment.
Q: You only support part of the Pervasives library. Which parts do you not support?
A: Can't currently pass effectful functions as arguments, so for example List.iter is not supported in the usual use case.
High Performance Client-Side Web Programming with SPOC and Js of ocaml (*), by Mathias Bourgoin and Emmmanuel Chailloux (Université Pierre et Marie Curie)This is the OCaml Users and Developers Workshop 2014 in Gothenburg.
Parallel OCaml? Lots of libraries. One is SPOC = Stream Processing OCaml (with OpenCL).
GPGPU programming. Two main frameworks: Cuda and OpenCL. Use different languages to write kernels (Assembly or C/C++ subset) and to manage kernels (more or less any general purpose language can be used here).
SPOC compiles to Cuda or OpenCL. It contains the Sarek DSL and a runtime.
WebSpoc: compile OCaml with SPOC and then to JS with js_of_ocaml.
Demo: Using SPOC from within a browser to do image manipulation.
WebSpoc helps develop complex web apps with intensive computations. Good for GPGPU courses.
Future work: add a JS memory manager dedicated to SPOC vectors; add bindings to WebGL.
Demo online: http://mathiasbourgoin.github.io/SPOC/tutos/OCaml2014.html
SPOC and Sarek are available in OPAM.
Q: Is there potential to run this code on the GPU of a mobile phone?
A: Not yet.
Using Preferences to Tame your Package Manager, Roberto Di Cosmo (presenting, D+I), Pietro Abate (D), Stefano Zacchiroli (D), Fabrice Le Fessant (I), Louis Gesbert (OCamlPro); (D = Université Paris Diderot, I = INRIA)
Ten years of research on package management -- EDOS and MANCOOSI, bridging research communities. Used as foundation of OPAM.
LOTS of package managers out there! Binary, source, language specific, application specific, decentralized, functional approach.
What's inside? Two sides: people maintaining packages (server side) -- maintain a coherent set of packages. Also "client side" -- fetch and authenticate metadata and packages, resolve dependencies, user preferences.
Dependency solving: installability of a single package and co-installability of a set of packages are NP-complete problems.
Application: find uninstallable packages in a repository: just call a SAT solver on each package in the repository! ("dose" library is specialized for this task)
ows.irill.org is the OPAM Weather Service -- shows which packages can be installed together.
Finding a solution is NP-complete but installing and upgrading is more demanding -- how many ways are there to install a package? Exponentially many.
Towards modular package managers. 0. stop coding a petty solver for every new component base system; 1. use a common upgrade description format; 2. provide means for expressing user choice.
User preferences: built from four ingredients. Package selectors, measurements, maximisation/minimisation, aggregation.
Example for minimisation:
-count(removed) -- we want a solution where the number of removed packages is minimised.
Slightly more exotic:
Repairing a broken system configuration:
This is all possible with OPAM 1.2! (Check opam --help, look for --criteria)
You can help: try different profiles, test expressivity of the preference language, help debug OPAM.
Conclusion: package managers are complex; a very hard part is dependency solving! Modern package managers must share common components, in particular dependency solvers and the user preference language.
Q: Does this keep track of explicitly installed packages?
A: Yes, OPAM knows which packages were installed directly (the "root set") and which were installed in order to satisfy dependencies.
Q: Why don't other package managers use this technology now?
A: Package managers are core parts of any system so people tend to be very resilient to change.
Simple, efficient, sound-and-complete combinator parsing for all context-free grammars, using an oracle (*), by Tom Ridge (University of Leicester)
The P3 combinator parsing library. Can handle all context-free grammars (CFGs). Scannerless or can use a lexer. Good theoretical basis, but slow.
Memoized counting -- you can't do this with any other parser!
Compute actions over all good parse trees; there are exponentially many such parse trees, but this doesn't have to take exponential time!
Disambiguation: directly encode in code with using "option".
Supports modular combination, e.g. "helper parsers".
Comparison with Happy: it's faster, in some cases ridiculously so.
Long term aim: general parser, verified correctness and performance, usable in the real world.
Q: What's the use case?
A: It's extremely flexible, but slower than deterministic parsers.