Why Jane Street Uses OCaml

A Jane Street talk explains how functional programming and static types support reliable trading software, and examines the costs of choosing a less common language.

채널
Jane Street
게시일
2016년 3월 31일
영상
1:06:39
읽기
8분
슬라이드
3
원문
영어
YouTube에서 열기
스크롤하면 영상이 오른쪽 아래로 작아져 계속 재생됩니다. 자막은 읽기 언어를 따릅니다.
읽기 언어2개 언어로 읽을 수 있음
이 글은 아직 한국어 번역이 없어 영어 원문으로 표시합니다.
요약

30초 요약

A Jane Street speaker maps the programming-language landscape and explains why the firm chose OCaml. Examples of immutable data, type inference, optional values and Boolean expressions illustrate the benefits; training, hiring and ecosystem development reveal the organizational trade-offs.

  1. 1A map with fuzzy boundariesThe talk compares functional and imperative styles alongside static and dynamic typing, while acknowledging overlap.
  2. 2A sum without mutationA recursive list sum illustrates an alternative to changing an accumulator in a loop.
  3. 3Make missing cases explicitA Python dictionary example contrasts an implicit assumption with an OCaml option that must be handled.
  4. 4Types as design toolsA Boolean-expression language combines recursive variants, pattern matching and first-class functions.
  5. 5A wide dynamic rangeJane Street uses OCaml for lightweight work and compiled trading systems, sharing tools across the firm.
  6. 6The ecosystem trade-offThe smaller community means fewer ready-made tools and libraries, requiring sustained investment.

핵심 정리

  1. Static types can support both performance and correctness, while type inference reduces annotation overhead.
  2. Functional programming makes functions easy to compose and limits hidden interactions caused by mutable state.
  3. Option types and pattern matching make missing cases explicit without determining the business decision.
  4. One language across scripts and trading systems can make libraries and people easier to share across projects.
  5. An uncommon language can attract candidates but requires investment in training and a smaller tool ecosystem.
  6. Productivity and adoption are difficult to attribute to a language alone.
전문

챕터별로 다듬은 전문 읽기

원본 자막만 보기
01

Mapping programming languages

The speaker introduces the language landscape and compares static and dynamic typing. Types affect both speed and correctness.

Jane Street uses OCaml for a remarkable range of its software. That choice can look strange from the outside, so I want to explain what the language gives us, why we think it is practical for a trading firm, and what it costs us.

A useful, if imperfect, map divides programming languages along two axes: imperative versus functional, and dynamic versus static typing. These categories are not precise boundaries; languages borrow ideas from one another, and people can use the same language in different styles.

On the imperative side, dynamic languages like Python and Ruby are often easy to write and quick to experiment with. Statically typed languages such as Java and C tend to require more explicit structure but can run much faster. Those are broad tendencies, not laws.

A dynamic language has to make decisions at runtime that a static language can often settle earlier. Even addition may mean different things depending on the values involved, and the machinery for deciding what operation to perform has a cost. This helps explain why similar-looking code can differ greatly in speed.

An audience member notes that statically typed code can also inspect types dynamically. I agree: the categories are fuzzy. Java, for example, has reflection, and that runtime flexibility can bring performance costs of its own.

Types also serve correctness. Historically, Fortran's static types helped make numerical computation fast, while Lisp occupied a very different part of the map. Today types can also express properties of a program and help us catch mistakes before it runs.

02

Functional programming and mutation

First-class functions and immutable data offer a different way to structure programs. A list-summing example leads to questions about recursion and shared state.

Functional languages commonly make functions lightweight values: you can pass them to other functions, return them, and store them in data structures. They also support a style that avoids mutation, meaning that values are not repeatedly changed as a computation proceeds.

That may sound odd if you are accustomed to computing by updating variables in a loop. But a computation can be expressed without changing the data it starts with. A small example is summing a list.

The Python version initializes a total to zero, loops over the list, and increments the total. In the OCaml version, a recursive function examines the list: an empty list sums to zero, and a nonempty list sums to its head plus the sum of its tail. Both express the same calculation using different habits.

Summing a list in Python and OCaml
슬라이드 1 / 3Summing a list in Python and OCamlThe example compares an imperative accumulator with a recursive functional formulation.

An audience member asks about recursion and stack usage. Some recursive forms can be optimized into loops, but this simple version is not the only possible implementation. The example is intended to show how to express the calculation without a mutable accumulator, not to claim that every recursive formulation has identical performance.

Why avoid mutation? When multiple pieces of code share a value that can change, one part can affect another in ways that are hard to see locally. Immutable data reduces these hidden channels of communication, making components easier to understand and combine.

The benefit becomes especially clear with concurrency: shared mutable state requires coordination so that different threads do not interfere. Pure functions are easier to reason about because their result depends on their inputs rather than on an unseen history of changes.

That does not mean a useful program can never have effects. Programs must interact with the world, read data, and produce results. The point is to manage mutation and effects deliberately rather than letting them spread everywhere.

An audience member asks whether object-oriented encapsulation can also control mutable state. It can help, but an abstraction still has to account for the ways its state changes. Functional techniques give us another way to limit the number of interactions we must understand.

03

Static types and inference

OCaml and related languages combine functional programming with static checking. Type inference can make code concise while retaining useful guarantees.

The static functional corner includes OCaml, Standard ML, Haskell, Scala, and F#. These languages combine functional programming with type systems that can catch mistakes before execution. OCaml's type inference often works out the types without requiring the programmer to annotate every expression.

For the list-summing function, the compiler can infer that the input is a list of integers and the result is an integer. The code can be concise while still obtaining the performance and checking associated with static types. Inference is not free of trade-offs: error messages can sometimes be difficult to interpret.

04

Correctness in trading software

The speaker explains why testing alone cannot cover every costly failure. An option type makes missing map entries explicit.

Jane Street began moving to OCaml roughly a decade before this talk. Trading software needs to be correct: mistakes can be extraordinarily expensive, and the environment includes unusual events and other market participants acting on their own interests.

Testing matters, but tests cannot cover every possible situation. Financial outcomes can have fat tails, and a rare failure may be much more consequential than ordinary failures. A type system offers another way to rule out classes of mistakes before production, complementing tests rather than replacing them.

Consider Python code that compares two dictionaries. If it loops through keys in the first dictionary and assumes each is also present in the second, a missing key can cause a runtime exception. The program's logic has silently depended on an assumption that was never checked.

A dictionary lookup assumption in Python
슬라이드 2 / 3A dictionary lookup assumption in PythonThe code illustrates a missing-key case that can fail at runtime.

In OCaml, a map lookup can return an option: either a value is present or it is absent. Pattern matching makes the programmer confront both possibilities. The language does not magically decide the correct business behavior, but it makes the missing case explicit at the point where a design decision is needed.

Handling lookup results with an option
슬라이드 3 / 3Handling lookup results with an optionThe comparison shows how an OCaml lookup exposes present and absent cases.

This is why I think of a type system as a design tool, not just a way to catch typos. It encourages us to describe the possibilities in our domain and makes it harder to forget one when implementing the behavior.

05

A language for Boolean expressions

A recursive expression type and evaluator demonstrate how types, pattern matching and first-class functions fit together. A comparison with Java illustrates the trade-offs.

Another example is a small language of Boolean expressions. We can represent true and false, conjunction, disjunction, negation, and a base case whose meaning is supplied separately. The structure of the expression is distinct from the particular facts it tests.

An evaluator walks that structure recursively. It combines the results of subexpressions and calls a supplied function to interpret the base cases. For an email filter, those base cases might ask whether a sender or subject matches a condition; another application can use the same Boolean machinery with different predicates.

The example illustrates the combination of first-class functions, algebraic data types, and pattern matching. A type can describe exactly the shapes an expression may take, and a match can make the cases visible. I contrast this with Java, while acknowledging that the particular comparison is not entirely fair to Java.

06

One language across the firm

OCaml supports both lightweight scripts and performance-sensitive systems. Shared tooling and libraries help people work across projects.

OCaml has a wide dynamic range. It is concise enough for tasks one might otherwise approach with a scripting language, yet compiles to efficient code and offers expressive static types. At Jane Street we use it for scripts, configuration-related work, and trading systems alike.

Using one language across many kinds of work has organizational benefits. Libraries and ideas can be shared, and people can move between projects more easily. At the time of this talk, the firm had roughly 400 employees, including about 70 full-time developers.

07

Teaching, hiring, and ecosystem costs

The speaker discusses training results, recruiting and the disadvantages of a smaller ecosystem. Jane Street invests in tools to make the choice sustainable.

A reasonable concern is whether a relatively unfamiliar language is too difficult for people to learn. I do not think OCaml requires unusually brilliant programmers, although I recognize that my own experience may reflect selection bias.

Our trader training includes about a month of programming instruction. Roughly half of participants become productive programmers. We also saw interns with different prior preparation—including Harvard students who had studied OCaml and MIT students who had not—make progress on a simple project after a few weeks.

Another concern is recruiting. Early on, we posted to an OCaml mailing list, received about 15 responses, pursued a dozen, brought five people in, and hired three. That was useful when we were small, but the more lasting effect has been that our choice attracts people interested in the language who might not otherwise consider a financial firm.

Stephen Weeks is one example of someone whose interest in the technical work helped bring him to Jane Street. The language choice can therefore be a recruiting advantage as well as a constraint, though it will not appeal to everyone.

The biggest drawback is the smaller ecosystem. There are fewer readily available libraries and tools than in the most popular languages, and we have had to invest in improving the surrounding infrastructure. Projects such as OPAM, Merlin, OCP-indent, and documentation tooling have helped, but the cost is real.

For us, the benefits have justified that investment. I am not claiming that OCaml is universally the right choice; I am explaining why the combination of expressive types, functional programming, speed, and a shared language has worked well in our setting.

08

Adoption and measuring productivity

Questions cover network effects, difficulty measuring long-term productivity, and examples of functional programming at other companies.

Asked why these ideas have not spread faster, I point to network effects and inertia. People are trained in existing tools, organizations have existing code, and programming languages also inspire strong personal commitments. It is difficult to establish a single cause for adoption or the lack of it.

Measuring a language's productivity advantage is also difficult. The most important differences may emerge over years of maintenance and across a large codebase, rather than in a short comparison of how fast someone writes a small program. That makes confident numerical claims hard to substantiate.

The audience asks about adoption elsewhere. Functional languages and related ideas have found use at other companies, including Facebook's work on Hack and Flow and Twitter's use of Scala. These examples describe the landscape at the time of the talk; they do not imply that every organization should make the same choice as Jane Street.

Language choices are shaped by technical requirements, existing communities, available tools, and the people an organization can attract and train. Our experience is that an unconventional choice can be practical when its strengths match the work and the organization is willing to invest in the ecosystem.

같은 채널의 다른 글

슬라이드 6장15:33EN
JSJane Street· 2026년 10월 26일Figgie Strategy: Reading Hands, Winning Majorities and Pricing CardsBradley, Mike · Jane StreetJane Street traders Bradley and Mike analyze three games to show how private information, market competition and timing affect card prices.Decision MakingMathematicsFintech
1:48:29EN
JSJane Street· 2026년 10월 16일How AI Is Changing Programming: John Crepezzi and Ron MinskyYaron Minsky, John Crepezzi · Jane StreetJane Street’s AI tooling lead and the Signals and Threads host examine agent infrastructure, security, code review and the changing experience of writing software.코딩 에이전트Developer productivity평가(Evals)+2
1:36:37EN
JSJane Street· 2026년 9월 23일Aaron Bauer on Teaching Software Engineering in the Age of AIYaron Minsky, Aaron Bauer · Jane StreetHow learning goals, active practice and editor design shape engineering education when models can generate the code.AI in EducationSoftware engineeringEducation+2
슬라이드 9장1:05:45EN
JSJane Street· 2026년 9월 11일Cyrus Omar on Live Programming and a Computational Commons for Humans and AICyrus OmarA demonstration of Hazel shows how immediate feedback, structured collaboration and carefully scoped permissions could support people and AI agents working together.Programming LanguagesHuman-AI Collaboration개발 워크플로와 테스트+2
1:25:00EN
JSJane Street· 2026년 9월 2일Eric Mannes on Turning Messy External Data Into Trading ResearchRon, Eric Mannes · Jane StreetFrom commodity futures and an Excel risk system to point-in-time datasets and AI, Eric Mannes explains the domain knowledge behind data engineering at Jane Street.Data quality & curation개발 워크플로와 테스트Investing+2
슬라이드 7장1:16:29EN
JSJane Street· 2026년 8월 26일Grant Sanderson and Alok Puranik: Positional Encodings Through Group TheoryGrant Sanderson, Alok Puranik · 3Blue1BrownStarting with assumptions about attention, they derive matrix exponentials and connect rotations, decay and Jordan blocks to RoPE and ALiBi.Transformers & attentionMathematics머신러닝 기초+1