Standard Chartered Drops Haskell Laziness to Stabilize Quant Engine

CUFP 2011 Keynote: Pragmatic Haskell (Lennart Augustsson Standard Chartered Bank) — anilmvs

anilmvs

Standard Chartered disabled default recursion and replaced lazy evaluation with strict execution in its proprietary compiler because unpredictable memory blowups and untraceable runtime crashes make standard Haskell unworkable for enterprise production.

AI-assisted summary of CUFP 2011 Keynote: Pragmatic Haskell (Lennart Augustsson Standard Chartered Bank) — original source. Check the original for full context.

Source published:

Key ideas

  • Lennart Augustsson details Mu, a proprietary Haskell dialect at Standard Chartered Bank that runs 400,000 lines of production code across 2,400 modules, replacing laziness with strict evaluation and implementing strings as compact abstract data types rather than linked lists of characters. (11:59)
  • General recursion is disabled by default in Mu, requiring the explicit language pragma {-# LANGUAGE Recursion #-}; an internal audit revealed that only roughly 6% of production modules ever activate recursion, as quants rely instead on bulk array combinators and relational operations. (14:31)
  • Standard Chartered integrates Mu deeply into Microsoft Excel by wrapping complex functional data structures into tagged handle strings, exposing sheet-defined functions to higher-order combinators, and providing runtime native JIT compilation via LLVM IR. (29:47)
  • Augustsson argues that while laziness provides theoretical elegance and semantic compositionality, strictness delivers critical operational benefits in enterprise software, notably predictable resource consumption and deterministic chronological stack traces on failure. (50:22)

Detailed notes

## Background This keynote was recorded at CUFP 2011 and published on YouTube by anilmvs on March 27, 2012. According to the description, functional programming pioneer Lennart Augustsson reflects on his commercial use of Haskell and his creation of four Haskell implementations—three of which are unorthodox—while demonstrating his strict internal dialect used at Standard Chartered Bank and providing a pragmatic assessment of strict versus lazy evaluation.

## TL;DR Augustsson chronicles his history building non-standard Haskell compilers—from the early days of HBC and pH to Bluespec and his strict proprietary dialect, Mu, built for Standard Chartered Bank. He explains how Mu departs from standard Haskell by enforcing strict evaluation, disabling general recursion by default, abstracting strings, and splitting effects into a two-tier IO model tailored for financial models. Through live demos, he shows how Mu compiles Haskell and sheet-defined functions directly inside Microsoft Excel, serializing intermediate representation for distributed compute farms and LLVM JIT compilation. Finally, he weighs the trade-offs of strict versus lazy semantics in production, arguing that strictness provides vital stack traces, predictable resource compositionality, and clear compiler diagnostics across a 400,000-line codebase.

## Atmosphere & style Augustsson delivers the address with an unassuming, dryly humorous, and thoroughly unpretentious tone, effortlessly deflating theoretical dogma with candid lessons from commercial engineering. The atmosphere is casual yet intellectually engaging, blending witty anecdotes about early Haskell history with wry commentary on corporate banking habits and Excel's interface quirks. Watching the session feels like listening to an experienced compiler veteran demystify complex language internals through an accessible, pragmatic lens.

## Bulletin - [11:59](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=719s) Lennart Augustsson details Mu, a proprietary Haskell dialect at Standard Chartered Bank that runs 400,000 lines of production code across 2,400 modules, replacing laziness with strict evaluation and implementing strings as compact abstract data types rather than linked lists of characters. - [14:31](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=871s) General recursion is disabled by default in Mu, requiring the explicit language pragma {-# LANGUAGE Recursion #-}; an internal audit revealed that only roughly 6% of production modules ever activate recursion, as quants rely instead on bulk array combinators and relational operations. - [29:47](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1787s) Standard Chartered integrates Mu deeply into Microsoft Excel by wrapping complex functional data structures into tagged handle strings, exposing sheet-defined functions to higher-order combinators, and providing runtime native JIT compilation via LLVM IR. - [50:22](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3022s) Augustsson argues that while laziness provides theoretical elegance and semantic compositionality, strictness delivers critical operational benefits in enterprise software, notably predictable resource consumption and deterministic chronological stack traces on failure.

## Key takeaways - [03:04](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=184s) Lennart Augustsson authored HBC in 1990 as the first public Haskell compiler using native code generators across multiple architectures, outperforming GHC on several benchmarks as late as 2007. - [05:49](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=349s) MIT's pH (Parallel Haskell) operated as an eager, non-strict functional language using speculative lightweight threads and runtime thread termination, directly prompting the Haskell committee to adopt the term 'non-strict' over 'lazy'. - [08:25](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=505s) Bluespec originally used pure Haskell as a compile-time elaboration stage to synthesize hardware with type-level natural arithmetic, but pivoted to SystemVerilog syntax due to commercial resistance to Haskell syntax among hardware engineers. - [11:59](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=719s) Mu diverges significantly from standard Haskell by adopting strict-by-default evaluation, abstract string representations instead of [Char], and omitting arbitrary-precision Integer by default, which prevents direct adoption of Hackage packages. - [14:31](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=871s) To mirror Microsoft Excel's distinction between pure cell formulas, volatile read calculations, and mutating macros, Mu separates side effects into a read-only SafeIO monad and standard IO. - [17:31](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1051s) Lists in Mu are internally backed by flat arrays, delivering O(1) indexed random access but altering the operational cost model for prepending and concatenation compared to linked lists. - [19:57](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1197s) The Mu compiler assumes that all input programs terminate, allowing it to freely apply both strict and lazy compiler optimizations, including dead-code elimination of unused bindings containing trace side effects. - [22:47](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1367s) Standard Chartered's Cortex platform enables cross-language interoperability across C++, compiled Haskell, Mu, C#, Java, and Excel via uniform binary serialization and calling conventions. - [29:47](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1787s) Unlike competing investment banks that map pointers directly to floating-point numbers or negative integers, Standard Chartered safely represents complex object handles inside Excel's four-type system using tagged string identifiers. - [37:50](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2270s) Excel users can turn ordinary grid formulas spanning input and output cells into first-class sheet-defined functions that can be passed directly into higher-order functional combinators like map. - [42:46](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2566s) Mu exposes native JIT compilation under explicit user control via LLVM, performing runtime partial evaluation, constant propagation, and dead-branch elimination on partially applied functions. - [46:54](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2814s) All Mu functions retain their intermediate representation throughout their lifecycle, enabling distributed cross-architecture execution where platform-neutral IR is serialized and compiled natively on remote compute nodes. - [50:22](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3022s) Strict evaluation delivers superior resource compositionality and immediate, chronological call-stack traces upon runtime errors, resolving two of the biggest operational friction points of lazy Haskell. - [53:36](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3216s) Mu implements non-strict control-flow primitives such as when, unless, and fromMaybe using a by-name keyword that uses hygienic let-binding expansion to avoid repeated evaluations of shared arguments. - [58:27](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3507s) Mu improves developer productivity for non-CS quants by providing two-location type error diagnostics that pinpoint both conflicting type sources simultaneously, rather than reporting an arbitrary traversal unification failure. - [58:27](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3507s) The entire 400,000-line Mu codebase type-checks in roughly 30 seconds on a developer desktop, and adoption has flourished organically among front-office traders using Mu as a type-safe glue layer over C++ numerical routines.

## Detailed walkthrough ### [00:09](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=9s) Introduction to CUFP 2011 and Lennart Augustsson

The Commercial Users of Functional Programming (CUFP) 2011 conference opens with introductory remarks reflecting on the accelerating momentum of functional programming across industry. More developers and companies than ever are discovering functional languages as pragmatic "secret weapons" to solve complex real-world problems across diverse domains. To kick off the keynote, the host introduces Lennart Augustsson of Standard Chartered Bank, describing him as a legendary pioneer who has been at the center of functional language design and compilation since the very beginning, including his role in building the early compilers for lazy functional languages and serving as one of the founding figures of the Haskell language committee.

Taking the stage to applause, Augustsson sets a relaxed, unassuming tone for his talk, titled *Pragmatic Haskell*. He announces that rather than offering an overly theoretical academic presentation, he will explore the practical realities of using functional programming in production, walk through several idiosyncratic and unorthodox Haskell implementations he has created over his career, give a demonstration of the functional tools used at Standard Chartered Bank, and present a pragmatic critique of strict versus lazy evaluation. As Lennart Augustsson outlines his agenda: “So this is not going to be a deep talk; I'm going to talk about a couple of different things.”

```mermaid flowchart LR accTitle: Evolution of Lennart Augustsson's Haskell Implementations accDescr: Diagram tracing the four non-standard Haskell implementations developed by Lennart Augustsson from HBC in 1990 to Mu at Standard Chartered. subgraph Early["Academic & Parallel"] HBC["HBC (1990)<br/>First public Haskell compiler<br/>Lazy evaluation & native code"] PH["pH (ca. 1995)<br/>Parallel Haskell at MIT<br/>Eager non-strict & MVars/IVars"] end subgraph HardwareAndIndustry["Hardware & Finance"] BS["Bluespec (ca. 2000)<br/>Two-level hardware synthesis<br/>Type-level numeric arithmetic"] MU["Mu (Standard Chartered)<br/>Strict by default & no recursion<br/>SafeIO & array combinators"] end HBC --> PH PH --> BS BS --> MU ```

[03:04](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=184s) HBC: The First Public Haskell Compiler

Augustsson clarifies a misconception about his role at the dawn of Haskell. While he did build HBC (the Chalmers Haskell Compiler), the very first publicly available Haskell compiler, he was not present at the initial formative meeting in Portland, Oregon in 1988 where the committee was formed. Instead, his Chalmers colleague Thomas Johnsson attended. As Augustsson tells the story, when it came time to implement the language, he and Johnsson literally flipped a coin; Johnsson won the toss and chose to remain working on the Lazy ML (LML) compiler, leaving Augustsson with the task of writing HBC.

Released in 1990, HBC saw its most recent release in 2004—a distinction Augustsson jokingly emphasizes. Even years later, the compiler showed surprising endurance: in 2007, when Don Stewart ran Haskell benchmark suites, HBC still managed to beat the Glasgow Haskell Compiler (GHC) on several tests. However, maintaining HBC was grueling because Augustsson had built native code generators targeting an excessive number of machine architectures, ranging across SPARC, VAX, m68k, Alpha, HP-PA, and x86. Shipping a release meant cross-compiling and testing across obsolete systems, making updates painful. HBC stuck closely to the emerging Haskell standard with minimal extensions, though it did pioneer early support for existential types.

- HBC was first released in 1990, with a final maintenance release in 2004. - In 2007 performance benchmarks, HBC still outperformed GHC on several benchmark programs. - As Augustsson wryly quipped about HBC's timeline: “I said first released in 1990; I say latest release in 2004, I didn't say last.” - The compiler avoided C as an intermediate layer, relying instead on handcrafted native code backends for far too many architectures.

[05:49](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=349s) pH: Parallel Non-Strict Haskell at MIT

Augustsson later set out to rewrite the Haskell compiler entirely in Haskell. While he never completed the original project, his front-end codebase became the foundation for pH (Parallel Haskell), developed at MIT under Professor Arvind and Rishiyur S. Nikhil. pH took an entirely different approach to executing functional code: it discarded lazy evaluation in favor of fine-grained eager parallel evaluation while preserving non-strict semantics. Augustsson explains that the Haskell report explicitly uses the phrasing "a non-strict functional language" rather than "lazy" specifically because Arvind objected to the term during committee meetings, having pH's execution model in mind.

In pH, expressions were evaluated speculatively and ahead of time in independent lightweight threads rather than waiting for values to be demanded. If a computation turned out to be unneeded, an aggressive runtime scheduler was responsible for detecting that fact and killing off the speculative thread, yielding non-strict semantics identical to lazy evaluation without retaining lazy thunks. pH also introduced concurrency primitives such as MVars and IVars long before they were adopted by GHC. However, because monads were not yet widely understood at the time, pH introduced these synchronization variables without a monadic wrapper, resulting in a notoriously messy programming model.

- Professor Arvind insisted on the formal phrasing of the Haskell 98 standard: “It didn't say that from the beginning; it said lazy, but Arvind, who was there, he objected to this and said it shouldn't say lazy, it should say non-strict, because he had exactly this kind of implementation in mind.” - pH achieved non-strict semantics through fine-grained parallelism, speculative thread execution, and scheduler-based thread termination. - MVars and IVars were incorporated around 1995 without monadic typing, making concurrent state side-effects chaotic to manage.

[08:25](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=505s) Bluespec: Compiling Haskell into Hardware

Around 2000, Augustsson worked on Bluespec, an innovative hardware description language (HDL) conceived by Rishiyur S. Nikhil. In its original design, Bluespec was pure Haskell, operating as a distinct two-level language. The entire functional Haskell language was available as an elaboration and metaprogramming stage executed strictly at compile time. This compile-time metaprogramming phase unrolled data paths and generated the concrete hardware description, which operated under an entirely different execution model based on guarded atomic actions. The catch was that any compile-time functional code had to terminate; if a programmer wrote an infinite loop, the hardware synthesis compiler simply hung indefinitely.

Bluespec also pioneered advanced type-level programming features years before they appeared in mainstream Haskell. Because digital circuit designers work constantly with fixed-width bit registers, the type system supported type-level natural numbers and arithmetic constraints. Concatenating a register of length `n` with a register of length `m` yielded a register of length `n + m`, verified at compile time using type classes that solved arithmetic relations. When Bluespec spun off into an independent venture-backed commercial company, venture capitalists conducted due diligence and discovered that electrical engineers balked at Haskell's syntax. Consequently, Bluespec abandoned its Haskell-style syntax in favor of a SystemVerilog-like facade, even though the underlying semantics remained purely functional.

- Bluespec utilized full Haskell as a compile-time macro language to generate structural circuit designs. - It introduced type-level naturals and arithmetic constraints to track bit-vector sizes statically. - As Augustsson recounted regarding the commercial pivot to SystemVerilog syntax: “The venture capitalists, they did some due diligence, and they found out that hardware people were not really interested in Haskell syntax; they wanted something they could actually read.”

[11:59](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=719s) Mu: A Pragmatic, Strict Dialect at Standard Chartered

Augustsson turns to his latest Haskell compiler implementation, an internal dialect created at Standard Chartered Bank known as Mu. Rather than developing another compiler for fun, Mu was created out of specific institutional and performance constraints. Unlike standard Haskell, Mu is strict by default, departing from lazy evaluation. Augustsson argues that lazily evaluated data structures create friction and unpredictability in enterprise computing, so Mu evaluates arguments eagerly unless explicitly deferred.

A second critical departure in Mu is its handling of text. In standard Haskell, `String` is defined as a lazy linked list of characters (`[Char]`). In Mu, strings are a distinct, compact abstract data type, and the standard list-of-characters definition is rejected entirely. Augustsson identifies this design difference as the primary obstacle preventing Standard Chartered from taking off-the-shelf packages from Hackage, as nearly all standard libraries assume list operations work on strings. Furthermore, Mu omits Haskell’s arbitrary-precision `Integer` type by default, preferring fixed-width integers and floats suited to financial algorithms.

- Mu is evaluated strictly by default, discarding pervasive lazy evaluation. - Reflecting on Haskell's legacy string representation, Augustsson remarked: “When Haskell was designed, I thought it was a great idea to have String be a list of characters; now I think that was a big mistake, it should be an abstract type.” - The incompatibility between abstract strings and Hackage's `[Char]` prevents direct reuse of standard open-source Haskell packages. - Arbitrary-precision `Integer` values are absent from the core dialect in favor of machine-sized numeric types.

[14:31](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=871s) Recursion Pragmas and the SafeIO Monad

One of the most surprising features of Mu is that recursion is disabled by default. While functional programming is often taught as being synonymous with recursive functions, Augustsson points out that the primary users of Mu inside the bank are financial quantitative analysts and traders. These practitioners do not write manual recursive loops over recursive data types; instead, they operate on tabular arrays of records, numerical matrices, and relational datasets. To prevent infinite loops and encourage idiomatic bulk operations, the platform supplies rich combinator libraries for manipulating arrays and relational data. If an engineer genuinely requires explicit recursion, they must opt in by writing the compiler directive `{-# LANGUAGE Recursion #-}` at the top of their file. An audit of the bank's production codebase revealed that only about 6% of all Mu modules ever enable recursion.

```mermaid flowchart TD accTitle: Effect Boundaries in Mu and Excel accDescr: Comparison of side-effect classifications showing how Mu mirrors Microsoft Excel's distinction between pure, volatile read, and write effects. subgraph ExcelEffects["Microsoft Excel Model"] E_Pure["Pure Functions<br/>Deterministic calculation"] E_Volatile["Volatile Functions<br/>e.g., RAND(), NOW() (Read-only)"] E_Write["Macros / Commands<br/>VBA side effects & sheet writes"] end subgraph MuMonads["Mu Language System"] M_Pure["Pure Expressions<br/>Mathematical transformations"] M_SafeIO["SafeIO Monad ('I')<br/>Read market data / environment"] M_IO["Full IO Monad<br/>Write database / network side-effects"] end E_Pure <--> M_Pure E_Volatile <--> M_SafeIO E_Write <--> M_IO ```

Mu also adapts Haskell’s effect system to integrate cleanly with Microsoft Excel, one of the bank’s primary user interfaces. Excel maintains a more fine-grained effect model than standard Haskell, separating calculations into pure functions, volatile functions with read-only effects (such as fetching live market prices), and mutating commands with write effects. To reflect this hierarchy, Mu splits the standard `IO` monad into two tiers: standard `IO` and `SafeIO` (which Augustsson suggests should really just be named `I` for input). Code executing within `SafeIO` can observe external environment states and read live data streams, but it cannot trigger mutations or external actions.

- Only roughly 6% of Standard Chartered's production modules activate the `{-# LANGUAGE Recursion #-}` pragma: “I checked our modules, by the way, so it's about six percent of the modules that actually turn on recursion.” - Core computational primitives and performance-critical operations in Mu are implemented under the hood in C++. - The `SafeIO` monad prevents unauthorized mutations in analytical formulas: “You can't fire the missiles in the SafeIO monad; you can only read things from the world.” - The two-tier IO model mirrors Excel's boundary between pure cell formulas, volatile read-only inputs, and state-altering spreadsheet macros.

[17:31](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1051s) Strict Evaluation, Non-Recursion, and Lists as Arrays

Lennart Augustsson illustrates the differences in Mu by giving the example of a `getArgs` function that retrieves command-line arguments, highlighting how standard assumptions break down when transitioning away from pure laziness. When an audience member asks whether there is an inherent connection between the language being strict and the absence of general recursion, Augustsson is skeptical: “No, I don’t think so. Well, maybe there is, but I don’t know what the connection is.” The questioner clarifies that the major divergence between strict and lazy paradigms typically manifests in the programming style used when composing many loop-like components. Augustsson agrees that if a programmer is not assembling chains of loop-like constructs, the practical difference narrows significantly.

Turning to data representations, Augustsson points out that what appears syntactically as a list in Mu is actually an array under the hood. Arrays carry fundamentally different cost models compared to linked lists: indexed element access is $O(1)$, but concatenation and consing are not genuinely constant time. Because Mu avoids recursion, developers do not construct sequences by iteratively consing elements onto the head; instead, they operate on data structures in bulk. As a consequence, the divergent operational profile of arrays rarely poses an issue in practice.

- Mu code is upwardly compatible with standard Haskell: running Mu code in Haskell requires only importing a compatibility library, but the reverse does not hold. - Syntactic lists are implemented as arrays, providing constant-time random access at the cost of $O(1)$ prepend operations. - The absence of general recursion encourages bulk transformations over incremental cons-cell construction.

---

[19:57](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1197s) Semantic Freedoms and Compiler Transformations

Augustsson admits to taking notable theoretical liberties when designing the Mu compiler. In standard programming language theory, strict and lazy languages allow strictly disjoint sets of program transformations. Rather than conforming strictly to either semantic regime, the Mu compiler operates under the pragmatic assumption that all programs terminate, granting itself permission to execute whatever optimizations it prefers. As Augustsson quips to the audience: “Remember the name of the talk: Pragmatic Haskell.” When mathematically inclined colleagues object that these transformations do not preserve semantics, he freely admits they are right, but proceeds regardless.

```mermaid flowchart TD accTitle: Mu Compiler Optimization Strategy accDescr: The Mu compiler assumes total termination to apply both strict and lazy transformations freely. subgraph Input["Language Paradigms"] SL["Strict Semantics (S)"] LZ["Lazy Semantics (L)"] end subgraph Engine["Mu Compiler Engine"] Assumption["Pragmatic Axiom:<br/>Assume all expressions terminate"] Opt["Apply both S-valid and L-valid optimizations"] end subgraph Outcome["Runtime Behavior"] Dead["Dead binding elimination<br/>(discards unused trace effects)"] Reorder["Haskell-style binding reordering<br/>(independent of lexical order)"] end Input --> Assumption Assumption --> Opt Opt --> Outcome ```

These shortcuts make program transformations far simpler: “It’s much easier to do compiler transformation or program transformation if you don’t have to preserve semantics.” One direct consequence involves side effects and debugging. While Mu lacks arbitrary side-effect escape hatches like `unsafePerformIO`, it provides debug-trace primitives. If a developer places an output trace inside an unused `let` binding, the Mu compiler treats the binding as dead code and drops it completely, suppressing the expected log. Furthermore, Mu preserves standard Haskell binding semantics where declarations are mutually recursive and unordered; writing `y = x + 1` before `x = 5` causes the compiler to reorder evaluation automatically, which can occasionally disorient users accustomed to the strict, line-by-line evaluation of imperative languages.

---

[22:47](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1367s) The Cortex Architecture: Cross-Language Financial Modeling

Augustsson introduces Cortex, the foundational quant analytics platform deployed at Standard Chartered Bank. Cortex houses the core financial libraries utilized by quantitative analysts to price exotic instruments, perform risk calculations, execute Monte Carlo simulations, run partial differential equation (PDE) solvers, and ingest live market data. To meet these demands, Cortex integrates multiple programming environments into an interoperable runtime ecosystem.

```mermaid flowchart LR accTitle: Cortex Multi-Language Interoperability Architecture accDescr: Core and peripheral languages interacting via a unified binary serialization and calling convention. subgraph Core["First-Class Core"] direction TB CPP["C++"] HS["Haskell"] MU["Mu"] end subgraph Layer["Integration Layer"] direction TB ABI["Uniform Calling Conventions"] SER["Binary Serialization Protocol"] end subgraph Interop["Client / Host Environments"] direction TB CS["C#"] JV["Java"] XL["Microsoft Excel"] end Core <--> Layer Layer <--> Interop ```

The core components are implemented in C++, Haskell, and Mu, while client bindings expose the functionality to C#, Java, and Microsoft Excel. C++, Haskell, and Mu operate as first-class citizens with seamless bidirectional interoperability, while C#, Java, and Excel serve primarily as host and consumer environments. This architecture allows high-level idioms to bridge language runtimes effortlessly: a C# program can invoke a generic `map` function implemented in C++, passing it a closure defined in Mu to process an array in memory.

- Development spans a heterogeneous operating environment: desktops run Windows, while high-throughput compute farms run Linux. - Data structures and function closures are serializable using a shared binary format, enabling computations to be offloaded to remote server farms and returned. - GHC’s distributed runtime and Cloud Haskell tooling were not sufficiently mature at the time to support this model natively, driving the internal development of Mu.

---

[26:42](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1602s) Code Mobility and the Realities of Banking Infrastructure

Addressing an audience question regarding code mobility and binary format governance, Augustsson observes wryly that financial institutions are notorious for the “not invented here” mindset: “Banks are seem to be lots about not invented here... they prefer, at least the two where I’ve worked, they prefer to have done things themselves even when it’s not really a good idea.”

He explains the exact dividing line for how distributed calculations are resolved across networked compute nodes: - Compute nodes run a stable base image containing the shared infrastructure written in C++ and compiled Haskell (such as pricing kernels and PDE solvers packaged into shared libraries and DLLs with uniform entry points). - Dynamic quant business logic and custom payoff formulas are authored on top using Mu; because these scripts fluctuate constantly, they are serialized and shipped across the wire dynamically. - Attempting to serialize non-serializable structures triggers a catastrophic runtime failure, analogous to evaluating the `head` of an empty list, though internal workarounds exist for specialized use cases.

---

[29:47](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=1787s) Excel Integration: Hacking Complex Types into Four Cell Primitives

Augustsson transitions to a live demonstration showing how Mu integrates into Microsoft Excel, polling the room on who has used Excel and wished it were programmable. Projecting a spreadsheet on screen, he highlights the fundamental impediment: “The designers in their infinite wisdom decided that the world has only four types: there are numbers, strings, booleans, and errors.” To represent structured functional values within these limitations, developers must encode complex object handles inside Excel’s basic primitives.

Standard Chartered encodes functional handles as tagged strings enclosed in curly braces with an internal object identifier, such as `"{12345}"`. Augustsson compares this against the bizarre schemes adopted by other investment banks: - **Credit Suisse**: Represented complex object references as negative numbers starting at `-60,000` and counting downward, which Augustsson calls “insane” because numeric reference handles can easily be swept into spreadsheet formulas and corrupted. - **Deutsche Bank**: Cast raw 64-bit memory pointers directly into double-precision floating-point numbers to store them inside worksheet cells. - **Standard Chartered**: Uses marked strings, avoiding accidental arithmetic operations on pointer addresses.

Augustsson demonstrates compiling a Mu source module directly from within an Excel formula. The formula evaluation returns an opaque object handle representing a `SafeIO Object IModule`. He explains that module compilation is categorized within an IO monad because compiling imports requires interacting with external file storage and dependencies. To use the compiled functions inside sheet calculations, the user must explicitly invoke a loader function that instructs Excel to load the compiled module into the host process’s memory space.

[35:04](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2104s) Writing and Executing Haskell Code Inside Excel

Lennart Augustsson demonstrates how Mu interacts directly with Microsoft Excel sheets, showing that side effects are strictly gated and cannot simply execute passively during recalculation. To run an IO action written in a cell, the user must explicitly select the cell, navigate to the custom menu, and trigger "Run Action." Once executed, the newly defined function—such as an increment helper named `demo_inc`—becomes callable inside standard spreadsheet formulas. Augustsson cautions against authoring substantive code directly inside spreadsheet cells, offering a candid critique of the interface: “Honestly Excel is about the worst text editor ever.” For expositional purposes, two lines in a cell suffice, but in real commercial workflows, code is kept in external files and loaded into the sheet via module import commands.

He then illustrates the deep integration between Mu and Excel’s native interface by adding comments to a cell function using standard Haskell syntax. When comments are prefixed with double dashes, Excel occasionally complains about text formatting, but once accepted and registered, Mu extracts those annotations and passes them directly into Excel's native Function Wizard dialog. As a result, non-programmer spreadsheet users browsing available functions can inspect proper documentation strings generated directly from Haskell type signatures and source comments.

[37:50](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2270s) Higher-Order Functions and Sheet-Defined Computations

Turning to functional programming patterns, Augustsson notes that functional programming is fundamentally about abstraction, and even traditional spreadsheet users intuitively grasp that endlessly copying formulas across rows and columns is brittle and inadequate. However, Excel fundamentally lacks first-class functions. To map a freshly compiled Mu function over an array of numbers like `1, 2, 3`, Mu wraps functions as first-class objects within the grid. Augustsson wrestles briefly with keybindings and keyboard layouts on his demo machine, remarking with amusement on the prowess of dedicated financial modelers: “Excel power users are amazing to watch; there are secret key combinations that do all kinds of weird things.”

```mermaid flowchart LR accTitle: Sheet-Defined Function Flow accDescr: Mapping an Excel cell computation into a first-class Mu function object that can be passed to higher-order combinators. subgraph Sheet["Excel Grid"] In["Input Cell (x)"] --> Calc["Formula: 2*x + 1"] --> Out["Output Cell f(x)"] end subgraph MuSystem["Mu Runtime Engine"] Calc --> Extr["Extract Cell Range as Function"] Extr --> FirstClass["First-Class Function Object"] end FirstClass -->|"Map over array [1, 2, 3]"| Result["Result Array"] ```

Augustsson then unveils a unique, non-Mu-specific feature tailored for spreadsheet mental models: "sheet-defined functions." Excel users naturally think by chaining computations across cells. Mu allows a user to write an ordinary formula—such as `2 * x + 1` across an input cell and an output cell—and then capture that entire grid computation as a first-class function object. If a formula spans multiple input or output cells, the runtime packages them as tuples. That sheet-derived function can then be handed directly to higher-order combinators like `map`, eliminating repetitive cell formula copying while preserving the visual, interactive way quantitative analysts construct models.

[42:46](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2566s) User-Controlled Native JIT Compilation and Partial Evaluation

Mu normally compiles code into an intermediate representation (IR) that is interpreted by an abstract machine, but high-throughput financial calculations often demand bare-metal speed. Rather than applying a global heuristic, Mu places native compilation directly under user control via a compiler hook. When passed an arbitrary value or function, the compiler attempts to produce a functionally identical, natively executed replacement:

> “If you give it five it's kind of uninteresting because five is about the fastest they get, but if you give it a function it will take that function and it will turn it into machine code; it does this by generating LLVM IR and then using the LLVM JIT.”

Augustsson notes that if a user attempts to call native compilation on a C++ function that is already linked into the environment, or on an already-compiled artifact, Mu returns the original function unchanged and emits a warning in a monitor window stating that it could not inspect or recompile it, because there is no accessible intermediate representation for opaque foreign code.

Crucially, the JIT compiler handles partial applications by performing runtime partial evaluation. When a user provides only the first argument to a two-argument function and requests native compilation, the compiler does not simply wrap the function in a closure; it folds the argument directly into the function body, specializes the intermediate representation, propagates constants, and eliminates dead branches before generating machine code. When an audience member asks whether ordinary users know where to place these compilation primitives, Augustsson concedes:

> “Probably not; so I mean people who just see this as some kind of hammer—'this is running slowly, let me see what happens if I say compile, bang, that's a bit better'—you know, but where performance really matters means they can talk to people who understand what happens and we can help a little bit where we put these things.”

[46:54](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2814s) IR Serialization and Remote Farm Execution

An audience member asks whether Mu retains intermediate representation for all functions across their entire lifecycle. Augustsson confirms that the runtime preserves the IR for every interpreted and sheet-defined function, which unlocks cross-platform distributed execution. If a user needs to serialize a function to disk or ship an intensive job across the network from an x86 workstation to a PowerPC compute farm, Mu does not transmit target-specific machine code; it serializes the platform-independent intermediate representation. Upon arrival at a remote node, the receiving host deserializes the IR and code-generates native machine instructions tailored to its local architecture on the fly.

Augustsson demonstrates this on his sheet-defined function. He adjusts the formula to `3 * x + 1`, adds an internal debug flag, and shows how calling `funCompile` transforms the cell calculation into specialized machine code. Once compiled, the function can be mapped locally over an array, or passed to a distributed `map` primitive that transparently sends the workload to a compute cluster:

```mermaid flowchart TD accTitle: Distributed Mu Execution Architecture accDescr: How Mu functions are serialized as intermediate representation and compiled via LLVM JIT across local and remote platforms. subgraph Client["Client Machine (e.g. x86 Desktop)"] Src["Haskell / Sheet-Defined Function"] --> IR["Intermediate Representation (IR)"] IR --> LocalJIT["LLVM JIT Compiler"] --> LocalBin["x86 Machine Code"] end subgraph Cluster["Remote Compute Farm (e.g. PowerPC Node)"] IR -->|"Network Serialization"| Deser["Deserialized IR"] Deser --> RemoteJIT["LLVM JIT Compiler"] --> RemoteBin["Native Target Code"] end ```

- **IR ubiquity:** All Mu functions retain their intermediate form, enabling runtime inspection, partial evaluation, and cross-compilation. - **Foreign functions:** C++ functions linked into Mu cannot be partially evaluated or recompiled because their internal representation is opaque. - **Distributed farm mapping:** Replacing a standard `map` with a farm-enabled map serializes the function IR and data slices, dispatches them to remote servers, and gathers the reduced results seamlessly back into Excel.

[50:22](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3022s) Strict vs. Lazy: Stack Traces, Resources, and Compositionality

Augustsson shifts to a philosophical and pragmatic comparison of strict versus lazy evaluation, deflating the dogmatism that often surrounds the debate: “So I just wanted to say something about strict versus lazy, which is sort of, oh, it's this fantastic battle between good versus evil—I'm not saying which is which—but actually it doesn't really matter that much, I mean it kind of works in both worlds.” Both approaches have significant trade-offs, but in industrial software engineering, strict evaluation provides distinct operational advantages.

Foremost among these advantages are actionable stack traces. Because Mu is strict, when a runtime failure occurs, the engine outputs an exact, chronological call chain explaining which function called which. Augustsson emphasizes the productivity impact of this feature:

> “It's the single most time-saving thing, immediately, compared to Haskell, because things do go wrong and then it's so great to see exactly what the call chain was and then you can fix it.”

Furthermore, strictness provides what Augustsson terms "resource compositionality." In a strict language, developers can determine the computational complexity and memory footprint of two independent subroutines and compose them with confidence that the combined resource footprint will simply be their sum. In a lazy language, composing an element generator `[1..n]` with a fold like `sum` might execute in constant space or blow the heap with unevaluated thunks, varying entirely on “how the strictness analyzer felt that day.” Similarly, exception handling behaves reliably under strict semantics, whereas in lazy Haskell, catching an error around an unforced expression does not actually trap the failure until evaluation is triggered elsewhere.

However, strictness sacrifices "semantic compositionality." Augustsson points out classic idioms like `any p`, which naturally halts the moment a predicate matches when composed over an infinite or lazy list. In a strict language, that separation of generation from consumption breaks down unless explicitly encoded with bespoke control flow. He concludes that while laziness represents a theoretically cleaner and more expressive paradigm for writing modular code, its unpredictable resource consumption remains a persistent hazard in production systems.

[53:36](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3216s) Call-by-Name in a Strict Haskell (`Mu`)

Lennart Augustsson explains that even in a fundamentally strict language, certain core primitives must evaluate lazily. He observes that even C contains lazy semantics in short-circuiting logical operations, where writing `false && error` will never evaluate the second operand. In Mu, his strict Haskell dialect at Standard Chartered Bank, this behavior is exposed to programmers via the `by-name` keyword. Rather than relying on fragile compiler macros with risk of variable capture, `by-name` provides hygienic call-by-name macro expansion semantics. While languages like C, C++, Standard ML, and OCaml hardcode such short-circuiting behaviors directly into the compiler as privileged syntax, Augustsson wanted regular developers to be able to define their own non-strict combinators.

```mermaid flowchart TD accTitle: Macro Expansion of Composition in Mu accDescr: Flow diagram showing how Mu evaluates call-by-name function composition to avoid duplicated evaluation of arguments.

subgraph Problematic["Naive Inlining"] A["(reallySlow f). g"] --> B["\x -> (reallySlow f) (g x)"] B --> C["Evaluates reallySlow inside lambda per call!"] end

subgraph MuExpansion["Mu by-name Expansion"] D["by-name (.) f g"] --> E["let f' = f; g' = g in \x -> f' (g' x)"] E --> F["reallySlow evaluated outside lambda once"] end ```

He offers a word of caution born from implementation headaches: “By the way if you ever try, if you want to design a language, never use call by name as your calling convention.” He illustrates this using standard Haskell function composition, `(f. g) x = f (g x)`. If `.` is declared `by-name` and naively expanded into an expression like `reallySlow f. g`, the expensive computation `reallySlow` gets inlined directly inside the generated lambda body, repeating the work on every invocation. To fix this, Mu's definition of `.` binds the arguments in an outer `let` binding (`let f' = f; g' = g in \x -> f' (g' x)`) before referencing them beneath the lambda abstraction.

[56:04](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3364s) Pragmatic Laziness and What Breaks in Strict Mode

Across the entire codebase, only roughly twenty definitions require an explicit `by-name` annotation. These include standard control-flow utilities like `when`, `unless`, and `fromMaybe`. Interestingly, users without any prior functional programming experience still intuitively expect these combinators to evaluate conditionally. Augustsson recalls developers complaining when `fromMaybe` failed in Mu because an `error` call passed as the fallback default value triggered immediately upon application.

He also catalogs the recurring pain points where Haskell's default laziness cannot easily be recovered in a strict dialect: - **Lazy bindings:** Expensive computations used conditionally inside functions (such as a mapped closure) need to execute zero or one time, not unconditionally up front. - **Infinite structures:** Idioms like `zipWith` over an infinite list `[1..]` cannot execute and will diverge. - **Type proxies:** In the absence of explicit type applications, passing dummy values like `undefined` solely to carry type witness information triggers runtime bottom crashes unless marked with lazy bindings. - **Cyclic data structures:** Defining knot-tying graphs or self-referential structures directly does not work in strict evaluation. - **Idiomatic Haskell abstractions:** Common decoupled idioms separating generation from consumption fail to terminate or require manual chunking.

[58:27](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3507s) Scale, Naive Users, and Precise Error Locations

Augustsson reviews the scale of the deployment at Standard Chartered. The codebase encompasses roughly 400,000 lines of Mu code across approximately 2,400 modules, maintained by a broad mix of quantitative researchers and domain specialists. Augustsson characterizes many of them as mathematically sophisticated but computer science-naive users: “They don't write things like test cases and sometimes you really twist their arm, so it's good to have strict type checking to at least get some of the bugs out early.” Developers are strictly prohibited from checking in changes without running the type checker across the entire 400,000-line repository, a process that completes in just 30 seconds on his desktop.

```mermaid flowchart LR accTitle: Two-Location Type Checking Diagnostics accDescr: Visual breakdown of how Mu highlights conflicting source locations for type errors.

subgraph ErrorReport["Type Conflict Report"] direction TB E1["Bool vs String mismatch"] L1["Location 1: Red highlight (source of Bool)"] L2["Location 2: Blue highlight (source of String)"] E1 --> L1 E1 --> L2 end

subgraph Traditional["Traditional GHC Report"] G1["Point of discovery"] G2["'Useless order-dependent location'"] G1 -.-> G2 end ```

He credits the low frequency of complaints about type errors to diagnostic clarity that improves on GHC. Rather than pointing solely at the arbitrary traversal location where unification failed—which Augustsson dismisses as “completely useless” because it merely reflects compiler traversal order—Mu highlights the two concrete, conflicting source spans simultaneously (for instance, showing in red where a `Bool` originated and in blue where a `String` originated). In expressions like `1 + True`, it pinpoints both the `Num` constraint originating from `1` and the boolean type introduced by `True`, enabling users to instantly spot and correct discrepancies.

[01:01:25](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3685s) Tooling: Linter, IDE, and Hiding the Compiler

To keep naive developers productive, the team built a tailored developer toolset around Mu: - **Mu Lint:** Adapted from Neil Mitchell’s HLint, augmented with proprietary bank-specific rules. Augustsson quips: “It's nicer to get critique from the machine than from people.” - **Interactive REPL:** A read-eval-print loop analogous to GHCi for rapid interactive experimentation. - **IDE with Rich Introspection:** An editor providing type hover inspections, identifier auto-completion, browsing, and an interactive debugger. Augustsson observes with amusement that while users initially insisted “we must have a debugger, we must have a debugger,” hardly anyone actually touches it once delivered. - **Transparent Compilation:** The build pipeline mimics a dynamic scripting language. Users point at raw source files and execute them directly without managing intermediate binaries, compilation artifacts, or Makefiles. As Augustsson emphasizes: “It's running the program that is the interesting thing, not compiling.”

[01:03:56](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3836s) Q&A: Financial Workloads, User Adoption, and Hardware Compilation

Answering audience questions, Augustsson explains the day-to-day work handled by Mu: - **Typical Workloads:** Scripts routinely ingest disparate records from multiple databases, massage financial inputs, pass structured grids to external C++ partial differential equation (PDE) solvers, calculate derivative pricing and risk metrics, and assemble polished reports. Intensive floating-point operations are deferred across the FFI into C++, positioning Mu as a type-safe glue language. - **Spreadsheet Integration:** While earlier demonstrations highlighted rich Excel integration, the bulk of the 400,000 lines runs headlessly outside of spreadsheets. - **Adoption Across Roles:** Formal quantitative analysts remain split, with many still clinging to C++. Surprisingly, adoption proved strongest among front-office traders who were never hired to program: “It's kind of interesting to go walk out on the trading floor and see Graham Hutton's book there next to someone who's trading precious metals.” - **Learning Curve:** Because Mu is an internal proprietary language, users learn primarily by reading Graham Hutton's *Programming in Haskell* alongside existing bank repositories—though Augustsson concedes that existing code often serves as a poor template. - **Targeting FPGAs:** When asked whether he would ever compile Mu directly to FPGA hardware rather than targeting LLVM bytecode, Augustsson rejects the premise outright: “I don't think that will work. I think if you want to design hardware you need to have some clue about what you're doing.”

## Notable quotes > [11:59](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=719s) When Haskell was designed, I thought it was a great idea to have String be a list of characters; now I think that was a big mistake, it should be an abstract type. — Lennart Augustsson

> [01:01:25](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3685s) It's nicer to get critique from the machine than from people. — Lennart Augustsson

> [08:25](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=505s) The venture capitalists, they did some due diligence, and they found out that hardware people were not really interested in Haskell syntax; they wanted something they could actually read. — Lennart Augustsson

> [53:36](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3216s) By the way if you ever try, if you want to design a language, never use call by name as your calling convention. — Lennart Augustsson

> [01:01:25](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=3685s) It's running the program that is the interesting thing, not compiling. — Lennart Augustsson

> [14:31](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=871s) You can't fire the missiles in the SafeIO monad; you can only read things from the world. — Lennart Augustsson

> [35:04](https://www.youtube.com/watch?v=hgOzYZDrXL0&t=2104s) Honestly Excel is about the worst text editor ever. — Lennart Augustsson

## Mentioned Lennart Augustsson, Standard Chartered Bank, Commercial Users of Functional Programming (CUFP), Thomas Johnsson, Chalmers University of Technology, Lazy ML (LML), HBC, Don Stewart, Glasgow Haskell Compiler (GHC), Arvind, Rishiyur S. Nikhil, Parallel Haskell (pH), Massachusetts Institute of Technology (MIT), Bluespec, SystemVerilog, Mu, Hackage, Microsoft Excel, Cortex, C++, C#, Java, Credit Suisse, Deutsche Bank, LLVM, Neil Mitchell, HLint, Graham Hutton

## Video description Keynote: Pragmatic Haskell

Saturday, September 24, 2011 - 09:00 AM - 10:00 AM Speakers:

Lennart Augustsson Standard Chartered Bank Abstract:

Over the years I've both used Haskell a lot commercially and also made four Haskell implementations. Of the four implementations three are very non-standard because they were aimed for particular targets. I will talk about various aspects of using and implementing non-standard Haskell as well as show a number of examples from my latest Haskell implementation which is strict. I will also make a pragmatic assessment of strict versus lazy.

[Source](https://www.youtube.com/watch?v=hgOzYZDrXL0)

中文简报

渣打银行弃用Haskell惰性求值以稳定量化引擎 渣打银行在其专有编译器中禁用了默认递归,并用严格求值取代了惰性求值,因为不可预测的内存暴涨和无法追踪的运行时崩溃使得标准Haskell无法应用于企业生产环境。 Augustsson回顾了他构建非标准Haskell编译器的历程——从早期的HBC和pH,到Bluespec,再到专为渣打银行打造的严格求值专有方言Mu。他解释了Mu如何背离标准Haskell:强制采用严格求值、默认禁用通用递归、对字符串进行抽象,并将副作用拆分为针对金融模型量身定制的两层IO模型。通过现场演示,他展示了Mu如何直接在Microsoft Excel内部编译Haskell及工作表定义的函数,并将中间表示序列化以用于分布式计算集群和LLVM JIT编译。最后,他权衡了生产环境中严格语义与惰性语义的利弊,指出在40万行代码库中,严格求值能够提供至关重要的堆栈回溯、可预测的资源组合性以及清晰的编译器诊断信息。 Lennart Augustsson详细介绍了渣打银行的专有Haskell方言Mu;该方言运行着涵盖2400个模块的40万行生产代码,以严格求值取代了惰性求值,并将字符串实现为紧凑的抽象数据类型而非字符链表。 (11:59) Mu默认禁用通用递归,需要显式声明语言编译指示{-# LANGUAGE Recursion #-};一项内部审计显示,生产模块中只有大约6%启用了递归,因为量化人员转而依赖批量数组组合子和关系操作。 (14:31) 渣打银行将Mu深度集成到Microsoft Excel中,具体方式包括将复杂的函数式数据结构包装为带标签的句柄字符串、向高阶组合子公开工作表定义的函数,以及通过LLVM IR提供运行时原生JIT编译。 (29:47) Augustsson认为,尽管惰性求值提供了理论上的优雅性和语义组合性,但严格求值在企业软件中带来了关键的运维优势,尤其是可预测的资源消耗以及发生故障时确定性的时间序堆栈回溯。 (50:22)

Source quotes

[11:59] Lennart Augustsson: When Haskell was designed, I thought it was a great idea to have String be a list of characters; now I think that was a big mistake, it should be an abstract type. [61:25] Lennart Augustsson: It's nicer to get critique from the machine than from people. [8:25] Lennart Augustsson: The venture capitalists, they did some due diligence, and they found out that hardware people were not really interested in Haskell syntax; they wanted something they could actually read. [53:36] Lennart Augustsson: By the way if you ever try, if you want to design a language, never use call by name as your calling convention. [61:25] Lennart Augustsson: It's running the program that is the interesting thing, not compiling. [14:31] Lennart Augustsson: You can't fire the missiles in the SafeIO monad; you can only read things from the world. [35:04] Lennart Augustsson: Honestly Excel is about the worst text editor ever.

Original transcript

[0:09] all right [0:09] welcome everyone uh i would like to [0:11] welcome you all to [0:13] the 2017 [0:28] um [0:42] it mirrors the exciting growth [0:45] development in [0:46] the functional programming world i think [0:48] over time [0:49] more and more people seem to be [0:52] discovering [0:53] uh the virtues and functional programs [0:55] which you know [0:56] various often [1:23] so we're going to hear a bunch of talks [1:25] today from a bunch of different people [1:27] who have approached the question of how [1:28] to use functional programming in the [1:30] real world [1:30] from different perspectives and [1:32] interesting industries [1:34] with different goals but before that [1:37] uh we're going to hear a keynote from [1:38] leonard augustine [1:40] who is someone who has understood these [1:43] secret weapons for a very long time [1:45] and has been there kind of happening at [1:47] the at the start of a lot of this [1:49] letter to the author of the first [1:52] involvement in writing the first lazy [1:55] functional language that is compiled [1:59] he was one of the founding members of [2:01] the wwe [2:21] address [2:49] despite today certain claiming that they [2:52] have [2:52] passed their life travel will not [2:54] support yet [2:57] my confusion in the wrong time fellows [3:04] uh so this is not going to be a deep [3:08] quote i'm going to talk about [3:09] a couple of different things uh [3:13] first i'm going to show you some it's [3:14] called pragmatic hassle so i'm going to [3:16] show you some [3:17] twisted haskell implementations i've [3:20] made over the years [3:23] the latest one is called news i must [3:25] talk mostly about that one [3:28] i'm going to do a little demo of the [3:31] stuff that we have [3:32] at the bank and i'm going to talk a bit [3:35] about strict [3:36] versus lazy [3:42] so some people seem to think that i was [3:46] on the hustle [3:47] maybe from the very beginning this is [3:49] not true [3:50] so i did like the first [3:55] first publicly available hassle compiler [3:57] called hpc [3:58] but actually i've started the meeting in [4:01] portland oregon in 1989 or whatever it [4:05] was when people said we needed a [4:07] language but [4:10] thomas johnson was also there and we [4:12] flipped [4:33] i was forced to make my own [4:39] i said first released in 1990 i say [4:41] latest release in 2004 i didn't say [4:44] last i mean [4:48] quite often though and last time [4:51] the bob stewart ran from benchmarks in [4:54] 2007 and it still beats [4:56] ghc or beat jc on some of them in 2007 [5:03] it also had native code generators for [5:07] far too many architectures making your [5:10] release was no [5:12] fun it didn't have all of us from the [5:14] startup course and some of them died [5:15] before the [5:16] later ones appeared but it was usually [5:22] so this was not a particularly twisted [5:24] password implementation this was um [5:28] implemented pascal standard some [5:31] extensions only [5:32] existential types which is a nice [5:35] extension but still seems [5:43] by the way if you have any questions [5:45] please interrupt me anytime you want [5:48] to take questions at once [5:53] so then i decided uh i should rewrite [5:57] the haskell compiler in password so i [5:59] started doing that [6:02] for some reason i never finished i'm not [6:04] quite sure what happened [6:06] but it was used as mit [6:09] for their ph parallel password compiler [6:14] ph is interesting it's [6:17] not using lazy evaluation [6:20] so if you look at the haskell standard [6:22] it says very carefully [6:24] a non-strict functional language it [6:27] didn't say that from the beginning it [6:28] said [6:28] lazy but marvin [6:32] who was data still is he objected to [6:34] this and said it shouldn't say lazy it [6:36] should say [6:37] non-strict because he had exactly this [6:40] kind of implementation in mind [6:42] so what's the difference well ph has [6:45] fine-grained parallelism so it can [6:47] easily start up [6:48] lots of computations in parallel so it [6:51] doesn't wait [6:52] until the very last moment to complete [6:54] something you can easily compute [6:55] something ahead of time [6:57] in a different thread and the mainstream [6:59] continues [7:00] and if you have a good scheduler if you [7:02] started something that you didn't really [7:04] need [7:05] you'll find out super electric and you [7:06] can kill off that square [7:08] that's a very different way of [7:10] eliminating haskell [7:11] but it gives you the same semantics if [7:13] you have a good scheduler [7:16] it also had uh strange things like m [7:19] bars and i bars that are [7:21] later here in ghc as well [7:25] unfortunately it had them [7:28] just about the time when uh monads were [7:30] introduced but we didn't quite [7:32] understand nomads at least i didn't [7:35] i'm sure she did but so [7:38] ph did not introduce them in a magnetic [7:42] way [7:42] they were very messy to use [7:47] so that came about around about [7:51] 1995 some years later before you [7:53] actually found my real program [7:55] and i did from them stuff [8:07] if you want to know more about ph you [8:09] can [8:22] so then a few years later so bluespec [8:27] is a hardware description language so it [8:29] looks like haskell [8:31] and you can actually use full hassle [8:34] but it's only available at a compiler [8:36] time so everything you write [8:38] will be executed while you're compiling [8:41] not when the actual hardware is running [8:45] so it's a kind of a strange programming [8:48] model [8:49] definitely two levels on the first level [8:51] you can do anything you like [8:53] you have to be careful this first level [8:55] that does anything you like [8:57] can't lose forever or anything like that [8:59] because if it loops forever it needs to [9:00] become by your own termination [9:02] you'd better only write terminating [9:04] stuff on the first level and the second [9:06] level [9:07] the one that actually executes on the [9:08] hardware and have a completely different [9:10] programming model [9:12] so i think blue spec is the [9:15] the best hardware design language out [9:18] there [9:18] and it's still around and if you want to [9:21] know more [9:22] you should talk to nikhil or by his blog [9:35] and so some some slightly uh [9:38] in interesting things that it had [9:42] that was not in standard haskell so you [9:44] could have [9:45] numbers and arithmetic in the types with [9:48] which is important when you're dealing [9:50] with things like big vectors if you have [9:51] three bits and five bits and [9:53] concatenate them you want to know that [9:55] you get eight bits so you have these [9:57] kind of [9:58] numeric things you can say a vector of [10:01] length [10:01] and concatenate with the vector length [10:03] and will give you this [10:05] vector of length m and here is some [10:09] class that says that if you add mnn you [10:11] get [10:12] mn and you can use [10:15] numbers on the type level and that's [10:17] something that we'll [10:19] will have in gfc soon as well i think [10:27] and so i i did from deadly things [10:31] to this and this as well and many people [10:34] have worked on this [10:38] development [10:45] yeah well i should say that if you get [10:48] it now [10:49] to use to design some piece of hardware [10:53] people in this room might be [10:55] disappointed because it no longer looks [10:57] like haskell like it did [10:59] in the beginning when this was found [11:02] as its own company the [11:05] the people who were investing all the [11:08] venture capitalists they did some due [11:11] diligence and they found out that [11:13] hardware people were not really [11:15] interested in astro syntax [11:17] they wanted something they could [11:18] actually read so [11:20] it was like very long but underneath [11:24] there some very slowly [11:41] how [11:58] so my latest [12:02] version of a haskell compiler the [12:05] language dialect we're calling it new [12:10] i'll get back to the tedious reasons [12:14] why we may get another haskell compiler [12:18] it's not that if i enjoy it that much [12:32] so here are some differences between you [12:34] and hasta because i mean if it was just [12:39] so it's strict [12:42] so i mean some people might think that [12:44] there's lazy bits of haskell that's [12:47] really a defining quality [13:01] this is the single biggest obstacle to [13:05] just taking it something off package and [13:07] using [13:08] the view because that means that [13:11] all string manipulations need to be [13:13] changed [13:14] so i think so when pascal was designing [13:17] i thought it was a great idea to have [13:19] straightened the list of characters [13:21] now i think that was a big mistake it [13:24] should be an abstract fight [13:27] we don't have the integer type but i [13:29] mean we could have [13:30] one reason despite [13:34] the name new which might imply some kind [13:37] of [13:38] fixed point we don't have recursion [13:41] you might think that functional [13:44] programming [13:45] is all about recursion but [13:50] i mean we the people who program in this [13:53] most of them are traders and things like [13:56] that [13:57] they don't really need recursion [14:01] the we give them enough operations on [14:04] the data structures that they typically [14:06] use [14:07] so typical data structure is [14:11] an array of records for an array of [14:13] numbers [14:15] or a relationship relations are also [14:17] very popular [14:18] and so we give them a bunch of [14:21] combinators that they need for that and [14:23] they're supposed to use those and not [14:25] roll their own recursions to do focused [14:28] on [14:29] so we've got the i'm added a language [14:32] pragmas you can turn on recursion but [14:34] you have to say [14:36] like in haskell you can say you have a [14:37] pragma at the beginning of the guide [14:39] saying [14:39] language where you list some extension [14:41] if you want doing person you have to say [14:43] language [14:43] recursion and you can actually use [14:46] recursion yeah [14:47] so are the core libraries [14:52] so some a lot of it is written [14:55] in c plus so most of the stuff that you [15:00] walk from well i shouldn't say monsters [15:02] are [15:03] all performance sensitive stuff is [15:05] written in c plus plus and [15:06] there's lots of new things on top of [15:08] that but say [15:25] so [15:42] so i checked our module by the way so [15:45] it's about [15:47] six percent of the modules that actually [15:50] turn on recursion [15:51] the rest of them [16:06] so we have a little twist on the iron [16:08] monitor so the ion [16:09] is there but there's also another io on [16:12] that called [16:12] safe iron which should really be called [16:15] eye [16:16] because [16:20] it's the one that don't you can't [16:23] fire the missiles in the eye mana you [16:26] can only [16:26] read things from the world [16:32] so it's slightly more benign so it's [16:36] it's actually there because [16:39] so one of the early uses of this was to [16:41] interface to excel [16:44] and imagine excel has a more expressive [16:48] effect system and asphalt in excel [16:51] you distinguish between pure [16:52] computations [16:54] computations that have read effects and [16:57] computations that can have right effects [17:01] so the pure ones are the normal ones [17:04] that you can mark a function to be [17:05] modified which means every time you [17:07] evaluate it [17:08] you might get the different results and [17:10] then there are the ones that you have [17:12] right effects [17:13] and those you're simply not allowed to [17:15] use [17:16] in [17:31] so an example is the getarms function [17:34] that [17:35] gets different command line arguments so [17:36] this is insane [17:39] and of course you can tribute it [17:41] anything insane [17:51] is the right connection between the fact [17:53] that it's strict and the fact that you [17:55] have no recursion [18:00] no i don't think so [18:05] well maybe there is but i don't know [18:07] what the connection is do you have [18:09] something in mind well i think the big [18:13] difference between strict languages and [18:14] amazing languages is the [18:16] styles of programs that get written when [18:19] you sort of compose [18:20] lots of loop-like things together i have [18:23] a little bit [18:25] yeah so but yeah [18:28] and if you're not writing loop like [18:30] things then maybe it's not a big [18:32] difference [18:38] the last point so the watch looks like [18:41] lists [18:42] are actually arrays whatever arrays are [18:44] i mean [18:46] they have slightly different [18:50] different cost models you can access any [18:53] element [18:53] in constant time on the other hand [18:56] concatenation and these kind of things [18:58] might not [18:59] well can't sing i should say you might [19:01] think it's constant time but it's not [19:03] when you're going to practice you can [19:05] imagine [19:06] if you want to but you so [19:09] since there's no recursion people [19:11] typically don't build lists by [19:13] counting things together you have to [19:15] operate on them in bulk so it doesn't [19:17] really matter that [19:18] they are somewhat different [19:22] so it's the more likes [19:28] so um [19:31] so mew is sort of compatible upwards or [19:34] downwards forever some [19:36] sideways with haskell so you have new [19:38] code [19:39] you can run it as a haskell program by [19:41] importing a suitable library [19:44] but not the other way around so haskell [19:46] code doesn't automatically work [19:47] individually [19:48] i mean i listed some differences and [19:50] also [19:57] so i must say i've taken some freedoms [20:00] in the in the new compiler so i like [20:05] both strict and lazy different [20:08] transformations are valid [20:09] in strict languages and in lazy [20:11] languages [20:12] so the compiler just assumes that it's [20:16] all terminating and it can do whatever [20:18] transformations it life [20:19] so some of them are only valid in lazy [20:22] languages some of them are undergraduate [20:23] strict managers [20:25] i do them anyway remember the name of [20:28] the talk in pragmatic haskell [20:31] so if someone someone mathematically [20:33] inclined [20:34] wonders i tell them this is not [20:38] true what i tell them anyway [20:41] so if s is the symmetrical string [20:43] languages of l is the semantics of lazy [20:46] languages [20:59] that is your fault [21:15] that it's not it's much easier to do [21:20] compiler transformation or program [21:23] transformation [21:24] if you don't have to preserve semantics [21:38] so for instance if someone just makes a [21:41] left binding [21:42] that has an effect so the only we don't [21:45] really have any effects we don't have [21:47] unsafe performance [21:48] for instance but we do have a sort of [21:51] debug [21:51] trace like things you can insert [21:54] something that [21:55] outputs developments you just put one of [21:58] those in the left binding [21:59] and you don't use the result of it the [22:02] compiler will throw it away and you will [22:03] never get the debug message [22:05] so you can't assume that it's like a [22:07] strict bandwidth where [22:08] the bindings are executed in order [22:12] and they're not executed in order anyway [22:13] because this is [22:15] taska like you don't have to put your [22:17] bindings in the order that they're [22:19] supposed to be executed i mean that's [22:22] how not how [22:23] haskell people to be right their [22:24] bindings to two say [22:26] y equals x plus one and then x equals [22:29] five [22:30] and the compiler will sort of reorder [22:32] that the x [22:33] first and the y just like uh pascal [22:36] would [22:37] so mu has kept that this is a bit [22:41] confusing if you want to debug [22:47] so i'm going to give you a little demo [22:49] here [22:50] before i do that i'm just going to say a [22:53] few [22:54] things about the sort of where this [22:57] compiler lives [22:59] so we have this system called cortex [23:01] which is [23:02] a library for our ones the people who [23:05] write the [23:05] financial models that compute prices of [23:08] products and [23:09] computes risk and those kind of things [23:12] so [23:13] it has stuff like basic data structures [23:16] lists relations records discounting [23:20] lots of maps regular maps lots of [23:23] financial stuff [23:24] monte carlo simulated stipulations pd [23:27] solvers getting market data [23:31] all kinds of things so this is written [23:34] in a combination of c plus plus haskell [23:38] and mu and it's used from c [23:42] plus plus has to the new obviously but [23:44] also from [23:45] cpr java and excel [23:48] and so it's a pretty smooth integration [23:52] so any of these languages well [23:55] so these these three languages are [23:57] slightly lesser [23:59] citizens so the other three languages [24:01] they can call each other [24:03] freely and here see shark tank [24:06] well i guess these cans somewhat it's [24:08] difficult maybe to call between c sharp [24:10] and just [24:11] charger but you can certainly fall back [24:13] and forth between c [24:14] class and c sharp princess and it all [24:18] works fairly smoothly and the way you [24:20] expect it to work even things like [24:22] higher order functions [24:24] so you can in c-sharp you can call the [24:28] map function which is written in c plus [24:32] plus a matter function written in view [24:34] over an array [24:41] so it's reasonably platform independent [24:45] because we have different platforms so [24:47] people running on their desktop [24:49] using windows and then there are compute [24:51] farms that run linux [24:54] and it's all sort of supposed to [24:55] interact [24:57] and you can move code and data between [25:00] all these things so [25:01] everything all data structures at least [25:04] everything that would [25:05] make sense is serializable so you can [25:08] take any data you have ship it over to [25:11] another computer [25:13] do something to it there shift the [25:15] results back [25:16] or save it to this load it up later this [25:18] includes [25:20] data structures functions what have you [25:24] so this is the reason that we have [25:28] new because this [25:31] just doesn't work with with ghd we [25:33] didn't work [25:35] starting to work slightly with gmc maybe [25:37] sort of the cloud computing thing [25:40] but it's not quite there yet so [25:43] we we had long talks about if we were [25:46] going to do [25:46] our own language and offer we're going [25:48] to try to use the ghc and [25:49] we decided to do our own also strict [25:53] evaluation fits back again [26:09] pioneer representation for all of these [26:11] things [26:12] and then the if you ship a code [26:16] it's yeah you might call basically that [26:19] you ship [26:20] but i'm going to show you some examples [26:23] code here at the moment and explain how [26:25] it works but [26:26] but yes there's sort of an agreed binary [26:28] format that all these use [26:30] so one so the serialization has one [26:32] binary format [26:34] and then all the interrupt between [26:37] languages uses [26:38] i mean has some quality conventions that [26:40] they all agree on [26:42] which is uh [26:53] it might happen but [26:57] banks are seem to be lots about [27:01] not invented here i mean [27:04] they prefer at least the two wide [27:07] working they prefer to have [27:10] done things themselves even when it's [27:13] not really a good idea [27:17] this is one thing [27:32] i don't understand how the calculation [27:34] is resolved [27:36] so [27:40] the things so you you assume that [27:44] the if you have some machine a [27:48] and some machine b that you need to [27:50] communicate between [27:51] that you have roughly the same some [27:55] fixed code based on your properties [27:57] that's sort of the core of the stuff [27:58] and then people write little things on [28:00] top of that the little things on top of [28:02] that [28:03] are written in you and those we can't [28:05] trust are the same on all these machines [28:07] those bits have to be transported [28:09] the ones below say the monte carlo or [28:13] solver or something like that that is [28:15] just the same on both sides and there [28:17] you can have pieces written in hassle [28:19] because it's just just a dll with a [28:22] bunch of entry points you know you have [28:24] a number of functions and they will be [28:25] the same on both sides so we don't have [28:27] to transport [28:28] those [28:41] mobility mechanism [29:06] i mean it's like taking the head of the [29:08] empty list but also [29:10] it's a catastrophic failure [29:13] so so somehow we we do [29:17] allow you to serialize the [29:18] non-stereotypes sometimes the later [29:20] structures that we use [29:23] but then you have to write some weird [29:26] pastels [29:38] okay [29:47] let's see if we can have this [29:50] microscopic [29:52] part of an excel sheet here is this uh [29:55] readable [29:58] if i can make it slightly smaller [30:04] so you how many people [30:08] here have ever used excel [30:12] did you ever did you ever wish that you [30:15] could [30:15] maybe program it a little bit [30:31] very faint [30:36] that's not very nice [31:02] ah [31:12] you know [31:30] completes yes of course [31:38] okay so this looks like a little module [31:42] so um [31:52] so now you might wonder [31:55] this value should this compile [31:59] the module here and we got the result [32:01] what's that [32:04] well so the the designers [32:07] in their infinite wisdom decided that [32:10] the world has only four pipes [32:13] there are numbers strings [32:16] booleans and errors [32:23] so we really want something more than [32:25] that [32:26] um so we do what all [32:30] serious excel users do we invent [32:33] some way of encoding some other [32:36] thing so when you see one of these it [32:39] means [32:40] it's some complicated value [32:43] that excel doesn't know what this is we [32:45] actually use strings for these [32:47] curly braces and some number in between [32:50] different banks use [32:51] different methods for encoding these so [32:54] i think strings with some markers are [32:56] fairly sensible [32:58] at credit swiss we used numbers that [33:01] started at minus 60 000 and counted down [33:05] which i think is insane because we can [33:07] easily [33:08] confuse those into some computation [33:10] somewhere [33:12] at deutsche bank they take the pointer [33:15] and convert it to double and store them [33:37] okay so that's the [33:44] let me see [33:47] so this i you can [33:51] you have a little monitor thing down [33:53] here that [33:54] where you can get some additional [33:56] information so i hit [33:58] the key here and it tells me what this [34:00] is there's a safe i o [34:02] object i module so it's actually not [34:06] done the compilation yet so this [34:09] compiling a module [34:10] is something that lives in io we call it [34:13] well in this reading i o [34:15] because you might import module that's [34:17] out there so you can't really say that [34:19] it's a pure function so we need to [34:22] perform some [34:24] somewhat impure operations [34:43] so it's still not very interesting now [34:44] we have one of these [34:47] by module things but we want to have [34:49] excel to know about it then you have to [34:54] tell excel where i want to actually load [34:56] this module in memory [35:04] and it has not been done yet and you [35:07] can't [35:07] do right effects in the sheet i've said [35:10] and you can [35:12] so if you want to actually perform this [35:14] you have to select this cell [35:16] and go up here and say run action [35:19] now it has performed the action [35:25] so now i can in a cell here say demo [35:28] ink [35:42] like [35:56] yes so i would not recommend writing [35:59] more than [36:00] two lines honestly excel is about the [36:03] worst [36:04] text editor ever [36:09] so i'm doing this for [36:12] expositional purposes so if it was going [36:16] to get much bigger than this i would put [36:17] it in a file [36:19] so that's what you typically use and [36:21] then you [36:22] i mean you can do the same kind of thing [36:23] you just say i want to load this file [36:25] instead [36:27] just to show you one more little thing [36:30] here about this [36:48] doesn't like the text that begins with [36:50] two [36:52] dashes [37:07] okay so now we select this cell [37:10] and we go over here to the function [37:13] wizard [37:14] we can see that the documentation i [37:17] added there it actually [37:18] shows up here [37:34] here [37:36] actually there's a guy back [37:50] so let me show you so now we have this [37:54] function [37:55] so let's uh let's do something with it [37:58] this sheet [38:03] here let's is a little array of numbers [38:08] uh [38:12] functional programming is what it's all [38:14] about after and even [38:17] users excel users understand that [38:21] sometimes there's it's good with some [38:23] abstraction and [38:24] copying formulas is not always the [38:26] answer [38:27] for saying that we function so [38:31] say we want to map this function that i [38:34] have [38:34] just created over this array one two [38:38] three [38:40] well this is excel everything is tedious [38:42] there's no [38:43] concept of functions as first-class [38:47] values or anything so we have to [38:50] write a little bit here to get access to [38:52] the [38:56] us keyboard for some reason it does that [39:05] so this is the object that represents [39:09] the functions [39:19] actually display those over here [39:40] oh [39:54] secretly [39:58] excel power users are amazing to watch [40:01] there are secret key combinations that [40:03] do all kinds of [40:04] weird things [40:07] okay so that's the math directive [40:11] change the value here so automatic [40:14] recalculation is off here at the moment [40:16] but i can [40:17] tell it to recalculate and also [40:20] recombine the module that warns me again [40:22] that i [40:23] don't have an export list here [40:28] okay let me just show you another thing [40:31] that is [40:32] not new related but [40:35] who will feature nevertheless [40:50] um so excel users [40:54] they like to use the sheet to sort of [40:56] define [40:57] the computation so you can [41:01] do something you can define a function [41:03] using the sheet so [41:05] x is just about information on here [41:07] right i'm going to write a little [41:09] function [41:10] uh so example argument and f of x [41:14] okay so i'm going to do two times [41:17] this thing plus one [41:21] so now the computation i've performed [41:24] from this cell to that cell that's [41:26] really like a function [41:28] so maybe you want to use this function [41:30] for something and you can [41:49] now this thing here represents the [41:52] function [41:53] that corresponds to the computation from [41:55] the input cell to the output cell which [41:56] could be [41:57] several cells and then you get something [41:58] with tuples and we could over here where [42:02] we mapped [42:04] we mapped this newly made function [42:14] instead [42:29] let me show you [42:33] a little bit more in a moment first i [42:35] will [42:38] go back to this [42:46] so what about [42:52] i mean this is a compiler what does it [42:54] compile [42:55] so normally combines some intermediate [42:57] code that is interpreted [43:00] but that's not always fast enough so we [43:03] allow people to do [43:07] compilation to native code but that's [43:10] very much on the user control so the [43:12] user has to say [43:13] i want to compile this thing to native [43:16] code [43:16] this thing [43:20] can be anything it's so there is this [43:23] function that will [43:25] of titles and you give it something [43:29] and you get something back that does the [43:31] same thing [43:32] hopefully faster [43:36] if you give it five it's kind of [43:37] uninteresting because [43:39] five is about the faster they get [43:43] but if you give it the function it will [43:46] take that function [43:47] and it will turn it into machine code [43:51] it does this by generating llp and it's [43:53] called and then using the allo become [43:55] jitter [43:57] so for instance if i do this [44:01] so the two functions fcn and cfcm they [44:05] do the same thing [44:06] but the first one will be well there's a [44:08] function here i see [44:11] fcn should have an argument x i'm sorry [44:15] imagine that it says [44:19] x there so that these two would do the [44:22] same thing but the second [44:24] second one would do it quicker if you [44:26] compile cfcf [44:29] you can have nothing interesting to get [44:31] the same thing back together [44:33] or if you try to give it some c plus [44:35] plus function to compile [44:38] also you get the same thing back you get [44:40] a warning message in this monitor saying [44:42] i couldn't actually compile this thing [44:44] so i'm giving the same [45:03] also works for compiling partial [45:05] applications [45:07] so you have a function of two arguments [45:10] and you give it one argument [45:11] and then you say compile on that that [45:14] will actually do some partial evaluation [45:16] it will take the function and the first [45:18] argument [45:19] and march it into the function [45:22] and then it will compile the resulting [45:24] thing so [45:26] by compiling partial applications you [45:28] can really speed things up [45:30] compared to compiling the function and [45:32] that part we apply it [45:35] to this you can do some really cool [45:37] stuff so you write your [45:39] pretty general algorithm that has a [45:42] bunch of arguments [45:43] and then you give it some arguments and [45:45] you say compile on that and you will [45:47] wire a lot of consonants into your [45:49] compiled code [45:52] you will eliminate branches yeah [46:04] um probably not [46:09] so i mean people who just see this as [46:12] some kind of hammer [46:14] this is running slowly let me see what [46:16] happens if i say oh hi [46:18] bang that's a bit better [46:24] you know i mean but where where [46:27] performance really matters [46:28] uh means they can talk to people who [46:31] understand [46:32] what happens and we can help a little [46:34] bit where we put these things [46:38] i'm guessing that we want to partially [46:39] evaluate them [46:54] i lost you somewhere in the middle so so [46:57] it it for all functions it keeps [46:59] all of the the intermediate [47:02] representation around [47:04] so that's all so you can you can do this [47:07] at any stage [47:08] so this this is needed for other [47:11] instance folks [47:13] so what happens if you try to [47:16] uh transport one of these functions a [47:19] segment down the disk or something that [47:21] will shift them from your [47:23] x86 platform to your power pc [47:26] well then it only shifts over the [47:28] intermediate representation and when it [47:30] gets as part of serialization and when [47:32] it's deserialized at the other end [47:34] you co-generate at the other end for it [47:36] so [47:37] machine [47:53] so um [47:56] let's just do this so that here's a [47:58] function i define this one in the next [48:00] cell [48:01] let's just do a [48:13] yeah i got something it's pretty boring [48:27] just close your eyes for a moment [48:30] i'm going to add a debug flag here [48:43] 2x plus 1 [48:47] x plus one morning because two extras it [48:49] would add [48:50] that's that's not fun let me change that [48:53] to [48:57] three x plus [49:01] there [49:05] multiply by that constant which is up [49:07] there which is three and add the one [49:12] this is a little function you've written [49:14] in in excel defined by [49:16] excel and you do fun compile you get [49:18] some [49:19] machine code and you can map that over [49:22] your function or whatever [49:24] you map it over your 10 million element [49:27] array [49:28] it runs too slowly you use the different [49:31] map that runs over on the farm [49:33] and it will transport everything over [49:35] there run it and [49:36] bring the results back i won't show you [49:40] an example of that so this sort of works [49:43] for functions that you define in excel [49:45] or new or yeah basically those [49:49] that you can combine them sort of freely [49:51] and do this [49:52] compile thing on them if you try to do [49:56] it on [49:56] c plus functions well i'm sorry [49:59] it's not like they could have been [50:02] proved but you can't look inside them [50:04] there is no immediate representation for [50:06] them [50:10] uh [50:22] so i just wanted to say something about [50:24] strict versus lazy which is [50:26] sort of oh it's this fantastic [50:30] battle between good versus evil i'm not [50:33] saying which is which [50:37] but actually it doesn't really matter [50:41] that much i mean [50:43] it kind of works in both worlds so there [50:46] are they're good at bad points [50:48] so strictness is really fantastic i must [50:50] say [50:52] stack traces work when something goes [50:55] wrong [50:55] in you it says well you call this thing [50:58] from there from there from there [51:00] it's the single most [51:04] time-saving thing i immediate compared [51:07] to haskell [51:08] because things do go wrong and then it's [51:11] so great to see [51:13] exactly what the call chain was and then [51:15] you can fix it [51:35] what for lack of a meta name i would [51:37] call resource [51:38] compositionality so if you understand [51:41] the [51:41] complexity of two pieces you can stick [51:44] them together [51:45] and nothing weird happens they sort of [51:49] it adds up that's not true within [51:52] in laser language like if one dot [51:56] n is something that the list produced [51:58] lately say [51:59] do you think that that might run into [52:00] confidence rate well that's important [52:03] and some shouldn't consume it it use [52:06] produces a constant size to result [52:09] even so it blows up or might or might [52:12] not depending on how the strictness and [52:14] our lives are felt that day [52:16] so uh yeah and so and debugging [52:20] kind of sensible illustrators and [52:22] exceptions they actually work [52:24] i mean you like this thing in haskell [52:29] you might think you're catching the [52:30] error you're not [52:32] i actually have to run this just to make [52:34] sure this will [52:35] generate the error oops no matter that [52:38] it's a catch there evaluation that's [52:41] what you think [52:43] it's great it's terrible also [52:49] so it has nice resource compositionality [52:52] but it doesn't [52:53] compose nicely semantically so this [52:56] function [52:57] any p which the hassle function that [53:00] tests [53:00] if any element of the list has a certain [53:04] property [53:05] and you want it to stop but it's found [53:07] an element that has that property and [53:08] absolutely provided [53:10] yeah and i do war on those and it will [53:12] automatically stop [53:14] at the right point you write that in the [53:15] strict language it will compute more of [53:18] it [53:20] so you you laziness has some [53:23] good things as well so i would think [53:26] craziness is a much [53:29] nicer way on programming except for [53:32] these [53:33] pesky resources [53:36] so you definitely need some basic [53:38] functions i mean even [53:40] c has lazy functions like if i write [53:43] false [53:43] confidence and error [53:47] that will not call error in c [53:51] so in you you can say [53:54] by name which means use call by name for [53:57] this function [53:59] which basically means use macro [54:01] expansion for this function i mean it's [54:03] not [54:04] the bad kind of macro expansion [54:08] no weird name captures so if you write [54:10] something it requires [54:12] the length of l and l or you get it's [54:14] the same as you've written this [54:16] so sometimes you really need these [54:18] functions [54:20] you must have them so you can do what [54:24] c c plus plus standard ml camel [54:28] i think your camera please does you can [54:30] say hoodies [54:31] are special they're wired in only us who [54:34] made the compiler can make these [54:36] you can make them i don't like that so [54:38] we knew you could [54:40] say this but by the way if you ever try [54:43] if you want to design a language [54:45] never use call by name as your calling [54:48] convention [54:49] so here is that's the definition of [54:51] function composition [54:52] in haskell here's the definition in view [54:56] i want dot to be all my name [55:00] it looks weird it looks weird [55:03] what's this f prime g [55:07] consider this really slow a [55:10] composed with g now if you were just to [55:14] take the definition up there and [55:17] expand those in there you would move [55:20] really slow [55:22] inside the laptop [55:26] don't do that and it doesn't do that it [55:29] has it in the left [55:30] outside there and then it uses x prime [55:32] under the laptop [55:34] but it took a while before i even [55:36] realized i had to do this [55:38] so perhaps [55:45] yeah i could have but i only found this [55:49] one function where i needed to [55:50] yeah i was going to say something [55:52] similar the other thing about that is [55:53] that you were naming [55:54] just a single use of the arguments [56:04] uh so this little program you would [56:08] think that [56:08] it should print 42 and it doesn't hassle [56:11] it wouldn't do that in you because if [56:13] you de-sugar it [56:14] it's called this function where you [56:17] generated them [56:18] and with two arguments and of course [56:20] evaluate the arguments first [56:22] to get an error so well you say by name [56:25] on that too so there are like [56:28] 20 places maybe in the code base that [56:30] says [56:31] by name there are some other functions [56:34] like when none [56:36] from maybe so it seems to be [56:39] somewhat natural to have laziness in [56:41] some of these [56:42] people would never use pascal or [56:45] functional languages [56:46] they came to me and complained that from [56:48] maybe [56:49] was not lazy well they didn't express it [56:51] that way trump maybe takes [56:53] a maybe value to look at and the sort [56:57] default process if it's nothing you'll [56:58] get the default value [57:00] and then put it calls the error as a [57:02] default value [57:03] and that really worked of course so i [57:05] have to change that [57:06] uh i'll skip over this so you really [57:09] want lazy binding sometimes [57:13] uh so if you have some really slow [57:15] computation i'm going to use that say [57:16] inside the map [57:18] you really want to do it zero or one [57:20] times not every time [57:22] or not i mean not one time every time [57:39] to make it straight and straight later [57:42] placing data structures on eyes [57:43] sometimes [57:44] there's still things that don't work [57:46] like zipping with [57:48] one dot dot this doesn't work [57:53] type proxies which happens now and then [57:55] you need [57:56] you really want to make a type [57:57] application but doesn't have that [58:00] you have to pass a value of that [58:03] particular type if you don't have a [58:04] value of that particular type so it has [58:06] undefined or some type [58:08] just to convey some type of information [58:10] that blows up of course unless you put [58:11] the [58:12] binding on that cyclic data structures [58:16] don't work [58:18] and what i've already talked about is [58:20] that this kind of [58:22] idiomatic way of pascal programming [58:24] doesn't work [58:27] um so just some quick [58:30] final statistics so i don't really know [58:33] how many people we have using [58:49] maybe a lot of the others are people who [58:52] don't really [58:53] that's not their main business to [58:55] program [58:56] we have about 400 000 lines of new code [58:59] in about 2400 modules [59:02] we are very clever about computer [59:04] science ignite users [59:07] so i and they don't write things like [59:10] test cases [59:12] and sometimes you really twist they're [59:14] on so it's good to have [59:16] string type checking to at least get [59:20] some of the bugs out early [59:23] and um so we they are not really [59:26] supposed to any no one's supposed to [59:28] check in code [59:29] without having to run the type checker [59:31] over the the entire whole base [59:34] and this on my desktop it takes about 30 [59:36] seconds [59:43] too many complaints about type errors [59:45] maybe because they are slightly better [59:47] than the ghc ones [59:51] i think the key to it is to give more [59:53] locations [59:55] so here's a type error and it says the [59:58] two different types are cool and strange [60:00] and it tells you where did the tool come [60:02] from where did the string come from [60:05] and you just highlighted them in red and [60:07] blue there and once you have that you [60:08] look at them [60:09] oh yeah that's wrong i fix that [60:13] or one plus through [60:17] the class we came from the one that it [60:20] was the number [60:20] and the bull came from true oh yeah [60:23] strong [60:23] i'll fix that it also gives you the [60:27] this other location that tells you [60:30] i was here in the type checking when i [60:33] found this error [60:34] which is completely useless that depends [60:36] on the order in which you were doing [60:38] things [60:38] these are the interesting ones where [60:55] noun could come from both plus [61:01] then it would probably point at plus and [61:04] false so i mean it's not completely [61:08] deterministic where it will point but it [61:10] will point the two things that are in [61:11] conflict [61:13] and one is certainly another thing so [61:16] you could say it comes from plus [61:18] but it also comes from one i mean if i [61:20] put those two in a list [61:22] it would give the same kind of errors [61:25] um you need to have tools for all these [61:29] kind of naive users so we have [61:32] niels h lint which takes haskell code [61:34] and gives you sort of hints on how you [61:36] should rewrite this so we have a version [61:38] of that [61:38] for you with some specific rules added [61:43] and it's nicer to get critique from [61:46] the machine than from people [61:50] there is a redeveloped print thing like [61:53] ghci [61:54] we also have an ide which i think is [61:56] absolutely crucial for these [62:00] beginning users and it has all of the [62:02] usual browsing and editing [62:04] when you're compiling the cover over [62:06] things and see the types and [62:08] you have internal sense for completing [62:10] identifiers [62:11] and it also has a debugger people say oh [62:14] we must have a debugger we must have a [62:15] debugger and then when we finally [62:17] hit the value backer they don't seem to [62:19] be using it [62:24] so we try to hide all [62:27] everything you have to do with the [62:29] compilation from them [62:30] so sort of like the scripting language [62:32] you only have the source code [62:34] you point at the source code and i want [62:36] to run this the fact that this involves [62:39] all kinds of things and maybe artifacts [62:42] like [62:42] executables being produced or something [62:45] like that [62:46] they don't want to know we don't want [62:47] them to know if they need to know that [62:49] they might just get things wrong [62:51] we don't want them to have make files [62:53] and things like that they should have [62:54] source code and say they want to run [62:56] that [62:56] i mean it's running the program that is [62:58] the interesting thing not compiling [63:56] i didn't get the application you [63:58] programmed with you [64:00] know rx and based on services so i [64:02] didn't tell you [64:03] the application what so people well so i [64:06] don't really know i mean there's 400 000 [64:08] lines of code there [64:09] so typical code might [64:13] read some data from different data [64:15] sources databases [64:17] month generate a little bit maybe give [64:20] them to the pde [64:21] solver compute some prices or risks and [64:26] make some numbers off of them make some [64:28] nice little reports that you presented [64:30] as the final thing [64:32] so that might be one thing another thing [64:34] might just be to take a database [64:36] whack another record into it so it's [64:38] really like to [64:39] use like a little scripting language [64:41] one-off tasks and [64:43] bigger things that do a lot of [64:46] data manipulation and so all the [64:49] numerically intensive code is it's just [64:51] falling into c [64:52] plus five so we was really used to [64:54] together other pieces on the system [64:57] so excellent was just for the demo [65:00] so some people use it from excel i mean [65:03] there are some excel sheets but uh [65:08] most of this code is not intended to be [65:11] used from excel for those four hundred [65:13] thousand lives [65:21] no i mean that's difficult to measure [65:25] so a lot of people really seem to like [65:27] it so the people who really seem to like [65:29] it are not [65:30] the ones that are supposed to do [65:34] programming i mean so the quants their [65:36] job is trying to do maths and [65:37] programming so some other ones like it [65:39] some of them [65:40] prefer c plus plus the people who seem [65:43] to like it more [65:44] are the ones the traders and things like [65:46] that we're not supposed to [65:49] program but they do a little bit they [65:50] have to whack something together [65:53] so it's kind of interesting to go walk [65:54] out on the training floor and see prayer [65:56] partners book [65:58] they are next to someone who's trading [66:01] precious metals [66:04] so is it the public language or is it [66:07] just the [66:07] privacy it's our private language [66:12] so i showed you what how nice you can [66:14] program excel [66:29] hardly anyone so how did you learn [66:33] we recommend great book and then they [66:36] look [66:36] at existing code unfortunately a lot of [66:40] the existing code is not [66:42] good examples of how you should [66:50] so are you satisfied compiling um to [66:53] software using llpm or would you ever [66:55] combine the new spec [66:56] view and just try to let developers [66:58] across through the fpga [67:01] i don't think that will work i think if [67:03] you want to [67:05] design hardware you need to have some [67:07] clue about what you're doing [67:15] all right so we've been a little bit [67:16] over so we're going to be back here in [67:18] about 20 minutes