OCaml Planet

October 05, 2015

Github OCaml jobs

Full Time: Software Developer (Functional Programming) at Jane Street in New York, NY; London, UK; Hong Kong

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

October 04, 2015

Shayne Fletcher

List comprehensions in C++ via the list monad

As explained in Monads for functional programming by Philip Wadler, a monad is a triple $(t, unit, *)$. $t$ is a parametric type, $unit$ and $*$ are operations:

  val unit : α -> α t  val ( * ) : α t -> (α -> β t) -> β t

$m * \lambda\;a.n$

as, "perform computation $m$, bind $a$ to the resulting value, and then perform computation $n$". Referring to the signatures of $*$ and $unit$, in terms of types we see $m$ has the type α t, $\lambda\;a.n$ has type α -> β t and the whole expression has type β t.

In order for $(t, unit, *)$ to be a monad the operations $unit$ and $*$ need satisfy three laws :

• Left unit. Compute the value $a$, bind $b$ to the result, and compute $n$. The result is the same as $n$ with value $a$ substituted for variable $b$.

$unit\;a * \lambda\;b.n = n[a/b]$.

• Right unit. Compute $m$, bind the result to $a$, and return $a$. The result is the same as $m$.

$m * \lambda\;a.unit\;a = m$.

• Associative. Compute $m$, bind the result to $a$, compute $n$, bind the result to $b$, compute $o$. The order of parentheses doesn't matter.

$m * (\lambda\;a.n * \lambda\;b.o) = (m * \lambda\;a.n) * \lambda\;b.o$.

Lists can be viewed as monads.That is, there exist operations $unit$ and $*$ that we may define for lists such that the three monad laws from the preceding section hold.

#include <list>#include <iterator>#include <type_traits>#include <algorithm>#include <iostream>/*  The list monad*///The unit list containing 'a'/*  let unit : 'a -> 'a t = fun a -> [a]*/template <class A> std::list<A> unit (A const& a) { return std::list<A> (1u, a); }//The 'bind' operator/*  let rec ( * ) : 'a t -> ('a -> 'b t) -> 'b t =    fun l -> fun k ->      match l with | [] -> [] | (h :: tl) -> k h @ tl * k*/template <class A, class F>typename std::result_of<F(A)>::type operator * (std::list<A> a, F k) {  typedef typename std::result_of<F(A)>::type result_t;  if (a.empty ())    return result_t ();  result_t res = k (a.front ());  a.pop_front ();  res.splice (res.end (), a * k);  return res;}
The invocation $unit\;a$ forms the unit list containing $a$. The expression, $m * k$ applies $k$ to each element of the list $m$ and appends together the resulting lists.

There are well known derived forms. For example, $join\;z$ is the expression $z * \lambda\;m. m$. In the list monad, it results in a function that concatenates a list of lists.

//'join' concatenates a list of lists/*    let join : 'a t t z = z * fun m -> m*/template <class A>std::list <A> join (std::list<std::list<A>> const& z) {  return z * [](auto m) { return m; };}
The function $map$ is defined by the expression $map\;f\;m = m * \lambda\;a.unit\;(f\;a)$.
//'map' is the equivalent of 'std::transform'/*    let map : ('a -> b') -> 'a t -> 'b t =      fun f -> fun m -> m * fun a -> unit (f a)*/template <class A, class F>std::list<A> map (F f, std::list<A> const& m) {  return m * [=](auto a) { return unit (f (a)); };}

List comprehensions

List comprehensions are neatly expressed as monad operations. Here are some examples.
int main () {  //l = [1, 2, 3]  std::list<int> l = {1, 2, 3};    //m = [1, 4, 9]  auto m = l * [](int x) { return unit (float (x * x)); };  //n = l x m = [(1, 1), (1, 4), (1, 9), (2, 1), (2, 4), (2, 9), ...]  auto n = l * ([&m](int x){ return m * ([=](float y){ return unit (std::make_pair (x, y)); });});  return 0;}

September 18, 2015

Amir Chaudhry

Governance of OCaml.org

For several months, I’ve been working with the maintainers of OCaml.org projects to define and document the governance structure around the domain name. I wrote about this previously and I’m pleased to say that the work for this phase has concluded, with the document now live.

Recurring themes

There were some recurring themes that cropped up during my email discussions with people and I thought it would be useful to present a summary of them, along with my thoughts. Broadly, the discussions revolved around the philosophy of the document, the extent of its scope, and the depth of coverage. This discourse was very important for refining and improving the document.

Ideals and Reality

Some of the comments I received were essentially that the document did not represent how we should be organising ourselves. There was occasionally the sense (to me at least) that the only appropriate form of governance is a fully democratic and representational one.

That would entail things like official committees, ensuring that various communities/organisations were represented, and perhaps establishing some form of electoral processes. Overall, something relatively formal and quite carefully structured. Of course, instituting such an arrangement would necessarily require somewhat involved procedures, documentation, and systems — as well as the volunteer time to manage those processes.

These may be noble aims — and I expect one day we’ll be closer to such ideals — but one of the critical factors for the current approach was that we record how things are right now. In my experience, anything else is purely aspirational and therefore would have little bearing with how things currently function.

To put it another way, the current document must not describe the structure we desire to have, but the organisation we actually have — warts and all. Yes, right now we have a BDFL*, who personally owns the domain and therefore can do as he pleases with it. Irrespective of this, the community has been able to come together, coordinate themselves, and build very useful things around the domain name. This has happened independently of any formal community processes and, in my view, has largely been driven by people supporting each other’s works and generally trying to ‘do the right thing’.

Another aspect to point out is that is that such documents and procedures are not necessary for success. This is obvious when you consider how far the OCaml community has come in such a relatively short space of time. Given this, one might argue why we need any kind of written governance at all.

To answer that, I would say that once things grow beyond a certain scale, I believe it helps to gather the implicit behaviours and document them clearly. This allows us to be more systematic in our approach and also enables newcomers to understand how things work and become involved more quickly. In addition, having a clear record of how things operate in the present is an invaluable tool in helping to clarify what exactly we should work on changing for the future.

Extent of scope

It’s a little confusing to consider that ‘OCaml.org’ is simultaneously a collection of websites, infrastructural components, and projects. Disambiguating these from the wider OCaml community was important, and relatively straightforward, but there were a few questions about the relationship between the domain name and the projects that use it.

Although the governance covers the OCaml.org domain name, it necessarily has an impact on the projects which make use of it. This matters because anything under the OCaml.org domain will, understandably, be taken as authoritative by users at large. In a way, OCaml.org becomes the sum of the projects under it, hence it’s necessary to have some lightweight stipulations about what is expected of those projects.

Projects themselves are free to organise as they wish (BDFL/Democracy/etc) but there are certain guiding principles for OCaml.org that those projects are expected to be compatible with (e.g. openness, community-related, comms, etc). These stipulations are already met by the current projects, so codifying them is intended to clarify expectations for new projects.

Depth of coverage

Another of the recurring points was how the current document didn’t capture every eventuality. Although I could have attempted this, the end result would have been a lengthy document, full of legalese, that I expect very few people would ever read. The document would also have needed to cover eventualities that have not occurred (yet) and/or may be very unlikely to occur.

Of course, this is not a legal document. No-one can be compelled to comply with it and there are very few sanctions for anyone who chooses not to comply. However, for those who’ve agreed to it, acceptance signals a clear intent to take part in a social contract with the others involved in work around the domain name.

Overall, I opted for a lightweight approach that would cover how we typically deal with issues and result in a more readable document. Areas that are ‘unchartered’ for us should be dealt with as they have been so far — through discussion and action — and can subsequently be incorporated when we have a better understanding of the issues and solutions.

A solid starting position

The current version of the governance document is now live and it is very much intended to be a living document, representing where we are now. As the community continues to grow and evolve, we should revisit this to ensure it is accurate and is meeting our needs.

I look forward to seeing where the community takes it!

In case you’re interested, the set of links below covers the journey from beginning to end of this process.

* Yeah, I made sure to add Xavier to the BDFL list before publishing this. :)

Thanks to Ashish, Philippe and Anil for comments on an earlier draft.

OCamlCore Forge Projects

time

The time library provides POSIX clock and time types and functions for OCaml. The bindings try to keep the semantics close to the POSIX API of time.h.

September 10, 2015

OCamlCore Forge Projects

darckup

Manage dar backups.

August 20, 2015

OCaml Labs compiler hacking

Tenth OCaml compiler hacking evening and OCaml/ML talks

We'll be meeting in the Computer Lab next Friday (28th August 2015) for another evening of compiler hacking. All welcome!

We'll also be having an afternoon of OCaml- and ML-related talks beforehand, with titles suspiciously similar to talks at the ML Workshop and OCaml Workshop the following week.

If you're planning to come along to either the talks or to compiler hacking, please add yourself to the Doodle poll. Further updates, if any, will be posted to the compiler hacking mailing list.

Schedule

3.30pm Polymorphism, subtyping and type inference in MLsub
Stephen Dolan (with Alan Mycroft)

3.55pm The State of the OCaml Platform: September 2015
Anil Madhavapeddy (with Amir Chaudhry, Thomas Gazagnaire, Jeremy Yallop, David Sheets)

4.20pm Modular macros
Jeremy Yallop (with Leo White)

4.45pm Break

5.15pm Effective Concurrency through Algebraic Effects
KC Sivaramakrishnan (with Stephen Dolan, Leo White, Jeremy Yallop, Anil Madhavapeddy)

5.40pm A review of the growth of the OCaml community
Amir Chaudhry

6.05pm Persistent Networking with Irmin and MirageOS

6.30pm Food

7.30pm Compiler hacking

Further details

When: 3.30pm (workshop); 6.30pm (compiler hacking), Friday 28th August 2015

Who: anyone interested in improving OCaml. Knowledge of OCaml programming will obviously be helpful, but prior experience of working on OCaml internals isn't necessary.

What: fixing bugs, implementing new features, learning about OCaml internals.

We're defining "compiler" pretty broadly, to include anything that's part of the standard distribution, which means at least the standard library, runtime, tools (ocamldep, ocamllex, ocamlyacc, etc.), ocamlbuild, the documentation, and the compiler itself. We'll have suggestions for mini-projects for various levels of experience (see also some things we've done on previous evenings), but feel free to come along and work on whatever you fancy.

August 19, 2015

Jane Street

No (functional) experience required

Jane Street is a serious functional programming shop. We use OCaml, a statically typed functional language for almost everything and have what is probably the largest OCaml codebase anywhere.

This leads lots of people to think that they shouldn't even bother applying, under the assumption that we are only interested in hiring deep functional programming gurus. I think people get to this conclusion in part because they think of functional languages, especially those with fancy type systems, as arcane tools that can only be used effectively after deep study.

To the contrary, one of the reasons we started building production systems with OCaml was that it was relatively easy to understand, even for people with no formal CS background. Since then, we've had good experiences taking students with no functional experience at all and getting them to the point of being able to complete a project in just a few weeks. We also have a very successful "OCaml Bootcamp" program, where over four weeks, we train all of the incoming traders and many other non-developer hires on OCaml and our development tools and libraries. By the end, most of them are able to create useful applications.

All of this is to say that we don't go out of our way to hire people who are already familiar with functional programming. In practice, it's just not that hard for strong programmers to pick it up after they start.

That said, a solid majority of the developers we hire do come in with functional programming experience --- but that's because of their preferences, not ours. Programmers with an interest in functional languages have an extra reason to want to work here, and so we get an unusually high number of good applicants from that pool.

There's a more general lesson here: using well-loved tools is a good way of attracting (and retaining) great developers.

August 18, 2015

Functional Jobs

We’re a team of functional programmers writing apps and services in Haskell (and Javascript). Yes, it’s true: Haskell is our main backend language. We also use functional programming practices across our stack.

Wagon is a great place to do your best work. We love to teach and learn functional programming; our team is humble, hard working, and fun. We speak at the Bay Area Haskell Meetup, contribute to open source, and have weekly lunches with interesting people from the community.

Work on challenging engineering problems at Wagon. How to integrate Haskell with modern client- and server-side technologies, like Electron and Docker? How to deploy and manage distributed systems built with Haskell? Which pieces of our infrastructure should we open-source?

Background

• love of functional programming
• personal project or production experience using Haskell, OCaml, Clojure, or Scala
• passionate (but practical) about software architecture
• interested in data processing, scaling, and performance challenges
• experience with databases (optional)

Role

• write Haskell for client- and server-side applications
• integrate Haskell with modern tools like Docker, AWS, and Electron
• architect Wagon to work with analytic databases like Redshift, BigQuery, Spark, etc
• build systems and abstractions for streaming data processing and numeric computing
• work with libraries like Conduit, Warp, and Aeson
• use testing frameworks like QuickCheck and HSpec
• develop deployment and monitoring tools for distributed Haskell systems

Get information on how to apply for this position.