text:
OCaml Planet
The OCaml Planet aggregates various blogs from the OCaml community. If you would like to be added, read the Planet syndication HOWTO.
Weekly News — OCaml Weekly News, Apr 26, 2016
Full Time: Software Developer (Functional Programming) at Jane Street in New York, NY; London, UK; Hong Kong — GitHub Jobs, Apr 25, 2016
Software Developer
Jane Street is a proprietary quantitative trading firm, focusing primarily on trading equities and equity derivatives. We use innovative technology, a scientific approach, and a deep understanding of markets to stay successful in our highly competitive field. We operate around the clock and around the globe, employing over 400 people in offices in New York, London and Hong Kong.
The markets in which we trade change rapidly, but our intellectual approach changes faster still…Read more...
Software Developer
Jane Street is a proprietary quantitative trading firm, focusing primarily on trading equities and equity derivatives. We use innovative technology, a scientific approach, and a deep understanding of markets to stay successful in our highly competitive field. We operate around the clock and around the globe, employing over 400 people in offices in New York, London and Hong Kong.
The markets in which we trade change rapidly, but our intellectual approach changes faster still. Every day, we have new problems to solve and new theories to test. Our entrepreneurial culture is driven by our talented team of traders and programmers. At Jane Street, we don't come to work wanting to leave. We come to work excited to test new theories, have thought-provoking discussions, and maybe sneak in a game of ping-pong or two. Keeping our culture casual and our employees happy is of paramount importance to us.
We are looking to hire great software developers with an interest in functional programming. OCaml, a statically typed functional programming language with similarities to Haskell, Scheme, Erlang, F# and SML, is our language of choice. We've got the largest team of OCaml developers in any industrial setting, and probably the world's largest OCaml codebase. We use OCaml for running our entire business, supporting everything from research to systems administration to trading systems. If you're interested in seeing how functional programming plays out in the real world, there's no better place.
The atmosphere is informal and intellectual. There is a focus on education, and people learn about software and trading, both through formal classes and on the job. The work is challenging, and you get to see the practical impact of your efforts in quick and dramatic terms. Jane Street is also small enough that people have the freedom to get involved in many different areas of the business. Compensation is highly competitive, and there's a lot of room for growth.
You can learn more about Jane Street and our technology from our main site, janestreet.com. You can also look at a a talk given at CMU about why Jane Street uses functional programming (http://ocaml.janestreet.com/?q=node/61), and our programming blog (http://ocaml.janestreet.com).
We also have extensive benefits, including:
- 90% book reimbursement for work-related books
- 90% tuition reimbursement for continuing education
- Excellent, zero-premium medical and dental insurance
- Free lunch delivered daily from a selection of restaurants
- Catered breakfasts and fresh brewed Peet's coffee
- An on-site, private gym in New York with towel service
- Kitchens fully stocked with a variety of snack choices
- Full company 401(k) match up to 6% of salary, vests immediately
- Three weeks of paid vacation for new hires in the US
- 16 weeks fully paid maternity/paternity leave for primary caregivers, plus additional unpaid leave
More information at http://janestreet.com/culture/benefits/Hide
Oh! Pascal! — Shayne Fletcher, Apr 21, 2016
I can't help but want to share my joy at coming across this pearl of a program from the "Pascal User Manual and Report" - Jensen and Wirth (circa 1974). In my edition, it's program 4.7 (graph1.pas).
This is it, rephrased in OCaml.
Read more...
(* Graph of f x = exp (-x) * sin (2 * pi * x)
Program 4.7, Pascal User Manual and Report, Jensen & Wirth
let round (x : float) : int =
let f, i =
let t = modf x in
(fst t, int_of_float@@ snd t) in
if f = 0.0 then i
else if i >= 0 then
if f >= 0.5 then i…
I can't help but want to share my joy at coming across this pearl of a program from the "Pascal User Manual and Report" - Jensen and Wirth (circa 1974). In my edition, it's program 4.7 (graph1.pas).
This is it, rephrased in OCaml.
(* Graph of f x = exp (-x) * sin (2 * pi * x)
Program 4.7, Pascal User Manual and Report, Jensen & Wirth
let round (x : float) : int =
let f, i =
let t = modf x in
(fst t, int_of_float@@ snd t) in
if f = 0.0 then i
else if i >= 0 then
if f >= 0.5 then i + 1 else i
else if -.f >= 0.5 then i - 1 else i
let graph (oc : out_channel) : unit =
(*The x-axis runs vertically...*)
let s = 32. in (*32 char widths for [y, y + 1]*)
let h = 34 in (*char position of x-axis*)
let d = 0.0625 in (*1/16, 16 lines for [x, x + 1]*)
let c = 6.28318 in (* 2pi *)
let lim = 32 in
for i = 0 to lim do
let x = d *. (float_of_int i) in
let y = exp (-.x) *. sin (c *. x) in
let n = round (s *. y) + h in
for _ = n downto 0 do output_char oc ' '; done;
output_string oc "*\n"
let () = print_newline (); graph stdout; print_newline ()
The output from the above is wonderful :)
Weekly News — OCaml Weekly News, Apr 19, 2016
Unboxed floats in OCaml — LexiFi, Apr 14, 2016
This post describes how unboxing for float values works in OCaml, focusing on recent evolutions. Most of the content here applies to boxed integer types as well (int32, int64 and nativeint).
OCaml server-side developer at Ahrefs Research (Full-time) — Functional Jobs (FunctionalJobs.com), Apr 14, 2016
Who we are
Ahrefs Research is a San Francisco branch of Ahrefs Pte Ltd (Singapore), which runs an internet-scale bot that crawls whole Web 24/7, storing huge volumes of information to be indexed and structured in timely fashion. On top of that Ahrefs is building analytical services for end-users.
Ahrefs Research develops a custom petabyte-scale distributed storage to accommodate all that data coming in at high speed, focusing on performance, robustness and ease of use. Performance-critical low…Read more...
Who we are
Ahrefs Research is a San Francisco branch of Ahrefs Pte Ltd (Singapore), which runs an internet-scale bot that crawls whole Web 24/7, storing huge volumes of information to be indexed and structured in timely fashion. On top of that Ahrefs is building analytical services for end-users.
Ahrefs Research develops a custom petabyte-scale distributed storage to accommodate all that data coming in at high speed, focusing on performance, robustness and ease of use. Performance-critical low-level part is implemented in C++ on top of a distributed filesystem, while all the coordination logic and communication layer, along with API library exposed to the developer is in OCaml.
We are a small team and strongly believe in better technology leading to better solutions for real-world problems. We worship functional languages and static typing, extensively employ code generation and meta-programming, value code clarity and predictability, constantly seek out to automate repetitive tasks and eliminate boilerplate, guided by DRY and following KISS. If there is any new technology that will make our life easier - no doubt, we'll give it a try. We rely heavily on opensource code (as the only viable way to build maintainable system) and contribute back, see e.g. https://github.com/ahrefs . It goes without saying that our team is all passionate and experienced OCaml programmers, ready to lend a hand or explain that intricate ocamlbuild rule.
Our motto is "first do it, then do it right, then do it better".
What we need
Ahrefs Research is looking for backend developer with deep understanding of operating systems, networks and taste for simple and efficient architectural designs. Our backend is implemented mostly in OCaml and some C++, as such proficiency in OCaml is very much appreciated, otherwise a strong inclination to intensively learn OCaml in a short term will be required. Understanding of functional programming in general and/or experience with other FP languages (F#,Haskell,Scala,Scheme,etc) will help a lot. Knowledge of C++ and/or Rust is a plus.
The candidate will have to deal with the following technologies on the daily basis:
- networks & distributed systems
- 4+ petabyte of live data
- OCaml
- linux
- git
The ideal candidate is expected to:
- Independently deal with and investigate bugs, schedule tasks and dig code
- Make argumented technical choice and take responsibility for it
- Understand the whole technology stack at all levels : from network and userspace code to OS internals and hardware
- Handle full development cycle of a single component, i.e. formalize task, write code and tests, setup and support production (devops)
- Approach problems with practical mindset and suppress perfectionism when time is a priority
These requirements stem naturally from our approach to development with fast feedback cycle, highly-focused personal areas of responsibility and strong tendency to vertical component splitting.
What you get
We provide:
- Competitive salary
- Modern office in San Francisco SOMA (Embarcadero)
- Informal and thriving atmosphere
- First-class workplace equipment (hardware, tools)
- No dress code
Get information on how to apply for this position.Hide
Announcing the upcoming Frama-C Day 2016. — Frama-C, Apr 14, 2016
Senior Software Engineer (Haskell) at Front Row Education (Full-time) — Functional Jobs (FunctionalJobs.com), Apr 13, 2016
Senior Functional Web Engineer to join fast-growing education startup transforming the way 3+ million K-8 students learn Math and English.
What you will be doing
Architect, design and develop new applications, tools and distributed systems for the Front Row ecosystem in Haskell, Flow, PostgreSQL, Ansible and many others. You will get to work on your deliverable end-to-end, from the UX to the deployment logic.
Once you're an integral part of the team you will act as Dev Lead and…Read more...
Senior Functional Web Engineer to join fast-growing education startup transforming the way 3+ million K-8 students learn Math and English.
What you will be doing
Architect, design and develop new applications, tools and distributed systems for the Front Row ecosystem in Haskell, Flow, PostgreSQL, Ansible and many others. You will get to work on your deliverable end-to-end, from the UX to the deployment logic.
Once you're an integral part of the team you will act as Dev Lead and oversee the success of your team
Mentor and support more junior developers in the organization
Create, improve and refine workflows and processes for delivering quality software on time and without incurring debt
Work at our offices in San Francisco as part of a very small (there's literally half a dozen of us!), world-class team of engineers with a track record of rapidly delivering valuable software to millions of users.
Work closely with Front Row educators, product managers, customer support representatives and account executives to help the business move fast and efficiently through relentless automation.
Why you should join Front Row
Our mission is important to us, and we want it to be important to you as well: millions of students learn math using Front Row every month. Our early results show students improve twice as much while using Front Row than their peers who aren't using the program.
You'll be THE first Senior Engineer ever at Front Row, which means you'll have an immense impact on our company, product, and culture; you'll have a ton of autonomy and responsibility; you'll have equity to match the weight of this role. If you're looking for an opportunity to both grow and do meaningful work, surrounded and supported by like-minded professionals, this is THE place for you.
You will be working side by side with many well known world-class personalities in the Haskell and Functional Programming community whose work you've likely used. Front Row is an active participant to the Open Source community and contributor to some of the most popular Haskell libraries.
A lot of flexibility: while we all work towards the same goals, you'll have a lot of autonomy in what you work on. You can work from home up to one day a week, and we have a very flexible untracked vacation days policy
The company and its revenue are growing at a rocketship pace. Front Row is projected to make a massive impact on the world of education in the next few years. It's a once in a lifetime opportunity to join a small organization with great odds of becoming the Next Big Thing.
Must haves
- You have experience doing full-stack web development. You understand HTTP, networking, databases and the world of distributed systems.
- You have functional programming experience.
- Extreme hustle: you'll be solving a lot of problems you haven't faced before without the resources and the support of a giant organization. You must thrive on getting things done, whatever the cost.
- Soft skills: we want you to move into a leadership position, so you must be an expert communicator
- You have led a software development team before
- You have familiarity with a functional stack (Haskell / Clojure / Scala / OCaml etc)
- You understand and have worked all around the stack before, from infrastructure automation all the way to the frontend
- You're comfortable with the Behavior-Driven Development style
- You have worked at a very small startup before: you thrive on having a lot of responsibility and little oversight
- You have worked in small and effective Agile/XP teams before
- You have delivered working software to large numbers of users before
- Competitive salary
- Generous equity option grants
- Medical, Dental, and Vision
- Catered lunch and dinner 4 times a week
- Equipment budget
- One flexible work day per week
- Working from downtown SF, very accessible location
- Professional yet casual work environment
Get information on how to apply for this position.Hide
Dictionaries as functions — Shayne Fletcher, Apr 13, 2016
This is an "oldie but a goodie". It's super easy.
A dictionary is a data structure that represents a map from keys to values. The question is, can this data structure and its characteristic operations be encoded using only functions?
The answer of course is yes and indeed, here's one such an encoding in OCaml.
Read more...
(*The type of a dictionary with keys of type [α] and values of type
type (α, β) dict = α -> β option
(*The empty dictionary maps every key to [None]*)
This is an "oldie but a goodie". It's super easy.
A dictionary is a data structure that represents a map from keys to values. The question is, can this data structure and its characteristic operations be encoded using only functions?
The answer of course is yes and indeed, here's one such an encoding in OCaml.
Test it like this.
(*The type of a dictionary with keys of type [α] and values of type
type (α, β) dict = α -> β option
(*The empty dictionary maps every key to [None]*)
let empty (k : α) : β option = None
(*[add d k v] is the dictionary [d] together with a binding of [k] to
let add (d : (α, β) dict) (k : α) (v : β) : (α, β) dict =
fun l ->
if l = k then Some v else d l
(*[find d k] retrieves the value bound to [k]*)
let find (d : (α, β) dict) (k : α) : β option = d k
Name | Age
"Felonius Gru" | 53
"Dave the Minion" | 4.54e9
"Dr. Joseph Albert Nefario" | 80
let despicable =
empty "Felonius Gru" 53
"Dave the Minion" (int_of_float 4.54e9)
"Dr. Nefario" 80
let _ =
find despicable "Dave the Minion" |>
function | Some x -> x | _ -> failwith "Not found"
Moving on, can we implement this in C++? Sure. Here's one way.
#include <pgs/pgs.hpp>
#include <functional>
#include <iostream>
#include <cstdint>
using namespace pgs;
// -- A rough and ready `'a option` (given the absence of
// `std::experimental::optional`
struct None {};
template <class A>
struct Some {
A val;
template <class Arg>
explicit Some (Arg&& s) : val { std::forward<Arg> (s) }
template <class B>
using option = sum_type<None, Some<B>>;
template <class B>
std::ostream& operator << (std::ostream& os, option<B> const& o) {
return o.match<std::ostream&>(
[&](Some<B> const& a) -> std::ostream& { return os << a.val; },
[&](None) -> std::ostream& { return os << "<empty>"; }
//-- Encoding of dictionaries as functions
template <class K, class V>
using dict_type = std::function<option<V>(K)>;
//`empty` is a dictionary constant (a function that maps any key to
template <class A, class B>
dict_type<A, B> empty =
[](A const&) {
return option<B>{ constructor<None>{} };
//`add (d, k, v)` extends `d` with a binding of `k` to `v`
template <class A, class B>
dict_type<A, B> add (dict_type<A, B> const& d, A const& k, B const& v) {
return [=](A const& l) {
return (k == l) ? option<B>{ constructor<Some<B>>{}, v} : d (l);
//`find (d, k)` searches for a binding in `d` for `k`
template <class A, class B>
option<B> find (dict_type<A, B> const& d, A const& k) {
return d (k);
//-- Test driver
int main () {
using dict_t = dict_type<std::string, std::int64_t>;
auto nil = empty<std::string, std::int64_t>;
dict_t(*insert)(dict_t const&, std::string const&, std::int64_t const&) = &add;
dict_t despicable =
insert (
insert (
insert (nil
, std::string {"Felonius Gru"}, std::int64_t{53})
, std::string {"Dave the Minion"}, std::int64_t{4530000000})
, std::string {"Dr. Joseph Albert Nefario"}, std::int64_t{80})
std::cout <<
find (despicable, std::string {"Dave the Minion"}) << std::endl;
return 0;
Weekly News — OCaml Weekly News, Apr 12, 2016
Coq 8.5pl1 is out — Coq, Apr 10, 2016
Weekly News — OCaml Weekly News, Apr 05, 2016
C++ : Streams — Shayne Fletcher, Apr 03, 2016
In this blog post, types and functions were presented in OCaml for modeling streams. This post takes the action to C++.
First, the type definition for a stream.
The definition is in terms of the
struct Nil {};
template <class T> class Cons;
template <class T>
using stream = sum_type <
, recursive_wrapper<Cons<T>>
sum_type<> type from the "pretty good sum" library talked about here.
The definition of
Cons<>, will be in terms of "thunks" (suspensions…
In this blog post, types and functions were presented in OCaml for modeling streams. This post takes the action to C++.
First, the type definition for a stream.
The definition is in terms of the
struct Nil {};
template <class T> class Cons;
template <class T>
using stream = sum_type <
, recursive_wrapper<Cons<T>>
sum_type<> type from the "pretty good sum" library talked about here.
The definition of
Cons<>, will be in terms of "thunks" (suspensions). They're modeled as procedures that when evaluated, compute streams.
To complete the abstraction, a function that given a suspension, "thaws" it.
template <class T>
using stream_thunk = std::function<stream<T>()>;
template <class T> inline
stream<T> force (stream_thunk<T> const& s) {
return s ();
The above choices made, here is the definition for
template <class T>
class Cons {
using value_type = T;
using reference = value_type&;
using const_reference = value_type const&;
using stream_type = stream<value_type>;
using stream_thunk_type = stream_thunk<value_type>;
template <class U, class V>
Cons (U&& h, V&& t) :
h {std::forward<U> (h)}, t {std::forward<V> (t)}
const_reference hd () const { return h; }
stream_type tl () const { return force (t); }
value_type h;
stream_thunk_type t;
Next, utility functions for working with streams.
The function
hd () gets the head of a stream and
tl () gets the stream that remains when the head is stripped off.
template <class T>
T const hd (stream<T> const& s) {
return s.template match<T const&> (
[](Cons<T> const& l) -> T const& { return l.hd (); }
, [](otherwise) -> T const & { throw std::runtime_error { "hd" }; }
template <class T>
stream<T> tl (stream<T> const& l) {
return l.template match <stream<T>> (
[] (Cons<T> const& s) -> stream <T> { return s.tl (); }
, [] (otherwise) -> stream<T> { throw std::runtime_error{"tl"}; }
The function
take () returns the the first $n$ values of a stream.
template <class T, class D>
D take (unsigned int n, stream <T> const& s, D dst) {
return (n == 0) ? dst :
s.template match<D>(
[&](Nil const& _) -> D { return dst; },
[&](Cons<T> const& l) -> D {
return take (n - 1, l.tl (), *dst++ = l.hd ()); }
It's time to share a little "hack" I picked up for writing infinite lists.
- To start, forget about streams;
- Write your list using regular lists;
- Ignore the fact that it won't terminate;
- Rewrite in terms of Cons and convert the tail to a thunk.
For example, in OCaml the (non-terminating!) code
leads to this definition of the stream of natural numbers.
let naturals =
let rec loop x = x :: loop (x + 1) in
next 0
let naturals =
let rec loop x = Cons (x, lazy (loop (x + 1))) in
loop 0
Putting the above to work, a generator for the stream of natural numbers can be written like this.
The first $10$ (say) natural numbers can then be harvested like this.
class natural_numbers_gen {
using int_stream = stream<int>;
int start;
int_stream from (int x) const {
return int_stream{
constructor<Cons<int>>{}, x, [=]() { return this->from (x + 1); }
explicit natural_numbers_gen (int start) : start (start)
explicit operator int_stream() const { return from (start); }
std::vector<int> s;
take (10, stream<int> (natural_numbers_gen{0}), std::back_inserter (s));
The last example, a generator of the Fibonacci sequence. Applying the hack, start with the following OCaml code.
The rewrite of this code into streams then leads to this definition.
let fibonacci_numbers =
let rec fib a b = a :: fib b (a + b) in
fib 0 1
Finally, casting the above function into C++ yields the following.
let fibonnaci_sequence =
let rec fib a b = Cons (a, lazy (fib b (a + b))) in
fib 0 1
class fibonacci_numbers_gen {
using int_stream = stream<int>;
int start;
int_stream loop (int a, int b) const {
return int_stream{
constructor<Cons<int>>{}, a, [=]() {return this->loop (b, a + b); }
explicit fibonacci_numbers_gen ()
explicit operator int_stream() const { return loop (0, 1); }
Rotate — Shayne Fletcher, Apr 02, 2016
This post is inspired by one of those classic "99 problems in Prolog".What we are looking for here are two functions that satisfy these signatures.
val rotate_left : int -> α list -> α list
val rotate_right : int -> α list -> α list
rotate_left n rotates a list $n$ places to the left,
rotate_right n rotates a list $n$ places to the right. Examples:
Read more...
# rotate_left 3 ['a';'b';'c';'d';'e';'f';'g';'h'] ;;
- : char list = ['d'; 'e'; 'f'; 'g'; 'h'; 'a'; 'b'; 'c']
# rotate_lef…
This post is inspired by one of those classic "99 problems in Prolog".What we are looking for here are two functions that satisfy these signatures.
val rotate_left : int -> α list -> α list
val rotate_right : int -> α list -> α list
rotate_left n rotates a list $n$ places to the left,
rotate_right n rotates a list $n$ places to the right. Examples:
Of course,
# rotate_left 3 ['a';'b';'c';'d';'e';'f';'g';'h'] ;;
- : char list = ['d'; 'e'; 'f'; 'g'; 'h'; 'a'; 'b'; 'c']
# rotate_left (-2) ['a';'b';'c';'d';'e';'f';'g';'h'] ;;
- : char list = ['g'; 'h'; 'a'; 'b'; 'c'; 'd'; 'e'; 'f']
rotate_left and
rotate_right are inverse functions of each other so we expect, for any int $x$ and list $l$,
rotate_right x @@ rotate_left x l $=$
rotate_left x @@ rotate_right x l $=$
Well, there are a variety of solutions to this problem with differing degrees of verbosity, complexity and efficiency. My own attempt at a solution resulted in this.
let rec drop (k : int) (l : α list) : α list =
match k, l with
| i, _ when i <= 0 -> l
| _, [] -> []
| _, (_ :: xs) -> drop (k - 1) xs
let rec take (k : int) (l : α list) : α list =
match k, l with
| i, _ when i <= 0 -> []
| _, [] -> []
| _, (x :: xs) -> x :: take (k - 1) xs
let split_at (n : int) (l : α list) : α list * α list =
(take n l), (drop n l)
let rec rotate_left (n : int) (l : α list) : α list =
match n with
| _ when n = 0 -> l
| _ when n < 0 -> rotate_right (-n) l
| _ ->
let m : int = List.length l in
let k : int = n mod m in
let (l : α list), (r : α list) = split_at k l in
r @ l
and rotate_right (n : int) (l : α list) : α list =
match n with
| _ when n = 0 -> l
| _ when n < 0 -> rotate_left (-n) l
| _ ->
let m : int = List.length l in
let k : int = m - n mod m in
let (l : α list), (r : α list) = split_at k l in
r @ l
So far so good, but then I was shown the following solution in Haskell.
I found that pretty nifty! See, in the function
rotateLeft n xs
| n >= 0 = take (length xs) $ drop n $ concat $ repeat xs
| otherwise = rotateLeft (length xs + n) xs
rotateRight n = rotateLeft (-n)
repeat xs creates an infinite list of lists, (each a copy of
length xs which gets us the original list rotated left $n$ places.
I felt compelled to attempt to emulate the program above in OCaml.
The phrasing "works" in Haskell due to the feature of lazy evaluation. OCaml on the other hand is eagerly evaluated. Lazy evaluation is possible in OCaml however, you just need to be explicit about it. Here's a type for "lazy lists" aka "streams".
A value of type
type α stream = Nil | Cons of α * α stream Lazy.t
α Lazy.t is a deferred computation, called a suspension that has the result type
α. The syntax
lazy$(expr)$ makes a suspension of $expr$, without yet evaluating $expr$. "Forcing" the suspension (using
Lazy.force) evaluates $expr$ and returns its result.
Next up, functions to get the head and tail of a stream.
Also useful, a function to lift an
let hd = function | Nil -> failwith "hd" | Cons (h, _) -> h
let tl = function | Nil -> failwith "tl" | Cons (_, t) -> Lazy.force t
α list to an
α stream.
let from_list (l : α list) : α stream =
List.fold_right (fun x s -> Cons (x, lazy s)) l Nil
Those are the basic building blocks. Now we turn attention to implementing
repeat x to create infinite lists of the repeated value $x$.
let rec repeat (x : α) : α stream = Cons (x, lazy (repeat x))
Now to implement
concat (I prefer to call this function by its alternative name
The characteristic operation of
flatten is the joining together of two lists. For eager lists, we can write a function
join that appends two lists like this.
This generalizes naturally to streams.
let rec join l m =
match l with
| [] -> m
| h :: t -> h :: (join t m)
For eager lists, we can write
let rec join (l : α stream) (m : α stream) =
match l with
| Nil -> m
| Cons (h, t) -> Cons (h, lazy (join (Lazy.force t) m))
flatten in terms of
Emboldened by our earlier success we might try to generalize it to streams like this.
let rec flatten : α list list -> α list = function
| [] -> []
| (h :: tl) -> join h (flatten tl)
Sadly, no. This definition is going to result in stack overflow. There is an alternative phrasing of
let rec flatten (l : α stream stream) : α stream =
match l with
| Nil -> lazy Nil
| Cons (l, r) -> join l (flatten (Lazy.force r))
flatten we might try.
Happy to say, this one generalizes and gets around the eager evaluation problem that causes the unbounded recursion.
let rec flatten = function
| [] -> []
| [] :: t -> flatten t
| (x :: xs) :: t -> x :: (flatten (xs :: t))
let rec flatten : α stream stream -> α stream = function
| Nil -> Nil
| Cons (Nil, t) -> flatten (Lazy.force t)
| Cons (Cons (x, xs), t) ->
Cons (x, lazy (flatten (Cons (Lazy.force xs, t))))
take and
drop are straight forward generalizations of their eager counterparts.
let rec drop (n : int) (lst : α stream ) : α stream =
match (n, lst) with
| (n, _) when n < 0 -> invalid_arg "negative index in drop"
| (n, xs) when n = 0 -> xs
| (_, Nil) -> Nil
| (n, Cons (_, t)) -> drop (n - 1) (Lazy.force t)
let rec take (n : int) (lst : α stream) : α list =
match (n, lst) with
| (n, _) when n < 0 -> invalid_arg "negative index in take"
| (n, _) when n = 0 -> []
| (_, Nil) -> []
| (n, Cons (h, t)) -> h :: (take (n - 1) (Lazy.force t))
Which brings us to the lazy version of
rotate expressed in about the same number of lines of code!
let rec rotate_left (k : int) (l : α list) : α list =
let n = List.length l in
if k >= 0 then
l |> from_list |> repeat |> flatten |> drop k |> take n
else rotate_left (n + k) l
let rotate_right (n : int) : α list -> α list = rotate_left (-n)
ASM.OCaml — OCamlPro, Apr 01, 2016
As you may know, there is a subset of Javascript that compiles efficiently to assembly used as backend of various compilers including a C compiler like emscripten. We'd like to present you in the same spirit how never to allocate in OCaml.
Before starting to write anything, we must know how to find if a code is allocating. The best way currently is to look at the Cmm intermediate representation. We can see it by calling `ocamlopt` with the `-dcmm` option:
`ocamlopt -c -dcmm test.ml`
let f…Read more...
As you may know, there is a subset of Javascript that compiles efficiently to assembly used as backend of various compilers including a C compiler like emscripten. We'd like to present you in the same spirit how never to allocate in OCaml.
Before starting to write anything, we must know how to find if a code is allocating. The best way currently is to look at the Cmm intermediate representation. We can see it by calling `ocamlopt` with the `-dcmm` option:
`ocamlopt -c -dcmm test.ml`
let f x = (x,x)
Some excerpt from the output:
(function camlTest__f_4 (x_6/1204: val) (alloc 2048 x_6/1204 x_6/1204))
To improve readability, in this post we will clean a bit the variable names:
(function f (x: val) (alloc 2048 x x))
We see that the function f (named `camlTest__f_4`) is calling the `alloc` primitive, which obviously is an allocation. Here, this creates a size 2 block with tag 0 (2048 = 2 << 10 + 0) and containing two times the value `x_6/1204` which was `x` is the source. So we can detect if some code is allocating by doing `ocamlopt -c -dcmm test.ml 2>&1 | grep alloc` (obviously any function or variable named alloc will also appear).
It is possible to write some code that don't allocate (in the heap) at all, but what are the limitations ? For instance the omnipresent fibonacci function does not allocate:
let rec fib = function | 0 -> 0 | 1 -> 1 | n -> fib (n-1) + fib (n-2)
(function fib (n: val) (if (!= n 1) (if (!= n 3) (let Paddint_arg (app "fib" (+ n -4) val) (+ (+ (app "fib" (+ n -2) val) Paddint_arg) -1)) 3) 1))
But quite a lot of common patterns do:
* Building structured values will allocate (tuple, records, sum types containing an element, …)
* Using floats, int64, … will allocate
* Declaring non-toplevel functions will allocate
Considering that, it can appear that it is almost impossible to write any non-trivial code without using those. But that's not completely true.
There are some exceptions to those rules, where some normally allocating constructions can be optimised away. We will explain how to exploit them to be able to write some more code.
Local references
Maybe the most important one is the case of local references.
let fact n = let result = ref 1 in for i = 1 to n do result := n * !result done; !result
To improve readability, this has been cleaned and demangled
(function fact (n: val) (let (result 3) (seq (let (i 3 bound n) (catch (if (> i bound) (exit 3) (loop (assign result (+ (* (+ n -1) (>>s result 1)) 1)) (assign i (+ i 2)) (if (== i bound) (exit 3) []) with(3) [])))) result)))
You can notice that allocation of the reference disappeared. The modifications were replaced by assignments (the `assign` operator) to the result variable. This transformation can happen when a reference is never used anywhere else than as an argument of the ! and := operator and does not appear in the closure of any local function like:
let counter () = let count = ref 0 in let next () = count := !count + 1; !count in next
This won't happen in this case since count is in the closure of next.
The float, int32, int64 and nativeint types do not fit in the generic representation of values that can be stored in the OCaml heap, so they are boxed. This means that they are allocated and there is an annotation to tell the garbage collector to skip their content. So using them in general will allocate. But an important optimization is that local uses (some cases that obviously won't go in the heap) are 'unboxed', i.e. not allocated.
If/match couple
Some 4.03 change also improve some cases of branching returning tuples
let positive_difference x y = let (min, max) = if x < y then (x, y) else (y, x) in max - min
(function positive_difference (x: val y: val) (catch (if (< x y) (exit 7 y x) (exit 7 x y)) with(7 max min) (+ (- max min) 1)))
Control flow
You can do almost any control flow like that, but this is quite
unpractical and is still limited in many ways.
If you don't want to write everything as for and while loops, you can
write functions for your control flow, but to prevent allocation you
will have to refrain from doing a few things. For instance, you should
not pass record or tupple as argument to functions of course, you
should pass each field separately as a different argument.
But what happens when you want to return multiple values ? There is
some ongoing project to try to optimise the allocations of some of
those cases away, but currently you can't. Really ? NO !
Returning multiple values
If you bend a bit your mind, you may see that returning from a
function is almost the same thing as calling one… Or you can make it
that way. So let's transform our code in 'Continuation Passing Style'
For instance, let's write a function that finds the minimum and the maximum of a list. That could be written like that:
let rec fold_left f init l = match l with | [] -> init | h :: t -> let acc = f init h in fold_left f acc t let keep_min_max (min, max) v = let min = if v < min then v else min in let max = if v > max then v else max in min, max let find_min_max l = match l with | [] -> invalid_arg "find_min_max" | h :: t -> fold_left keep_min_max (h, h) t
Continuation Passing Style
Transforming it to continuation passing style (CPS) replace every function return by a tail-call to a function representing 'what happens after'. This function is usually called a continuation and a convention is to use the variable name 'k' for it.
Let's start simply by turning only the keep_min_max function into continuation passing style.
let keep_min_max (min, max) v k = let min = if v < min then v else min in let max = if v > max then v else max in k (min, max) val keep_min_max : 'a * 'a -> 'a -> ('a * 'a -> 'b) -> 'b
That's all here. But of course we need to modify a bit the function calling it.
let rec fold_left f init l = match l with | [] -> init | h :: t -> let k acc = fold_left f acc t in f init h k val fold_left : ('a -> 'b -> ('a -> 'a) -> 'a) -> 'a -> 'b list -> 'a val find_min_max : 'a list -> 'a * 'a
Here instead of calling f then recursively calling fold_left, we prepare what we will do after calling f (that is calling fold_left) and then we call f with that continuation. find_min_max is unchanged and still has the same type.
But we can continue turning things in CPS, and a full conversion would result in:
let rec fold_left_k f init l k = match l with | [] -> k init | h :: t -> let k acc = fold_left_k f acc t k in f init h k val fold_left_k : ('a -> 'b -> ('a -> 'c) -> 'c) -> 'a -> 'b list -> ('a -> 'c) -> 'c let keep_min_max_k (min, max) v k = let min = if v < min then v else min in let max = if v > max then v else max in k (min, max) val keep_min_max_k : 'a * 'a -> 'a -> ('a * 'a -> 'b) -> 'b let find_min_max_k l k = match l with | [] -> invalid_arg "find_min_max" | h :: t -> fold_left_k keep_min_max (h, h) t k val find_min_max_k : 'a list -> ('a * 'a -> 'b) -> 'b let find_min_max l = find_min_max_k l (fun x -> x) val find_min_max : 'a list -> 'a * 'a
Where rectypes matter for performance reasons
That's nice, we only have tail calls now, but we are not done removing allocation yet of course. We now need to get rid of the allocation of the closure in fold_left_k and of the couples in keep_min_max_k. For that, we need to pass everything that should be allocated as argument:
let rec fold_left_k2 f init1 init2 l k = match l with | [] -> k init1 init2 | h :: t -> f init1 init2 h t fold_left_k2 k val fold_left_k2 : ('b -> 'c -> 'd -> 'd list -> 'a -> ('b -> 'c -> 'e) -> 'e) -> 'b -> 'c -> 'd list -> ('b -> 'c -> 'e) -> 'e as 'a let rec keep_min_max_k2 = fun min max v k_arg k k2 -> let min = if v < min then v else min in let max = if v > max then v else max in k keep_min_max_k2 min max k_arg k2 val keep_min_max_k2 : 'b -> 'b -> 'b -> 'c -> ('a -> 'b -> 'b -> 'c -> 'd -> 'e) -> 'd -> 'e as 'a let find_min_max_k2 l k = match l with | [] -> invalid_arg "find_min_max" | h :: t -> fold_left_k2 keep_min_max_k2 h h t k val find_min_max_k2 : 'a list -> ('a -> 'a -> 'b) -> 'b
For some reason, we now need to activate 'rectypes' to allow functions to have a recursive type (the 'as 'a') but we managed to completely get rid of allocations.
(function fold_left_k2 (f: val init1: val init2: val l: val k: val) (if (!= l 1) (app "caml_apply6" init1 init2 (load val l) l "fold_left_k2" k f val)) (app "caml_apply2" init1 init2 k val))) (function keep_min_max_k2 (min: val max: val v: val k: val k: val k2: val) (let (min (if (!= (extcall "caml_lessthan" v min val) 1) v min) max (if (!= (extcall "caml_greaterthan" v max val) 1) v max)) (app "caml_apply5" "keep_min_max_k2" min max k k2 k val))) (function find_min_max_k2 (l: val k: val) (if (!= l 1) (let h (load val l) (app "fold_left_k2" "keep_min_max_k2" h h t k val)) (raise "exception")))
So we can turn return points into call points and get rid of a lot of potential allocations like that. But of course there is no way to handle functions passing or returning sum types like that ! Well, I'm not so sure.
Sum types
Let's try with the option type for instance:
type 'a option = | None | Some of 'a let add_an_option_value opt v = match opt with | None -> v | Some n -> n + v let n1 = add_an_option_value (Some 3) 4 let n2 = add_an_option_value None 4
The case of the sum type tells us if there is some more values that we can get and their type. But there is another way to associate some type information with an actual value: GADTs
type ('a, 'b) option_case = | None' : ('a, unit) option_case | Some' : ('a, 'a) option_case let add_an_option_value (type t) (opt: (int, t) option_case) (n:t) v = match opt with | None' -> v | Some' -> n + v let n1 = add_an_option_value Some' 3 4 let n2 = add_an_option_value None' () 4
And voilà, no allocation anymore !
Combining that with the CPS transformation can get you quite far without allocating !
Manipulating Memory
Now that we can manage almost any control flow without allocating, we need also to manipulate some values. That's the point where we simply suggest to use the same approach as ASM.js: allocate a single large bigarray (this is some kind of malloc), consider integers as pointers and you can do anything. We won't go into too much details here as this would require another post for that topic.
For some low level packed bitfield manipulation you can have a look at some more tricks
So if you want to write non allocating code in OCaml, turn everything in CPS, add additional arguments everywhere, turn your sum types in unboxed GADTs, manipulate a single large bigarrays. And enjoy !Hide
Ocsigen: step by step tutorial for client-server Web application (2/2) — Ocsigen blog (Ocsigen team), Mar 30, 2016
This is the end of the tutorial about writing a collaborative Web drawing in OCaml. Have a look at the full tutorial if you haven't read the first part or if you want a version with full colors and links.
We will now see how to draw on the canvas, program mouse events with Lwt, and do server…Read more...
This is the end of the tutorial about writing a collaborative Web drawing in OCaml. Have a look at the full tutorial if you haven't read the first part or if you want a version with full colors and links.
We will now see how to draw on the canvas, program mouse events with Lwt, and do server to client communication on a bus.
Collaborative drawing application
Drawing on a canvas
We now want to draw something on the page using an HTML5 canvas. The
drawing primitive is defined in the client-side function called
draw that just draws a line between two given points in a canvas.
To start our collaborative drawing application, we define another
client-side function
init_client, which just draws a single
line for now.
Here is the (full) new version of the program:
JavaScript datatypes in OCaml
Here we use the function
from Js_of_ocaml's library to convert an OCaml string
into a JS string.
Client side side-effect on the server
What sounds a bit weird at first, is a very convenient practice for processing request in a client-server application: If a client value is created while processing a request, it will be evaluated on the client once it receives the response and the document is created; the corresponding side effects are then executed. For example, the line
creates a client value for the sole purpose of performing side
effects on the client. The client value can also be named (as
opposed to ignored via
_), thus enabling server-side
manipulation of client-side values (see below).
Single user drawing application
(Lwt, Mouse events with Lwt)
We now want to catch mouse events to draw lines with the mouse like
with the brush tools of any classical drawing application. One
solution would be to mimic typical JavaScript code in OCaml; for
example by using function
that is the Js_of_ocaml's equivalent of
addEventListener. However, this solution is at least as verbose
as the JavaScript equivalent, hence not satisfactory. Js_of_ocaml's
library provides a much easier way to do that with the help of Lwt.
Replace the
init_client of the previous example by the
following piece of code, then compile and draw!
We use two references
x and
y to record the last mouse
position. The function
set_coord updates those references from
mouse event data. The function
compute_line computes the
coordinates of a line from the initial (old) coordinates to the new
coordinates–the event data sent as a parameter.
The last four lines of code implement the event-handling loop. They
can be read as follows: for each
mousedown event on the canvas,
set_coord, then
line (this will draw a dot), then
behave as the
first of the two following lines that terminates:
- For each mousemove event on the document, call
line(never terminates)
- If there is a mouseup event on the document, call
More on Lwt
Functions in Eliom and Js_of_ocaml which do not implement just a
computation or direct side effect, but rather wait for user activity,
or file system access, or need a unforseeable amount of time to return
are defined with Lwt; instead of returning a value of type
they return an Lwt thread of type
a Lwt.t.
The only way to use the result of such functions (ones that return
values in the Lwt monad), is to use
It is convenient to define an infix operator like this:
Then the code
is conceptually similar to
but only for functions returning a value in the Lwt monad.
For more clarity, there is a syntax extension for Lwt, defining
let%lwt to be used instead of
let for Lwt functions:
Lwt.return creates a terminated thread from a value:
Lwt.return : 'a -> 'a Lwt.t Use it when you must
return something in the Lwt monad (for example in a service handler,
or often after a
Why Lwt?
An Eliom application is a cooperative program, as the server must be able to handle several requests at the same time. Ocsigen is using cooperative threading instead of the more widely used preemptive threading paradigm. It means that no scheduler will interrupt your functions whenever it wants. Switching from one thread to another is done only when there is a cooperation point.
We will use the term cooperative functions to identify functions
implemented in cooperative way, that is: if something takes
(potentially a long) time to complete (for example reading a value
from a database), they insert a cooperation point to let other threads
run. Cooperative functions return a value in the Lwt monad
(that is, a value of type
'a Lwt.t for some type
Lwt.bind and
Lwt.return do not introduce cooperation points.
In our example, the function
Lwt_js_events.mouseup may introduce
a cooperation point, because it is unforseeable when this event
happens. That's why it returns a value in the Lwt monad.
Using cooperative threads has a huge advantage: given that you know precisely where the cooperation points are, you need very few mutexes and you have very low risk of deadlocks!
Using Lwt is very easy and does not cause trouble, provided you never use blocking functions (non-cooperative functions). Blocking functions can cause the entre server to hang! Remember:
- Use the functions from module
Lwt_unixinstead of module
- Use cooperative database libraries (like PG'Ocaml for Lwt),
- If you want to use a non-cooperative function, detach it in another
preemptive thread using
- If you want to launch a long-running computation, manually insert
cooperation points using
Lwt.binddoes not introduce any cooperation point.
Handling events with Lwt
The module
allows easily defining event listeners using Lwt. For example,
Lwt_js_events.click takes a
DOM element and returns an Lwt thread that will wait until a click
occures on this element.
Functions with an ending "s" (
Lwt_js_events.mousedowns, …) start again waiting after the
handler terminates.
Lwt.pick behaves as the first thread
in the list to terminate, and cancels the others.
Collaborative drawing application
(Client server communication)
In order to see what other users are drawing, we now want to do the following:
- Send the coordinates to the server when the user draw a line, then
- Dispatch the coordinates to all connected users.
We first declare a type, shared by the server and the client, describing the color (as RGB values) and coordinates of drawn lines.
We annotate the type declaration with
[@@deriving json] to allow
type-safe deserialization of this type. Eliom forces you to use this
in order to avoid server crashes if a client sends corrupted data.
This is defined using a JSON plugin for
ppx_deriving, which you
need to install. You need to do that for each type of data sent by the
client to the server. This annotation can only be added on types
containing exclusively basic types, or other types annotated with
[@@deriving json].
Then we create an Eliom bus to broadcast drawing events to all client
with the function
This function take as parameter the type of
values carried by the bus.
To write draw commands into the bus, we just replace the function
line in
init_client by:
Finally, to interpret the draw orders read on the bus, we add the
following line at the end of function
Now you can try the program using two browser windows to see that the lines are drawn on both windows.
Communication channels
Eliom provides multiple ways for the server to send unsolicited data to the client:
Eliom_bus.tare broadcasting channels where client and server can participate (see also «a_api project="eliom" subproject="client" | type Eliom_bus.t » in the client API).
Eliom_reactallows sending React events from the server to the client, and conversely.
Eliom_comet.Channel.tare one-way communication channels allowing finer-grained control. It allows sending
Lwt_streamto the client.
Eliom_busare implemented over
It is possible to control the idle behaviour with module
Color and size of the brush
(Widgets with Ocsigen-widgets)
In this section, we add a color picker and slider to choose the size
of the brush. For the colorpicker we used a widget available in
To install Ocsigen widgets, do:
opam pin add ocsigen-widgets https://github.com/ocsigen/ocsigen-widgets.git
opam install ocsigen-widgets
Makefile.options, created by Eliom's distillery, add
ocsigen-widgets.client to the
CLIENT_PACKAGES := ... ocsigen-widgets.client
To create the widget, we add the following code in the
init_client immediately after canvas configuration:
We subsequently add a simple HTML5 slider to change the size of the
brush. Near the
canvas_elt definition, simply add the following
Form.int is a typing information telling that this input takes
an integer value. This kind of input can only be associated to
services taking an integer as parameter.
We then add the slider to the page body, as follows:
To change the size and the color of the brush, we replace the last
line of the function
compute_line in
init_client by:
Finally, we need to add a stylesheet in the headers of our page. To
easily create the
head HTML element, we use the function
You need to install the corresponding stylesheets and images into your
project. The stylesheet files should go to the directory
graffiti.css is a custom-made CSS file.
You can then test your application (
make test.byte).
Ocsigen-widgets is a Js_of_ocaml library providing useful widgets for your Eliom applications. You can use it for building complex user interfaces.
Sending the initial image
(Services sending other data types)
To finish the first part of the tutorial, we want to save the current drawing on server side and send the current image when a new user arrives. To do that, we will use the Cairo binding for OCaml.
For using Cairo, first, make sure that it is installed (it is
available as
cairo2 via OPAM). Second, add it to the
SERVER_PACKAGES in your
SERVER_PACKAGES := ... cairo2
draw_server function below is the equivalent of the
draw function on the server side and the
function outputs the PNG image in a string.
We also define a service that sends the picture:
The module
Eliom_registration defines several modules with
registration functions for a variety of data types. We have already
Eliom_registration.Html5 and
The module
Eliom_registration.String sends arbitrary byte output
(represented by an OCaml string). The handler function must return
a pair consisting of the content and the content-type.
There are also several other output modules, for example:
Eliom_registration.Fileto send static files
Eliom_registration.Redirectionto create a redirection towards another page
Eliom_registration.Anyto create services that decide late what they want to send
Eliom_registration.Ocamlto send any OCaml data to be used in a client side program
Eliom_registration.Actionto create service with no output (the handler function just performs a side effect on the server) and reload the current page (or not). We will see an example of actions in the next chapter.
Loading the initial image
We now want to load the initial image once the canvas is created. Add the following lines just between the creation of the canvas context and the creation of the slider:
You are then ready to try your graffiti-application by
make test.byte.
Note, that the
Makefile from the distillery automatically adds
the packages defined in
SERVER_PACKAGES as an extension in your
configuration file
<extension findlib-package="cairo2" />
Weekly News — OCaml Weekly News, Mar 29, 2016
forge.ocamlcore.org NOT reported as unsafe anymore — OCamlCore Forge News ( (Sylvain Le Gall), Mar 29, 2016
forge.ocamlcore.org reported as unsafe in Firefox/Chrome — OCamlCore Forge News ( (Sylvain Le Gall), Mar 27, 2016
REPLs — Shayne Fletcher, Mar 26, 2016
Reusable interactive REPLI play around with little languages enough that I've found it useful to have a minimal language independent REPL for use as a library component. It is expressed as a single higher order function satisfying this signature:
The first argument
val repl
(eval : α list -> β -> γ)
(pe : δ -> Lexing.lexbuf -> β)
(tok : δ)
(string_of_t : γ -> ε) : unit
eval is a function to evaluate expressions in the language, the secon…Read more...
Reusable interactive REPLI play around with little languages enough that I've found it useful to have a minimal language independent REPL for use as a library component. It is expressed as a single higher order function satisfying this signature:
The first argument
val repl
(eval : α list -> β -> γ)
(pe : δ -> Lexing.lexbuf -> β)
(tok : δ)
(string_of_t : γ -> ε) : unit
eval is a function to evaluate expressions in the language, the second argument
pe the parser entry point,
tok is the lexer start token and the last argument
string_of_t is a function that can compute a string from the result of an evaluated expression.
Here's an example session with a concrete repl for a basic $\lambda$ calculus interpreter (more on that later in this post):
The driver for this program ('lambda_repl.ml') is as simple as this:
? (\p x y.p x y) (\x y. x) a b
? (\p x y.p x y) (\x y. y) a b
The module
let main =
Repl follows ('repl.ml').
let parse
(pe : α -> Lexing.lexbuf -> β)
(le : α)
(lexbuf : Lexing.lexbuf) : β =
pe le lexbuf
| Parsing.Parse_error ->
let curr = lexbuf.Lexing.lex_curr_p in
let line = curr.Lexing.pos_lnum in
let cnum = curr.Lexing.pos_cnum - curr.Lexing.pos_bol in
let tok = Lexing.lexeme lexbuf in
(Failure (
"file \"\", line %d, character %d\nError : Syntax error \"%s\""
line cnum tok))
let from_bytes ?(file : string = "
") (str : string)
(pe : α -> Lexing.lexbuf -> β)
(le : α) : β =
let set_filename lexbuf name =
let open Lexing in
lexbuf.lex_curr_p <- {
lexbuf.lex_curr_p with pos_fname = name
} in
let lexbuf = Lexing.from_string str in
set_filename lexbuf file ;
parse pe le lexbuf
let prompt (continuing:bool) =
(print_string (if (not continuing)
then "? " else "... ");(flush stdout))
let read (continuing:bool)=prompt continuing; input_line stdin
let handle_interpreter_error ?(finally=(fun () -> ())) ex =
match ex with
| Failure s -> finally () ; (Printf.printf "%s\n" s)
| Stack_overflow -> finally () ; Printf.printf "Stack overflow\n"
| Division_by_zero -> finally () ; Printf.printf "Division by zero\n"
| End_of_file -> finally (); raise ex
| _ as e ->
finally ();
Printf.printf "Unknown exception : %s\n" (Printexc.to_string e);
raise e
let safe_proc ?finally f =
try f ()
with exn -> handle_interpreter_error ?finally exn
let reduce
(eval : α list -> β -> γ)
(pe : δ -> Lexing.lexbuf -> β)
(le : δ)
(to_bytes : γ -> ε)
(buf : Buffer.t) : ε =
let t =
eval [] (from_bytes (Buffer.contents buf) pe le) in
to_bytes t
let repl
(eval : α list -> β -> γ)
(pe : δ -> Lexing.lexbuf -> β)
(tok : δ)
(to_bytes : γ -> ε) : unit =
let initial_capacity = 4*1024 in
let buf = Buffer.create initial_capacity in
while true do
let f () =
let l = read ((Buffer.length buf)!=0) in
let len = String.length l in
if len > 0 then
if l.[0] = '%' then ()
if l.[len - 1] = '\\' then
(Buffer.add_string buf ((String.sub l 0 (len-1))^"\n"))
if l.[len-1] = (char_of_int 7) then Buffer.clear buf
let _ = Buffer.add_string buf l in
let s = reduce eval pe tok to_bytes buf in
Buffer.clear buf; print_endline s
in (safe_proc ~finally:(fun () -> Buffer.clear buf) f)
| End_of_file -> print_string "\n"
$\lambda$ calculus interpreterThis implementation is based on the techniques explained in Garrigue's excellent article "Code reuse through polymorphic variants".
First, a module implementing the simple language of variables ('var.ml').
type α impl = [`Var of string]
type t = α impl as α
let mk_var : string -> [> `Var of string] = fun s -> `Var s
let string_of_impl (_ : α -> string) : α impl -> string = function
| `Var s -> s
let rec string_of_t : t -> string = fun v -> string_of_impl string_of_t v
let eval_impl
(env : (string * ([> `Var of string ] as α)) list)
(`Var s as v : α impl) : α =
List.assoc s env
| Not_found -> v
Next, a module extending this base language to implement the language of $\lambda$ expressions ('lambda.ml').
type α impl = [α Var.impl | `Abs of string * α | `App of α * α]
type t = α impl as α
let mk_app : α * β -> [> `App of α * β] =
fun (u, v) -> `App (u, v)
let mk_abs : string * β -> [> `Abs of string * β] =
fun (s, t) -> `Abs (s, t)
module Detail = struct
let gen_sym =
let n = ref 0 in
fun () -> incr n; "_" ^ string_of_int !n
let rec strip (bs : string list) t =
match t with
| `Abs (b, t) -> strip (b :: bs) t
| _ as u -> (List.rev bs, u)
end (*module Detail*)
let string_of_impl (string_of_rec : α -> string) : α impl -> string =
| #Var.t as v -> Var.string_of_impl string_of_rec v
| `App (u, v) ->
"("^(string_of_rec u) ^ ") (" ^ (string_of_rec v)^")"
| `Abs _ as t ->
match (Detail.strip [] t) with
| (b :: bs, u) ->
let binder =
"\\" ^ b ^ (List.fold_right (fun z b -> " " ^ z ^ b) bs ". ") in
binder ^ (string_of_rec u)
| ([], _) -> assert false
let rec string_of_t : t -> string = fun v -> string_of_impl string_of_t v
let eval_impl eval_rec
(env : (string *
`Abs of string * α
| `App of α * α
| `Var of string ] as α))
list) : α impl -> α = function
| #Var.t as v -> Var.eval_impl env v
| `App (u, v) ->
let v' = eval_rec env v in
begin match eval_rec env u with
| `Abs (s, body) -> eval_rec [s, v'] body
| u' -> `App (u', v')
| `Abs (s, u) ->
let s' = Detail.gen_sym () in
`Abs (s', eval_rec ((s, `Var s') :: env) u)
let rec eval (env : (string * t) list) : t -> t =
eval_impl eval env
That's it for the interpreter. All that remains is to put a "front end" on it. First the parser ('lambda_parser.mly').
Lastly, the lexical analyzer ('lambda_lexer.mll').
type t = Lambda.t
let var (s : string) : t =
Var.mk_var s
let abs ((bs : string list), (t : t)) : t =
List.fold_right (fun b u -> Lambda.mk_abs (b, u)) bs t
let app ((t0 : t), (us : t list)) : t =
List.fold_left (fun t u -> Lambda.mk_app (t, u)) t0 us
%token Tlambda Tdot Tlparen Trparen Teof
%nonassoc Tident Tdot Tlparen Trparen Teof
%start main
| term Teof { $1 }
| Tlambda id id_list Tdot term { abs (($2 :: $3), $5) }
| atom atom_list { app ($1, $2) }
| { [] }
| atom atom_list { $1 :: $2 }
| id { var $1 }
| Tlparen term Trparen { $2 }
| { [] }
| id id_list { $1 :: $2 }
| Tident { $1 }
open Lambda_parser
let alpha=['a'-'z' 'A'-'Z']
rule token = parse
['\r' ' ' '\t' '\n'] { token lexbuf }
| '(' { Tlparen }
| ')' { Trparen }
| '\\' { Tlambda }
| '.' { Tdot }
| ((alpha)(alpha)*) as s { Tident s }
| eof { Teof }
Weekly News — OCaml Weekly News, Mar 22, 2016
Format All the Data Structures — Cedeela (simon), Mar 20, 2016
Last October, I moved in Nancy to start working as an engineer with
Jasmin Blanchette on an exciting
project called Nunchaku.
Since my domain is formal logic, I spend a lot of time manipulating,
transforming, and traversing ASTs (abstract syntax trees). My primary
method for debugging is pretty-printing structures; in nunchaku,
I even have a
--print-all flag to print the AST after each transformation,
since the tool is basically a bidirectional pipeline that composes
transformations. I will cert…
Last October, I moved in Nancy to start working as an engineer with
Jasmin Blanchette on an exciting
project called Nunchaku.
Since my domain is formal logic, I spend a lot of time manipulating,
transforming, and traversing ASTs (abstract syntax trees). My primary
method for debugging is pretty-printing structures; in nunchaku,
I even have a
--print-all flag to print the AST after each transformation,
since the tool is basically a bidirectional pipeline that composes
transformations. I will certainly blog on the design of Nunchaku
later, but today I want to present the
module from OCaml, that I use for pretty-printing all my data structures.
I will also use containers
because it provides some additional utils, in particular
CCFormat module contains predefined pretty-printers and printer
combinators that are handy.
Every module name starting with
CC belongs to containers and not to the
standard library.
Even then, it is easy, although a bit tedious, to re-write the
combinators from
CCFormat using only what
Format provides,
so what I'll explain here can be done with vanilla OCaml,
or with, say, the Fmt library.
A quick work on
Fmt and
CCFormat: both are modules that provide additional
facilities on top of
Format (combinators for printing lists, options,
arrays, etc., ANSI codes for coloring the output) that makes life easier.
Format provides the pretty-printing algorithm, the support for
format strings (same as
Printf), basic printers, but does not provide
more than the bare minimum for printing data structures, and that is why
extension libraries exist.
A first taste
Let us say we have a value of type
(int * bool) list, and we want
to print it. We could print it "by hand"
print_int, etc. or even using
but it would be nice to have proper alignment.
let l = CCList.init 100 (fun n-> n, n mod 2 = 0);;
Format.printf "l = [@[<hov>%a@]]@."
CCFormat.(list ~start:"" ~stop:"" (pair int bool)) l;;
And we get something like this (depending on the margin, you might not get the exact same output):
l = [(1, false), (2, true), (3, false), (4, true),
(5, false), (6, true), (7, false), (8, true),
(9, false), (10, true), (11, false), (12, true),
(13, false), (14, true), (15, false), (16, true),
(17, false), (18, true), (19, false), (20, true),
(21, false), (22, true), (23, false), (24, true),
(25, false), (26, true), (27, false), (28, true),
(29, false), (30, true), (31, false), (32, true),
(33, false), (34, true), (35, false), (36, true),
(37, false), (38, true), (39, false), (40, true),
(41, false), (42, true), (43, false), (44, true),
(45, false), (46, true), (47, false), (48, true),
(49, false), (50, true), (51, false), (52, true),
(53, false), (54, true), (55, false), (56, true),
(57, false), (58, true), (59, false), (60, true),
(61, false), (62, true), (63, false), (64, true),
(65, false), (66, true), (67, false), (68, true),
(69, false), (70, true), (71, false), (72, true),
(73, false), (74, true), (75, false), (76, true),
(77, false), (78, true), (79, false), (80, true),
(81, false), (82, true), (83, false), (84, true),
(85, false), (86, true), (87, false), (88, true),
(89, false), (90, true), (91, false), (92, true),
(93, false), (94, true), (95, false), (96, true),
(97, false), (98, true), (99, false), (100, true)]
Nice, but what does this horrible
"l = [@[<hov>%a@]]@." mean?
It's a formatting string (same as in C printf), but more expressive.
- The terminating
@.prints a newline;
- The
@[<hov>......@]is a box that prints the same as
...., but will align its content either horizontally ("h") or vertically ("v"). The other kinds of boxes are "h" (horizontal), "v" (vertical), and "hv" (behaves either like "h" or like "v", but does not mix them). There is a tutorial about boxes on OCaml's website.
- the
"%a"is similar to
"%s", etc. (which print respectively an integer and a string), but it's used for user-defined printers. For instance,
Format.printf "hello %a"has type
(Format.formatter -> 'a -> unit) -> 'a -> unit: it takes a first argument that is an
'aprinter, then the
'ato print. Luckily (or not), the combinators in
CCFormathave similar types, so for instance
CCFormat.int : Format.formatter -> int -> unit, and
CCFormat.(pair int bool) : Format.formatter -> (int * bool) -> unit. Here,
CCFormat.pairis a printer combinator; the stdlib provides a few useful combinators such as
It is usually convenient, when you define some type
t, to
also define nearby a value
val print : Format.formatter -> t -> unit.
This way, it is straightforward to print values of type
t when
debugging time has come. Note that printers take a
formatter as
their first argument (to be used, typically, with
which makes it possible to use them directly on files, etc. without
creating a big string first.
Trees, Recursion, and nested Boxes
A case where boxes are really important is for printing recursive
structures, such as trees. As far as I know, OCaml itself (the compiler)
Format to print its intermediate ASTs, the signatures, etc.
Let us define a small expression type, as an example:
type expr =
| Add of expr * expr
| Fun of bytes * expr
| Const of int
| Var of string
| Let of string * expr * expr
| App of expr * expr ;;
let e1 = Fun ("x", Add (Var "x", Const 1));;
val e1 : expr = Fun ("x", Add (Var "x", Const 1))
Ok, it does the job of representing a λ-calculus expression (with
let-bindings and syntactic sugar for integers, wow!), but the representation
of expressions is not very pretty. So let us use
let rec print_expr out = function
| Const i -> CCFormat.int out i
| Var s -> CCFormat.string out s
| Add (e1,e2) ->
Format.fprintf out "@[<2>%a@ + %a@]" print_expr_inner e1 print_expr_inner e2
| Let (x,e1,e2) ->
Format.fprintf out "@[<v>@[<2>let %s =@ @[%a@] in@]@ %a@]"
x print_expr e1 print_expr e2
| App (e1,e2) ->
Format.fprintf out "@[<2>%a@ %a@]" print_expr_inner e1 print_expr_inner e2
| Fun (x,e) ->
Format.fprintf out "@[<2>fun %s ->@ @[%a@]@]" x print_expr_inner e
and print_expr_inner out e = match e with
| Const _ | Var _ -> print_expr out e
| Add _ | Fun _ | App _ | Let _ ->
Format.fprintf out "(@[%a@])" print_expr e
- the argument
outis the formatter we write into,
CCFormat.intis short for
- the second printer is used to wrap an expression in parenthesis when needed to avoid ambiguities,
- we put boxes around composite expressions to enforce proper indentation,
"@,"is a break (can be replaced by a newline + indentation if it pleases the pretty-printer),
"@ "is either a space or a break,
"@[<2>"starts a box with indentation 2.
This is a very simple printer, and it could be improved, but it contains the gist of how to write a printer for recursive structures. Let see how it performs:
(* define a bigger expression *)
let e2 =
Let ("f", e1,
Let ("x",
App (Var "f", App (Var "f", Const 0)),
Let ("result",
Let ("g",
Fun ("y", App(Var "f", Add (Var "x", Var "y"))),
App (Var "g", (Add (Const 40, Var "x")))),
Add (Const 0, Var "result"))))
(* print it: see the indentation *)
Format.printf "@[<2>e2 =@ %a@]@." print_expr e2;;
e2 =
let f = fun x -> (x + 1) in
let x = f (f 0) in
let result = let g = fun y -> (f (x + y)) in
g (40 + x) in
0 + result
- : unit = ()
For a more realistic example, here is the main printer in Nunchaku. It's not perfect (it prints too many parenthesis) but works pretty well, as the following example shows. Just imagine if there was no indentation…
The toplevel
The toplevel itself (or utop, you
should probably use it!) uses
Format for printing values.
There is a pragma
#install_printer to make it use your own printer:
type complex = Complex.t = { re: float; im: float; };;
let pp_complex out c =
Format.fprintf out "%.2f + %.2fi" c.re c.im;;
#install_printer pp_complex;;
[ {re=1.0; im=(atan 1. *. 4.)}
; {re=0.; im=37.}
- : complex list = [1.00 + 3.14i; 0.00 + 37.00i]
Yes, the toplevel will use the custom printer even inside structures such as lists.
Deriving printers
It is possible to derive printers automatically, using ppx_deriving.show (and possibly camlp4-based things, in versions anterior to 4.02, but ppx is the future). This makes printers even easier to use as, in general, you don't have to write anything to use them on your types (unless you want some specific behavior). It is as simple as:
#require "ppx_deriving.show";;
type foo =
| A of int
| B of string * bool list
[@@deriving show] ;;
type bar = {
foo1 : foo;
foo2 : foo option
} [@@deriving show];;
let b = {foo1=A 42; foo2=Some (B ("a string", [true; false])); };;
Format.asprintf "b=%a" pp_bar b;;
- : string = "b={ foo1 = (A 42); foo2 = (Some B (\"a string\", [true; false])) }"
A word on performance
Adding GADTs to OCaml made it possible to clean
the old magic code dealing with format strings that, once, gave
a reputation for slowness (see the awesome work of Benoit
Vaugon). I hope that flambda
(the new optimization pass in OCaml 4.03) will reduce the performance
overhead even further.
Format is great and you should use it! :)
Unraveling of the tech hiring market — Jane Street (David Powers), Mar 17, 2016
Recruiting talented people has always been challenging.
In some years that meant competing with a hot new company that aggressively courted every fresh graduate with promises of stock options and IPO glory. In other years there wasn't a specific company so much as an entire rising industry looking for people (I'm looking at you cloud services, driverless cars, and peer-to-peer sharing). Either way, we understood the yearly back and forth. Our job was to explain to candidates how we sta…Read more...
Recruiting talented people has always been challenging.
In some years that meant competing with a hot new company that aggressively courted every fresh graduate with promises of stock options and IPO glory. In other years there wasn't a specific company so much as an entire rising industry looking for people (I'm looking at you cloud services, driverless cars, and peer-to-peer sharing). Either way, we understood the yearly back and forth. Our job was to explain to candidates how we stacked up, and more importantly, why a career at Jane Street might be the right choice for many of them.
But this year I got to learn a new name for a new challenge. "Unraveling".
I first encountered it in a book I was reading for fun: "Who Gets What, and Why", by the Nobel Prize-winning economist Alvin Roth. He does a lovely job explaining the idea of a matching market. In a matching market each person wants only one of each item, each item is unique, and each item can be given to at most one person at a time. Jobs are a classic matching market, and just like any market, matching markets can work well, or poorly.
Unraveling is one of the primary things that makes a matching market fail. When a market unravels matches start to happen earlier and earlier, to the point where people no longer get a complete view of their options. In the book Roth relates the story of a person who stepped off of a plane to find three voicemails on his phone. The first offered him a job, the second urged him to respond soon, and the last rescinded the offer because he hadn't responded quickly enough.
We call them exploding offers, and this year they have gotten completely out of hand as companies race to the bottom in their efforts to recruit the next wave of interns and fresh graduates.
Colleges try to impose deadline limits explicitly to stop unraveling, and in the past these have largely been honored. The cheating and fudging, such as it was, was kept to the fringes. But this year it seems like the seal is broken, and we've seen major companies delivering internship and full-time offers with 2 week (and less) hard deadlines. Other companies now routinely deliver expiring bonus offers for signing early. Many of these offers circumvent or outright break the guidelines set down by schools, and if past matching markets are a model for this one, next year will come with even earlier offers and worse conditions.
This unraveling has been the subject of a lot of discussion, both internally at Jane Street and with the various schools we recruit at, who see it - rightly - as bad for their students. How can someone make a thoughtful decision about where they want to build a career without the time to interview at more than one or two places? Unfortunately, most of this discussion is out of the public light, and so the unraveling continues.
We can't control the actions of others, but we also don't have to follow the herd, so we'd like to be clear:
Jane Street is committed to making sure that you have the time and information you need to decide on an offer from us. Our offer letters do have good-until dates as a matter of professional practice, but we try to work with every candidate to choose a date that works for them. We are also happy to extend the date if something unexpected comes up, or, frankly, if someone just needs more time.
Choosing where to start your career is a big decision and we hope you have the time to make a good one.Hide
A Machine Made this Book: Ten Sketches of Computer Science — OCaml Book, Mar 17, 2016
How do we decide where to put ink on a page to draw letters and pictures? How can computers represent all the world's languages and writing systems? What exactly is a computer program, what and how does it calculate, and how can we build one? Can we compress information to make it easier to store and quicker to transmit? How do newspapers print photographs with grey tones using just black ink and white paper? How are paragraphs laid out automatically on a page and split across multiple pages?
InRead more...
How do we decide where to put ink on a page to draw letters and pictures? How can computers represent all the world's languages and writing systems? What exactly is a computer program, what and how does it calculate, and how can we build one? Can we compress information to make it easier to store and quicker to transmit? How do newspapers print photographs with grey tones using just black ink and white paper? How are paragraphs laid out automatically on a page and split across multiple pages?
In A Machine Made this Book, using examples from the publishing industry, John Whitington introduces the fascinating discipline of Computer Science to the uninitiated.
Sample Chapters
- Putting Marks on Paper
- Letter Forms
- Storing Words
- Looking and Finding
- Typing it In
- Saving Space
- Doing Sums
- Grey Areas
- Our Typeface
- Words to Paragraphs
Amazon $19.99 | Website | Google Books | PDF Ebook $9.99
A new Popular Science Book about Computer ScienceHide
Weekly News — OCaml Weekly News, Mar 15, 2016
Ocsigen: step by step tutorial for client-server Web application (1/2) — Ocsigen blog (Vincent Balat), Mar 15, 2016
This post (and the following one) is a step by step tutorial about client-server Web applications in OCaml. You can find the full tutorial here. It introduces the basics of Web programming with OCaml: type-checking HTML, defining services, using lightweight threads, writing a client-server program …
We will write a collaborative drawing application. It is a client-server Web application displaying an area where users can draw using the mouse, and see what other users are drawing at the same t…Read more...
This post (and the following one) is a step by step tutorial about client-server Web applications in OCaml. You can find the full tutorial here. It introduces the basics of Web programming with OCaml: type-checking HTML, defining services, using lightweight threads, writing a client-server program …
We will write a collaborative drawing application. It is a client-server Web application displaying an area where users can draw using the mouse, and see what other users are drawing at the same time and in real-time.
The final eliom code is available for download on github. Git tag eliom-5.0 has been tested against Eliom 5.0.
The application is running online here.
To get started, we recommend using Eliom's distillery, a program which creates scaffolds for Eliom projects. The following command creates a very simple project called graffiti in the directory graffiti:
$ eliom-distillery -name graffiti -template basic.ppx -target-directory graffiti
My first page
(Services, Configuration file, Static validation of HTML)
Our web application consists of a single page for now. Let's start by creating a very basic page. We define the service that will implement this page by the following declaration:
If you are using eliom-distillery just replace the content of the eliom-file by the above lines and run
$ make test.byte
This will compile your application and run ocsigenserver on it. (Refer to the manual on how to compile your project "by hand".)
Your page is now available at URL
Unlike typical web programming techniques (CGI, PHP, …), with Eliom you do not need to write one file per URL. The application can be split into multiple files as per the developer's style. What matters is that you eventually produce a single module (*.cmo or *.cma) for the whole website.
Module Eliom_service allows to create new entry points to your web site, called services. In general, services are attached to a URL and generate a web page. Services are represented by OCaml values, through which you must register a function that will generate a page.
~path corresponds to the URL where you want to attach your service. It is a list of strings. The value
["foo"; "bar"] corresponds to URL
["dir"; ""] corresponds to URL
dir/ (that is: the default page of the directory dir).
Configuration file
In the directory of the project created by the Eliom-distillery, you can find the file
graffiti.conf.in. This file is used in conjunction with the variables in Makefile.options to generate the ocsigenserver configuration file.
Once you start up your application via
make test.byte, the configuration file becomes available at
local/etc/graffiti/graffiti-test.conf. It contains various directives for Ocsigen server (port, log files, extensions to be loaded, etc.), taken from Makefile.options, and something like:
<static dir="static" />
<eliommodule module="/path_to/graffiti.cma" />
<eliom />
<eliommodule ... /> asks the server to load Eliom module
graffiti.cma, containing the Eliom application, at startup and
attach it to this host (and site).
<static ... /> (staticmod) and
<eliom /> are called successively:
- If they exist, files from the directory
/path_to/graffiti/staticwill be served,
- Otherwise, Server will try to generate pages with Eliom (
<eliom />),
- Otherwise it will generate a 404 (Not found) error (default).
Static validation of HTML
There are several ways to create pages for Eliom. You can generate pages as strings (as in other web frameworks). However, it is preferable to generate HTML in a way that provides compile-time HTML correctness guarantees. This tutorial achieves this by using module Eliom_content.Html5.D, which is implemented using the TyXML library. The module defines a construction function for each HTML5 tag.
Note that it is also possible to use the usual HTML syntax directly in OCaml.
The TyXML library (and thus Eliom_content.Html5.D) is very strict and compels you to respect HTML5 standard (with some limitations). For example if you write:
You will get an error message similar to the following, referring to the end of line 2:
Error: This expression has type ([> `PCDATA ] as 'a) Html5.elt
but an expression was expected of type
Html5_types.head_content_fun Html5.elt
Type 'a is not compatible with type Html5_types.head_content_fun =
[ `Base
| `Command
| `Link
| `Meta
| `Noscript of [ `Link | `Meta | `Style ]
| `Script
| `Style ]
The second variant type does not allow tag(s) `PCDATA
Html5_types.head_content_fun is the type of content allowed inside
<head> (
<meta>, etc.). Notice that
<PCDATA (i.e. raw text) is not included in this polymorphic variant type.
Most functions take as parameter the list representing its contents. See other examples below. Each of them take un optional
?a parameter for optional HTML attributes. Mandatory HTML attributes correspond to mandatory OCaml parameters. See below for examples.
Important warning: All the functions you write must be written in a cooperative manner using Lwt. Lwt is a convenient way to implement concurrent programs in OCaml, and is now also widely used for applications unrelated to Ocsigen.
For now we will just use the
Lwt.return function as above. We will come back to Lwt programming later. You can also have a look at the Lwt programming guide.
Execute parts of the program on the client
(Service sending an application, Client and server code, Compiling a web application with server and client parts, Calling JavaScript methods with Js_of_ocaml)
To create our first service, we used the function Eliom_registration.Html5.register_service, as all we wanted to do was return HTML5. But we actually want a service that corresponds to a full Eliom application with client and server parts. To do so, we need to create our own registration module by using the functor
It is now possible to use
My_app for registering our main service
(now at URL
After running again make test.byte, and visiting
http://localhost:8080/, the browser will load the file
graffiti.js, and open an alert-box.
Splitting the code into server and client parts
At the very toplevel of your source file (i.e. not inside modules or other server- /client-parts), you can use the following constructs to indicate which side the code should run on.
[%%client ... ]: the list of enclosed definitions is client-only code (similarly for
[%%server ... ]). With
[%%shared ... ], the code is used both on the server and client.
let%shared: same as above for a single definition.
[%%shared.start]: these set the default location for all definitions that follow, and which do not use the preceding constructs.
If no location is specified, the code is assumed to be for the server.
The above constructs are implemented by means of PPX, OCaml's new mechanism for implementing syntax extensions. See Ppx_eliom for details.
Client parts are executed once, when the client side process is launched. The client process is not restarted after each page change.
In the
Makefile created by the distillery, we automatically split the code into client and server parts, compile the server part as usual, and compile the client part to a JavaScript file using
Client values on the server
Additionally, it is possible to create client values within the server code by the following quotation:
typ is the type of an expression
expr on the client. Note, that such a client value is abstract on the server, but becomes concrete, once it is sent to the client with the next request.
typ can be ommitted if it can be inferred from the usage of the client value in the server code.)
Client values are executed on the client after the service returns. You can use client values when a service wants to ask the client to run something, for example binding some event handler on some element produced by the service.
The client-side parts of the program are compiled to JavaScript by
js_of_ocaml. (Technically,
js_of_ocaml compiles OCaml bytecode to JavaScript.) It is easy to bind JavaScript libraries so that OCaml programs can call JavaScript functions. In the example, we are using the Dom_html module, which is a binding that allows the manipulation of an HTML page.
Js_of_ocaml is using a syntax extension to call JavaScript methods:
obj##m a b cto call the method
mof object
objwith parameters
obj##.mto get a property,
obj##.m := eto set a property, and
new%js constr a b cto call a JavaScript constructor.
More information can be found in the Js_of_ocaml manual, in the module Ppx_js.
Accessing server side variables on client side code
(Executing client side code after loading a page, Sharing server side values, Converting an HTML value to a portion of page (a.k.a. Dom node), Manipulating HTML node 'by reference')
The client side process is not strictly separated from the server side. We can access some server variables from the client code. For instance:
Here, we are increasing the reference count each time the page is accessed. When the page is loaded and the document is in-place, the client program initializes the value inside
[%client ... ], and thus triggers an alert window. More specifically, the variable
c, in the scope of the client value on the server is made available to the client value using the syntax extension
~%c. In doing so, the server side value
c is displayed in a message box on the client.
###Injections: Using server side values in client code
Client side code can reference copies of server side values using syntax
~%variable. Values sent that way are weakly type checked: the name of the client side type must match the server side one. If you define a type and want it to be available on both sides, declare it in
[%%shared ... ]. The Eliom manual provides more information on the Eliom's syntax extension and its compilation process.
Note that the value of an injection into a
[%%client ... ] section is sent only once when starting the application in the browser, and not synced automatically later. In contrast, the values of injections into client values which are created during a request are sent alongside the next response.
Next week
In next tutorial, we will turn the program into a collaborative drawing application, and learn:
- How to draw on a canvas,
- How to program mouse events with
- More about Lwt,
- How to create communication channels with the server
- How to create other types of services
The impatient can find the full tutorial here.Hide
Seven Implementations of Incremental — Jane Street (Yaron Minsky), Mar 10, 2016
We finally got a decent recording of one of my favorite talks. This one is about our Incremental library (which I wrote about here), and in particular about the story of how we got to the present, quite performant, implementation.
It's not clear from the talk, but the work on this library wasn't done by me: The initial version was implemented by Stephen Weeks and Milan Stanojevic, and most of the intermediate versions were implemented by Nick Chapman and Valentin Gatien-Baron.
The high quality …Read more...
We finally got a decent recording of one of my favorite talks. This one is about our Incremental library (which I wrote about here), and in particular about the story of how we got to the present, quite performant, implementation.
It's not clear from the talk, but the work on this library wasn't done by me: The initial version was implemented by Stephen Weeks and Milan Stanojevic, and most of the intermediate versions were implemented by Nick Chapman and Valentin Gatien-Baron.
The high quality org-mode slides, though, are all me.Hide
Software Engineer at Purple (Full-time) — Functional Jobs (FunctionalJobs.com), Mar 08, 2016
Purple is a well-funded startup of about 15 people, backed by an Uber co-founder, and revolutionizing the way people get gas.
We are looking for an experienced Software Engineer who can thrive in a startup environment to help us continue to build and test our backend web service and mobile app platform. You would work closely with our small engineering team in a relatively flat organizational structure. You should be confident taking ownership of your specific piece of the product while being …Read more...
Purple is a well-funded startup of about 15 people, backed by an Uber co-founder, and revolutionizing the way people get gas.
We are looking for an experienced Software Engineer who can thrive in a startup environment to help us continue to build and test our backend web service and mobile app platform. You would work closely with our small engineering team in a relatively flat organizational structure. You should be confident taking ownership of your specific piece of the product while being comfortable reaching across the full stack. We want people who are aware of latest trends and know how to adopt the most appropriate technology. We're looking for someone who is a strong advocate for the best engineering practices.
Most of our codebase is written in Clojure and ClojureScript. While prior Clojure experience is not a requirement, serious candidates must have an interest and willingness to learn Clojure as well as any technologies we are using that they may not currently be familiar with.
Minimum qualifications:
- BS degree in Computer Science, similar technical field of study or equivalent practical experience.
- Strong experience in one or more general purpose programming languages
- Strong experience in at least one scripting language (e.g., JavaScript)
- Interest and ability to learn new programming languages as needed
- Working knowledge of Git
- Ability to communicate with non-technical team members to meet product needs/goals
A big plus, but not required:
- Experience using React and React Native
- Clojure and ClojureScript experience, or:
- Experience in at least one functional programming language (Scala, OCaml, Lisp, Haskell, etc.)
- Familiarity with the JVM and related tooling
Purple is a great team! We are small, savvy, and fun. We have an office based in Westwood. We offer a competitive salary, flexible work schedule, health insurance supplement, and unlimited vacation. Come join our growing team!
Get information on how to apply for this position.Hide
Weekly News — OCaml Weekly News, Mar 08, 2016
OCaml Diary, Part 4b — Rudenoise, Mar 03, 2016
View older blog posts.
- Alex Leighton
- Amir Chaudhry
- Andrei Formiga
- Andrej Bauer
- Andy Ray
- Anil Madhavapeddy
- Ashish Agarwal
- Cameleon news
- Caml INRIA
- Caml Spotting
- Cedeela
- Coherent Graphics
- Coq
- Cranial Burnout
- Cryptosense
- Daniel Bünzli
- Daniel Bünzli (log)
- Dario Teixeira
- David Baelde
- David Mentré
- David Teller
- Erik de Castro Lopo
- Etienne Millon
- Frama-C
- Functional Jobs
- GaGallium
- Gaius Hammond
- Gerd Stolpmann
- GitHub Jobs
- Grant Rettke
- Hong bo Zhang
- Incubaid Research
- Jake Donham
- Jamie Brandon
- Jane Street
- KC Sivaramakrishnan
- Leo White
- LexiFi
- Mads Hartmann
- Magnus Skjegstad
- Marc Simpson
- Matthias Puech
- Matías Giovannini
- Mike Lin
- Mike McClurg
- Mindy Preston
- OCaml Book
- OCaml Labs compiler hacking
- OCaml Platform
- OCaml Weekly News
- OCaml-Java
- OCamlCore Forge News
- OCamlCore Forge Projects
- OCamlCore.com
- OCamlPro
- ODNS project
- Ocaml XMPP project
- Ocsigen blog
- Ocsigen project
- Opa
- Open Mirage
- Orbitz
- Paolo Donadeo
- Perpetually Curious
- Peter Zotov
- Phil Tomson
- Pietro Abate
- Psellos
- Richard Jones
- Rudenoise
- Rudi Grinberg
- Sebastien Mondet
- Shayne Fletcher
- Simon Grondin
- Stefano Zacchiroli
- Sylvain Le Gall
- The Caml Humps
- Thomas Leonard
- Till Varoquaux
- Xinuo Chen
- Yan Shvartzshnaider


text:
Tags Matching:
LGBT pride
Originally published 06/10/2013
Over 50 years, local activists helped gay-rights movement surmount setbacks, make huge gains
Go back 50 years in time.Homosexuality was deemed a mental disorder by the nation's psychiatric authorities, and gay sex was a crime in every state but Illinois. Federal workers could be fired merely for being gay.Today, gays serve openly in the military, work as TV news anchors and federal judges, win elections as big-city mayors and members of Congress. Popular TV shows have gay protagonists.And now the gay-rights movement may be on the cusp of momentous legal breakthroughs. Later this month, a Supreme Court ruling could lead to legalization of same-sex marriage in California, and there's a good chance the court will require the federal government to recognize same-sex marriages in all U.S. jurisdictions where they are legal — as of now, 12 states and Washington, D.C....
- Now it's the University of Louisville's turn to remove a Confederate statue
- A fortress built by Alexander the Great after he conquered Jerusalem has been discovered
- Yale students protest decision to keep Calhoun's name
- Six maps that will make you rethink the world
- Middle Tenn. State President Wants to Strip Confederate General's Name From Building
- The historian and cartographer Bill Rankin has developed a new way to visualize slavery
- Paula S. Fass says young Americans need required national service
- Historians are now trying to show that the gay revolution also took place in the midwest
- The Unconference Movement Grows – And Historians Are Taking the Lead
- New appeal to "Bring Back Military History"

subset: commoncrawl


text:
EXCLUSIVE: Kumare and the Art of iTunes Trailer
Vikram Gandhi's compelling and very funny documentary Kumaré is now available on iTunes, Amazon, Movies on Demand, and more! In the film, Vikram Gandhi himself impersonates a wise Indian Guru and builds a following in Arizona. At the height of his popularity, this Guru named Kumaré must reveal his true identity to his disciples and expose the greatest teaching of all! We have an exclusive trailer for the film, which finds Vikram Gandhi appearing in character as Kumaré, offering a tutorial on how you can purchase or rent his film from iTunes. Watch but don't be fooled. As we near December 21st and the end of our world, some prophets are proving to be false! Worship, instead, at the alter of VOD.
To rent or purchase on iTunes: CLICK HERE
Best of the Web
Latest Headlines
The Interview Was a Horrible Experience Says Seth Rogen
Seth Rogen does not fondly remember the time he almost started a War with The Interview.
Captain America Is Bucky's Only Hope in Latest Civil War Preview
Captain America is The Winter Solider's only hope in a new Civil War sneak peek from Marvel.
Star Wars 8 Set Photos Show Millennium Falcon at the Jedi Temple
New set photos show off the iconic Jedi steps on Ahch-To, where Luke Skywalker has been hiding in seclusion.
James Cameron's Albino Alien Concept Gets an Action Figure
NECA is releasing an Albino Alien action figure based on a discarded Xenomorph James Cameron designed for Aliens.
Aquaman Movie in Danger of Losing Director James Wan?
In the wake of director Seth Grahame-Smith leaving The Flash movie, it's rumored that Aquaman director may be the next to flee DC Comics.
Over 100 Captain America: Civil War Photos Spotlight the New Avengers
Marvel has released over 100 Captain America: Civil War images that bring an all-new Avengers team together.