React Creator Jordan Walke Pitches Reason to Escape JavaScript Limits

Jordan Walke - React to the Future — ReasonConf

ReasonConf

Extending React's declarative immutability to an OCaml-based language with native compilation eliminates the performance penalties and runtime instability inherent to the JavaScript virtual machine.

AI-assisted summary of Jordan Walke - React to the Future — original source. Check the original for full context.

Source published:

Key ideas

  • Jordan Walke characterizes Reason as an evolution that expands the core principles of React—minimizing mutable state and restricting side effects—from UI components to the entire programming language using OCaml's battle-tested type system. (0:01)
  • Adoption dynamics depend heavily on reducing static friction rather than just kinetic friction; familiar ergonomics like JSX in React and JS-like grammar in Reason were pivotal in overcoming initial developer resistance. (16:06)
  • Reason's dual-target architecture enables compiling to readable, idiomatic JavaScript via BuckleScript or compiling natively to high-performance binaries, bridging the gap between web ergonomics and native execution speeds. (21:43)
  • The native package manager esy applies React-style reconciliation and global cross-project binary caching to package management, resolving traditional C/C++ and native dependency friction using a familiar package.json workflow. (34:11)

Detailed notes

## Background Published on YouTube by the ReasonConf channel on November 29, 2019, this video captures Jordan Walke's keynote at ReasonConf US 2019, held in Chicago on October 8, 2019. The page description points to the conference's official website and Twitter account while documenting the gathering organized by Draftbit and community sponsors.

## TL;DR Jordan Walke, creator of React and co-founder of React Native, reflects on how React revolutionized frontend development by enforcing immutability, minimizing state, and lowering developer friction through JSX. He argues that these safety and reasoning advantages should not remain confined to UI rendering libraries or held captive inside the JavaScript runtime sandbox. Introducing Reason and its companion tooling like BuckleScript and the esy native package manager, Walke demonstrates how bringing OCaml's battle-tested type system into familiar syntax enables engineers to compile both to idiomatic JavaScript and blazingly fast native binaries. Pointing to real-world native successes like Onivim 2 and Meta's internal testing tools, he challenges developers to push beyond existing paradigms and invent what comes after React.

## Atmosphere & style Walke delivers a thoughtful, measured, and intellectually expansive presentation marked by quiet authority and candid self-reflection. Rather than an aggressive sales pitch, the talk feels like an intimate retrospective and visionary manifesto from a veteran systems designer, seamlessly connecting 1930s lambda calculus and the chaotic landscape of 2010 web development to present-day tooling challenges. His tone is warm, pragmatic, and wryly humorous when recalling the hostile initial reception to JSX, creating an inspiring and grounded atmosphere that invites the audience to rethink the boundaries between web development and native systems programming.

## Bulletin - [00:01](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1s) Jordan Walke characterizes Reason as an evolution that expands the core principles of React—minimizing mutable state and restricting side effects—from UI components to the entire programming language using OCaml's battle-tested type system. - [16:06](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=966s) Adoption dynamics depend heavily on reducing static friction rather than just kinetic friction; familiar ergonomics like JSX in React and JS-like grammar in Reason were pivotal in overcoming initial developer resistance. - [21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) Reason's dual-target architecture enables compiling to readable, idiomatic JavaScript via BuckleScript or compiling natively to high-performance binaries, bridging the gap between web ergonomics and native execution speeds. - [34:11](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2051s) The native package manager esy applies React-style reconciliation and global cross-project binary caching to package management, resolving traditional C/C++ and native dependency friction using a familiar package.json workflow.

## Key takeaways - [00:01](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1s) The driving motivation behind React, React Native, and Reason is making it easier to build high-performance, robust software that does not break when extended. - [02:16](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=136s) Reasoning about code means being able to inspect a localized component and understand its behavior without having to hold the entire application state in memory. - [02:16](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=136s) Immutability by default eliminates the cognitive burden of auditing every caller and callee to verify whether shared data has been mutated out from under an event handler. - [07:13](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=433s) Key programming language foundations like lambda calculus and the Hindley-Milner type system proved decades ago that computation can be expressed purely as functions without requiring manual type annotations. - [10:59](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=659s) Around 2010, web development suffered from uncoordinated DOM mutation and tightly coupled rendering locations before React introduced declarative rendering and client/server flexibility. - [13:22](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=802s) JSX was created to overcome developer pushback against nested JavaScript function calls, modeling syntax after XHP to dramatically accelerate internal adoption at Facebook. - [16:06](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=966s) In technology adoption, static friction (initial barrier to entry) is far more hazardous than kinetic friction (effort required once proficient); syntax acts as the crucial UI of a language. - [18:25](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1105s) Library-level immutability cannot fully guarantee safety across business logic, prompting the design of Reason to provide language-level guarantees, immutable records, and opt-in mutation. - [18:25](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1105s) Exhaustive pattern matching brings compiler-level verification to state transitions, alerting developers to missing cases at build time rather than failing at runtime. - [21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) Reason preserves OCaml's hardened type checker and semantics while replacing the front-end syntax with familiar JavaScript ergonomics, paired with BuckleScript for emitting idiomatic JavaScript. - [24:30](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1470s) React developers already rely on a compile-to-JS step for JSX, making the compilation step of Reason a natural continuation rather than a radical departure. - [26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) Code authored exclusively in JavaScript remains captive to the JavaScript runtime, where JIT heuristics cannot always guarantee the instant startup and hardware efficiency users demand. - [30:56](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1856s) Native compilation in Reason powers tools like fnm and the Onivim 2 editor, while enabling Facebook teams to run unit tests as native binaries via Rely for near-instant execution. - [33:03](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1983s) Traditional native build systems suffer from unmodeled implicit dependencies, making automated, one-click builds and cross-machine artifact sharing historically difficult. - [34:11](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2051s) The esy package manager treats dependency builds like a React reconciliation process, leveraging package.json conventions and global artifact caching to accelerate compilation. - [36:01](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2161s) Unifying native and web development within a single language empowers developers to build universal data-fetching layers, novel UI frameworks, and future successors to React.

## Detailed walkthrough ### [00:01](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1s) Introduction, Background, and the Goal of Reason

Jordan Walke opens ReasonConf US 2019 by thanking Draftbit and Mike for organizing the event, along with all the sponsors who made the gathering possible. Introducing his day job, Walke explains that he works on programming languages and frameworks at Facebook on the Ads Interfaces team. He shares the fundamental motivation driving his work: an enduring frustration with how difficult it remains to build high-performance, robust software. As Jordan Walke puts it: “So my ultimate goal or at least my personal goal is to build an application that is fast and that doesn't break when it's extended and I keep finding that it's just way way too hard to do that so I end up working on languages and frameworks with the goal of being able to make that job easier but really I just want to use those tools myself.” Even with substantial industry progress, he feels UI tooling still contains an abundance of low-hanging fruit waiting to be harvested.

Walke traces his involvement across Facebook’s UI infrastructure over the preceding decade. In 2011, he created the React.js framework. Later, shifting focus to mobile development, he co-founded React Native alongside three teammates. Most recently, he initiated the Reason effort, collaborating with co-workers and the broader open-source community to build out its compiler, syntax, and tooling ecosystem. Reason itself is a fast, type-safe programming language based directly on OCaml. Rather than introducing wholly foreign ideas, Walke views Reason as extending the very principles developers already love about React into the entire programming language itself, thereby opening the door to a significantly more ambitious future for UI development.

- **Speaker Role:** Jordan Walke, Ads Interfaces team at Facebook, working on languages and frameworks. - **Projects Founded / Co-founded:** - React.js (created in 2011) - React Native (co-founded with three others) - Reason (initiated with colleagues and community) - **Reason Definition:** A fast, type-safe programming language built directly on top of OCaml.

---

[02:16](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=136s) Why React Made Programming Fun Again: Minimizing State and Mutation

Reflecting on the open-sourcing of React in 2013—which he presented alongside Tom Occhino at JSConf—Walke notes that while he rarely gives conference talks anymore, he frequently attends meetups and hears common feedback from engineers: React made their jobs fun again. He argues that this reaction is not merely the result of out-of-the-box IDE support or npm's abundance of packages, but stems from a deeper intellectual shift. React instills a core guideline: minimize application state and minimize side effects. While developers often express this by calling React "composable" or stating that code is "easier to reason about," Walke defines reasoning about code precisely: it means an engineer can examine a localized slice of code and understand its interactions and complexities without having to keep the entire program in their head at once.

To demonstrate that this is a measurable property rather than mere opinion, Walke walks through a code snippet where a component renders a list of friends inside a container, with an outer click handler reporting the total friend count. Because time elapses between the initial render and the user's click, mutable data creates an enormous cognitive burden. If any module mutates or trims that array in the interim, the click alert falls out of sync with the rendered UI. To confirm whether a mutation can occur, a developer must trace every caller passing in the array, as well as every downstream callee that receives it. Conversely, in a language or type system where the array is immutable by default, that mental overhead drops to zero. As Jordan Walke observes: “This is all you have to keep in your head to understand almost completely how this component works you could reason about it so programming like this you know it allows you to experience many small wins when you're programming it's kind of like your brain gets this this reward every so often and you're confident with what you've achieved it makes programming fun it's kind of like a game.” While purists point out ways guardrails can be bypassed in JavaScript, React established a "pit of success" and represented a major course correction for modern UI engineering.

```mermaid flowchart TD accTitle: Cognitive Burden of Mutable vs Immutable UI State accDescr: Comparison between tracing callers and callees in mutable systems versus localized reasoning in immutable systems.

subgraph Mutable ["Mutable State: Global Tracing Required"] direction TB M_Callers["Check all upstream caller modules"] --> M_Comp["Component renders friend array"] M_Comp --> M_Downstream["Check all downstream callee modules"] M_Downstream --> M_Bug["Risk: Array mutated out from under event handler"] end

subgraph Immutable ["Immutable State: Localized Pit of Success"] direction TB I_Comp["Component renders immutable friend array"] I_Comp --> I_Safe["Guaranteed: Click count matches view without global audits"] end ```

- **Definition of "Reasoning About Code":** Being able to understand the majority of complexities in a small component locally without needing the entire application state loaded into memory. - **The Pit of Success:** Designing APIs and language constraints such that the easiest, most natural path is also the correct, robust one. - **The Core React Principle:** Minimizing mutable application state and restricting side effects to make UI construction composable like building blocks.

---

[07:13](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=433s) Looking to History: Lambda Calculus and the ML Family

Recognizing that React's core ideas feel fresh to many developers despite being as old as computer science itself, Walke looks backward into language history to project what might lie ahead for UI development. In 1932, mathematician Alonzo Church formulated lambda calculus, the simplest conceivable foundation of computation centered entirely on lexically scoped functions and expressions. Astonishingly, lambda calculus proved that any computable problem could be expressed purely as function applications returning expressions rather than imperative mutation sequences. As Jordan Walke highlights: “What's really amazing here though that lambda calculus was discovered before the first programmable computer was ever invented so that should tell us something so this wasn't contrived out of the constraints of technological progress in the time these ideas they seem to be timeless.”

Moving from abstract mathematics to running hardware, the Lisp family emerged in the 1950s, bringing lambda calculus into a human-usable programming paradigm running on real machines. As systems grew larger and teams collaborated across larger codebases, there was an increasing demand to automatically detect and reject erroneous programs ahead of time via static type systems. This culminated in the invention of the ML family of programming languages and the Hindley-Milner type system by J. Roger Hindley and Robin Milner (with Walke clarifying with a grin that "ML" here stands for Meta-Language, not machine learning). ML proved that static types do not need to be an onerous burden that derails rapid prototyping, because compiler type inference can automatically determine types without requiring explicit annotations everywhere. With languages like Standard ML, OCaml, and Elm descending from this lineage, Walke notes the remarkable speed of early computer science evolution—going from no programmable computers to Hindley-Milner type systems in roughly forty years—setting up the tantalizing expectation of where developer tooling ought to be another forty years later.

- **1932:** Alonzo Church discovers lambda calculus, introducing functions, lexical scoping, and pure expressions prior to the physical computer. - **1950s:** The Lisp family translates lambda calculus concepts into practical, executable software on physical hardware. - **1970s:** J. Roger Hindley and Robin Milner develop the Hindley-Milner type system and the ML language family. - **ML Lineage:** Encompasses languages such as Standard ML, OCaml, and Elm, distinguished by powerful type inference that eliminates manual annotation overhead.

[10:59](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=659s) The State of Web Development circa 2010 and the Genesis of React

Jordan Walke reflects on the bizarre state of web engineering between the early 1970s and 2010. Despite decades of computer science advancements, working as a web app developer around 2010 meant living without static types, without paradigms that allowed easy reasoning, and relying on two dynamic scripting languages: JavaScript and PHP. The standard architecture was convoluted: developers rendered markup on the server, shipped it across the wire, and then attempted to "sprinkle some JavaScript on it on the client" in the faint hope of making a static document interactive. Although that setup is easy to criticize in hindsight, it was the ubiquitous industry status quo.

The most debilitating aspect of this workflow was that every interaction relied entirely on direct mutation. If an engineer wanted to change the color of an element, they would simply reach out directly to that DOM node and command it to change. If another script or colleague decided to do the exact same thing simultaneously, both operations executed with no coordinated structure or predictable ordering. Jordan began building several prototypes of what eventually became the React.js library to address these compounding structural issues.

Rather than solving a single isolated concern, React tackled several foundational problems simultaneously, which ironically made it harder to pitch at first. First, it decoupled rendering location: applications were no longer forced to commit upfront to either server or client rendering. Developers could render everything on the client and, if network latency or bandwidth constraints shifted, migrate that rendering back to the server. Most significantly, React smuggled functional programming principles and immutability into the mainstream. Recognizing that many engineers recoiled from academic jargon, Jordan adopted pragmatic framing: “I find that if you just call it declarative programming it just it's an easier pill to swallow it's like they don't want the question there their identity as a programmer.”

[13:22](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=802s) The JSX Breakthrough and the Friction of Syntax

```mermaid flowchart LR accTitle: Evolution of React Syntax and Adoption accDescr: Diagram showing the progression from raw JavaScript function calls to internal JSX adoption and subsequent open source friction.

subgraph Internal["Internal Adoption at Facebook"] A["Raw Function Calls<br/>(Nested brackets & parens)"] -->|"Feedback & fatigue"| B["JSX Prototype<br/>(Diffs from Adam Wolff & Marcel Laverdet)"] B -->|"Familiar to XHP/PHP devs"| C["Internal Enthusiasm<br/>& Rapid Adoption"] end

subgraph OpenSource["Open Source Launch"] C -->|"JSConf 2013 Reveal"| D["External Skepticism<br/>(Furrowed brows & Twitter backlash)"] D -->|"Gradual persistence"| E["Widespread Industry Standard"] end ```

When Jordan first demoed raw React prototypes to fellow Facebook engineers, he hoped to debate high-level conceptual merits like declarative architectures and component trees. Instead, engineers fixated purely on the ergonomics: all they saw was an intimidating, endless cascade of nested closing brackets, parentheses, and braces. Because Facebook engineers were already accustomed to XHP—a dialect of PHP that allowed developers to embed XML tags directly within backend code—Jordan listened to the pushback. He dusted off earlier work and parser diffs from Adam Wolff and Marcel Laverdet, piecing together the syntax extension now known as JSX. JSX was not an architectural overhaul; it was pure syntactic sugar that compiled directly down to the exact function calls shown before. The internal response swung dramatically overnight from skepticism to enthusiastic curiosity once this ergonomic friction disappeared.

Encouraged by widespread internal adoption, the team decided to open-source React, naively expecting the broader developer community to greet it with identical enlightenment. Jordan recounts presenting React publicly and displaying the JSX syntax on screen, only to be met with total bewilderment: “I remembered looking out at the audience and just seeing the sea of furrowed brows in like angry faces and people were it was like visibly upset and I was like wow what's what did I say do they just they just really not like immutability or something”. Attendees recoiled at mixing HTML-like markup into JavaScript files, unleashing a storm of harsh criticisms across Twitter. While developers eventually looked past the syntax to appreciate the declarative programming model, the launch reinforced a lasting lesson about developer psychology.

[16:06](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=966s) The Physics of Adoption: Static vs. Kinetic Friction

To explain why superficial design details can derail brilliant software, Jordan compares driving technology adoption to pushing a heavy boulder along the ground, governed by two distinct physical forces: static friction and kinetic friction. Static friction represents the high threshold of initial force required to set an object into motion from a dead stop, whereas kinetic friction represents the ongoing energy required to maintain momentum once moving. Innovators often assume that as long as kinetic friction is low—meaning the tool is undeniably productive once mastered—developers will willingly exert the effort to overcome the initial hurdle.

However, developers never evaluate a tool in a vacuum. On any given morning on Hacker News, engineers are presented with twenty different boulders competing for their attention, many of which require zero static friction to start rolling immediately. Furthermore, building software is collaborative; engineers must convince skeptical teammates, project contributors, and pull-request authors to push that same stone alongside them. High initial friction kills promising ideas before their kinetic benefits can be realized:

> “My suggestion is to ruthlessly remove all of the static friction that you can in your technologies and so the core lesson that we learned from just the open sourcing process of react and the internal adoption is that syntax matters it really does it's really highly subjective but it matters because it influences the outcomes that's what we care about.”

- React grew from a contested prototype into an industry standard maintained by a dedicated, full-time engineering team. - The library surpassed a quarter-billion downloads per year on NPM alone. - Including downstream client content delivery networks (CDNs) and consumer devices, actual distribution totals billions of instances annually.

[18:25](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1105s) Beyond Components: Expanding Declarative Safety to the Entire Language with Reason

While React successfully introduced declarative rendering and component-level immutability to the web, Jordan emphasizes that components represent only a fraction of an application. The remainder of the codebase—business logic, data structures, and state management—still suffered from runtime mutation and dynamic typing. Because library-level abstractions cannot definitively solve static typing, genuine safety requires language-level guarantees. Reason (later ReasonML) was created to carry React’s core design principles beyond UI boundaries into general-purpose application programming.

```mermaid flowchart TD accTitle: Reason Language Guardrails accDescr: Breakdown of how Reason delivers local reasoning through immutability, opt-in mutation, and exhaustive pattern matching.

subgraph MemoryModel["Data Structures"] R1["Immutable Records by Default"] -->|"Guaranteed Local Reasoning"| T1["IDE Hover Inspection<br/>(Proven Unchanged)"] R2["Opt-in Mutable Fields"] -->|"Familiar JS-like syntax"| T2["`record.field = value`"] end

subgraph TypeSafety["Pattern Matching Engine"] P1["Turbocharged Switch"] -->|"Exhaustiveness Check"| P2["Compile-Time Error Diagnostics"] P2 -->|"Terminal Warning"| P3["'Here is an example of a case that is not matched'"] end ```

In Reason, records are completely immutable by default. A programmer reading code or hovering over identifiers in an IDE can instantly verify that a data structure cannot be mutated elsewhere, eliminating ambient side effects and restoring local reasoning. Yet Reason deliberately avoids ideological rigidity: developers can explicitly annotate specific record fields as mutable when necessary, updating them using intuitive syntax (`mySettings.isAdmin = true`) that feels indistinguishable from conventional JavaScript. By designing the grammar to share syntax with both JavaScript and JSX, Reason systematically minimizes the static friction required to onboard colleagues.

Beyond familiar JavaScript ergonomics, Reason integrates advanced language features such as exhaustive, fully type-driven pattern matching. Jordan characterizes pattern matching as a turbocharged switch statement ideally suited for modeling Redux-style state machines and discrete state transitions directly within the core grammar. If an engineer alters an application state or forgets an edge case—such as pressing the `Escape` key while a user session is active—the Reason compiler rejects the build and outputs an explicit terminal warning highlighting the unhandled case. These guarantees provide compile-time mathematical certainty rather than brittle runtime assumptions.

[21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) Demystifying Reason: Syntax, Compilers, and BuckleScript

Jordan Walke breaks down what Reason actually is behind the scenes: it is OCaml, one of the classic ML-family languages. Addressing the question of whether Reason counts as a new language or just OCaml, Walke explains that a language encompasses community, package managers, libraries, patterns, and use cases, but at its heart lies a compiler. Reducing compiler architecture to three core stages—front end (syntax and user interaction), middle stage (type system and semantics), and back end (code generation, whether native machine code or JavaScript)—he explains that Reason begins by swapping the front end of OCaml for a syntax immediately intuitive to JavaScript developers.

```mermaid flowchart LR accTitle: Compiler Architecture of Reason and BuckleScript accDescr: Three-stage compiler pipeline showing how Reason replaces the frontend syntax and BuckleScript replaces the backend code generator while preserving the OCaml type system.

subgraph Frontend["Front End"] RS["Reason Syntax (JS-like UI)"] end

subgraph Middle["Middle End"] TS["OCaml Type System & Semantics"] end

subgraph Backend["Back End"] BS["BuckleScript (Idiomatic JS)"] Native["OCaml Native Compiler (Machine Code)"] end

RS --> TS TS --> BS TS --> Native ```

Syntax is not merely superficial; as Walke points out, “Syntax matters; it's the UI of your programming language.” Quoting reactions from Twitter, he notes developers finding Reason immediately approachable because of that familiar look. While no single syntax pleases everyone, the choice is pragmatic: the JavaScript developer community is vast, and technology adoption requires eliminating friction for the largest audience possible, even if it adds friction for a smaller group. Furthermore, pairing Reason with BuckleScript swaps out OCaml's back end to emit clean, idiomatic JavaScript that teams can commit to source control without coworkers getting upset. Walke summarizes the setup: “Importantly, it's still OCaml exactly where you want to be—in that battle-tested, hardened type system.”

- Compiler stages: front end (syntax/interaction), middle end (type checker/semantics), and back end (code generator/target output). - Reason replaces the OCaml syntax front end with JavaScript-familiar ergonomics. - BuckleScript replaces the native compiler back end with an idiomatic JavaScript emitter.

---

[24:30](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1470s) Compiling to JS and Bringing React's Ideals to the Whole Language

Anticipating skepticism that adopting Reason is a radical departure for JavaScript codebases, Walke pushes back using the history of React itself. Ever since React was open-sourced, developers have written JSX, which is not valid JavaScript and cannot run directly in browsers without compilation. Anyone writing React is already using a compile-to-JS pipeline, reducing the debate to a question of compiler trade-offs. Walke has little patience for preserving legacy practices simply for comfort: “I'm not really interested in talking—you know, biasing towards the status quo, because if we did that, we'd still be rendering PHP on the server and we wouldn't have React.”

Walke argues that React fundamentally improved developer ergonomics and made UI code easier to reason about, but it deliberately did not solve every problem across the codebase. He envisions Reason as the natural extension of those developer experience gains across everything else: “The way I think about Reason is that it brings the things that people like about React to the entire language, so that every use case in the JavaScript ecosystem benefits from those same core ideas.”

---

[26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) The User, Native Performance, and Escaping the JavaScript Sandbox

Walke shifts focus from developer convenience to the person who matters most: the end user. While both React and Reason improve user experience by drastically cutting bugs ahead of time, users also care deeply about performance. Looking outside the JavaScript bubble, engineers routinely choose Rust, C, and Go despite the popular industry mantra: “What part of 'always bet on JavaScript' do they not understand?”

The reality is that users demand instant startup times, better hardware utilization, predictable performance, and higher throughput. While JIT (just-in-time) compilers can achieve impressive peaks, their reliance on complex runtime heuristics makes performance unpredictable and hard to guarantee across untested application workflows. Web developers wanting to reuse code across environments find themselves trapped: either learn an entirely separate native language and rewrite their stack, or push JavaScript past its breaking point and force the user to pay the performance penalty. As Walke puts it, “Ultimately, any library that's authored in JavaScript is held captive by JavaScript—it can really only be used in so many scenarios.”

- Users demand fast startup, high throughput, and reliable hardware utilization that JIT heuristics cannot consistently guarantee. - JavaScript developers face an uncomfortable dilemma: rewrite and maintain duplicate codebases for constrained targets, or overextend the JS VM at the user's expense. - Reason skills transfer directly between web-targeted code and native executables.

---

[30:56](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1856s) Native Reason in Practice: fnm, Onivim 2, and Internal Tooling at Meta

The native compilation story for Reason is already yielding tangible wins across developer tools and applications. Walke highlights `fnm` (Fast Node Manager), a Node.js version manager built natively that runs so fast it can execute in shell startup scripts imperceptibly. He also points to Onivim 2 (Oni 2), a modal text editor built on Vim whose GUI was rewritten using native Reason. Quoting users stunned by Onivim 2's responsiveness, Walke reads: “It's crazy performant, like scary fast. I actually didn't know an app could start that fast on my Mac. Did I click it? Already started.” These native projects outperform Electron- or Node-based competitors purely on performance, and they were built by engineers originating from the web community.

Inside Meta (Facebook), Walke’s team utilizes this dual-target capability daily. They author Reason modules that compile to JavaScript via BuckleScript for production web use, while simultaneously compiling them into native binaries for local test suites. Running native binaries eliminates the overhead of launching a JavaScript VM, delivering instant test turnaround. This workflow is powered by Rely, a Jest-inspired native testing framework, and Reason Native, a suite of open-source utilities designed to bring familiar Node-style APIs to native Reason programming. Walke closes by asking why native compilation historically had such a poor reputation among web developers, pointing to the nightmare of C++ toolchains requiring dozens of conflicting global packages installed on a developer's machine.

- **`fnm` (Fast Node Manager):** A native Reason CLI utility fast enough to run transparently in interactive shell sessions. - **Onivim 2:** A lightweight, high-performance modal editor combining Vim internals with a Reason Native GUI. - **Rely:** A native test runner mimicking the Jest API to execute unit tests without a JavaScript runtime. - **Reason Native:** Meta's open-source library ecosystem porting standard Node-style developer utilities to native Reason.

[33:03](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1983s) Why Native Builds Are Painful and the Need for Automation

Jordan Walke reflects on the frustrating rite of passage common to traditional native programming: spending hours wrestling with Makefiles and environment variables just to get a foreign codebase to compile. This friction stems from historical conventions in the native software ecosystem, where dependency graphs were rarely modeled in full end-to-end automation. In classic C, C++, or system programming cultures, projects frequently relied on implicit ambient dependencies already present on the maintainer's machine.

When packages do not model every dependency explicitly, consumers are forced to manually reproduce the original author's exact system configuration. If those environmental prerequisites are not thoroughly documented in a README, onboarding grinds to a halt. Furthermore, this absence of strict dependency isolation makes it almost impossible to share reliable pre-built binary artifacts across machines or reuse compiled artifacts between different projects on the same computer. Walke stresses that if the Reason ecosystem wants to attract web engineers to native development workflows, the tooling cannot demand manual compiler wrangling; it must offer a frictionless, one-click experience that feels completely natural to developers coming from the modern web.

As Jordan Walke summarizes the historical challenge of native tooling: > “Well native builds have historically not completely automated and modeled all the dependencies that are required it's just part of the culture in a lot of the previous native programming so there's no one clicked there.”

- **Unmodeled system dependencies:** Native build recipes frequently assume global header files, shared libraries, and specific compiler versions, forcing consumers to reverse-engineer undocumented host environments. - **Lack of artifact portability:** Because builds are tightly coupled to idiosyncratic machine configurations, pre-built binary artifacts cannot easily be distributed or shared across local workspaces. - **Web developer expectations:** To lower the barrier of entry, native compilation must provide deterministic, push-button ergonomics comparable to modern web toolchains.

---

[34:11](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2051s) Esy: Declarative, Reconciled Native Package Management

To eliminate the pain of native compilation, Andrey Popp created `esy`, a package workflow designed to serve as the single "easy button" for configuring, accelerating, and executing native builds. Outwardly, `esy` mimics the interface of JavaScript package managers: developers declare their dependencies in a familiar `package.json` file, allowing any frontend engineer to inspect a repository and immediately understand its structure. However, Walke clarifies that `esy` is not a wrapper around npm or Yarn. It is an independent, native package management implementation written directly in Reason Native, engineered from scratch for maximum execution speed and predictability.

Walke characterizes `esy` as applying the core philosophy of React to package management. When an engineer runs `esy` in their terminal, the tool behaves like a reconciliation engine: it inspects the dependency tree, fetches required sources over the network, resolves dependencies, and triggers the necessary build steps. Crucially, `esy` implements an immutable global cache for compiled build artifacts across all projects on a developer's machine. Once a dependency is built for one project, every other project sharing that configuration reuses the cached build instantly, meaning the developer's build times continuously accelerate the longer they use the tool. It also stands on the shoulders of OCaml's OPAM package manager—incorporating OPAM solver logic and Windows compatibility research—while seamlessly bridging C and C++ libraries, OPAM packages, and JavaScript dependencies into a single, unified workflow.

Explaining how `esy` mirrors React's architecture, Jordan Walke observes: > “I think of it as like a react but for package management so in the same way that we're bringing the ideas of react to the language of threes and we're bringing the ideas of react to the package management with easy so when you run easy it reconciles your project fetches what needs to be fetch from the network builds it needs to be built and does it really fast.”

```mermaid flowchart TD accTitle: Esy Architecture and Dependency Resolution accDescr: Diagram showing how esy reconciles dependencies from multiple ecosystems into an immutable cache and native artifacts. subgraph Sources["Dependency Sources"] A["package.json"] B["OPAM Ecosystem"] C["C / C++ Libraries"] end

subgraph Engine["Esy Workflow Engine"] D["Reconciliation & Solver"] E["Native Build Engine (Reason)"] end

subgraph Storage["Output & Artifacts"] F[("Global Cross-Project Cache")] G["Fast Native Binary"] end

A --> D B --> D C --> D D --> E E <--> F E --> G ```

- **Familiar configuration:** Uses a standard `package.json` format, making Reason Native repositories immediately recognizable to JavaScript and npm users. - **Native performance:** Implemented in Reason Native rather than Node.js, providing rapid command execution and parallelized compilation. - **Cross-project binary caching:** Compiled packages are stored in a shared global store, preventing redundant recompilations across different local codebases. - **Polyglot dependency support:** Interoperates with the OCaml OPAM registry, native C/C++ source code, and JavaScript packages within one consistent toolchain.

---

[36:01](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2161s) Expanding Horizons: What Will You Build After React?

Walke ties the overarching vision of Reason back to the revolution started by React. By translating declarative, functional UI concepts into a fast, statically typed language that compiles to both native targets and JavaScript, Reason unlocks a developer's potential to master a single foundational language and deliver optimal user experiences across wildly divergent constraints—from memory-constrained mobile devices to high-performance servers and client-side browsers.

In his closing call to action, Walke challenges the community to look beyond existing frontend abstractions. He invites the audience to leverage Reason's cross-platform capabilities to invent fundamentally new paradigms: universal data-fetching solutions that operate everywhere, next-generation user interface frameworks, or entirely new application models that could eventually succeed React itself.

Jordan Walke delivers his closing message on the transformative scope of the platform: > “Reason takes the ideas of react to the next level and i see it as a way to unlock your potential as a developer because it allows you to learn one language that improves the user experience across a wide variety of use cases and constraints so i want to leave you with one question what could you build a threesome maybe you could build a really cool data fetching paradigm a framework that runs everywhere maybe you could build a new UI library maybe you could build what comes after react thank you.”

- **Unified developer leverage:** Mastering Reason allows engineers to target diverse operational environments without forfeiting type safety, expressive syntax, or fast execution. - **Open frontiers for innovation:** The community is urged to invent next-generation paradigms, including cross-platform data fetching runtimes, novel UI primitives, and the conceptual successors to React.

## Notable quotes > [21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) Syntax matters; it's the UI of your programming language. — Jordan Walke

> [26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) Ultimately, any library that's authored in JavaScript is held captive by JavaScript—it can really only be used in so many scenarios. — Jordan Walke

> [24:30](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1470s) The way I think about Reason is that it brings the things that people like about React to the entire language, so that every use case in the JavaScript ecosystem benefits from those same core ideas. — Jordan Walke

## Mentioned Jordan Walke, Facebook, React.js, React Native, Reason, OCaml, Tom Occhino, Alonzo Church, Lisp, J. Roger Hindley, Robin Milner, Standard ML, Elm, JavaScript, PHP, XHP, Adam Wolff, Marcel Laverdet, JSX, BuckleScript, fnm, Onivim 2, Rely, Reason Native, Andrey Popp, esy, OPAM, Draftbit, ReasonConf

## Video description ReasonConf US 2019, Chicago, 10/08/2019

Twitter: https://twitter.com/reasonconf Website: https://reason-conf.com

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

中文简报

React创造者Jordan Walke推介Reason以突破JavaScript局限 将React的声明式不可变性扩展至基于OCaml且支持原生编译的语言,消除了JavaScript虚拟机固有的性能损耗与运行时不稳定性。 React创造者兼React Native联合创始人Jordan Walke回顾了React如何通过强制不可变性、最小化状态以及借助JSX降低开发者阻力来彻底革新前端开发。他认为,这些安全性和推理层面的优势不应局限于UI渲染库,也不应被禁锢在JavaScript运行时沙箱之内。通过介绍Reason及其配套工具(如BuckleScript和esy原生包管理器),Walke展示了将经受过实战检验的OCaml类型系统融入熟悉的语法中,如何让工程师既能将其编译为符合惯用法的高质量JavaScript,又能编译为极速的原生二进制文件。他列举了Onivim 2以及Meta内部测试工具等实际原生成功案例,并激励开发者突破现有范式,开创超越React的下一代技术。 Jordan Walke将Reason描述为一种演进,它利用OCaml经受过实战检验的类型系统,将React的核心原则(最小化可变状态和限制副作用)从UI组件扩展至整个编程语言。 (0:01) 技术的采纳动态在很大程度上取决于减少静摩擦而非仅仅是动摩擦;诸如React中的JSX以及Reason中类JS语法等符合直觉的工效设计,对于克服开发者最初的抵触心理起到了关键作用。 (16:06) Reason的双目标架构支持通过BuckleScript编译为可读、符合惯用法的JavaScript,或原生编译为高性能二进制文件,弥合了Web人体工程学与原生执行速度之间的差距。 (21:43) 原生包管理器esy将React风格的协调和全局跨项目二进制缓存应用于包管理,利用熟悉的package.json工作流解决了传统的C/C++及原生依赖阻力。 (34:11)

Reading summary

Jordan Walke argues that the core architectural wins of React—minimizing mutable state, enabling localized reasoning, and removing ergonomic friction—must be extended across the entire programming language via Reason. By pairing OCaml's type system with familiar syntax and automated native tooling, developers can achieve predictable, high-throughput native performance without abandoning web ergonomics. Local Reasoning and the Pit of Success (2:16) Walke attributes the enthusiasm surrounding React not to IDE tooling or package registries, but to a structural reduction in cognitive overhead. Under traditional mutable architectures, auditing an event handler requires developers to trace every upstream caller and downstream callee across an entire application to guarantee state has not mutated out of sync with the rendered view. In contrast, React introduced a "pit of success" by prioritizing immutable data and restricted side effects, allowing engineers to verify a component's behavior entirely within a localized slice of code. These design principles originate in foundational computer science rather than contemporary web trends. Walke points to Alonzo Church's 1932 discovery of lambda calculus—formulated before physical computers existed—to illustrate that computation fundamentally relies on lexically scoped expressions and pure functions rather than stateful mutation. The later introduction of the Hindley-Milner type system and the ML language family in the 1970s proved that compilers could infer types automatically, removing the burden of manual type annotations while preventing catastrophic runtime failures. Adoption Physics and the Role of JSX (13:22) When early React prototypes relied on raw, deeply nested JavaScript function calls, internal adoption at Facebook stalled because engineers found the syntax ergonomically exhausting. By incorporating parser diffs from Adam Wolff and Marcel Laverdet, Walke implemented JSX as syntactic sugar over nested calls, mirroring the familiarity of XHP. Although the syntax provoked widespread skepticism when debuted externally at JSConf 2013, lowering this initial barrier proved essential for mass adoption, ultimately scaling the library to hundreds of millions of downloads annually. Walke frames technology adoption using the physical concepts of static friction and kinetic friction. While kinetic friction represents the ongoing effort required once an abstraction is mastered, static friction is the upfront cognitive hurdle developers face when first evaluating a tool. Because engineers evaluate competing technologies collaboratively under tight constraints, tools with high static friction are frequently abandoned regardless of their long-term kinetic efficiency. Consequently, Walke advises language designers to ruthlessly optimize surface syntax to lower onboarding resistance. Extending Declarative Safety to the Entire Language (18:25) While React brought declarative rendering and immutability to user interface components, it left surrounding application logic, data structures, and state pipelines exposed to JavaScript's dynamic mutations and runtime exceptions. Walke positions Reason as a mechanism to bring React's safety guarantees to general-purpose programming by leveraging OCaml's battle-tested Hindley-Milner type system. Rather than forcing web developers to learn an unfamiliar ML syntax, Reason replaces OCaml's front-end parser with a JavaScript-like grammar while compiling to idiomatic JavaScript via BuckleScript or directly to native machine code. Reason enforces local reasoning by making records immutable by default, while retaining opt-in mutable record fields for scenarios where imperative updates are strictly necessary. Furthermore, the language introduces exhaustive pattern matching, which functions as a compile-time verification engine for discrete state machines. If an engineer adds an unhandled state or overlooks an interaction edge case, the Reason compiler rejects the build and highlights the missing branch in the terminal, eliminating brittle runtime assumptions. Escaping JavaScript Runtimes with Native Tooling (26:12) Walke emphasizes that end users prioritize instant startup times, predictable throughput, and hardware efficiency—metrics where JavaScript JIT heuristics struggle. Applications authored in JavaScript remain held captive by VM constraints, forcing developers either to duplicate business logic in separate systems languages or impose performance costs on end users. Using Reason, teams can target native executables directly, as demonstrated by utilities like the fast Node version manager fnm, the Onivim 2 editor, and Meta's native test runner Rely, which executes unit tests without the latency of launching a JavaScript runtime. To address the historical friction of native compilation—such as unmodeled system dependencies, complex Makefiles, and brittle machine configurations—Andrey Popp created esy. Built in Reason Native, esy operates like a declarative reconciliation engine for native builds using familiar package.json files. It isolates dependencies across C, C++, OCaml OPAM packages, and JavaScript, while managing an immutable, global cross-project artifact cache that continuously accelerates subsequent compilations across a developer's machine. Walke views Reason as a mechanism to free developers from the operational limits of JavaScript VMs by unifying native and web execution under a single, type-safe paradigm. He leaves the community with an open challenge to look beyond existing frontend constraints and leverage cross-compilation tooling to create universal data-fetching models, next-generation UI primitives, and the eventual successors to React itself.

精炼阅读摘要

Jordan Walke认为,React的成功在于通过减少可变状态和副作用实现了局部推理,而Reason(基于OCaml)的目标是将这一声明式与不可变理念从组件层推向整门编程语言,结合原生编译与现代化工具链,打破JavaScript虚拟机的性能与平台限制。 局部推理与可变状态的认知负担 (2:16) Walke回顾了React的核心设计哲学,指出让编程重新变得有趣的并非工具集成或生态规模,而是心智模型的转变。他将“代码可推理”严格定义为:开发者仅凭审视局部组件即可理解其行为与复杂度,无需在脑海中维持整个程序的全局状态。在以可变数据为主的传统UI交互中,从数据初始渲染到事件触发(例如点击统计好友列表),数据随时可能被其他模块篡改。为了排查潜在问题,工程师必须溯源所有上游调用方与下游被调方,从而产生沉重的认知负担;而默认不可变的数据结构则消除了这种全局追踪开销。 语法与摩擦力:从JSX到Reason的采纳物理学 (13:22) 结合React早期的原型迭代与开源历程,Walke提出了技术采纳中的“静摩擦力”与“动摩擦力”模型。动摩擦力指工具掌握后的长期生产力,而静摩擦力是初始接受阶段的心理门槛。当年纯JavaScript嵌套调用让Facebook内部工程师感到疲劳,团队引入JSX语法糖后迅速消除了阻力并实现内部普及;但在2013年JSConf公开发布时,将HTML标签混入JS又引发了外部开发者的强烈反弹与质疑。这一历程证明,语法作为语言的用户界面,对实际采纳结果具有决定性影响。Reason借鉴了这一经验,选择在OCaml成熟的Hindley-Milner类型系统前端套上贴近JavaScript的语法外壳,并配合BuckleScript生成地道的JavaScript,以最小化生态迁移的静摩擦力。 将安全保障延伸至语言核心与原生执行 (18:25) Walke强调,组件仅占应用的一部分,业务逻辑与状态管理若停留在动态语言层面,仍无法摆脱运行时异常。Reason在语言层面确立了默认不可变的记录结构,同时提供明确标注的可变字段以避免教条主义,并结合穷尽性模式匹配,在编译期强制处理所有分支与边缘情况。更重要的是,Reason摆脱了JavaScript虚拟机的束缚:依靠OCaml的编译器管线,同一套代码既可通过BuckleScript编译为Web端的JS,也能直接编译为原生机器码。Walke列举了fast-node-manager(fnm)和Onivim 2等原生项目,展示了亚毫秒级响应和零开销启动等JIT虚拟机难以稳定保证的用户端性能优势。而在Meta内部,团队已在生产中将Reason模块编译为JS部署,同时编译为原生二进制配合Rely框架实现极速单元测试。 原生构建的自动化与esy声明式包管理 (33:03) 传统C/C++原生开发之所以在Web开发者眼中充斥痛点,根本原因在于其历史文化往往缺乏对系统依赖项的端到端形式化建模,导致用户必须手动还原编译环境,无法跨机器或跨项目复用二进制产物。为了解决该阻力,Andrey Popp开发了基于Reason Native构建的包管理工具esy。Walke将esy类比为“包管理领域的React”:它采用Web工程师熟悉的package.json作为声明式配置,在终端运行时扮演调和引擎(reconciliation engine)的角色,自动解析网络依赖、桥接OPAM生态与C/C++依赖库,并通过全局不可变缓存避免重复构建,从而为原生开发带来了现代Web级别的一键化与确定性体验。 Walke总结认为,Reason将React的理念延展到了整门语言与跨平台原生工程中,使开发者掌握单一语言即可应对从受限移动设备、Web端到高性能后端的全场景需求。他最后呼吁社区跳出既有框架,在统一的静态类型和原生性能基础上探索下一代数据获取模型和超越React的新型UI抽象。

Detailed notes — zh

## Background 本内容由 ReasonConf 于 2019 年 11 月 29 日发布在 YouTube 平台上。页面描述显示,这是 React 创始人 Jordan Walke 在 2019 年 10 月 8 日于芝加哥举行的 ReasonConf US 2019 上的主题演讲,题为《React to the Future》。 ## TL;DR React 创始人 Jordan Walke 回顾了从早年混乱的 Web 开发到发明 React 与 JSX 的演进历程,阐述了不可变性与声明式编程如何降低开发者的认知负担。他指出仅靠一个前端 UI 库无法彻底解决静态类型缺失与原生性能瓶颈,因此发起了基于 OCaml 的编程语言 Reason,力求将 React 的核心哲学上升到通用语言层面。通过降低语法的“静摩擦力”以及引入原生编译工具链与现代化包管理器 esy,Reason 让开发者能用统一且安全的心智模型跨越浏览器限制,构建出具备毫秒级冷启动体验的高性能原生应用。 ## Atmosphere & style 整场演讲呈现出一种深思熟虑、真诚谦逊且极具前瞻性的工程哲思氛围。Walke 没有过多炫技,而是以一位深耕一线的创造者视角娓娓道来,将计算机科学演进史与当年的开发痛点串联成一段引人入胜的叙事。现场气氛在回顾早期 JSX 遭遇争议的幽默自嘲中逐渐升温,最终收拢在号召开发者跳出舒适区、共同探索“React 之后下一个未来”的振奋与期许之中。 ## Bulletin - [18:25](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1105s) React 创作者 Jordan Walke 阐述了 Reason 项目的核心定位:将 React 的声明式与不可变设计哲学提升至整门编程语言层面,以解决 JavaScript 仅靠 UI 库无法解决的静态类型与局部推导问题。 - [16:06](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=966s) 语法是编程语言的用户界面(UI),Walke 提出技术推广存在静摩擦力与动摩擦力模型,JSX 和 Reason 的 JS 语法糖通过极度贴合前端直觉,成功消除了技术落地的初始阻力。 - [26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) 任何用 JavaScript 编写的库都会受制于 JS 运行时本身,Reason 借助 OCaml 编译器既能生成规范的 JS,又能直接 AOT 静态编译为超快启动的原生二进制,消除了跨语言重写的巨大代价。 - [34:11](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2051s) 为破解传统原生开发依赖缺失与配置噩梦,Reason 生态推出了纯 Native 实现的包管理器 esy,以类似 React Reconciliation 的协调机制和全局跨项目缓存,实现了前端熟知的一键式原生构建体验。 ## Key takeaways - [00:00](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=0s) Jordan Walke 投身编程语言与框架设计的初衷,是为了解决构建“运行既快又在扩展时不会崩溃的应用”极其困难的行业痛点。 - [02:16](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=136s) 代码“易于推导”(easier to reason about)的本质,是开发者仅需阅读局部代码即可理解复杂逻辑,无需在脑海中维持整套程序的完整上下文。 - [04:18](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=258s) 允许原位突变(Mutation)的数据结构会导致心智负担呈指数级扩散,迫使开发者耗费大量精力去人肉排查上下游所有潜在的修改路径。 - [07:26](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=446s) 现代高级编程范式并非新发明,从 1932 年早于实体计算机诞生的 Lambda 演算到 Hindley-Milner 自动类型推导,经典计算理论早在数十年前便奠定了基础。 - [10:59](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=659s) 2010 年代的 Web 架构充斥着直接突变 DOM 与服务端 PHP 拼装 HTML 的混乱,React 通过声明式映射与不可变数据将函数式编程思想大规模普及。 - [16:06](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=966s) 技术推广必须对抗“静摩擦力”,开发者往往低估语法的关键性;JSX 通过将函数调用包装为类 HTML 语法,消除了开发者直面纯函数式抽象时的心理抵触。 - [18:25](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1105s) Reason 在语言级别贯彻不可变记录(Record)和穷尽性模式匹配,使开发者在不依赖复杂第三方规范的情况下彻底恢复局部推理能力与编译期安全性。 - [21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) 通过解耦编译器流水线,Reason 替换了 OCaml 的前端语法以适配 JS 习惯,配合 BuckleScript 后端输出地道可审查的 JS,完整保留了坚固的 OCaml 中端类型系统。 - [24:30](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1470s) JSX 本身也需编译,开发者实质早已是编译语言的用户,对于“编译至 JS”的技术路线不应抱有留恋现状的偏见。 - [26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) JavaScript 虚拟机的 JIT 启发式预测无法保障所有未覆盖分支的性能与冷启动,任何 JS 库都会被语言本身的运行时上限牢牢禁锢。 - [29:47](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1787s) Reason Native 允许开发者将一份逻辑跨平台复用:在生产端编成 JS 供浏览器使用,在测试端(如 Rely)或工具端(如 fnm、Oni 2)直接编成原生机器码以获得瞬间启动性能。 - [33:03](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1983s) 传统原生开发缺乏彻底自动化的依赖建模与构建复用,导致环境配置成为阻碍 Web 开发者跨界的主要壁垒。 - [34:11](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2051s) 包管理工具 esy 将类似 React 的 Reconciliation 依赖协调机制带入构建体系,使用熟悉的 package.json 和全局跨项目缓存实现一键原生编译。 - [35:56](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2156s) Reason 的愿景是打破平台与场景的界限,用统一的语言哲学赋能开发者去探索并构建“React 之后的下一个技术范式”。 ## Detailed walkthrough ### [00:00](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=0s) 开场:Jordan Walke 的经历与 Reason 的诞生背景 Jordan Walke 在 ReasonConf US 2019 开场时首先致谢主办方 Draftbit、Mike 以及现场赞助商。他在 Facebook 的广告界面团队(Ads Interfaces Team)从事编程语言与框架的研发工作。关于自己为什么从事这项工作,他坦言自己的终极目标其实很纯粹:“我的最终目标,或者至少我个人的目标,是构建一个既快速又在扩展时不会崩溃的应用程序,但我一再发现,要做到这一点实在太难、太难了(way way too hard)。”正因现存工具的缺陷,他才选择投身于语言和框架设计,以此打造自己真正想使用的工具。 在过往的经历中,Jordan Walke 于 2011 年创建了 React.js 框架;随后他将重心转向移动端,与其他三位联合创始人一同发起了 React Native 项目;而近期他发起了 Reason 项目,并与同事及社区成员共同构建其工具链生态。Reason 是一门基于 OCaml 的快速、类型安全的编程语言。在 Jordan 看来,Reason 的核心意义在于将 React 备受喜爱的理念和原则扩展到整门编程语言层面,从而为 UI 开发解锁一个更具野心的未来。 ### [02:16](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=136s) 为什么 React 让写代码“再次变得有趣”:心智负担与可推导性(Reason About) 自 2013 年 Jordan Walke 与 Tom Occhino 在 JSConf 上正式开源 React 之后,Jordan 很少在大型会议上演讲,但他频繁参加各类线下聚会(Meetup),倾听开发者接纳 React 的真实故事。在这些反馈中,出现频率最高的一句话是:“React 让我的工作再次变得有趣(React made my job fun again)。”Jordan 认为,这绝非单纯因为现成的 IDE 集成或海量开箱即用的 npm 包,而是因为 React 向开发者脑海中植入了一种全新且让人产生成就感的构建方式:**尽量减少应用状态,尽量减少副作用**(minimize application state and minimize side-effects)。 开发者常说 React “可组合性强(composable)”,搭组件就像拼积木,或者称赞其代码“更容易推导(easier to reason about)”。针对“易于推导”这一常被视为主观感觉的说法,Jordan 给出了清晰的定义: > “所谓对某件事物进行推导,意味着你可以只看代码的一小部分,就能理解其中的绝大部分复杂性与交互逻辑,而不需要强迫在大脑中同时塞进一整套完整的程序。”(when we reason about something it means that you can look at a small part of your code and you can understand a majority of the complexities and the interactions there without order to keep the whole entire program and your brain at once.) ### [04:18](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=258s) 可变性带来的心智爆炸:从一个列表渲染组件谈起 为了证明“易于推导”不仅是一种主观喜好,更是一种可以用代码追踪路径来衡量的确定性事实,Jordan 展示了一个看似简单的 React 示例: 一个外层容器内部渲染了一个好友列表(`friends` 数组)。列表为每个好友渲染一个展示其名字的 `div`。外层容器上绑定了一个点击事件处理函数,用户点击内部任何区域时,都会弹出一条提示消息告知“你拥有多少位好友”。 ```mermaid flowchart TD accTitle: 可变状态下的外部调用推导负担 accDescr: 展示在允许可变引用的代码库中,开发者为了确认一个数组是否被修改而必须跨越的推导路径。 subgraph ComponentScope["组件内部执行"] R["初始渲染: 渲染 friends 列表"] E["点击事件触发: 读取 friends.length 弹出通知"] R -.->|"时间流逝 (Time Elapses)"| E end subgraph ExternalScope["外部模块排查负担"] C["上游调用模块 (Callers)"] D["下游传递模块 (Callees)"] end C -->|"是否在传入后发生突变 (Mutate)?"| R C -->|"是否将引用传给其他模块?"| D D -->|"第三方模块是否会异步修改该引用?"| E ``` 在初次渲染与用户点击事件触发之间,存在一段不确定的时间差(Time can elapse)。在此期间,如果有外部逻辑向 `friends` 数组中追加或删除了好友(即直接突变数据),点击弹出的好友总数就会与用户屏幕上已呈现的列表脱节。 在大型且充斥着可变数据(Mutation)的代码库中,开发者若想确认这行代码是否安全,必须做极其痛苦的人脑代码审计: 1. 必须排查所有调用当前组件的上游模块,确认它们在把数组传给该组件后,绝不会在后续逻辑中修改该数组; 2. 还必须追踪上游模块是否又把该数组引用传递给了其他下游模块,并逐一确认那些下游模块同样未对该数组执行任何突变操作。 这种错综复杂的引用排查光是口头描述都极为绕嘴,在实际代码库中人肉排查更如同一场噩梦。相反,如果语言或类型系统本身在底层直接禁止不可变数据被就地突变,开发者的大脑就完全不需要背负这些外部包袱,只需关注组件内部这几行代码即可,这就让编程体验演变成一系列令人自信的“微小胜利(small wins)”。React 通过这些模式为开发者构建了一个“成功的陷阱(Pit of Success)”,让人自然而然地滑入正确的实现范式中。 - 纯粹主义者常指出 React 中依然可以通过逃生舱手段绕过防护实施数据突变,但不可否认,它比以往的 UI 编程范例构成了决定性的转向。 - React 如今已经超出了单一 UI 库的范畴,成为将经典计算原则落地到界面工程的思维范式。 ### [07:26](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=446s) 编程语言演进史:从 Lambda 演算到 Hindley-Milner 类型系统 为了探究 UI 编程未来还缺失了什么,Jordan 回顾了高级编程语言的早期演进史。他强调,许多现代人觉得前沿的思想,其实质和计算机科学本身一样古老: - **1932 年(Lambda 演算)**:Alonzo Church 发现了 Lambda 演算(Lambda Calculus)。作为极其简约的计算模型,它仅由单参数函数、词法作用域与表达式求值构成,却能表达任何可计算程序。它在计算机科学刚萌芽时就确立了“通过表达式描述计算机应该做什么,而非通过命令式突变序列执行”的思想。最惊人的是,Lambda 演算是在人类发明第一台可编程计算机之前就被发现的,这证明它并非妥协于特定硬件限制的产物,而是超越时代的数学真理。 - **1952 年(Lisp 语言族)**:Lisp 诞生,它将抽象的 Lambda 演算改造成人类可用、并能切实运行在物理硬件上的现代编程语言。 - **ML 语言族与类型推导**:随着代码规模扩大和多人协作加深,行业对“在代码交付前静态验证或剔除错误程序”的类型系统需求激增。Roger Hindley 与 Robin Milner 发明了搭载 Hindley-Milner 类型系统的 ML 语言族(Jordan 风趣地补充道:“与大众普遍认知相反,ML 在这里代表的并不是机器学习”)。ML 的革命性在于:静态类型不再是开发的拖累,编译器可以在绝大多数场景下自动完成精确的类型推导,打破了“静态类型必然破坏敏捷开发”的刻板印象。Standard ML、OCaml 以及 Elm 均是 ML 家族的直系后代。 从完全没有计算机硬件到构建出精巧完备的自动类型推导系统,计算机先驱仅用了大约 40 年时间。Jordan 在此处向观众抛出引人深思的反问:如果技术在这前 40 年的演进速度如此迅猛,那么沿着这条轨迹再往后推演 40 年,当今的开发者理应全面使用更不可思议的技术,但现实情况究竟如何呢? ### [10:59](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=659s) 2010 年代初 Web 开发的乱象与 React 的诞生 在回顾软件开发史时,Jordan Walke 感慨从 1973 年到 2010 年这几十年间似乎出了大问题。当他刚开始从事 Web 应用开发时,现代开发者所熟知的那些绝妙范式、易于推理的编程模式,甚至是静态类型系统,在当时的生产环境中通通缺席。彼时业界依赖的是两门动态语言——JavaScript,以及运行在服务端的 PHP。当时的典型架构十分别扭:在服务器端用 PHP 渲染 HTML 标签,通过网络传输到客户端,然后在浏览器端“撒上一点点 JavaScript”(sprinkle some JavaScript),寄希望于让原本静态的文档获得些许交互性。虽然如今很容易去批评这种做法,但在当时这就是人人都遵守的行业现状(status quo)。 更糟糕的是,整个前端交互完全建立在可变性(mutation)的基础之上。如果开发者想修改某个元素的颜色,做法就是直接抓取该 DOM 节点并强行修改其颜色属性;与此同时,若其他代码逻辑也尝试做修改,两者就会产生冲突,谁的修改先生效或被覆盖完全不可控,整个运行时毫无执行顺序与规则可言。为了终结这种混乱,Jordan Walke 开始着手构建原型,也就是后来的 React.js。虽然通常软件设计推崇一次只解决一个问题,但 React 却同时解决了多个痛点——这甚至让初期向他人解释 React 的核心价值变得有点困难。 React 的核心突破之一,在于它打破了客户端与服务端渲染的界限:开发者无需在架构设计之初就做死决定。你既可以在客户端渲染全部界面,也可以在网络带宽受限或延迟极高时平滑切换为服务端渲染。更重要的是,React 将函数式编程(Functional Programming)与不可变性(Immutability)的精髓带给了极其广泛的开发者群体。针对那些对概念敏感的开发者,Jordan Walke 总结出了一套沟通哲学:“I think we should meet people where they are and I find that if you just call it declarative programming it just it's an easier pill to swallow it's like they don't want the question there their identity as a programmer.” ```mermaid flowchart TD accTitle: 传统 Web 架构与 React 架构对比 accDescr: 对比 2010 年前传统的 PHP 与 JS 混用模式与 React 统一组件渲染模式 subgraph Legacy["2010 年代传统架构 (易冲突且难维护)"] PHP["服务端 PHP 渲染 HTML"] -->|"网络传输"| DOM["客户端浏览器 DOM"] JS1["业务逻辑 A (直接修改 DOM)"] -->|"直接修改"| DOM JS2["业务逻辑 B (直接修改 DOM)"] -->|"竞态覆盖"| DOM end subgraph ReactArch["React 声明式架构"] State["应用状态 (State)"] -->|"纯函数 / 声明式映射"| VDOM["虚拟 UI 描述"] VDOM -->|"统一计算差异并更新"| Target["渲染目标 (客户端 DOM 或 服务端标记)"] end ``` ### [13:22](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=802s) 语法的重要性:JSX 从内部救赎到开源争议 当 Jordan Walke 拿着最初的原型展示给 Facebook 内部同事时,原本期待能就不可变性、函数式组件等架构思想展开深入讨论,结果却碰了壁。人们看到满屏幕原生的 JavaScript 函数调用,脑海中浮现的全是数不清的嵌套括号与大括号。彼时 Facebook 工程师早已习惯了一种允许直接在代码中嵌入 XML 的 PHP 方言(即 XHP)。针对这些反馈,Jordan Walke 找出了 Adam Wolff 此前的一些技术方案以及 Marcel 编写的旧解析器,拼凑出了一个 Diff,在 React 内部实现了最初的 JSX 语法糖。从技术本质上讲,JSX 并没有改变底层实现,它仅仅是将类 HTML 标签机械式地转化为普通的函数调用,但内部工程师的接受度却发生了天翻地覆的变化:语法障碍一旦清除,大家终于能越过障碍,聚焦于探讨真正重要的架构思想。 然而,当团队觉得内部落地已趋成熟并决定将 React 开源时,同样的语法问题在社区中以完全相反的方式爆发了。Jordan Walke 回忆起在演讲台上展示包含 JSX 语法的幻灯片时,台下的听众瞬间面露不悦,整个观众席全是紧皱的眉头和愤怒的表情。演讲结束后,推特(Twitter)上爆发了激烈的口诛笔伐与讽刺。在当时的前端社区看来,将 HTML 标签硬塞进 JavaScript 违反了神圣的“关注点分离”原则。虽然随着时间推移,社区逐渐理解并接受了这一设计,但这让团队意识到:任何技术的推广都无法脱离语法带来的直观感受。 ```mermaid flowchart LR accTitle: JSX 消除认知阻力的演进 accDescr: 原型阶段嵌套函数调用向 JSX 语法的转变 RawFunc["早期原生 JS 调用<br/>(嵌套括号、视觉混乱)"] -->|"引入 JSX 转换 (Marcel 解析器/Adam 经验)"| JSXView["类 HTML 标签语法<br/>(消除视觉摩擦)"] JSXView -->|"编译降级"| ExecFunc["等价的 JS 函数调用<br/>(底层思想完全一致)"] ``` ### [16:06](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=966s) 静摩擦力与动摩擦力:技术推广的技术阻抗 针对这次开源波折,Jordan Walke 提出了一个推动新技术的“物理摩擦力模型”。他将推广新技术比作在地面上推动一块沉重的巨石,这期间需要对抗两种阻力: 1. **静摩擦力(Static Friction)**:为了让静止的巨石开始移动,初始阶段必须付出的巨大推力。 2. **动摩擦力(Kinetic Friction)**:当巨石已经运动起来后,为了维持其前进状态所需持续投入的能量。 技术狂热者往往有一种理想主义设想:只要技术内核足够优秀,用户只要咬牙跨过初始门槛,就会领悟其价值。但现实是,行业里从来就不止有一块巨石。Jordan Walke 警告道,在 Hacker News 等技术社区上,每天都有二三十块“新巨石”声称能解决开发者的一切问题,而且其中许多竞品几乎没有静摩擦力,开箱即用,根本不需要开发者赌上信任去预先投入。不仅如此,软件工程是团队协同,你必须拉拢同事、项目维护者和贡献者一同发力提交 Pull Request。一旦静态阻力过大,他人根本不会加入。因此,技术设计必须无情地(ruthlessly)剔除所有多余的初始阻力,正如 Jordan Walke 所总结的那样:“The core lesson that we learned from just the open sourcing process of react and the internal adoption is that syntax matters. It really does. It's highly subjective, but it matters because it influences the outcomes.” - **NPM 下载规模**:到 2019 年演讲时,React 仅在 NPM 上的年下载量就已达到 2.5 亿次(quarter billion downloads per year)。 - **全链路分发量**:如果算上各大 CDN、中间缓存及终端分发节点,每年的实际请求与下载次数已轻松迈入数十亿(well into the billions)级别。 ### [18:25](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1105s) 超越组件:Reason 对函数式与类型的语言级继承 在开源六年之后,React 拥有了专门的全职维护团队,但 Jordan Walke 提出了下一步的追问:React 确实规范了前端组件层,但组件之外的业务代码该走向何方?2010 年遗留的另一个根本问题——静态类型系统,是无法单靠一个 UI 库彻底解决的,它需要一门契合的编程语言。这正是 Reason(后发展为 ReasonML / ReScript 生态)诞生的契机,它将人们喜爱的 React 设计哲学上升到了通用编程语言的高度,接过了 React 未竟的使命。 Reason 将不可变性置于语言最核心的位置。在 Reason 中,记录类型(Record)默认是绝对不可变的,任何字段均无法被外部意外改写。开发者在 IDE 中只需悬停鼠标,即可百分之百确信数据不会被突变,从而彻底恢复了纯粹的“局部推理能力”(local reasoning)。同时,Reason 拒绝成为极端纯粹主义者的玩具,它保留了受控的突变语法,例如开发者可以显式标注并执行 `mySettings.isAdmin = true`。更重要的是,Reason 的语法刻意模仿了 JavaScript,其 JSX 扩展语法几乎与 JavaScript 版 JSX 毫无二致,极大降低了静态学习门槛。在此基础上,Reason 融入了诸如类型驱动的模式匹配(Pattern Matching)等高级特性,它宛如强化版的 `switch` 语句,不仅能天衣无缝地表达类似 Redux 的状态转移,更会在编译期对未覆盖的状态分支(如漏掉某种退出登录状态)给出严格告警,为开发者提供强有力的类型安全屏障。 - **默认不可变性**:Reason 的 Record 字段天生不可变,消除了隐式副作用,使代码逻辑具备完全的确定性。 - **渐进支持可变**:允许开发者通过明确语法选择性启用 `mutable` 字段,兼顾实用性与工程现实。 - **语法零阻力迁移**:JSX 在 Reason 中作为一等公民语法存在,让 JavaScript 开发者能以极低的静摩擦力直接上手。 - **编译期完备性检查**:强大的模式匹配机制能在编译阶段直接拦截漏写的逻辑分支,彻底告别运行时逻辑漏洞。 ### [21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) 编译器拆解与 Reason 的语法哲学 Jordan Walke 揭示了 Reason 幕后的真实面貌:它实际上是 OCaml,一种典型的 ML 语言。面对“Reason 究竟是不是 OCaml 语言”的疑问,Walke 表示这取决于如何定义“语言”。一门语言包含包管理器、社区、库生态、设计模式和应用场景,但其核心在于编译器。为了让问题更通俗,Walke 将编译器高度简化为三个阶段:前端负责语法定义与用户交互方式;中端负责类型系统与语义实现;后端则负责输出机器码或 JavaScript 代码。Reason 的核心切入点,就是用一套 JavaScript 开发者能立即上手的语法,直接替换掉 OCaml 原有的语法。 ```mermaid flowchart LR accTitle: Reason 与 BuckleScript 在 OCaml 编译管道中的角色 accDescr: 展示 Reason 如何替换前端语法、BuckleScript 如何替换后端代码生成,而保留 OCaml 核心类型系统。 subgraph Compiler["OCaml 编译器流水线"] FE["前端: 语法交互<br/>(由 Reason 替换为 JS 风格)"] ME["中端: 类型系统与语义<br/>(保留经实战检验的 OCaml 核心)"] BE["后端: 代码生成<br/>(BuckleScript 生成干净 JS,或原生后端生成二进制)"] end FE --> ME ME --> BE ``` 为什么必须从语法入手?Walke 从 React 的诞生史中总结出最关键的启示:“语法极为重要,它是编程语言的 UI”(“syntax matters it's the UI of your programming language”)。他在现场展示了来自 Twitter 用户的反馈,很多开发者正是因为这套熟悉的语法才对 Reason 产生兴趣。虽然任何语法都不可能让所有人满意,但由于 JavaScript 开发者社区规模极为庞大,为了最大化技术的推广与普及,必须为最广大的群体扫清入门阻力;哪怕这会稍微增加极小一部分既有函数式编程开发者的认知摩擦,也是完全值得的权衡。 不仅如此,许多开发者还会将 Reason 与 BuckleScript 结合使用。BuckleScript 替换了 OCaml 的原生后端,输出极其规范、地道且可以直接提交到代码仓库的 JavaScript 代码,完全不会招致同事的指责。通过这种方式,OCaml 编译器的前后端都被改造成了 JavaScript 开发者最需要的形态,而中间留下的,恰恰是最核心的价值资产:那套经过数十年实战检验、极其坚固的 OCaml 类型系统。 - 编译器的三个抽象阶段:描述交互与语法的前端、实现类型系统与语义的中端、生成机器码或 JS 的后端。 - 采用 JS 风格语法的核心动机:降低全球最大开发者群体(JavaScript 生态)的使用摩擦,以语法作为语言的用户界面撬动采纳率。 - BuckleScript 的工程价值:输出符合惯用法且可审查的 JS 代码,同时无缝继承 OCaml 坚如磐石的类型推断与检查机制。 --- ### [24:30](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1470s) 从 React 到 Reason:拒绝现状偏见与全生态赋能 针对有些人将“编译到 JavaScript”视为激进变革的顾虑,Walke 予以了坚决反驳。他指出,自从 React 开源以来,整个生态就在大量使用 JSX,而 JSX 本身根本不是合法的 JavaScript,也无法直接在浏览器中运行,必须先编译为原生 JS 代码。既然社区早就接受了这种编译模式,大家本质上都已经是编译型语言的用户了,剩下的无非是探讨“哪种编译器带来的权衡收益更好”。 Walke 直言自己对维护现状毫无兴趣:“如果一味偏向现状,我们今天还在服务器端渲染 PHP,根本就不会有 React 的出现”(“I'm not really interested in you know talking you know biasing towards the status quo because if we did that we'd still be rendering PHP on the server and we wouldn't have react”)。他更关注能够为开发者释放多大的潜力。在 JavaScript 生态中,React 极大地改善了 UI 与交互层面的开发体验,让代码逻辑更容易被推导,但它不可能解决所有问题。Walke 对 Reason 的定位,正是将 React 中深受喜爱的设计哲学推广到整门编程语言层面,让 JavaScript 生态中的每一个场景都能享受到同等的核心优势。 --- ### [26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) 跨越 JS 的边界:性能鸿沟与语言捆绑的困境 讨论技术的最终落脚点永远是终端用户。Walke 强调用户既讨厌 Bug,又极度看重性能。放眼整个软件工程界,许多开发者使用 Rust、C 或 Go 构建工具与系统,他们不盲目追随“永远押注 JavaScript”(Always bet on JavaScript)的信条,原因就在于更实在的用户体验:更快的冷启动时间、更出色的硬件利用率、更可预测的性能表现,以及更高的吞吐量。尽管 JIT(即时编译)技术非常强大,但其依赖的启发式预测极不稳定,在未经充分测试的冷门业务路径上根本无法提供性能保证。为了追求极致的用户体验,系统往往无法承担 JavaScript 语言本身带来的运行时复杂度与开销。 部分 JavaScript 开发者有时会对这一事实视而不见。Walke 表示自己完全理解那种希望把现有代码与知识推向极致的心态——尤其是当项目必须部署到 Web 平台时。然而,一旦遇到更为严苛的非 Web 运行环境,开发者就被迫在极其痛苦的方案间做选择:要么从零学习一套全新的语言栈,重新实现一套并承受双向维护代码同步的痛苦;要么就只能“让用户去承受性能劣势,把 JavaScript 推向其承受极限甚至彻底压跨它”(“I can just let the user take the hit I could push JavaScript beyond its limits maybe pass its breaking point”)。 Walke 犀利地总结道:“从根本上讲,任何用 JavaScript 编写的库,都会被 JavaScript 自身牢牢禁锢”(“ultimately any library that's authored in JavaScript is held captive by JavaScript”),其应用场景有着不可逾越的上限。 | 评估维度 | JavaScript 运行时 (V8/JIT) | 原生编译工具链 (OCaml Native / Reason) | |:--- |:--- |:--- | | **冷启动表现** | 需初始化 VM 与解析字节码,耗时较长 | 机器码直接执行,毫秒级瞬时启动 | | **执行可预测性** | 依赖 JIT 运行时启发式优化,遇未覆盖分支性能波动大 | AOT 静态编译,性能表现恒定、确定性高 | | **系统资源消耗** | 内存与 CPU 开销相对较高,难适应极端约束环境 | 硬件利用率高,内存占用极紧凑 | | **跨环境复用** | 强绑定 JS VM,移植到原生底层生态代价高昂 | 编写逻辑既可编至 JS,也可直接编译为原生二进制 | --- ### [29:47](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1787s) Reason Native 的破局:极速应用与生产实践 Reason 最令人振奋的技术突破在于技能与代码的无缝迁移。即使今天仅仅为了开发 Web 前端而学习 Reason,所掌握的全部语言能力也可以完全复用到资源受限的原生(Native)环境开发中。Walke 坦承并不存在万能语言:极端严苛的场景依然需要下潜至 C 语言甚至手写汇编;现有 OCaml 原生编译器也并非完美匹配全部极低级场景。但在绝大多数常见的系统开发中——无论是构建超快启动的命令行工具,还是高并发服务端——OCaml 原生工具链都能直接编译出瞬时启动的高性能原生可执行文件。 这一优势已经在社区中开花结果: - **fnm(Fast Node Manager)**:由于执行速度极快,将其挂载到终端 Shell 中执行环境检测时,用户根本感知不到任何延迟。 - **Oni 2**:从初代 Oni 架构中重构而来,其图形用户界面基于 Reason Native 构建,启动速度惊人。Walke 引用了 Twitter 用户的惊叹:“我根本不知道一个应用居然能启动得这么快,我都怀疑我到底有没有点击,它就已经运行起来了”。 更关键的是,这些优秀工具完全是由 Web 社区的开发者发起或贡献的。Walke 所在的 Facebook 用户界面团队也在深度采用 Reason Native:他们通过 BuckleScript 将 Reason 模块编译成 JavaScript 运行在生产环境中,同时又将其编译为本地原生可执行文件。在跑测试时,团队借助灵感源自 Jest 的原生测试框架 Rely,彻底摆脱了缓慢启动 JavaScript 虚拟机的泥潭,实现了极速流畅的原生交互式测试反馈。Walke 最后提及,以往原生开发(例如编译 C++)总是一场需要安装几十个全局依赖的噩梦,而 Reason Native 系列工具正致力于把类似 Node 生态的平滑体验彻底带入原生世界。 - **fnm**:利用 Reason 原生编译打造的 Node 版本管理器,性能优异到可常驻 Shell 钩子而不卡顿。 - **Oni 2**:基于 Vim 核心与 Reason Native GUI 打造的代码编辑器,以“疯狂级”的冷启动速度超越基于 Electron 等 JS 运行时的编辑器。 - **Facebook UI 团队实践**:同一份 Reason 业务逻辑,线上利用 BuckleScript 编成 JS 供浏览器使用;测试环境通过 Rely 编成 Native 机器码,绕开 Node VM 实现瞬间执行测试。 ### [33:03](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1983s) 原生构建的历史痛点与开发者的配置梦魇 Jordan Walke 回顾了传统原生应用开发的痛苦经历:为了编译运行一个项目,开发者经常不得不连续数小时手动修改 Makefile 和环境变量,甚至在开始实际构建之前就被困在各种环境报错中。这种局面的根源在于历史上的原生构建工具链往往缺乏彻底的自动化,也没有对所需的全部依赖进行严谨的建模。在以往的原生编程文化中,“一键运行”(one-click)的体验几乎是不存在的。 更糟糕的是,包作者极容易在无意中依赖了自己机器特有的本地环境配置,而其他人的机器上并没有这些依赖项。结果就是,下游开发者把大量时间浪费在试图复现包作者的系统环境与机器配置上,寄希望于对方写了详尽的文档——但现实中文档往往付之阙如。这种自动化的缺失导致预编译构建产物(pre-built artifacts)极难在跨团队、跨用户甚至在同一台机器的不同项目之间共享复用。这些障碍直接导致原生开发显得艰难、缓慢且令人痛苦。Jordan Walke 指出,如果想让 Web 开发者真正拥抱原生开发工作流,就必须提供他们所熟悉的、简单易用的一键式开发体验:“Well, if we want to get web developers on board with the native development workflows, we need something that's familiar, it's got to be one-click, we need something that's easy.” ### [34:11](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2051s) esy:包管理界的 React 与一键式原生构建 为了解决原生环境的这一沉疴,Andrey Popp 在 Reason 生态下打造了名为 esy 的工具。Jordan Walke 将 esy 形容为原生构建所急需的“简易按钮”(easy button):在开发者眼中,它的操作手感和日常的前端开发别无二致,依然是通过熟悉的 `package.json` 来声明依赖,任何 Web 开发者都能立刻上手并看懂项目结构。但 esy 绝不是简单地调用 npm 或 Yarn,而是完全使用 Reason Native 从头重新实现的全新包管理工作流,这赋予了它极高的执行速度。开发者只需在终端项目中敲入 `esy`,它就会全自动完成所有依赖项的安装与编译构建。 Jordan Walke 将 esy 的设计哲学精辟地类比为组件开发界的 React。在 Reason 将 React 的组件思想注入编程语言本身的同时,esy 也把 React 的思想带入了包管理领域:运行 esy 时,它会像 React 对比虚拟 DOM 那样对项目依赖树进行协调(reconciles),按需从网络拉取依赖,按需执行构建,并且极度迅速。尤为突出的是其跨项目的全局构建缓存机制,相同的底层依赖在被构建过一次之后就会被全局缓存,这意味着开发者越频繁地使用它进行原生开发,后续构建就会变得越快。在底层,esy 站在了 OCaml 与其官方包管理器 opam 的肩膀上,复用了部分代码并深度集成了 opam,吸收了该社区多年的研究成果(包括对 Windows 平台的支持)。此外,esy 还能原生编译 C 语言程序、C++ 库以及 JavaScript 包,成为能通吃各种语言生态的统一工具链。 ```mermaid flowchart TD accTitle: esy 构建与包管理工作流架构图 accDescr: 展示 esy 如何通过 reconcile 协调机制处理多种生态依赖并实现全局缓存加速 subgraph Config["配置与入口"] PJ["package.json<br>(前端熟悉的依赖声明)"] Cmd["命令行输入 esy"] PJ --> Cmd end subgraph Engine["esy 核心引擎 (Reason Native 实现)"] Recon["Reconciliation 机制<br>(类似 React 协调算法)"] Cmd --> Recon DepResolution{"解析与拉取<br>各生态依赖"} Recon --> DepResolution end subgraph Ecosystems["多语言依赖生态"] Opam["opam / OCaml 源码包"] NativeCPP["原生 C / C++ 库"] JSPkg["JavaScript 包"] DepResolution --> Opam DepResolution --> NativeCPP DepResolution --> JSPkg end subgraph CacheAndBuild["构建与产物系统"] BuildStep["快速并行原生构建"] GlobalCache["全局构建缓存<br>(跨项目共享,越用越快)"] Opam --> BuildStep NativeCPP --> BuildStep JSPkg --> BuildStep BuildStep <--> GlobalCache BuildStep --> Artifacts["最终原生可执行文件 / 产物"] end ``` - **esy 的核心机制**:纯粹使用 Reason Native 实现,运行极快;仅需一个 `esy` 命令即可自动完成依赖安装与编译。 - **类比 React 的思想**:“I think of it as like a React, but for package management.”(Jordan Walke 语)。 - **多生态集成**:支持 opam/OCaml 库、C/C++ 原生依赖以及 npm 上的 JavaScript 包,兼具跨平台(包括 Windows)支持。 - **全局缓存能力**:构建产物不仅缓存在单个项目中,而是跨本地所有项目共享,大幅减少二次构建耗时。 ### [35:56](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=2156s) 解锁开发者潜能:在 React 之后你将构建什么? 在演讲的尾声,Jordan Walke 总结了 Reason 的终极愿景。Reason 并不仅是一门语法或一组工具,它代表着将 React 开创性思想推向更深远维度的尝试。掌握一门统一的语言,就能打破平台藩篱,在各种截然不同的应用场景和系统约束下全方位提升最终用户的体验,这正是释放开发者创造力与生产潜能的关键路径。 在结束演讲前,Jordan Walke 留给全场开发者一个发人深省的问题:“Reason takes the ideas of React to the next level, and I see it as a way to unlock your potential as a developer, because it allows you to learn one language that improves the user experience across a wide variety of use cases and constraints. So I want to leave you with one question: what could you build with Reason?” 他畅想道,开发者或许能借此打造出一套全新的跨平台数据获取范式,或许是一个运行在任何环境的崭新框架,亦或是一个次世代的 UI 库,甚至可能是“构建出 React 之后的下一个未来”(build what comes after React)。演讲在全场热烈的掌声中圆满落幕。 ## Notable quotes > [21:43](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1303s) syntax matters it's the UI of your programming language — Jordan Walke > [26:12](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1572s) ultimately any library that's authored in JavaScript is held captive by JavaScript — Jordan Walke > [24:30](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1470s) I'm not really interested in you know talking you know biasing towards the status quo because if we did that we'd still be rendering PHP on the server and we wouldn't have react — Jordan Walke > [33:03](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=1983s) Well, if we want to get web developers on board with the native development workflows, we need something that's familiar, it's got to be one-click, we need something that's easy. — Jordan Walke > [00:00](https://www.youtube.com/watch?v=5fG_lyNuEAw&t=0s) 我的最终目标,或者至少我个人的目标,是构建一个既快速又在扩展时不会崩溃的应用程序,但我一再发现,要做到这一点实在太难、太难了。 — Jordan Walke ## Mentioned Jordan Walke, ReasonConf, Draftbit, Mike, Facebook, React.js, React Native, Reason, OCaml, Tom Occhino, JSConf, Alonzo Church, Roger Hindley, Robin Milner, Standard ML, Elm, JavaScript, PHP, Adam Wolff, Marcel, JSX, XHP, Twitter, NPM, BuckleScript, ReScript, Redux, Rust, C, Go, fnm (Fast Node Manager), Oni 2, Vim, Electron, Jest, Rely, Andrey Popp, esy, opam, Yarn ## Video description ReasonConf US 2019, Chicago, 10/08/2019 Twitter: https://twitter.com/reasonconf Website: https://reason-conf.com [Source](https://www.youtube.com/watch?v=5fG_lyNuEAw)

Source quotes

[21:43] Jordan Walke: syntax matters it's the UI of your programming language [26:12] Jordan Walke: ultimately any library that's authored in JavaScript is held captive by JavaScript [24:30] Jordan Walke: I'm not really interested in you know talking you know biasing towards the status quo because if we did that we'd still be rendering PHP on the server and we wouldn't have react [33:03] Jordan Walke: Well, if we want to get web developers on board with the native development workflows, we need something that's familiar, it's got to be one-click, we need something that's easy. [0:00] Jordan Walke: 我的最终目标,或者至少我个人的目标,是构建一个既快速又在扩展时不会崩溃的应用程序,但我一再发现,要做到这一点实在太难、太难了。

Source quotes

[21:43] Jordan Walke: Syntax matters; it's the UI of your programming language. [26:12] Jordan Walke: Ultimately, any library that's authored in JavaScript is held captive by JavaScript—it can really only be used in so many scenarios. [24:30] Jordan Walke: The way I think about Reason is that it brings the things that people like about React to the entire language, so that every use case in the JavaScript ecosystem benefits from those same core ideas.

Original transcript

[0:01] [Music] [0:09] all right hi thanks for coming to reason [0:12] comp and I also want to thank draught [0:14] bit and Mike for putting this event on [0:16] it's really incredible what you've done [0:18] I really appreciate it and so does [0:20] everyone else also thank you to all of [0:23] the sponsors that that pitched in and [0:26] helped make this event possible [0:28] so I'm Jordan and I want to talk about [0:32] react and reason today so I work on [0:36] programming languages and frameworks at [0:38] Facebook on the ads interfaces team and [0:41] you know you might ask why do I work on [0:43] this stuff so my ultimate goal or at [0:49] least my personal goal is to build an [0:51] application that is fast and that [0:53] doesn't break when it's extended and I [0:54] keep finding that it's just way way too [0:56] hard to do that so I end up working on [0:59] languages and frameworks with the goal [1:00] of being able to make that job easier [1:02] but really I just want to use those [1:04] tools myself and we have a long ways to [1:07] go no matter what we do it always seems [1:09] like there's a there's so much [1:12] low-hanging fruit making the app [1:14] developers experience better but we have [1:17] made some progress I've been able to [1:21] participate in some of these projects as [1:22] well so in 2011 I created the react.js [1:25] framework then I shift my focus to [1:29] mobile or a co-founded the reactive [1:31] native project with three other people [1:33] and most recently I started the reason [1:37] effort and with other co-workers and the [1:39] community helped build out a lot of the [1:41] tooling that makes up the reason the [1:43] ecosystem so what is reason reason is a [1:50] fast food safe programming language [1:51] based directly on oh camel so the way I [1:56] like to think about it is that reason [1:58] brings the ideas and the principles that [2:00] you like about react to the whole [2:01] language [2:04] but most importantly I see this a way to [2:07] unlock a much more ambitious future for [2:11] UI development all right [2:16] so react we open source react in 2013 [2:20] and Tamaki no and I presented at JS conf [2:22] and I haven't really done a lot of [2:24] conference talks since then but I do go [2:27] to a lot of meetups and I talk to a lot [2:29] of people and I hear the stories about [2:30] people adopting react and a lot of the [2:33] stories have something in common [2:34] people say reactivate my job fun again [2:36] and I think that's really cool feedback [2:38] and I try to think about why is that I [2:41] don't really think it's because react [2:44] provides like out-of-the-box IDE [2:46] integration and you know an abundance of [2:48] packages that they can just pull down [2:49] immediately although all that stuff is [2:52] really great we should strive for it I [2:53] think that something deeper is going on [2:55] I think that react is putting a new idea [3:00] about how to build apps into people's [3:02] brains and it's that core idea that [3:05] feels rewarding to people the idea is [3:10] really simple it's just that you should [3:11] minimize application state and minimize [3:14] side-effects [3:14] we don't need to go go to the extreme [3:16] with it but that's just a general [3:17] guiding principles of react and I think [3:20] that that idea is what feels rewarding [3:21] to people so people might not already [3:25] always express it like this but you know [3:28] they might say things like I really like [3:30] that react is composable I feel like I [3:32] can just stack my components together [3:33] and it feels like I'm you know playing [3:35] with building blocks basically or they [3:37] might say I really like that with react [3:40] apps my code is easier to reason about [3:44] it sounds like an opinion and it's not [3:49] really clear what people mean when they [3:50] say reason about but I think I have a [3:52] pretty good idea what they're trying to [3:53] say we reason about something it means [3:56] that you can look at a small part of [3:57] your code and you can understand a [3:58] majority of the complexities and the [4:00] interactions there without order to keep [4:02] the whole entire program and your brain [4:03] at once so it's easy to reason about now [4:08] building apps this way the way that [4:10] react encourages minimising side effects [4:11] and state that makes your app easier to [4:14] reason about and it sounds like an [4:15] opinion but it's more than an opinion [4:17] because it's also some [4:18] you can measure so take this example [4:20] here this is a react component and it [4:23] renders an array of friends and for each [4:25] friend it's going to render a div and [4:27] it's going to print their name inside of [4:29] that div but then it's going to wrap the [4:31] whole thing in a container and we have [4:32] another handler on the outer container [4:33] that says whenever you click on anything [4:35] in here we're gonna send a message to [4:36] the user saying this is how many friends [4:38] you have all right but notice something [4:40] interesting about this time can elapse [4:43] between when you render that list [4:45] initially and when that event handler [4:48] occurs a lot can happen in that time [4:52] what if somebody were to add an [4:55] additional friend of that array just [4:56] mutate it out from under you I mean if [4:59] they remove a friend well then that [5:02] message that you send to the user it's [5:04] going to be out of sync with the list [5:06] that the user sees on the screen let's [5:08] be patient [5:10] alright so imagine you're in a really [5:13] complicated codebase it's really big and [5:16] uses lots of mutation everywhere no [5:18] magic trying to go through you know in [5:20] your head look at this code and [5:22] determine whether or not that mutation [5:24] could happen it turns out it's really [5:26] hard so first of all you have to go to [5:29] every other module that calls into yours [5:30] you got to confirm that after they pass [5:32] that array to your component they don't [5:34] go and you take that later okay that can [5:37] be pretty time-consuming but it's worse [5:40] you also have to go find any other [5:42] module that you're calling module passes [5:44] that array to and confirm that they also [5:46] don't mutate that array that was that's [5:50] complicated and difficult for me to even [5:51] explain so imagine trying to go through [5:52] the actual code base and reason through [5:54] that alright so contrast that with if [5:57] you know this array is not mutable can [5:59] never be mutated some language or type [6:02] system that won't even allow you to do [6:04] it the problem becomes much simpler this [6:10] is all you have to keep in your head to [6:12] understand almost completely how this [6:14] component works you could reason about [6:16] it [6:18] so programming like this you know it [6:21] allows you to experience many small wins [6:23] when you're programming it's kind of [6:25] like your brain gets this this reward [6:27] every so often and you're confident with [6:30] what you've achieved it makes [6:32] programming fun it's kind of like a game [6:33] I think that that's what people are [6:35] talking about when they say reacting my [6:36] job fun okay so react creates this pit [6:41] of success with these kind of patterns [6:43] they're more easy you know they're [6:44] easier to accomplish they're more common [6:46] that's oh the pit of success means you [6:48] you just naturally fall into it now a [6:51] lot of purists might say hey I know the [6:53] ways that you can circumvent these [6:55] guardrails and react and I can make that [6:57] array be mutated and that's true but [7:00] there's no denying that compared to the [7:01] alternative paradigms and UI programming [7:03] it's a huge improvement and it was also [7:04] a massive course correction for the [7:06] direction that you I was heading in [7:07] before react so react has become bigger [7:13] than in Ian's library at this point it's [7:17] really the idea of applying these [7:18] timeless principles to the domain of UI [7:20] programming so it's interesting that a [7:26] lot of these ideas they feel new to [7:28] people but they're not they're actually [7:31] is old as computer science so it made me [7:34] wonder like what else did we miss right [7:39] what's in store for the future of UI [7:41] programming so in order to project out [7:45] into the future I think is really [7:47] helpful to take a look at the history of [7:49] programming languages or at least the [7:51] high level programming languages to see [7:52] where some of these ideas originated [7:54] from in 1932 Sargon way back in 1932 [8:01] Alonzo Church discovered lambda calculus [8:04] so lambda calculus is the simplest [8:07] possible programming language you can [8:08] imagine in its core construct it's just [8:10] a function with some lexical lexical [8:11] scoping and really it turns out that [8:15] from this really simple idea of just a [8:17] function that takes a single argument it [8:19] returns an expression and then functions [8:21] that you can apply you can construct any [8:23] computable program that's interesting [8:26] so we're already starting to see the [8:28] idea of computer programs being [8:30] expressed as an expression that [8:32] describes what the computer should do [8:33] instead of actually just doing it in a [8:36] sequence of imperative mutations this is [8:38] really early what's really amazing here [8:41] though that lambda calculus was [8:44] discovered before the first programmable [8:46] computer was ever invented so that [8:50] should tell us something so this wasn't [8:52] contrived out of the constraints of [8:55] technological progress in the time these [8:58] ideas they seem to be timeless all right [9:04] so it's not just mathematical theory [9:06] though in 1952 we see the invention of [9:09] the Lisp programming language family and [9:11] were able to take which basically took [9:13] labour to calculus and made it human [9:15] usable and it's actually running on real [9:19] hardware at that point but then as time [9:23] went on more people developed and [9:25] collaborated together there's this [9:27] increased demand for type systems and a [9:29] way to automatically prove or you know [9:32] reject bad programs ahead of time before [9:34] you ship them it sounds like a good idea [9:36] to me so Roger Hindley and Robin Milner [9:41] invented the ML family of programming [9:44] languages by creating the hindley-milner [9:45] type system so contrary to popular [9:50] belief ml does not stand for machine [9:53] learning [9:55] but what's really cool about ml is that [9:58] it it really pioneered a really great [10:01] type system where types one a burden you [10:05] don't have to always write them so the [10:07] compiler can infer them in most cases [10:08] that's really great because a lot of [10:11] types of some skeptics might say yeah [10:12] but static typing is all these benefits [10:14] but it's a huge burden I have to always [10:15] write them out everywhere [10:17] it ruins the rapid development it's not [10:19] so so ml is like the overall family of [10:25] languages that standard ml o camel and [10:28] elm all descent from so it looks like [10:38] we're innovating in this really rapid [10:39] pace here went from no computers even [10:42] existing to actually amazing type [10:44] systems like forty years so if you [10:47] project out into the future I mean in 40 [10:49] years from now how amazing is it going [10:52] to be I mean everybody's gonna be using [10:53] these awesome technologies right well [10:59] apparently something had gone terribly [11:01] wrong from 1973 to 2010 because when I [11:05] started working as a web app developer [11:06] we weren't using all of these awesome [11:08] paradigms we weren't programming in [11:10] patterns that were easy to reason about [11:12] we weren't even using static types as [11:15] into that at that time and we were using [11:17] actually two dynamic languages [11:20] javascript and on top of that one of [11:23] them was PHP so and we also have these [11:26] like chronic kind of crazy server setups [11:28] where we would render this markup on the [11:30] server we'd send it across the wire and [11:32] we try to sprinkle some JavaScript on it [11:33] on the client you know with the hopes of [11:35] making the static document somewhat [11:37] interactive you know it's easy to kind [11:44] of bash this but at the time this was [11:46] the status quo this was how everybody [11:49] built web apps the worst part about it [11:52] though was that everything was based on [11:53] mutation so that means if you wanted to [11:56] change a color of something you just [11:57] reach out to that dom node and you just [11:59] tell it to change the color and then [12:01] somebody else wants to do the same thing [12:02] then they'll also do that and then [12:03] hopefully well I don't know who wins [12:05] there's really no order to it so I [12:09] started creating several prototypes of [12:11] what we now call the react.js library so [12:15] wrapt didn't just solve one problem I [12:17] know it's good to solve one problem but [12:19] we actually solve multiple problems at [12:21] once kind of made it confusing to [12:22] explain to people like here's the value [12:24] of react but but it did solve several so [12:27] first allowed us to render that markup [12:29] on either the server or the client we [12:32] didn't have to decide upfront so that [12:34] means that you can render all your app [12:37] on the client and then if the [12:39] constraints change maybe you're in a [12:40] different area where network location or [12:42] you know network bandwidth is less or [12:44] latency is higher you can switch to [12:45] rendering that on the server but the [12:48] coolest thing about react is that have [12:49] brought the ideas of functional [12:51] programming and immutability to a wide [12:53] audience some people might not really [12:57] like to admit that but you know they [13:00] might say oh you know I never said I [13:02] like functional programming or anything [13:05] and that's fine I think we should meet [13:07] people people where they are and I find [13:09] that if you just call it declarative [13:10] programming it just it's an easier pill [13:12] to swallow it's like they don't want the [13:14] question there their identity as a [13:16] programmer ok so I showed some of these [13:22] earlier prototypes of people and this is [13:25] more or less what it look like a couple [13:27] of renames are different there but when [13:29] I show this to people I was hoping we'd [13:31] have a great conversation about all the [13:32] ideas of react you know this is a good [13:34] idea that's not a good idea maybe poke [13:35] some holes in it but it didn't go down [13:38] like that so when I show this to people [13:41] what a large percentage of them saw in [13:44] their heads was this endless stream of [13:48] closing brackets and braces so it turns [13:52] out that developers of Facebook at the [13:53] time so they were used to this but this [13:56] dialect of PHP where you can embed XML [13:59] inside of their code ok so I kind of [14:01] listened to that feedback and I dusted [14:03] off some tips from atom hub and some old [14:05] parsers by Marcel and I piece together [14:08] this diff where I implemented JSX as we [14:10] know it today inside of react so it [14:13] looked like this what's cool is that [14:15] this wasn't like a fundamental change or [14:17] anything [14:18] all all we were doing was just taking [14:19] this and then turning it exactly into [14:21] what we saw before literal dysfunction [14:23] call see you just do it the first time [14:25] almost so I thought okay that's great [14:28] and if I mean the difference in [14:30] reception was 90 day people were like [14:32] whoa that looks great so what's this [14:34] react about you know because we could [14:37] actually get past this industrial [14:38] friction here and talk about the real [14:39] ideas that matter so reacting some [14:44] adoption internally and it looked like [14:48] it was going pretty well and we decided [14:50] it's time to open source react and so [14:52] all we had to do was just show the world [14:53] what we built and then you know look at [14:55] the same kind of enlightened response [14:57] that we had internally that's what I [15:03] thought until I got to this slide where [15:06] I showed the syntax that we were using [15:08] and it's kind of funny because I [15:12] remembered looking out at the audience [15:13] and just seeing the sea of furrowed [15:16] brows in like angry faces and people [15:18] were it was like visibly upset and I was [15:22] like wow what's what did I say do they [15:24] just they just really not like [15:25] immutability or something and so we [15:28] talked with some people out after the [15:30] conference and turns out that they [15:31] really didn't they took issue with our [15:33] syntax extension and you know it's water [15:37] under the bridge you know there were [15:39] some harsh words on Twitter which we we [15:41] don't really need to relive right now [15:42] but you know eventually people got over [15:45] it and they were able to see the ideas [15:47] and react and we can talk about that and [15:48] that's important so some people might [15:51] say all right syntax yeah it can be an [15:54] issue at first but if I just persist [15:56] through it if other people just persist [15:58] through it you know they'll get over it [16:00] they'll see the real value behind your [16:02] technology that's true but I like to [16:06] think about pushing new technology kind [16:08] of like I think of it like pushing a [16:10] really heavy stone on the ground and you [16:12] have to kind of friction two kinds of [16:13] frictions that you're working against [16:14] here you have static friction and [16:18] kinetic friction so static friction [16:19] tells you how hard you have to push this [16:20] thing initially to get it moving and [16:22] then kinetic friction tells you how hard [16:24] you or how much more energy you need to [16:25] put into the system to keep moving with [16:27] the sardian motion and so you might [16:30] think oh yeah this stone is really great [16:31] and if people just push the initial [16:33] phase you know they'll see how great it [16:34] is afterwards but the problem is there [16:36] isn't just one stone so every day on [16:38] Hacker News you have 20 stones all [16:40] telling you you know this is going to [16:42] solve your problems and some of these [16:45] stones they don't have any kinetic or [16:47] they don't have any static friction at [16:48] all you just start pushing them right [16:50] now so people don't have to trust them [16:52] that the technology is going to deliver [16:54] once they invest so that's what you're [16:58] working against [17:03] the other problem is that you're not the [17:06] only one pushing so you want to get [17:08] co-workers project contributors on board [17:10] you want to get them ramped up you want [17:12] them to take a look at your project and [17:13] send a pull request so it's not really [17:16] just about you it's about what other [17:18] people think too and that matters so my [17:22] suggestion is to ruthlessly remove all [17:25] of the static friction that you can in [17:27] your technologies and so the core lesson [17:30] that we learned from just the open [17:32] sourcing process of react and the [17:34] internal adoption is that syntax matters [17:38] it really does it's really highly [17:43] subjective but it matters because it [17:45] influences the outcomes that's what we [17:48] care about [17:49] all right so fast wording six years [17:52] you've open-source reacts you know it's [17:55] growing it's become popular it's a full [17:58] time team dedicated to innovating react [18:01] and maintaining it improving it and [18:03] they're doing a killer job react has [18:07] quarter billion quarter billion [18:11] downloads per year from NPM if you were [18:15] to count all of the downloads from the [18:16] content delivery and you know all the [18:18] way to the client machines it's it's [18:19] well into the billions per you I haven't [18:22] ever really calculated it but all right [18:25] so react brings better patterns to your [18:27] components sounds great [18:28] but where do we go from here is that all [18:32] we can do what about the rest of your [18:36] codebase what about your code that isn't [18:39] components [18:40] what about static types that was that [18:42] other problem that seemed unsolved it in [18:45] 2010 that's something that only a [18:51] language should really solve [18:57] if we're going to embrace a new language [19:00] we really want one that matches react so [19:06] reason brings what people like about [19:07] react to the programming language level [19:10] to the rest of their codebase it picks [19:15] up where react lifts off so for example [19:20] remember all that pain that immuno that [19:22] mutation brought to our render function [19:24] earlier well and reason by default [19:28] records are immutable it means you know [19:31] that nothing in the field nothing in the [19:33] fields can be changed but most [19:36] importantly you can trust that so all [19:39] you have to do is just hover over [19:40] something in your IDE and you can tell [19:42] this can't possibly be mutated you don't [19:45] have to wonder so you can see the reason [19:51] already brings us local reasoning back [19:54] to you [19:55] but reason isn't just for the purists [19:58] because you can also opt in to [19:59] mutability as well so in this case these [20:02] fields are mutable now I can actually [20:04] update it there my immutable Settings [20:06] dot is admin equals tree so that looks a [20:10] lot like JavaScript well you know if it [20:14] wasn't clear reason is designed to be [20:17] immediately usable by JavaScript [20:19] developers or really anybody from any of [20:21] the other popular popular languages as [20:23] well so this example here that we saw [20:25] with the list that we were underneath [20:27] that's both valid JavaScript JSX [20:30] and valid reason so hey you already know [20:35] a little bit of reason you can imagine [20:37] how you know how much easier that makes [20:38] it to get your co-workers on board but [20:42] it's not just JavaScript so it also [20:46] includes some features beyond JavaScript [20:47] like pattern matching which is kind of [20:49] like a turbocharged switch statement [20:51] that's totally tight based and it allows [20:53] you to express redux style state [20:56] transitions really naturally like it's [20:59] embedded into the language because it is [21:04] it also catches a bunch of other kind of [21:06] errors and bugs that you would have in [21:08] these kind of situations like let's say [21:10] well in this case I forgot to cover one [21:12] state here like what if the event type [21:15] is an escape but you're already logged [21:16] in well I didn't cover that well this is [21:19] my terminal output that I see when I [21:22] forget to cover that says hey here's an [21:23] example of a case that's not matched so [21:25] as all these kinds of these additional [21:28] checks statically guaranteed at compile [21:30] time it's really helpful okay so how [21:34] does all this work how's this type [21:36] system so good did this just come out of [21:39] nowhere well no when you're looking at [21:43] reason behind the scenes it's actually [21:46] oh camel one of those mmm languages so [21:51] you might ask okay well then is reason [21:53] the camel language well yeah sort of I [21:58] guess it depends on what you mean by [21:59] language right so what is in a language [22:02] a language is a lot of things it's the [22:04] the community of the package manager' [22:05] libraries patterns use cases all these [22:08] things that matter but most importantly [22:10] a language is at the heart of the [22:12] compiler so what's in a compiler I'm [22:16] gonna totally reduce this down to an [22:17] absurd level here but you can think of [22:19] it in a few stages the front end which [22:22] you know it describes its syntax and how [22:24] you actually interact with it the middle [22:26] stage which is type the actual type [22:27] system where implements and implementing [22:29] it the semantics and then the back end [22:31] which is like actually rendering out the [22:33] machine code or the JavaScript whatever [22:35] you're compiling to so reason starts by [22:39] replacing the syntax of a camel with one [22:41] that is immediately usable by JavaScript [22:43] developers okay [22:45] so why start with syntax well I mean if [22:49] we saw anything if we learned anything [22:50] from the story of reactance that syntax [22:52] matters it's the UI of your programming [22:55] language [23:00] so there's some quotes from people that [23:02] I just randomly pulled from from Twitter [23:04] to me the syntax the familiar syntax was [23:09] that originally what lit my interest in [23:11] reason I did some exploration of reason [23:14] and some time ago and it was super [23:15] intuitive to write it so this is some of [23:18] the stuff that we're hearing but not [23:21] everybody likes the syntax because I [23:22] mean there's no syntax that everybody [23:25] likes but if you consider just who were [23:27] targeting it makes a lot of sense [23:29] because the JavaScript developer [23:31] community is huge its massive so if you [23:35] want to gain adoption in a technology [23:36] you want to remove friction for the [23:39] largest set of people at once [23:40] static fiction even if it means maybe [23:43] increasing friction for a tiny [23:45] relatively tiny set of the entire world [23:49] of programming it's a worthy trade-off [23:53] okay but then I mean it gets kind of [23:55] confusing because a lot of people use [23:57] reason with buckle script so which [24:00] replaces the back end of a camel with [24:01] one that emits idiomatic JavaScript that [24:04] you can check in and that your [24:04] co-workers won't yell at you for so I [24:08] mean at this point when it's used this [24:10] way more the Oh camel compiler is [24:12] replaced with with parts of the tool [24:15] chain that JavaScript developers want [24:18] but importantly it's still oh camel [24:21] exactly where you want to be in that [24:24] battle-tested hardened type system okay [24:30] so I mentioned compiling to JavaScript [24:31] there's going to be other awesome talks [24:33] about that at this conference but yeah [24:36] this might sound kind of like a radical [24:37] proposal like you're gonna change my way [24:40] I you know like develop my JavaScript [24:42] code base sounds like a radical [24:44] departure well I would say I'm not [24:46] really so sure about that I mean ever [24:49] since we open source react people have [24:51] been using JSX and that's not even valid [24:54] JavaScript it won't run in the browser [24:55] so people have to compile it into [24:58] JavaScript to run it in the browser so [25:00] your compile to j/s language user so now [25:03] we're just talking about trade-offs in [25:05] compilers like which one would you want [25:06] if you're developing react apps [25:10] I'm more interested in arguments and [25:13] discussions about about the kind of [25:17] potential that we can unlock for [25:18] developers I'm not really interested in [25:20] you know talking you know biasing [25:22] towards the status quo because if we did [25:24] that we'd still be rendering PHP on the [25:26] server and we wouldn't have react so if [25:29] you imagine you visualize the the [25:31] potential that a JavaScript programmer [25:33] has today in the JavaScript ecosystem [25:34] react definitely improved a large [25:38] portion of that so anything related to [25:40] UI and interactions develop the [25:42] developers life improved and the code [25:45] was easier to reason about it didn't [25:49] solve all the problems and that's it [25:51] wasn't supposed to so the way I think [25:55] about reason is that it brings the [25:57] things that people like about react to [25:59] the entire language so that every use [26:01] case in the JavaScript ecosystem [26:03] benefits from those same core ideas but [26:12] what's often - but what's often missing [26:14] from this discussion is the person who [26:18] matters most who matters most these are [26:23] yeah I mean you know reason and react [26:28] both improve the user experience because [26:30] users don't like bugs so the fact that [26:32] reason can prevent a large class of that [26:34] ahead of time that's great what else do [26:37] users care about performance right [26:43] exactly [26:46] so if you take a step back you look at [26:49] the entire world of programming you [26:50] realize how big it really is so there's [26:54] a lot of people building tools or [26:56] building applications with rest C go [27:02] what are they doing why are they doing [27:05] that [27:06] what part of always bet on JavaScript do [27:09] they not understand it turns out there's [27:15] some pretty good reasons users want [27:18] faster startup time they want better [27:21] utilisation of their hardware they want [27:25] more predictable performance faster [27:27] execution more throughput they [27:30] appreciate that and they notice jits can [27:35] be amazing just-in-time compilation but [27:38] they're also pretty unpredictable too [27:39] because they rely on heuristics that are [27:41] really hard to pin down ahead of time [27:42] hard to guarantee throw out the all the [27:45] workflows if your app that you didn't [27:46] test so when you want to provide the [27:50] best user experience can't always afford [27:53] the complexity of the JavaScript [27:55] language J's developers can sometimes be [27:59] in a kind of denial about this and [28:02] they'll get me wrong I totally [28:03] understand the appeal of pushing [28:05] JavaScript in the VM to its limits [28:07] especially if you're in the case or in [28:10] the scenario where you also want to you [28:12] also want to deploy a large part of your [28:14] code base to the web say historically [28:17] that means you have to target you have [28:18] to write in JavaScript deploy to the web [28:21] now you're in this situation where you [28:22] have this existing code that's existing [28:24] knowledge but you also need to run it [28:26] run it in all these other environments [28:28] where a JavaScript VM wasn't you'd be [28:29] required to begin with so the appeal [28:32] there is well I want to take this code [28:33] and I want to use it in all these other [28:35] use cases even if those other news cases [28:38] are more demanding so so developers [28:41] they're there in this trade-off work I [28:43] want to target web I also want more [28:46] constrained environments I want to cover [28:48] all the bases so you're in a situation [28:52] where you have to learn web development [28:53] today and then if you want to cover [28:55] these other use cases you're faced with [28:57] a choice [28:58] completely learn from ground up and this [29:02] other staff in another language that [29:04] serves these other use cases better [29:07] import everything I wrote in JavaScript [29:09] over there keep it in sync or I can just [29:14] let the user take the hit I could push [29:17] JavaScript beyond its limits maybe pass [29:20] its breaking point makes sense why this [29:24] is happening [29:27] ultimately any library that's authored [29:30] in JavaScript is held captive by [29:34] JavaScript you really only be used in so [29:38] many scenarios and if you don't believe [29:40] me just ask all those people in the [29:42] right column there but here's what's so [29:47] cool about reason even if you're just [29:50] writing reason targeting the web today [29:51] all those skills they transfer to a huge [29:56] portion of those other native use cases [29:59] that are more constrained there's no [30:01] such thing as one language that can do [30:03] everything right there's going to be use [30:07] cases so demanding that you know you [30:09] need to drop down to low-level C and [30:10] there's gonna be other cases still or [30:12] even that's not good enough and C adds [30:14] too much overhead and you have to write [30:15] manual assembly hopefully none of us [30:17] ever have to do that but no there's also [30:21] going to be cases where you know the the [30:22] current feature set of the oh camel [30:24] native compiler it's not really well [30:25] matched to that use case so there's [30:28] definitely a lot of room there but what [30:29] I've noticed is that a lot of the [30:30] systems that people are building where [30:33] you know you want a fast command line [30:35] app you want a fast server it's actually [30:38] really well-suited by the need of a [30:39] camel tool chain a huge portion of them [30:43] because it produces fast executables [30:45] that start up instantly sounds almost [30:49] too good to be true except it's already [30:52] happening [30:56] here's just a couple of examples that I [30:58] pulled from the community fnm we [31:02] mentioned that earlier it's fastener [31:03] manager that is a node version manager [31:06] that is so fast you can put it in your [31:08] shell and you'll never notice it this [31:10] happens instantly another one is Oney [31:13] too so only two is a rewrite of only one [31:16] but this time it's based well it's [31:20] always been based on vim but this time [31:21] the GUI is based on recent native so [31:27] these projects they have a serious [31:28] advantage when they're competing against [31:30] other ones that are written and authored [31:32] in JavaScript just because the [31:35] performance alone the performance is an [31:38] incredibly important feature to users so [31:40] here's some quotes just pulled randomly [31:43] off Twitter about Tony [31:46] it's crazy performant like scary fast I [31:49] actually didn't know one app could start [31:51] that fast my Mac did I click it already [31:53] started and so what's cool is that all [31:57] these projects and there's many more - [31:59] they were started or contributed to by [32:03] people from the web community from the [32:05] web ecosystem that's a lot of potential [32:08] that we're unlocking we also use reason [32:11] native on my team as interfaces of [32:12] Facebook we compile a reason modules to [32:16] JavaScript easy buckle scrip compiler [32:17] but then we also have piled them [32:19] natively to native executables so that [32:22] we can run them extremely fast in our [32:24] testing environment we don't have to [32:26] spin up a JavaScript VM to actually run [32:28] our tests so it's very interactive we do [32:31] that using rely which is a testing [32:34] framework inspired by jest but meant for [32:36] native reason it's part of a larger set [32:38] of utilities that we have open source [32:39] called reason native which brings a lot [32:41] of the node utilities and the node style [32:43] of libraries and programming to reason [32:46] native you check it out there so why was [32:52] Native hard I mean looking at the [32:54] history if he ever tried to compile a [32:56] C++ program it's a nightmare [32:59] usually involves you know installing 20 [33:01] global things on your machine you didn't [33:03] have before [33:03] overheat that for another project so [33:06] that [33:06] that and your editing make files and [33:08] environment variables for like hours [33:09] before you can even get the thing to [33:10] build so why was that well native builds [33:14] have historically not completely [33:17] automated and modeled all the [33:19] dependencies that are required it's just [33:21] part of the culture in a lot of the [33:22] previous native programming so there's [33:26] no one clicked there [33:28] it's too easy for package authors to [33:31] accidentally rely on something on their [33:33] specific machine but you know how on [33:35] yours and so you spend all your time [33:36] trying to recreate that package authors [33:38] machine set up an environment on your [33:40] machine and it's hopefully it's [33:42] documented it might not be so because of [33:45] that lack of automation is really [33:47] difficult to get pre-built [33:48] artifacts to other people or even on [33:51] your own machine across projects so [33:53] these are some of the things that make [33:54] you Native hard or slow or painful so [33:57] what are we doing under the reason [33:58] umbrella to improve things well if we [34:01] want to get web developers on board with [34:03] the native development development [34:04] workflows we need something that's [34:06] familiar it's got to be one click we [34:09] need something that's easy [34:11] so Audrey Papa's been building something [34:13] called easy easy as it is like the one [34:16] easy button that you need to press to [34:18] automate to speed up and perform native [34:22] builds it feels just like NPM package [34:24] management also actually you got a [34:26] package JSON you specify your [34:28] dependencies so really any web developer [34:29] can just get started really quickly and [34:31] they immediately know how to navigate [34:33] the project but it's not NPM it doesn't [34:35] use NPM it doesn't use yarn there's a [34:38] complete Korean fomentation of a package [34:40] management workflow and it's implemented [34:43] in reason Native itself so it's also [34:44] really fast it's really easy to use you [34:48] just type yes why and the command line [34:50] when you're in a project and it'll just [34:51] do everything it'll build install the [34:54] penalties so actually pretty incredible [34:56] what's happening there I think of it as [34:58] like a react but for package management [35:00] so in the same way that we're bringing [35:02] the ideas of react to the language of [35:04] threes and we're bringing the ideas of [35:05] react to the package management with [35:07] easy so when you run easy it reconciles [35:11] your project fetches what needs to be [35:13] fetch from the network builds it needs [35:15] to be built and does it really fast [35:18] but what's really cool that are also [35:20] caches those builds for your project in [35:22] dependencies across all your projects so [35:24] the more you use it the faster it gets [35:26] when you're when you're developing [35:27] native it uses some code from oh camels [35:30] package manager OPM and also has [35:32] integration with oh pam so that it can [35:34] consume those packages and build them [35:35] and it's really standing on the [35:37] shoulders of giants here with both Oh [35:39] camel and oh pam and a lot of the [35:41] research that went in there including [35:42] some of the windows support but also [35:44] supports native seed programs in c++ [35:47] libraries i also supports javascript [35:51] packages so it's really kind of one tool [35:52] chain that can can do it all there so [36:01] reason takes the ideas of react to the [36:03] next level and i see it as a way to [36:08] unlock your potential as a developer [36:10] because it allows you to learn one [36:12] language that improves the user [36:13] experience across a wide variety of use [36:15] cases and constraints so i want to leave [36:18] you with one question what could you [36:21] build a threesome maybe you could build [36:24] a really cool data fetching paradigm a [36:26] framework that runs everywhere maybe you [36:29] could build a new UI library maybe you [36:32] could build what comes after react thank [36:35] you [36:44] [Applause]