Lang NEXT 2014 Panel Systems Programming in 2014 and Beyond

Lang NEXT 2014 Panel  Systems Programming in 2014 and Beyond — 25msr

25msr

AI-assisted summary of Lang NEXT 2014 Panel Systems Programming in 2014 and Beyond — original source. Check the original for full context.

Source published:

Key ideas

  • Language designers define systems programming through varying lenses: Bjarne Stroustrup emphasizes hard resource constraints, Rob Pike identifies it with server and cloud infrastructure, and Andrei Alexandrescu proposes litmus tests like implementing one's own memory allocator and forging integers into pointers. (2:50)
  • Sluggish compilation in legacy C++ stems primarily from textual header inclusions and class-per-header organization rather than templates, causing Google build metrics to show a million-fold text expansion (~4.2 million bytes parsed per byte of written source). (56:26)
  • Hyperscale production constraints make dynamic hot-patching unacceptable at companies like Facebook because the required indirection layers disrupt critical first-cache-line struct performance, making process restarting and external deployment orchestration far superior. (45:40)
  • Go avoids defining an internal Application Binary Interface (ABI) entirely by relying on rapid source-based compilation—building its standard library in six seconds on a laptop—while Rust preserves internal layout freedom and relies on `#[repr(C)]` strictly at FFI boundaries. (60:42)

Detailed notes

## Background This panel discussion was published on YouTube by the channel 25msr on April 14, 2018, originating from the Lang.NEXT 2014 conference. No video description was provided on the page.

## TL;DR Language designers Bjarne Stroustrup (C++), Rob Pike (Go), Andrei Alexandrescu (D), and Niko Matsakis (Rust) debate the shifting definition and engineering realities of systems programming in 2014 and beyond. The discussion explores fundamental tensions between safety, performance, and cognitive overhead, evaluating whether rigorous static type systems, garbage collection, or ownership models best serve real-world applications. They also address practical architectural pain points, including the trade-offs of runtime hot-patching versus cache-line optimization, the historical baggage causing catastrophic C++ compile-time header bloat, and divergent approaches to Application Binary Interfaces (ABIs).

## Atmosphere & style The panel carries an engaging blend of collegial warmth, intellectual honesty, and dry technical wit, underscored by decades of shared history among computing pioneers. The dynamic is candid and unpretentious; participants poke fun at their past design decisions, acknowledge competitor strengths, and bluntly dismiss dogmatic orthodoxy. Watching it feels like sitting in on an insider engineering salon where academic theory is continuously stress-tested against the brutal realities of production scale, hardware architecture, and legacy constraints.

## Bulletin - [02:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=170s) Language designers define systems programming through varying lenses: Bjarne Stroustrup emphasizes hard resource constraints, Rob Pike identifies it with server and cloud infrastructure, and Andrei Alexandrescu proposes litmus tests like implementing one's own memory allocator and forging integers into pointers. - [56:26](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3386s) Sluggish compilation in legacy C++ stems primarily from textual header inclusions and class-per-header organization rather than templates, causing Google build metrics to show a million-fold text expansion (~4.2 million bytes parsed per byte of written source). - [45:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2740s) Hyperscale production constraints make dynamic hot-patching unacceptable at companies like Facebook because the required indirection layers disrupt critical first-cache-line struct performance, making process restarting and external deployment orchestration far superior. - [01:00:42](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3642s) Go avoids defining an internal Application Binary Interface (ABI) entirely by relying on rapid source-based compilation—building its standard library in six seconds on a laptop—while Rust preserves internal layout freedom and relies on `#[repr(C)]` strictly at FFI boundaries.

## Key takeaways - [02:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=170s) Systems programming in 2014 spans a broad spectrum from client-side latency-critical software (Rust) to scalable cloud infrastructure (Go) and embedded resource constraints (C++ and D). - [07:22](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=442s) Andrei Alexandrescu defines a true systems programming language by two litmus tests: the ability to write its own memory allocator internally and the ability to forge numbers into pointers. - [12:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=724s) Bjarne Stroustrup sharply distinguishes between language-level type safety and real-world system security, noting that security involves physical and environmental vectors that type systems cannot solve alone. - [17:10](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1030s) Expanding hardware compute capacity has enabled global static verification passes—such as Gerard Holzmann's deadlock-free analysis of the Plan 9 kernel—without requiring manual formal proofs. - [21:39](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1299s) Backward compatibility and relentless user feature requests are the primary drivers of language bloat, forcing maintainers like Stroustrup to reject over 99% of feature proposals. - [24:18](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1458s) Go managed language evolution and broke backward compatibility prior to 1.0 using `go fix` and `gofmt` to perform idempotent, automated source-to-source AST refactoring across massive codebases. - [27:58](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1678s) Rust embraces upfront cognitive overhead and the borrow checker because complexity is intrinsic to systems domains; exposing resource ownership explicitly prevents subtle runtime memory defects. - [29:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1787s) At hyperscale data centers, a 0.5% gain in server-level CPU and memory efficiency translates into millions of dollars in power and hardware savings, justifying low-level manual resource control. - [36:55](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2215s) Rob Pike argues that garbage collection is an abstract concept whose interface simplifications cut API cognitive overhead in half compared to manual ownership management in C++. - [45:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2740s) Dynamic runtime hot-patching destroys CPU cache locality by introducing pointer indirection into structs, where layout of the very first cache line often dictates production performance. - [49:01](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2941s) Modern high-reliability architectures favor the Erlang paradigm of failing fast and restarting entire processes quickly rather than attempting error-prone in-memory data migrations. - [53:12](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3192s) C++ compilation latency is fundamentally rooted in Dennis Ritchie's early C batch preprocessor design and redundant textual header inclusions, a problem modularization aims to address. - [58:23](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3503s) A standard C++ ABI was never established due to ISO committee charter limits and fierce commercial competition among early compiler vendors who intentionally maintained incompatible binary formats. - [01:00:42](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3642s) Modern languages approach internal ABIs differently: Rust and Go refuse to freeze native ABIs to leave room for continuous compiler optimizations, relying on C compatibility solely at external boundaries.

## Detailed walkthrough ### [00:00](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=0s) Panel Introductions and Banter

The interactive panel, titled “Systems Programming in 2014 and Beyond,” brings together language designers representing C++, Go, D, and Rust: Bjarne Stroustrup, Rob Pike, Andrei Alexandrescu, and Niko Matsakis. As the session opens, the moderator encourages audience participation, noting that attendees had been somewhat shy earlier in the day and urging them to drop their masks and ask direct questions.

Before opening the floor, the panel engages in a round of casual, good-natured introductions among themselves. Bjarne introduces Rob Pike, recalling their shared history: > “I remember when he came to Bell Labs we even shared an office for about three months and he's been doing great things at Bell Labs and then Lucent and then went to the west coast did a lot of good stuff with Google and and he was physicist I remember was it Caltech yes thanks.”

Rob returns the favor by introducing Bjarne Stroustrup as the designer and inventor of C++ at AT&T Bell Labs, joking about the sheer endurance required to serve on the standardization committee for decades. When asked how many years he had spent on the committee, Bjarne simply quips, “Too many.”

The introductions turn humorous as Andrei Alexandrescu is asked to introduce the Rust representative. Andrei confesses that he came unprepared and admits: > “Rust is the language that we're going to steal a lot from inspiration do what I say I'm gonna get a lot of inspiration from and I actually don't know much about about you so but maybe you I mean I don't know.”

Rob steps in to identify Andrei Alexandrescu as the co-designer and advocate for D, noting his work at Facebook and observing that, like every Romanian he has met recently, Andrei wears shorts all the time—prompting Andrei to joke that he will spend the rest of the evening trying to hide his legs under the table. The moderator then officially introduces Niko Matsakis, a researcher at Mozilla working on Rust, setting up the common thread across these languages: delivering high-level abstractions, type safety, and memory safety without sacrificing native performance or direct control over hardware.

[02:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=170s) Defining Systems Programming in 2014

The moderator poses the foundational question of the session: what actually constitutes a “systems programming language” in 2014? The landscape has shifted dramatically from the days when the term applied strictly to writing operating systems or device drivers. Today, C++ powers much more than operating systems, while D, Go, and Rust occupy distinct spaces across servers, browsers, and distributed systems, leading the panelists to offer differing perspectives on what the term currently means.

```mermaid flowchart TD accTitle: Perspectives on Systems Programming in 2014 accDescr: Diagram illustrating the varied criteria and domains each panelist emphasizes when defining a modern systems programming language.

subgraph Criteria["Core Definitions & Litmus Tests"] A["Niko Matsakis (Rust)<br/>Client needs: latency, safety, resource predictability"] B["Bjarne Stroustrup (C++)<br/>Resource constraints: memory, time, hardware control"] C["Rob Pike (Go)<br/>Server & cloud infrastructure engineering"] D["Andrei Alexandrescu (D)<br/>Low-level tests: write own allocator & forge pointers"] end

subgraph Applications["Modern Target Domains"] E["Client Applications & Browsers"] F["Cloud & Scalable Distributed Backends"] G["Constrained Embedded & Hardware Systems"] end

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

Niko Matsakis points out that terminology is used quite differently across teams. From Mozilla's perspective, the primary focus is client-side application software, such as web browsers: > “So from our point of view I mean the thing that we're most interested in certainly you know in the most selfish point of view is writing kind of client-side applications right so sort of the polar opposite of what Go was designed for for example and in these kind of applications you have high latency needs you have high security requirements you have a lot of requirements that I think don't necessarily come up on the server side...”

However, Niko concedes that the boundaries are soft: Go can be used on clients, Rust can be used for server backends, and the true distinctions only emerge at the absolute extremes of those domains.

- **Niko Matsakis's Focus**: Client applications with strict latency bounds, robust security guarantees, and fine-grained execution predictability. - **Spectrum Overlap**: The consensus that general-purpose languages can technically operate anywhere, with their trade-offs manifesting primarily at domain edges.

[05:13](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=313s) Resource Constraints vs. Cloud Infrastructure

Bjarne Stroustrup frames systems programming not by the specific software being written, but by the constraints under which it operates. He explains that systems programming grew out of having to touch hardware directly and subsequently managing the runaway complexity that followed. For Bjarne, it is fundamentally a matter of operating under hard limits: > “It's a constraint that determines whether it's systems programming are you running out of memory are you running out of time are you running out of real time are you running out of file handles and then finally there's the aspect of actually touching hardware device drivers memory managers and such but it's it's like asking me to define play or game there's something obviously is there and then by analogy a lot of our listings are there don't don't expect a crisp definition.”

Rob Pike follows by reflecting on Go's naming history, admitting that labeling Go a “systems programming language” during its initial announcement created confusing expectations: > “When we first announced Go we called it a systems programming language and I slightly regret that because a lot of people assumed that meant it was an operating systems writing language and what we should have called it was a server server writing language which was what we really thought of it as...”

Rob notes that what used to be called servers has since been rebranded as cloud infrastructure. Consequently, in Rob's view, another modern and accurate definition of systems programming is simply the software stack that powers the cloud.

[07:22](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=442s) Andrei's Litmus Tests and the Allocator Challenge

Andrei Alexandrescu expresses relief that Rob preempted his question regarding why Go dropped the "systems programming" label from its website. Andrei notes that while debating definitions can easily slide into endless philosophy, he relies on two pragmatic, technical litmus tests to verify whether a language is truly a systems language: > “And I think there's a there's a simple litmus test which says systems programming language must be able to allow you to write its own memory allocator in it it shouldn't escape into another language to do so and it should be able to forge a number into a pointer because that's how hardware works this is kind of two litmus tests that are relatively simple.”

He elaborates that writing a memory allocator is far more difficult than most high-level language users realize. In high-level languages, memory management is treated as a solved, invisible implementation detail. But when a language must both implement and use an allocator, the task becomes notoriously bug-prone and runs directly counter to strong type systems: at some point, typed pointers must become raw, untyped blocks of storage and then be reconstituted into entirely different types on the fly.

Rob Pike immediately responds to Andrei's criterion with a practical counterpoint: the Go team has nearly finished rewriting Go's runtime memory allocator in Go itself (having previously been implemented in C), meaning Go qualifies under Andrei's allocator benchmark.

- **Litmus Test 1**: The language must be able to implement its own runtime memory allocator internally without dropping into a secondary systems language like C. - **Litmus Test 2**: The language must support forging integers into pointers, mirroring how physical memory-mapped hardware interfaces function. - **Go's Milestones**: Rewriting the Go memory allocator in pure Go from its original C implementation.

[09:45](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=585s) The Risk of External Definitions and Audience Questions on Security

Bjarne Stroustrup cautions against letting outsiders define technical domains. He points out that looking up “systems programming” on Wikipedia produces a definition so narrow—writing the lowest-level device drivers—that it renders the discipline practically obsolete: > “It is very tricky when somebody else defines your terms for you and I mentioned it with C++ with object-oriented programming we have an example here with systems programming being defined out of existence and the other example that I remember was Simula the language Simula are the introduced object-oriented programming to the world and got classes and class hierarchies in place was called Simula and I met a lot of people says no it was a special-purpose language of simulations there's nothing interesting there so let's try and define what we are doing a little bit better.”

The session then turns to the audience. An attendee brings up what they view as one of the central challenges of the era: writing secure, robust, and reliable code, which requires deep cooperation between the host platform and the programming language. The attendee asks what promising avenues of innovation the panelists see coming from the systems language space to enforce robustness.

Niko Matsakis takes the question first, answering that there are very real opportunities for innovation. He argues that before addressing broader reliability concerns, a language must establish a baseline layer of security guarantees: > “For me it sort of there's the base level of security which is kind of the properties I was talking about you know data-race freedom memory safety and so forth and you can argue about exactly which one should be in that list but there's a kind of basic set of things that you would like to get from your language most of the time at least and that gives you a good feeling...”

[12:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=724s) Expressing Semantic Invariants Beyond Basic Safety

Niko Matsakis explains that while current type systems provide more reliable software, they merely prevent specific categories of bad behavior rather than verifying that a program actually does the intended task. As Rust evolves, he hopes to see developers leverage the type system to express deeper application-specific invariants. Beyond providing automated refactoring and seamless tooling to trace function usage, types could model domain-level constraints. As an example, a type system could enforce that untainted data received from a network interface must pass through a sanitization routine before any internal consumer can process it.

Bjarne Stroustrup immediately intervenes to draw a clear line between formal type checking and real-world system defense. “I think we have to distinguish sharply between type safety and security,” Stroustrup states, cautioning that security encompasses physical and operational environments rather than just language properties:

> “If I'm going to steal your data I will probably not try and break in your computer first I'll try and steal your computer first and then I'll head to it my own good time that's a bit hard of a server farms but still the point is that it's a system property”

Stroustrup emphasizes that while 100% type safety is an enduring ideal, missing that mark entirely does not equal failure, nor does achieving it guarantee security. He warns against superficial debates that treat type safety as a panacea for security vulnerabilities like array overflows and resource starvation.

[15:11](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=911s) The Programming Language Community’s Local Optimum

Andrei Alexandrescu offers a contrarian perspective, joking that he will deliver a “Dear Leader North Korean prediction” where the luminous path lies ahead. He argues that Rust and modern languages are caught in a local optimum that constrains the entire programming languages (PL) community. Currently, properties that compilers prove effortlessly are intellectually uninteresting, while truly valuable guarantees—such as automatic array bounds check elimination—remain practically burdensome and computationally complex.

```mermaid flowchart TD accTitle: Alexandrescu's Breakthrough Cycle accDescr: Historical breakthrough cycle comparing speech recognition to type system evolution.

subgraph Hist["Historical Parallel"] SR1["Speech Recognition stuck in local minimum"] --> SR2["Breakthrough: Statistical models & Siri"] end

subgraph PL["Programming Languages"] PL1["Current PL local optimum:<br/>Trivial proofs easy, rich types onerous"] --> PL2["Ripe for breakthrough:<br/>High-assurance typing with minimal annotations"] end

Hist -.->|"Pattern convergence"| PL ```

Drawing an analogy to speech recognition research—which he abandoned just before statistical modeling led to major commercial breakthroughs like Siri—Alexandrescu suggests that type systems are approaching a similar inflection point. “Essentially the white seat we're ripe for a sort of a real breakthrough in in the area when programs are going to be typed in ways that at the same time are are interesting improve a lot of facts but don't require a lot of annotations,” he predicts. Systems programming languages, by imposing uncompromising demands for raw execution speed alongside safety, apply valuable upward pressure on academic researchers.

- Andrei Alexandrescu argues that language tools remain trapped in a rut where safe array bounds elimination is practically difficult to achieve without heavy annotation overhead. - Systems programming acts as an essential forcing function on PL theory because no level of overhead is tolerated in exchange for safety guarantees.

[17:10](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1030s) Tooling, Static Analysis, and Scale

Rob Pike counters the pessimism, arguing that the industry is already climbing out of its rut due to dramatic expansions in compute capacity. Hardware is now fast and voluminous enough to execute global program checks that were computationally impossible a generation ago. Pike recalls Gerard Holzmann’s work on the Plan 9 kernel at Bell Labs 15 years prior, where a specialized protocol analyzer parsed C source code and tracked mutex library invocations to demonstrate that the kernel was deadlock-free without requiring traditional manual proofs.

Stroustrup backs Pike's stance on mechanical inspection, arguing that static analysis scales with language sophistication. “One of the criticisms of static typing has been that they only catch trivial things,” Stroustrup observes, adding: “That's because they look at trivial type systems.”

- Gerard Holzmann built a static protocol analyzer at Bell Labs to verify locking behavior and lock-freedom across the Plan 9 operating system kernel. - Computational resources once monopolized by whole-program optimization passes can now be repurposed for deep static verification.

[19:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1190s) The Cognitive Burden of Systems Languages

Panel moderator Dave asks whether modern systems languages demand too much mental overhead from working programmers. Even though tools now generate better diagnostics, Dave notes that he constantly struggles with left-brain conceptual models while writing code. In Rust, one must continuously track reference lifetimes, borrow flags, and mutability; in C++, the mental landscape is similarly daunting. Dave contrasts this with Go, which intentionally trims language surface area to prevent overloading ordinary engineers, and asks the panelists if their languages force users to carry an exhausting mental model in their heads.

```mermaid flowchart LR accTitle: Language Complexity Sources accDescr: The dual pressures of legacy compatibility and user feature requests driving complexity.

subgraph Sources["Forces Expanding Complexity"] A["40-Year Heritage (C in 1972)"] --> C["Complex Mental Burden"] B["Feature Requests ('Simpler + My Feature')"] --> C end

subgraph Remedy["Proposed Path Out"] C -.-> D["Tool-Assisted Modernization & Rewriting"] end ```

[21:39](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1299s) Legacy, Language Bloat, and Mechanical Rejuvenation

Stroustrup responds directly, explaining that language complexity stems primarily from backward compatibility. Software developers perpetually request a simpler language accompanied by their own pet features, forcing him to reject upwards of 99 percent of language proposals over the decades. C++ carries four decades of legacy reaching back to Dennis Ritchie’s original 1972 design of C, containing features that should never have existed or that have long been superseded. Because existing codebases cannot be broken, obsolete mechanisms persist indefinitely.

Stroustrup calls for advanced tooling that moves beyond passive linting toward automated refactoring and language rejuvenation:

> “One thing that I hope for is not just code analysis I want code transformation and I wanted to maybe I can finally get modernization of code code rejuvenation or whatever you call it that's mechanically helped so we can get some of these things that aren't C++ just because Dennis had a bad day in the early 70s and Dennis would agree with me and actually has”

Stroustrup points out that if he were to design C++ templates today, their specification would occupy half the space. He wryly notes how new languages recurrently emerge claiming purity, referencing how early Java advocates brandished the *Annotated C++ Reference Manual* (ARM) while tearing out two-thirds of its pages to claim they had built a clean language from first principles using familiar C syntax.

- Bjarne Stroustrup estimates he has rejected more than 99% of feature proposals submitted for C++ to hold back complexity. - C++ retains design compromises inherited directly from Dennis Ritchie's original 1972 implementation of C. - Stroustrup claims that with modern design knowledge, the template mechanism in C++ could have been designed at roughly half its existing footprint.

[24:18](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1458s) Language Evolution and Automated Code Transformation with `go fix`

Bjarne Stroustrup remarks that as programming languages age, they accumulate endless “barnacles that hangs off the ship,” noting that the only languages avoiding this fate are those that fail to survive. Both C# and Java have doubled and tripled in size until their specifications rival C++. Hoping that automated code transformation might offer a way forward, he prompts Rob Pike to share how the Go team tackled language churn leading up to the release of Go 1.0. While Go did not have nearly the massive user base of C++, Pike explains that the team was determined to lock the language down without needlessly fracturing the existing community's codebase. They wanted the freedom to simplify syntax, prune experimental features, delete keywords, and overhaul standard libraries, but needed a mechanism that would prevent manual migration pain for their users.

```mermaid flowchart LR accTitle: The Go Fix Migration Pipeline accDescr: Pipeline showing legacy Go source code being parsed into an AST, transformed by modular rewrite passes, and output as clean source code via gofmt. subgraph Transformation["Automated Refactoring"] A["Legacy Go Source"] --> B["AST Parser"] B --> C["go fix Modules"] C --> D["gofmt Formatter"] end D --> E["Clean Go 1.0 Source"] ```

To achieve this, the Go team built `go fix`, a modular tool designed to parse both older and newer syntax variations into an abstract syntax tree (AST), apply idempotent rewrites, and emit clean code. This was enabled by Robert Griesemer's creation of `gofmt`, a formatting library that re-emits ASTs in canonical, human-readable source style—an addition Pike humorously observes “some people say is the best feature of the language; they may be right.” This tooling afforded the designers unprecedented freedom to experiment, reverse poorly aging ideas, and polish every edge of Go before release. Later, when Google decided to completely replace the Go Protocol Buffers API—used on virtually every third line of internal Google code—they wrote a single `go fix` module that migrated the entire monolithic repository in one step. As Pike sums up, “a lot of this is actually automatable if you're willing to have the courage to clean up, stick to your guns, and really get rid of the old stuff.”

- Go 1.0 established strict backwards compatibility; subsequent point releases focused purely on compiler performance, runtime implementation, and library additions. - The `go fix` migration modules were engineered to be idempotent so that running them repeatedly on partially converted trees caused no side effects. - The automated Protocol Buffers API rewrite at Google stood in sharp contrast to the massive, painful migrations typical of legacy C++ codebases.

---

[27:58](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1678s) Domain Complexity vs. Language Overhead: Ownership and Explicit Types

Niko Matsakis turns the discussion back to the audience's underlying concern: whether modern systems languages force programmers to keep an unreasonable amount of type machinery in their heads. Addressing the trade-off of upfront cognitive overhead versus hidden costs, Matsakis contrasts Rust’s explicit ownership and borrowing semantics with the deceptively simple pointer model of Java or C#. In managed languages, concepts like resource lifetimes, exclusive access, and mutation still exist beneath the surface, but they remain implicit and unchecked, leaving developers vulnerable to subtle design bugs.

Matsakis points out that developers migrating into systems programming often find Rust's compiler diagnostics far more forgiving than the trial-by-fire debugging required in C. Rather than spending weeks diagnosing obscure double-free panics and segmentation faults, newcomers are guided down correct structural patterns by the borrow checker. Contradicting the premise that modern systems languages are arbitrarily bloated, Matsakis argues: “I feel the most of the complexity is in the domain, and exposing it at the language level is not a mistake in that regard.”

---

[29:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1787s) The Full-Stack Scale of Systems Programming and Extreme Efficiency Margins

Andrei Alexandrescu begins with a personal aside to the audience member, David Ungar: “Dave, you should know, you're my academic grandfather; Craig Chambers has been my advisor through my Master's, so it's a great honor to see you.” He empathizes with Ungar's affection for the fluid, minimal cognitive friction found in dynamic prototype environments like Self and Smalltalk. However, Alexandrescu argues that systems programming carries an inescapable requirement to simultaneously manage macroscopic design and microscopic execution: “Systems languages have this extra burden on top of everything, which is, well, you got to worry about at the same time the cathedral, the bricks, and the molecules in the bricks.”

To demonstrate why dynamic or garbage-collected runtimes cannot satisfy every tier of this stack, Alexandrescu highlights recent experimentation conducted at Facebook. Benchmarking identical production payloads revealed that a garbage-collected architecture consumed roughly three times the memory of an eagerly reclaimed, manually managed counterpart—an overhead profile Facebook simply cannot afford. At hyperscale server deployments, fractional optimizations map directly to massive financial and operational outcomes:

- A mere 0.5% gain in core server-level efficiency translates to millions of dollars saved annually in electricity costs alone. - Reduced memory and physical footprint decreases server component failure rates, hardware churn, and acquisition costs. - While dynamic abstractions provide comfort to language researchers, production at scale demands that the inherent physical complexity of hardware remain exposed to the programmer.

---

[33:03](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1983s) Precision, Type Safety, and the High Stakes of Technical Correctness

Bjarne Stroustrup reinforces Alexandrescu's and Matsakis's points by forcefully rejecting the common aspiration that programming should mimic natural language. Stroustrup cautions that natural language is notoriously ambiguous, noting how frequently a statement that seems crystal clear in English is misinterpreted by everyone who hears it. In systems engineering, interfaces that enforce rigorous contracts via type systems and strict constraints are the only reliable defense against miscommunication across large organizations.

To demonstrate the real-world cost of weak or imprecise typing, Stroustrup cites the Mars Climate Orbiter disaster: the software failed not from a syntax error or a standard memory bug, but because the interface relied on bare floating-point primitives without dimensional unit verification. Because a floating-point `double` looks identical whether it represents metric Newtons or imperial pound-seconds of thrust, an undetected conversion mismatch doomed a $600 million spacecraft. Stroustrup emphasizes that for safety-critical systems—such as automotive brake software—rigorous technical specifications in the type system are non-negotiable: “For the kind of applications I think of most and care about most, like the brakes on my car and such, I would rather see it done at a technical level than an intuitive level.”

[35:02](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2102s) Cognitive Friction, Smalltalk, and the Prototyping Dilemma

An audience member follows up on an earlier point regarding testing versus language-enforced safety. He remarks that he does not know whether static type enforcement is actually sufficient to ensure the brakes work on his car compared to investing that exact same effort into comprehensive testing and fault injection. Addressing the panel, he notes that while high safety guarantees matter if code is being sent to Mars, many ideas begin as fragile concepts. In most systems languages, carrying all the low-level baggage in one's head makes it exceedingly hard to hold onto a bright new idea.

To illustrate, he quotes Randy Smith's reflection on the Alternate Reality Kit: if Smith had been forced to implement it in anything other than Smalltalk, he never would have gotten the first three lines written. The audience member expresses a desire to easily prototype an idea in a language that runs reasonably fast without being burdened upfront by manual reclamation or rigid mechanics, leaving room to add security or optimization later rather than having to rewrite the whole system from scratch.

[36:55](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2215s) Rob Pike on Garbage Collection: An Idea, Not a Performance Problem

Rob Pike steps in to clarify common misconceptions surrounding garbage collection, pointing out that not everything at Google is written in Go, nor should it be—especially where GC latency cannot be tolerated and lower-level control is strictly necessary. However, Pike argues that the systems programming community often dismisses garbage collection unnecessarily. While GC is not the solution for everything, it is the right answer for an enormous amount of software. He notes that this very realization drove the creation of Go: while C++ remains appropriate for certain core tasks at Google, it is not required for the majority of programs where developer productivity and memory ergonomics matter more.

Pike emphasizes that garbage collection itself is an abstract concept rather than an intrinsic performance bottleneck; poor performance usually stems from specific implementation strategies rather than the paradigm itself. Implementing modern allocators and collectors properly avoids bloated arenas and catastrophic slowdowns. Most crucially, removing ownership management drastically reduces interface complexity. Pike observes that Go's APIs often have half the complexity of their C++ equivalents because developers do not need to constantly negotiate memory ownership signatures.

> “The APIs in a typical Go program are half the complexity of a C++ equivalent because you don't have to talk about the memory management, and that makes the program smaller, simpler, easy to understand, and you have less to carry in your head as a result.” — Rob Pike

```mermaid flowchart TD accTitle: Go Memory Ergonomics vs C++ Complexity accDescr: Shows how removing ownership management from APIs reduces cognitive overhead in Go compared to C++.

subgraph CPP["C++ Paradigm"] direction TB C1["Explicit Ownership Semantics"] C2["Complex API Signatures"] C3["Higher Cognitive Load"] C1 --> C2 --> C3 end

subgraph GO["Go Paradigm"] direction TB G1["Automatic Garbage Collection"] G2["Streamlined API Signatures"] G3["Lower Mental Overhead"] G1 --> G2 --> G3 end ```

[39:17](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2357s) Niko Matsakis on Rust's Spectrum: From Inefficient Prototyping to High Performance

Niko Matsakis responds by citing a talk delivered earlier that morning by Bjarne Stroustrup, which busted the myth that programmers always demand maximum efficiency. Most of the time, developers do not need to inspect every generated assembly instruction; they just want to write down an idea, see it execute at a reasonable speed, and tune it later. Matsakis acknowledges that marketing a systems language like Rust creates tension because the project naturally promotes what it does best: combining absolute efficiency with rigorous memory safety.

However, Matsakis reveals that the Rust team also wants Rust to excel at writing quick, intentionally inefficient, and convenient code. In that mode, programmers should not have to fret about copying a buffer two or three times. He notes that the team has been exploring an optional garbage collection strategy as another ownership model that developers can opt into, though integrating GC alongside manual and reference-counted semantics remains technically demanding. The ultimate objective is a language where rapid prototyping is straightforward, yet the tools exist to harden and optimize the code in-place as soon as performance becomes critical.

[41:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2464s) Bjarne Stroustrup on Types as Thinking Tools and the Testing Epiphany

Bjarne Stroustrup offers a sharp counterpoint to the idea that type systems hinder creative prototyping. For Stroustrup, pinning down interfaces using strong, precise static types is not a bureaucratic hurdle; it is an indispensable aid to clear thinking. Relying purely on running dynamic examples only exposes design flaws after the fact, whereas putting a static type system up front flags faulty assumptions immediately.

Stroustrup views the compiler's type checker as an intellectual safety net, asserting: “I actually think of the type system as my first line of defense against my own sloppy thinking.” When an audience member jokes that this debate borders on the classic static versus dynamic typing dispute where reasonable minds disagree, Stroustrup delivers a punchline about the origins of modern testing dogma:

> “I had a bit of an epiphany last year when I realized that the reason that unit testing was being driven by the dynamic language people was that they had that instead of static typing.” — Bjarne Stroustrup

The room reacts with laughter, to which Stroustrup deadpans, “That wasn't funny, so it's a fact.”

[42:41](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2561s) Binary Versioning, Monkey-Patching, and the 5ESS Mystery

The session moves into an open Q&A. An audience member raises the financial cost of change and application binary interface (ABI) versioning, harking back to David Smith's work on adaptable systems. In production environments, breaking downstream clients across a top-to-bottom stack when modifying a shared library incurs immense economic cost. In languages like C++, memory layout is rigid, and the `this` pointer is fixed implicitly in memory, whereas more dynamic systems allow identity mutations and non-breaking post-release updates. The questioner asks why the systems language community does not place greater emphasis on explicit mechanisms designed to support large-scale program evolution and binary compatibility.

Rob Pike reflects on his time at AT&T alongside Bjarne Stroustrup, recalling the lucrative 5ESS telecommunications data switch. The 5ESS was a VAX-scale machine with massive hardware redundancy responsible for dial tones and digit switching. Every individual field installation ended up running slightly different software, as technicians applied localized binary patches—such as omitting the Spanish dialing plan in France. Pike marvels at how telecom engineers in the 1980s managed to dynamically monkey-patch live binary code over remote connections around the clock without ever dropping dial tones. Stroustrup confirms that he remembers the 5ESS era well, but clarifies that while an entire branch of the academic language community has pursued runtime adaptability and dynamic patching, his own focus has remained firmly grounded in absolute reliability: engineering the actual telephone switches and automotive braking systems so they never fail.

- The AT&T 5ESS was built with VAX-scale compute capacity and hardware redundancy to guarantee continuous dial tone and digit routing. - Real-world 5ESS deployments routinely diverged into unique configurations due to remote binary monkey-patching tailored to specific local dialing plans.

[45:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2740s) Hot-Patching, Cache Lines, and the Cost of Indirection

Bjarne Stroustrup opens by delineating his problem domain: keeping Mars probes and web servers reliable and efficient. Reflecting on his opening slide, where he emphasized that no single language fits every use case, he acknowledges that highly dynamic, flexible languages stemming from Lisp and Smalltalk have sustained vibrant ecosystems and never really gone out of fashion. However, that high-level dynamic space simply represents a completely different engineering concern from low-level systems programming.

Andrei Alexandrescu continues the thread, observing that having Bjarne and himself on a panel risks becoming boring because their core perspectives align so closely. He explains how Facebook handles deployments: the entire site is redeployed about twice a week across a massive, unspecified number of servers running deeply interconnected libraries. Facebook does not achieve this via dynamic hot-patching; rather, they deploy through external operational orchestration like BitTorrent-based distribution, winding down running binaries, swapping executables, and warming up services. Having spent months on Facebook's core PHP compiler team (HHVM), Alexandrescu notes that every single micro-optimization directly hits the company's financial bottom line.

Dynamic hot-patching inherently requires adding indirection—pointers, trees, and lists instead of flat structures—to swap code or data targets at runtime. Alexandrescu stresses that for production performance, indirection is completely unacceptable. At Facebook, data structures are stripped down to arrays and structs, and optimization work focuses specifically on the layout of the very first cache line:

> “The first cache line in the struct is where it's hot, that's where it happens, that's what the rubber hits the road and you come... if you come and say, ‘Oh, we need hot patching,’ and I'm like, ‘Oh, that's going to totally ruin my first line of cache right there and I'm going to die, right?’”

Swapping just two fields inside a struct can immediately cause a two-percent performance drop across a cluster, meaning hot-patching is an expensive architectural luxury low-latency infrastructure simply cannot afford.

```mermaid flowchart TD accTitle: Trade-off Between Hot-Patching Indirection and Flat Memory Cache Performance accDescr: Shows how dynamic updates require indirection that destroys CPU cache lines, contrasting with flat high-performance layouts.

subgraph Dynamic["Dynamic Hot-Patching Approach"] A["Dynamic Indirection Layers"] --> B["Lists, Trees, Indirect Pointers"] B --> C["Runtime Code/Data Swapping"] C --> D["Cache Misses & Performance Penalty"] end

subgraph Static["High-Performance Systems Approach"] E["Flat Array & Struct Layout"] --> F["Optimized First Cache Line"] F --> G["Fast CPU L1/L2 Processing"] G --> H["Restart/Reload via Process Swapping"] end ```

[49:01](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2941s) Fail Fast, Restart Quickly: Semantic Challenges of In-Memory Updates

Niko Matsakis highlights that modern system architecture tends to favor the Erlang paradigm: fail fast and restart quickly. Modern hardware can boot an entirely fresh server instance in a few milliseconds. If edge proxies and load balancers can incrementally drain traffic from a node, shut it down, and bring up the updated build without dropping user requests, trying to invent mechanisms for live in-process code modification becomes pointless added complexity.

Matsakis points out that dynamic code swapping and monkey-patching pose severe semantic challenges. While hooking in new code via virtual tables or function pointers incurs runtime cost, mutating in-memory runtime data is vastly harder. If an internal data structure changes shape or meaning—such as moving from Cartesian coordinates to polar coordinates—safely migrating live state without halting execution becomes a nightmarish problem. Establishing clean boundaries, defining what must persist versus what can be discarded, and letting the process crash or restart is far cleaner than trying to automate live in-place state migration. Stroustrup interjects with a historical note on telecommunication switches, recalling that achieving robust hot-patching required intentionally over-allocating resources:

> “The main ideas for being able to patch the data structures and switches is to deploy them with data structures that's slightly too big and with jump tables that are slightly too big so that if nothing else you can always have a thing that says switch to the new one for a while...”

Engineers could not merely ship what fit the system at that moment; they were forced to allocate memory two sizes larger than necessary just to leave room for future dynamic patches.

[51:19](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3079s) Slow C++ Compile Times and Header Bloat

An audience member working primarily in C++ raises a question about compilation pain. In their codebase, compile and link times take forever because extensive static analysis and domain logic have been pushed into the type system, creating vast numbers of template entities. He asks whether this compilation bottleneck is unique to C++, how newer languages handle it, and what the future holds for resolving the issue in C++.

Stroustrup affirms that build time is a massive industry pain point, wryly noting that Scala developers face similar struggles. However, he clarifies that template metaprogramming instances are rarely the primary culprit in most codebases. The real driver of slow compilation is textual file inclusion:

> “The instances in the in your program are not the real problem, it's the fact that we recompile the header files hundreds of times and this problem is getting unmanageable...”

Stroustrup notes that the ISO C++ Standards Committee has recognized this crisis, and he plans to dedicate significant time to modules and compilation improvements at an upcoming standards meeting three weeks later. While cautioning that standards bodies move slowly and rarely discover the most straightforward solutions on their first try, he asserts that a properly modularized C++ could achieve compilation speeds ten times faster.

[53:12](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3192s) Batch Models, Unity Builds, and the Serial Legacy of C

Niko Matsakis addresses compilation performance in Rust, mentioning that although the Rust compiler is not fast, the team had spent essentially zero time optimizing its internal throughput up to that point. Rust avoids C++’s header inclusion penalty by parsing an entire compilation unit (a crate) at once rather than repeatedly parsing individual source files. In Mozilla's C++ codebase, developers rely on unified (amalgamated) builds—concatenating multiple `.cpp` files into single large compilation units—to bypass redundant header parsing. Addressing casual community complaints about Rust's build times, Matsakis points out that running a full `make` bootstraps the compiler across three distinct stages:

- The existing compiler builds the new compiler from source. - The newly built compiler rebuilds itself using the new binaries. - The resulting binary compiles all standard libraries.

Alexandrescu argues that glacial compile times are an intrinsic design flaw inherited from C. Dennis Ritchie designed C around the memory constraints of early hardware, requiring a multistage batch compilation pipeline:

> “Does anyone know why the backslash termination line was ever introduced? Because it was run through a preprocessor that only did that because there's not enough memory for the whole thing...”

Original Unix systems lacked sufficient memory to parse files, perform macro expansion, resolve digraphs and trigraphs, and compile ASTs in a single pass, forcing a strictly serial model where every single character and token depends on everything parsed before it.

High-traffic tech giants like Google, Facebook, and Amazon grapple with this bottleneck every day. Despite marshaling massive fleets of build servers and assigning their most senior systems engineers to optimize distributed caching and build systems, C++ build latency remains fundamentally unresolved. Alexandrescu recalls that when he first joined Facebook, engineers urged him to look into the D programming language. Spending six months testing D made its lightning-fast parser and forward-referencing architecture immediately evident, leaving the C++ tooling team painfully aware of the archaic structural limits of the tools they were trying to optimize.

[56:26](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3386s) Compilation Speed and the C++ Header Blowup

The discussion continues on the decisive role compilation speed plays in developer adoption. When programmers discover a language that compiles dramatically faster, it changes their willingness to experiment: “it’s speeds of compilation that cannot be cannot be obtained at any with any money for C++; there’s no amount of money that would pay you that you could pay someone to compile code as fast as he does and that that was a winner.” For C++, the sluggish compilation times are fundamentally a design issue baked into its history, even though work on C++ modules is progressing.

Rob Pike brings up concrete data from a measurement cited in a previous SPLASH talk concerning a massive C++ build at Google. Due to transitive header inclusions, the sheer volume of text the compiler had to ingest expanded out of all proportion: “it was some like 4.2 million bytes per byte of input source to the compiler; it was a million factor blow up in the amount of source that the compiler actually looked at because of the header inclusion problem.” Pike emphasizes that this is not primarily caused by templates, but begins simply with placing a single class per header file. Bjarne Stroustrup retakes the microphone to concede the point without hesitation: “The reason I take this mic back is mostly to say that I don’t disagree with that; this this this is a major problem it’s a growing problem it needs to be dealt with.” Stroustrup notes that while he is not completely “rah-rah optimistic,” he believes the modules effort will ultimately solve the issue.

- Rob Pike cites Google build metrics showing a roughly million-fold blowup (~4.2 million bytes parsed per byte of actual written source). - The root cause is traced back to transitive `#include` directives and class-per-header patterns rather than templates alone. - Bjarne Stroustrup affirms that compilation bloat is an urgent, growing problem that modules aim to resolve.

---

[58:23](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3503s) Why C++ Never Standardized an ABI

An audience member working primarily in C++ asks Bjarne Stroustrup about the decision never to define an Application Binary Interface (ABI) as part of the language specification, whether he regrets it, and how newer language designers approach specifying binary interfaces within the limits of portability. Stroustrup replies that having a standardized binary interface would indeed have been beneficial, but the ISO C++ Standards Committee considered it completely outside its scope—just as the C committee had done earlier.

C was fortunate because each operating platform typically had a dominant, de facto owner setting the platform ABI, which C++ implementations initially rode on. However, C++ fractured rapidly because major compiler vendors each wanted to claim ownership of the platform toolchain: “the reason C++ didn't get one of those was that essentially everybody thought they could own C++ on the platform and so you had Microsoft and Borland and Symantec each defining their ABI carefully making sure you couldn't link to the enemy's code.” Whenever standardizers tried to tackle this afterwards, they hit two roadblocks: ABI was deemed outside the committee's charter, and vendors consistently chose backward compatibility with their existing customers over breaking code to achieve cross-vendor compatibility. Stroustrup notes faint hope in 64-bit standards and the Itanium ABI, but admits, “I hope people will get their act together but I'm not holding my breath.”

```mermaid flowchart TD accTitle: Obstacles to a Standard C++ ABI accDescr: Diagram illustrating the historical and technical barriers preventing a uniform C++ Application Binary Interface. subgraph Vendors["Vendor Competition"] MS["Microsoft"] BOR["Borland"] SYM["Symantec"] end

Vendors -->|"proprietary ABIs prevent linking"| Split["Fragmented Ecosystem"] Split --> Blockers{"Key Roadblocks to Reform"} Blockers --> R1["Out of ISO Standards Charter"] Blockers --> R2["Prioritizing backward compatibility over cross-vendor links"] Blockers --> Partial["Partial convergence via Itanium / 64-bit ABIs"] ```

---

[01:00:42](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3642s) Approaches to ABIs in Rust, D, and Go

The other panelists explain how their languages balance binary layout guarantees against compiler optimizations and foreign function interfaces (FFIs). Niko Matsakis explains that Rust adopted an opt-in model modeled on C: developers can annotate a representation with `#[repr(C)]` to obtain deterministic layout and write functions callable across C interfaces. However, Rust deliberately avoids locking down a global ABI for native code so the compiler retains room to innovate: “we've tried to reserve for ourselves the right to optimize representations beyond that... there's a little bit of a tension there between wanting to do the best optimizations you can given the target platform and everything else and and wanting to reserve the right to change that in the future when you think of something clever that you didn't think of when you wrote the spec.”

Andrei Alexandrescu reframes the problem around interoperability with the incumbent (C and C++) versus layout control within the language itself. D provides `extern (C)` and `extern (C++)` alongside namespace support and name mangling to talk directly to C++ code. Internally, D treats `struct` layout according to predictable C rules so programmers can organize cache performance without fear of arbitrary field reordering, whereas `class` types (accessed by reference) grant the compiler freedom to rearrange members, similar to C++ objects with virtual tables.

Rob Pike concludes with Go's starkly different design: Go only worries about ABI rules at the boundary when interacting with C or C++ via Cgo, which Pike calls “one of the hardest things to work on because every platform has its own rules.” Within pure Go, they deliberately ignore stable ABI specifications entirely. Because the compiler is so fast—building Go's entire standard library from source on a laptop in six seconds—Go mandates that all artifacts linked into a binary be compiled from source using the identical compiler version: “therefore it doesn't matter; whatever that compiler thinks is right is right.” The panel wraps up with gratitude to the audience and a humorous reminder that it is time to go drink beer.

- Rust provides `#[repr(C)]` for explicit C-FFI compatibility while keeping internal Rust ABI layouts unspecified to allow optimizations like niche packing. - D maintains C struct layout compatibility for deterministic memory layout while giving the compiler latitude to reorder fields inside reference `class` objects. - Go avoids an internal ABI altogether by relying on ultra-fast compilation from source (rebuilding the standard library in 6 seconds) and enforcing single-compiler-version builds.

## Notable quotes > [41:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2464s) I actually think of the type system as my first line of defense against my own sloppy thinking. — Bjarne Stroustrup

> [29:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1787s) Systems languages have this extra burden on top of everything, which is, well, you got to worry about at the same time the cathedral, the bricks, and the molecules in the bricks. — Andrei Alexandrescu

> [36:55](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2215s) The APIs in a typical Go program are half the complexity of a C++ equivalent because you don't have to talk about the memory management, and that makes the program smaller, simpler, easy to understand, and you have less to carry in your head as a result. — Rob Pike

> [12:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=724s) I think we have to distinguish sharply between type safety and security — Bjarne Stroustrup

## Mentioned Lang NEXT 2014, Bjarne Stroustrup, Rob Pike, Andrei Alexandrescu, Niko Matsakis, David Ungar, Craig Chambers, Dennis Ritchie, Gerard Holzmann, Robert Griesemer, Randy Smith, Bell Labs, AT&T, Google, Mozilla, Facebook, C++, Go, Rust, D, C, C#, Java, Smalltalk, Self, Simula, Erlang, Scala, PHP, HHVM, Plan 9, 5ESS, Mars Climate Orbiter, Alternate Reality Kit, Protocol Buffers, gofmt, go fix, Cgo, ISO C++ Standards Committee, Microsoft, Borland, Symantec, Itanium

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

中文简报

Lang.NEXT 2014座谈会:2014年及未来的系统级编程 语言设计者Bjarne Stroustrup(C++)、Rob Pike(Go)、Andrei Alexandrescu(D)以及Niko Matsakis(Rust)就2014年及以后系统级编程不断变化的定义与工程现实展开辩论。讨论探讨了安全性、性能和认知负担之间的根本博弈,评估了严格的静态类型系统、垃圾回收或所有权模型究竟何者最契合现实应用。他们还探讨了实际的架构痛点,包括运行时热补丁与缓存行优化之间的权衡、导致C++头文件编译耗时膨胀的历史包袱,以及各语言在应用程序二进制接口(ABI)上采取的不同处理方式。 语言设计者从不同视角定义系统级编程:Bjarne Stroustrup强调严苛的资源限制,Rob Pike将其等同于服务器和云端基础设施,而Andrei Alexandrescu则提出了诸如能否实现自主内存分配器以及能否将整数强转为指针等试金石标准。 (2:50) 传统C++编译缓慢主要源于基于文本的头文件包含机制以及单类对应单头文件的组织形式,而非模板本身;Google的构建指标显示这造成了百万倍的文本膨胀(每写1字节源码需解析约420万字节)。 (56:26) 超大规模生产环境的限制使得Facebook等公司无法接受动态热补丁,因为其所需的间接跳转层会破坏关键的首缓存行结构体性能,这使得进程重启与外部部署编排成为远优的方案。 (45:40) Go完全避免定义内部应用程序二进制接口(ABI),而是依赖基于源码的极速编译——在笔记本电脑上构建其标准库仅需六秒;而Rust则保留了内部布局自由,并严格在FFI边界处依赖`#[repr(C)]`。 (60:42)

Reading summary

At the Lang.NEXT 2014 panel, designers Bjarne Stroustrup (C++), Rob Pike (Go), Andrei Alexandrescu (D), and Niko Matsakis (Rust) debated the scope of systems programming, agreeing that managing hard hardware and scale constraints defines the discipline even as their languages prioritize different trade-offs in memory safety, compile times, and binary interfaces. Defining Systems Programming Beyond Device Drivers (2:50) The panel rejected narrow legacy definitions, such as restricting systems programming strictly to writing operating systems or device drivers. Niko Matsakis highlighted client-side software like web browsers, where strict latency and predictable security are paramount. In contrast, Rob Pike framed systems software as cloud infrastructure and server backends, conceding that Go's initial marketing created misplaced expectations of operating-system development. Bjarne Stroustrup argued that systems programming is characterized by hard constraints—operating under strict bounds on memory, execution time, real-time deadlines, or hardware handles rather than the application domain itself. Andrei Alexandrescu offered two concrete litmus tests: a systems language must allow developers to implement its runtime memory allocator without escaping into another language, and it must support forging arbitrary numbers into pointers to interface with physical hardware. Type Safety, Security, and System Boundaries (12:04) The panel distinguished formal language safety from end-to-end system security. Matsakis argued for establishing baseline security properties in the language—such as data-race freedom and memory safety—before leveraging type systems to express rich domain invariants, like verifying network input sanitization. Stroustrup countered that type safety should not be conflated with total security, noting that threats include physical hardware theft and operational breaches where language features offer no protection. He emphasized that while failing to hit 100% type safety is not fatal, interfaces must enforce rigorous contracts; he cited the $600 million Mars Climate Orbiter failure caused by unverified unit conversions in raw floating-point types to show the necessity of strict typing over intuitive natural language in critical systems. Managing Cognitive Overhead and Performance At Scale (27:58) Addressing concerns that modern systems languages impose exhausting mental overhead, Matsakis maintained that concepts like reference lifetimes, borrowing, and mutability reflect inherent domain complexity rather than arbitrary language bloat. Pike argued that automatic garbage collection dramatically reduces API complexity by eliminating explicit ownership signatures, noting that Go's APIs are often half as complex as C++ equivalents. Alexandrescu, however, demonstrated why hyperscale systems cannot always rely on dynamic or managed memory: Facebook tests showed a garbage-collected architecture consumed roughly three times the memory of eager, manual reclamation. Because a 0.5% server efficiency gain can translate into millions of dollars in electricity savings alone, exposing hardware realities and optimizing flat structs for the first CPU cache line remains non-negotiable for low-latency operations. Compilation Latency and Header Bloat Bottlenecks (51:19) Sluggish compilation speed emerged as a primary bottleneck across massive codebases. Stroustrup and Alexandrescu identified the textual header inclusion model inherited from Dennis Ritchie's 1972 C design as the primary cause of slow C++ builds, rather than template metaprogramming alone. Pike cited Google build telemetry showing a million-fold bloat—averaging roughly 4.2 million bytes parsed per byte of written source code due to transitive `#include` trees. While C++ pursues standardized modules to deliver estimated ten-fold compilation speedups, newer languages sidestepped this by design: Rust parses entire crates at once, while Go's ultra-fast compiler rebuilds its entire standard library from source on a laptop in six seconds. Divergent Strategies for Application Binary Interfaces (58:23) The panelists detailed contrasting architectural stances toward Application Binary Interfaces (ABIs). Stroustrup explained that C++ never standardized an ABI because the ISO committee deemed it out of charter, and competing vendors historically developed proprietary ABIs to retain market capture and customer backward compatibility. In contrast, Rust provides `#[repr(C)]` for explicit C foreign-function compatibility while intentionally leaving internal Rust representation undefined to retain room for future compiler optimizations. D applies predictable C layout rules to structs to protect cache performance while allowing member reordering in reference classes. Meanwhile, Go avoids a stable internal ABI altogether; because its compiler compiles so rapidly, Go requires that all binary dependencies be built directly from source using the identical compiler version. While each language embodies different compromises between upfront cognitive burden and downstream operational cost, the panelists demonstrated that systems programming in 2014 was moving toward deeper mechanical tooling—whether through AST-based code transformations like `go fix` or standardized compilation modules—to escape legacy design compromises without fracturing active developer ecosystems.

精炼阅读摘要

在 Lang NEXT 2014 研讨会上,Bjarne Stroustrup(C++)、Rob Pike(Go)、Andrei Alexandrescu(D)与 Niko Matsakis(Rust)探讨了现代系统编程的范式转变,指出该领域已从单纯的操作系统与驱动开发,扩展为在极端物理资源约束、内存安全、开发者认知负荷及工具自动化演化之间寻求权衡的多元工程体系。 系统编程重新界定与超大规模经济性 (2:50) 关于系统编程的定义,四位专家从不同场景切入。Stroustrup 认为系统编程本质取决于物理约束:程序是否受限于内存、执行时间或文件句柄,以及是否需要触碰硬件;Pike 坦言将 Go 称为系统语言引发了误解,其真实场景是面向云基础设施栈;Matsakis 指出 Rust 聚焦于浏览器等高安全、严苛延迟要求的客户端;Alexandrescu 则提出两项硬性指标:语言必须能以自身编写内存分配器,且允许将数值锻造为指针。Pike 对此回应称 Go 当时已接近用纯 Go 重写其内部运行时分配器。 在大规模工业部署中,底层控制直接关乎商业成本。Alexandrescu 透露 Facebook 的测试表明,垃圾回收架构所耗费的内存约为手动管理架构的三倍;在超大规模基础设施中,核心服务器效率即使仅提升 0.5%,每年节省的电力与硬件更替费用即可达数百万美元。系统语言必须暴露底层硬件的物理复杂性,正是为了换取这种极限能效。 类型安全、认知负荷与内存抽象的取舍 (12:04) 关于语言复杂度与心智负担,Matsakis 认为 Rust 的所有权与借用检查虽提高了前期认知门槛,但这种复杂度源自领域本身,显式暴露能避免 C 语言难以定位的双重释放和段错误。Stroustrup 严格区分了类型安全与整体系统安全,指出安全是涵盖物理与运行环境的系统级属性,但他仍将强类型视为防范思维疏漏的第一道防线,并举出火星气候探测者号因未对浮点数进行量纲校验导致坠毁(造成 6 亿美元损失)的教训。 与此相对,Pike 指出垃圾回收并非性能原罪,其价值在于免除了繁复的内存所有权协商,使 Go 的 API 复杂度仅为 C++ 的一半。Alexandrescu 则指出当前程序语言理论陷入局部最优:编译器极易证明琐碎属性,但在消除数组越界检查等关键能力上面临繁重的注记成本;而系统编程对零额外运行时开销的苛求,正是倒逼类型理论突破瓶颈的核心动力。 语言演进的历史债务与自动化重构 (21:39) 针对语言体积膨胀,Stroustrup 指出系统语言的复杂度主要源于向后兼容。C++ 承载着自 1972 年 Dennis Ritchie 设计 C 以来长达 40 年的历史包袱;几十年来他拒绝了超过 99% 的新特性提案,但仍无法轻易移除陈旧机制。他断言若以现代认知重构 C++ 模板,其体积仅需目前的一半,并极力倡导开发具备代码机械化重构能力的自动化工具,以替代人工更新。 Pike 介绍了 Go 团队在 Go 1.0 前化解演进断层的实践。依托 Robert Griesemer 开发的 gofmt 工具,团队打造了基于 AST 的幂等转换工具 go fix。该工具不仅让设计者在定版前能果断废除实验性语法与重构标准库,还帮助 Google 仅凭单一模块就全量自动迁移了内部广泛使用的 Protocol Buffers API。Pike 强调,只要有勇气彻底剔除旧代码,语言升级的摩擦完全能借助自动化工具平滑化解。 动态热补丁与硬件缓存行的物理冲突 (45:40) 针对系统长期运行与热修补(如电信级 5ESS 交换机远程二进制补丁历史)的需求,专家们指出动态热更新与超高性能基础设施存在物理层面的冲突。Alexandrescu 说明,动态热补丁必须引入指针或间接跳转层,这会彻底破坏 CPU 缓存行。在 Facebook 的核心底层服务中,数据结构的布局聚焦于首个缓存行,仅将结构体内的两个字段调换顺序,就可能直接引发集群性能下跌 2%,因此极端注重吞吐的系统无法承受间接层开销。 Matsakis 强调现代架构更倾向于 Erlang 式的“快速失败、快速重启”范式。现代服务器可在毫秒级启动,借助负载均衡排空节点即可无缝替换新镜像,避免了复杂的活体进程内存修改。内存中活体数据结构的语义变异极其脆弱,Stroustrup 补充道,当年电信交换机之所以能热修补,靠的是在初始部署时将数据结构和跳转表刻意过度分配,本质上是以持续的硬件冗余换取动态演化能力。 源码编译膨胀与分化的 ABI 演进路线 (56:26) 针对 C++ 编译缓慢的痛点,专家们指出瓶颈在于源自 C 语言的文本级头文件包含。Pike 援引 Google 生产数据说明,由于头文件的递归传递包含,编译器每解析 1 字节源码需处理高达 420 万字节的文本,导致文本百万倍膨胀。Stroustrup 对此表示赞同,强调这正是推进 C++ Modules 规范的核心动力,预期模块化可带来 10 倍的编译提速。Alexandrescu 补充道,这种串行批处理模型是 C 早期受制于有限物理内存所遗留的架构弊端。 在应用程序二进制接口(ABI)方面,各语言呈现分化路线。Stroustrup 解释 C++ 未统一 ABI 是由于超出当年 ISO 章程,且各大编译器厂商为生态壁垒刻意制造不兼容。Rust 选择以 #[repr(C)] 提供 C 兼容,但故意不锁定内部原生 ABI 以保留编译器优化空间;D 语言对结构体遵循 C 布局以保障缓存确定性,对类对象则允许自动重排;Go 凭借极快的编译速度(标准库仅需 6 秒构建完成),彻底摒弃原生内部 ABI,强制所有组件基于源码以统一编译器版本全量构建,根除了 ABI 锁死困扰。 研讨会展现出系统编程领域的深层共识:没有任何单一语言能统治所有软硬件约束场景。C++ 仍需在兼容包袱中推进模块化突破;Go 以开发效率与极速全量编译颠覆了传统系统工程流程;Rust 和 D 则探索在不破坏硬件缓存局部性的前提下,兼顾类型安全与细粒度控制。跨团队工程的真正焦点,已从语言语法的纯粹争论,转移至硬件缓存利用率、工具链自动化演化以及在全生命周期内平衡认知负担与执行效率的务实工程实践。

Detailed notes — zh

## Background 该视频由 YouTube 频道 25msr 于 2018 年 4 月 14 日发布,记录了 Lang.NEXT 2014 大会上题为《2014 年及未来的系统级编程》(Systems Programming in 2014 and Beyond)的圆桌讨论。视频页面未提供额外的描述文本,内容主要展现了多位系统级编程语言设计者的前沿对话。 ## TL;DR 本次圆桌汇聚了 C++ 之父 Bjarne Stroustrup、Go 联合设计者 Rob Pike、D 语言推动者 Andrei Alexandrescu 以及 Rust 核心设计者 Niko Matsakis,共同重新审视了系统级编程在现代软硬件生态下的本质定义与边界。嘉宾们深入探讨了内存分配器自举、类型系统与系统安全边界、GC 与 API 复杂度权衡,以及大规模服务在热补丁与快速重启之间的技术取舍。针对开发者长期面临的心智负担,大家不仅剖析了 C++ 头文件膨胀与各语言编译速度瓶颈的底层历史原因,还详述了各自语言在跨版本 ABI 兼容、内存布局优化与工具链自动化演进(如 go fix)中的不同哲学与实践路径。 ## Atmosphere & style 整场圆桌讨论洋溢着顶尖系统工程师与计算机科学家之间独有的默契与幽默,既有关于贝尔实验室往事的轻松打趣,也有对工程现实阵痛的深刻自省。台上的交锋敏锐而务实,嘉宾们面对 C++ 历史藤壶包袱、编译墙以及内存安全等刺手问题时毫不避讳,金句频出。观众能够真切感受到兼具学术严谨与产业实战厚重感的交流氛围,技术理想与工业级硬件约束在此激烈碰撞,令人大呼过瘾。 ## Bulletin - [03:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=220s) 系统级编程的核心标准并不局限于编写操作系统,而是由严苛的资源约束、自举内存分配器以及将任意数值转换为指针的底层控制能力所决定。 - [29:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1787s) 在超大规模基础设施中,微观内存布局直接影响能耗底线;Facebook 实测显示 GC 版本较即时回收版本多消耗两倍内存,结构体首个缓存行顺序调整甚至能导致 2% 的性能波动。 - [56:26](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3386s) C/C++ 漫长的编译瓶颈根源于多阶段预处理与头文件的文本级重复展开,Google 实测显示输入 1 字节源码会导致编译器处理吞吐约 420 万字节数据。 - [01:00:42](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3642s) 面对 ABI 兼容性难题,新一代系统语言采取分化路径:Rust 与 D 语言通过显式注解保留与 C/C++ 互操作契约并放开内部优化,Go 则凭借全源码极速构建彻底舍弃跨版本编译器 ABI 兼容包袱。 ## Key takeaways - [03:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=220s) 系统级编程的本质由资源约束(内存、时间、硬实时、句柄)定义,而非单纯用来编写操作系统或设备驱动。 - [07:22](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=442s) Andrei Alexandrescu 提出检验系统语言的两大试金石:能够用自身语言编写内存分配器,以及支持将任意数值锻造为指针以操作物理硬件与 MMIO。 - [12:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=724s) Bjarne Stroustrup 强调必须严格区分类型安全与系统安全,安全是系统级属性,不能将其简单等同于类型检查。 - [15:11](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=911s) 算力提升使得静态分析与全程序分析变得实用,能够以自动化方式证明诸如内核无死锁等复杂属性。 - [19:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1190s) 成熟语言背负着沉重的向后兼容包袱与历史“藤壶”,导致设计者无法直接删除陈旧特性,极大增加了开发者的认知负担。 - [24:59](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1499s) Go 在 1.0 发布前借助 go fix 与 gofmt 实现基于 AST 的幂等自动代码转换,为大规模平滑演进与 API 废弃提供了工业级解法。 - [27:58](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1678s) Rust 将隐式所有权与生命周期显式化提升至编译期,虽带来前期学习门槛,但从根源上降低了排查内存破坏与悬垂指针的调试成本。 - [29:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1787s) 系统级开发必须兼顾从宏观架构到微观缓存行的全尺度细节,在规模化场景中极其微小的性能差异直接影响巨额硬件与能耗成本。 - [33:03](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1983s) 火星气候探测者号因类型系统无法区分公制与英制单位而坠毁,表明在安全关键系统中强类型约束是抵御直觉缺陷与马虎思维的重要防线。 - [37:03](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2223s) 垃圾回收机制消除了接口中关于所有权归属的暴露,能使 API 复杂度大幅降低,且 GC 理念本身并不必然等于低性能。 - [45:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2740s) 动态热补丁引入的指针间接层会严重破坏硬件首个缓存行的连续布局;现代大规模系统更倾向于“快速失败、极速重启”的冷重启调度模式。 - [51:19](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3079s) C++ 漫长的编译时间主要由多重重复包含头文件的历史批处理机制引起,而非纯粹的模板类型推导,模块化(Modules)有望带来数量级的提速。 - [58:23](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3503s) C++ 始终缺乏统一的 ABI 标准,既因为这超出了标准委员会的传统职责管辖,也是各大编译器厂商历史商业壁垒竞争与保护既有用户的直接后果。 - [01:04:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3887s) Go 依托数秒级别的全量源码编译速度,强制要求同一版本编译器打包全部依赖,以“降维打击”方式完全规避了内部跨版本 ABI 的兼容包袱。 ## Detailed walkthrough ### [00:00](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=0s) 圆桌开场与嘉宾互相引荐 小组讨论主持人在开场时感谢大家到场,并介绍这场讨论的题目为《2014 年及未来的系统级编程》(Systems Programming in 2014 and Beyond)。台上的嘉宾分别代表了当今系统级编程的核心语言:C++、Rust、Go,以及 Andrei Alexandrescu 代表的 D 语言。 随后嘉宾们开始相互引荐,现场气氛轻松活跃: - Bjarne Stroustrup 首先介绍了坐在他身旁的 Rob Pike。Bjarne 回忆两人当年在贝尔实验室(Bell Labs)甚至共享过大约三个月的办公室;Rob 后来历经朗讯(Lucent)并前往西海岸加入 Google,做出许多重要成果;Bjarne 还记得 Rob 是加州理工学院(Caltech)的物理学背景出身。 - Rob Pike 随即引荐 Bjarne Stroustrup,称他是 AT&T 贝尔实验室时期 C++ 的设计者与发明者,并调侃 Bjarne 这么多年来一直在 C++ 标准委员会坚持任职。当被问及“你在这个委员会干了多少年”时,Bjarne 笑答:“太多年了(too many)。” - 接下来轮到 Andrei Alexandrescu。他风趣地表示由于自己“准备不足”,不知道该怎么引荐下一位,打趣说 Rust 是“我们打算从那里偷取大量灵感”的竞争对手。 - 随后有人帮 Andrei 做了介绍,指出他是 Andrei Alexandrescu,现任 D 语言的联合设计者兼主要推动者,在 Facebook 工作。介绍者还打趣道:“就像我这几年遇到的所有罗马尼亚人一样,他好像一年四季都穿短裤。”引得 Andrei 笑着说自己剩下的时间都得尽量把腿藏在桌子后面。 - 主持人接着补充引荐了 Mozilla 的研究员 Niko Matsakis,他是 Rust 语言的核心设计者之一。主持人强调 Rust 致力于在不牺牲性能的前提下提供类型安全和内存安全,赋予开发者硬件控制力和高抽象层级。 ### [03:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=220s) 重新审视系统级编程的定义与边界 主持人抛出核心议题:在 2014 年的今天,究竟什么是“系统级编程语言”(Systems Programming Language)?C++ 如今早已不仅用来写操作系统;D 语言和 Go 也并不是专门用来写操作系统的,但它们全都被视为系统编程语言。 各语言的核心设计者围绕这一定义展开了深入阐述: Niko Matsakis 指出,不同人对这个词的理解完全不同: - 从 Rust 最核心、甚至是最“自私”的视角来看,其初衷是构建客户端应用程序(Client-side Applications),这恰恰与 Go 的设计初衷构成了鲜明的对比。 - 客户端场景具有苛刻的延迟需求和严格的安全性约束,这些要求在服务端通常不会以同样的形式出现。 - 但 Niko 认为这几种语言的适用范围其实很宽,边缘极端用例上的差异才是区分它们本质的关键。 Bjarne Stroustrup 梳理了系统级编程的历史脉络: - 系统级编程起源于必须与硬件直接打交道的领域,后来随着应用日益复杂,它演变成处理复杂度的工具。 - 他认为判断是否是系统级编程的本质在于“资源约束”与“细粒度控制”。无论何时遭遇瓶颈,你就跨入了系统级编程的范畴。 - “It's a constraint that determines whether it's systems programming. Are you running out of memory? Are you running out of time? Are you running out of real time? Are you running out of file handles?”(Bjarne Stroustrup 强调:正是约束决定了它是不是系统级编程。你是内存耗尽了、运行时间不够了、还是硬实时响应不过来了?抑或是文件句柄用光了?) - 试图给它下一个精确刻板的定义是徒劳的,这就像去精确定义什么是“游戏”一样,边缘总是模糊的。 Rob Pike 回顾了 Go 语言在命名和定位上的曲折转变: - “When we first announced Go, we called it a systems programming language, and I slightly regret that, because a lot of people assumed that meant it was an operating systems writing language.”(Rob Pike 坦承:当我们首次对外发布 Go 时,我们称它为系统级编程语言,对此我略感后悔,因为很多人直接假定这意味着它是一种用来写操作系统的语言。) - 他表示 Go 真正的初衷是“服务端编写语言(Server writing language)”。如今由于行业术语的演进,当年的“服务器”在今天被称为“云基础设施”,因此系统级编程在现代的另一个定义其实就是“在云端运行的基础设施”。 ### [07:22](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=442s) 试金石标准:内存分配器与指针锻造 Andrei Alexandrescu 针对系统编程给出了具体的工程判断指标,提出了检验一门语言是否为系统级编程语言的“试金石”(Litmus tests): ```mermaid flowchart TD accTitle: 系统级编程语言试金石标准 accDescr: 展示 Andrei Alexandrescu 提出的系统级编程语言两大核心试金石:自举内存分配器和任意数值转指针。 subgraph Tests["试金石判断标准 (Litmus Tests)"] T1["能够用自身实现内存分配器<br/>(无需逃逸到其他语言)"] T2["支持将任意数值锻造为指针<br/>(Forge a number into a pointer)"] end subgraph Reality["底层硬件与系统现实"] HW["硬件底层寻址机制<br/>(设备寄存器 / MMIO)"] MemReuse["内存重用与类型解构<br/>(有类型指针 -> 无类型内存 -> 新类型指针)"] end T2 --> HW T1 --> MemReuse ``` - **第一条标准:自举内存分配器**。系统级编程语言必须允许开发者直接用该语言自身编写内存分配器,而不能借道或逃逸(escape)到另一种语言中去实现。 - **第二条标准:数值锻造成指针**。语言必须具备将任意数值强制转换为指针的能力(forge a number into a pointer),因为底层物理硬件和内存映射 I/O 就是这么工作的。 Andrei 进一步阐明,实现内存分配器远比表面看起来更加艰难。在高级语言看来,内存分配早已被抽象封闭,但对于系统级语言,指针最初具有某种类型,随后必须被剥离类型变成裸内存,再重新用于承载完全不同的另一种类型。这种“在生命周期中途变更指针类型”的原语操作,与高级语言推崇的静态类型系统在哲学上存在根本冲突。 听到这里,Rob Pike 笑着插话打破了严肃讨论:“It's interesting you mention that, because we're almost completed our rewrite of the Go memory allocator into Go from C, so I guess we passed that one anyway.”(有意思的是你刚好提到这点,因为我们刚几乎完成了用 Go 从 C 重写 Go 内存分配器的工作,所以我猜我们无论如何是过关了。) Bjarne Stroustrup 随后补充指出,如果在维基百科上查阅“系统级编程”,会被粗暴定义为编写最底层的设备驱动程序,这种狭隘的学术界定实际上将系统编程贬低成了边缘领域。这就好比当年 Simula 语言发明了面向对象编程与类继承体系,却被许多人轻描淡写地斥为“那只不过是一个用于系统仿真的专用语言”一样,切忌让不理解系统工作的人来定义行业术语。 ### [10:48](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=648s) 现场提问:平台与语言如何协同保障安全健壮 主持人将麦克风递交现场观众,开启问答互动环节。 一位现场观众提出了当下系统开发的核心痛点: - “I think one of the central challenges of our time is being able to write secure and robust reliable code.”(提问观众指出:我认为我们这个时代的核心挑战之一,就是能够编写出安全、健壮且可靠的代码。) - 该观众指出,高可靠与安全性无法单靠语言自身闭门造车,必须依赖底层平台与编程语言的紧密协同。他向专家们询问,系统语言领域目前出现了哪些令人兴奋的创新路径来辅助构建更安全的代码。 Niko Matsakis 率先接话回应,表示系统语言层面确实存在明确的创新方向。他指出,谈论安全与健壮首先需要划分层级:底层最基石的安全性关乎确定性的边界条件,例如无数据竞争(Data-race freedom)和绝对的内存安全(Memory safety)。有了这些由语言在编译期或运行时强制提供的底层安全防护,开发者才能在不提心吊胆的前提下,去构建上层复杂且可靠的系统。 ### [12:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=724s) 超越基础正确性:类型系统与安全性的界限 Niko Matsakis 继续探讨类型系统的发展潜力。他指出,类型系统不仅能带来更高的软件可靠性,更存在一个更高维度的健壮性:类型系统虽然无法直接保证程序正在做“正确的事”,但能确保它避开整整几大类“错误的事”。对于 Rust 的演进,Niko 期望开发者能够超越最基本的内存正确性保证,表达更强的应用不变量,从而为软件赋予更大的信心边界。比如静态类型让自动化重构、依赖查询变得简单,而同样的机制还可以扩展到特定业务语义上——例如从网络接收的污点数据(tainted data)在被消费前必须经过清理(sanitized)。 Bjarne Stroustrup 随即接续这一话题,强调必须将类型安全与系统安全彻底区分开来。他警告道,许多人把类型安全等同于安全性,但安全性本质上是一个系统级属性(system property)。如果攻击者想窃取数据,完全可能先直接偷走物理计算机,然后再慢慢破解。类型安全固然是理想目标,但因为现实中必须依赖数组边界的运行时检查、面临溢出崩溃和资源枯竭等问题,无法达到 100% 并不代表失败。 “I think we have to distinguish sharply between type safety and security.” —— Bjarne Stroustrup - Niko Matsakis 认为类型系统未来应帮助建模语义层面的特定属性,例如强制执行数据清洗(data sanitization)。 - Bjarne Stroustrup 提醒不要低估安全问题的系统性,不要将复杂的系统工程过度简化为单纯的类型安全。 --- ### [15:11](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=911s) 局部最优的困境与突破的曙光 Andrei Alexandrescu 开玩笑地表示要发表一段“最高领袖式”的前瞻预言,直言当前的编程语言社区正困在一个“局部最优”(local optimum)甚至“局部极小值”(local minimum)中。他指出,目前大家能够轻松自动证明的属性其实并不算很有趣;而真正强大的类型机制在工程落地时又极其繁琐沉重(例如消除边界检查和证明不变量)。他回忆自己在语音识别领域研究时的类似经历——社区在陷入多年停滞后,正是在他离开时迎来了爆发式突破(最终催生了类似 Siri 的成果)。他凭直觉判断,编程语言领域也正处于类似突破的前夕:未来将出现既高度有趣、能证明大量事实,又无需开发者书写海量标注的类型系统。 Rob Pike 则认为走出泥潭的道路已经显现,那就是围绕编程语言建立的静态分析与工具链质量正在发生质的飞跃。随着计算机性能的空前提升,整程序优化(whole-program optimization)和昂贵的静态分析在过去因算力限制不可行,如今已变得触手可及。Rob Pike 举了 15 年前贝尔实验室 Plan 9 内核的例子:当时在纯 C 语言环境下,Gerard Holzmann 开发了一套被称为“协议分析器”(protocol analyzer)的工具,该工具直接解析内核源码并拦截互斥锁调用,在静态代码上动态证明了内核是无死锁的(lock-free)。这种过去的技术在今天算力下具有更深远的实践意义。 “The things we can prove automatically and easily are not super interesting... and the kinds of types that we know how to do are practically very hard to do.” —— Andrei Alexandrescu “The computers are big enough and fast enough now that we can afford to do calculations that would have been prohibitive a generation ago because they would have taken too long.” —— Rob Pike - Andrei Alexandrescu 强调系统级编程语言向 PL 学术研究界施加了巨大的向上现实拉力:在极致性能的领域里,既要追求极致速度,又必须兼顾安全。 - Bjarne Stroustrup 赞同 Rob Pike 关于静态分析的看法,反驳了“静态类型只能捕获琐碎错误”的论调,指出那只是因为批评者使用的是琐碎平庸的类型系统。 --- ### [19:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1190s) 认知负担的争议与 C++ 的历史包袱 观众席的 Dave 抛出了一个直击痛点的问题:随着编译器塞入越来越多的静态分析,开发者的认知负担(mental overhead)是否反而急剧上升?在 Rust 中,程序员必须时刻在脑海中追踪借用检查器(所有权、共享引用、可变与不可变);在 C++ 中也有海量的隐式规则需要大脑维持上下文。Dave 认为即使 Go 试图极简设计,现代系统语言似乎依然强迫程序员在脑海里时刻构建一幅复杂的抽象图景,充斥着“左脑式”的沉重思考。 Bjarne Stroustrup 当仁不让地接过这一话题。他坦承语言之所以如此庞大复杂,是因为它们背负着沉重的历史资产。简化一门成熟语言几乎是不可能的——用户嘴上说着希望语言简单,身体却总在不断索求新特性。虽然他拒绝了超过 99% 的特性提案,但承载着自 1972 年 C 语言以来 40 多年包袱的 C++ 显然体量过于庞大。许多历史特性本不该存在,或早已被新机制淘汰,但出于“绝对不能破坏用户现有代码”的底线,旧特性只能永远保留。Bjarne 表达了对“代码转换”(code transformation)与“代码年轻化”(code rejuvenation)自动化工具的强烈渴望。他坦率表示,如果今天重新设计模板(templates),体积只需现在的一半;但这并非责怪 Dennis Ritchie 或过去的自己,而是历史发展的必经规律。 “The users always want a simpler language with a few extra features.” —— Bjarne Stroustrup “Whatever else we do to our languages, the users do not want their code to change.” —— Bjarne Stroustrup - Bjarne Stroustrup 举例当年 Java 阵营在推介新语言时,直接翻开 C++ 的《带注释的 C++ 参考手册》(The Annotated C++ Reference Manual,ARM),撕掉三分之二的篇幅并宣称“这些我们统统不要,基于第一性原理并保留 C 语法,这就得到了优美的 Java”。 - 他指出新兴语言在初期看似纯洁无瑕,但随着时间推移和现实需求的叠加,所有成功的语言都必须直面历史兼容性带来的复杂性膨胀。 ```mermaid flowchart TD accTitle: 语言演进中的复杂性积累机制 accDescr: 展示现实用户需求与向后兼容性如何导致编程语言体量不可逆膨胀的循环图 subgraph Design["设计与演进"] A["初始设计或语言新特性"] --> B["用户采纳并积累海量存量代码"] B --> C["新需求涌现:渴望更强语义与便利"] end subgraph Tension["现实约束冲突"] C --> D["99% 的新增提案被否决"] C --> E["必需功能吸纳引入(代码库膨胀)"] E --> F["早期不完善设计被淘汰/废弃"] F --> G{"能否直接移除废弃特性?"} end subgraph Result["后果"] G -- "绝不!用户代码严禁被破坏" --> H["旧特性永久保留,历史包袱加重"] H --> I["开发者认知负荷剧增,依赖静态重构工具"] I --> B end ``` ### [24:18](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1458s) 语言老化、藤壶附着与代码转换工具的希望 本段讨论从主流编程语言随时间推移而不断膨胀的痛点切入。台上讲者指出,几乎所有长期存活的语言都会随着年岁增长而附着大量“藤壶”(barnacles)——即那些为了保持向后兼容而无法剔除的历史包袱与冗余特性。至今几乎没有彻底根治这个问题的银弹,唯一不面临这种困境的语言往往是那些早早夭折、未能存活下来的小众语言。以 Java 和 C# 为例,它们在漫长的演进历程中规模翻了两倍甚至三倍,其规范文档的体量如今已经膨胀到堪比 C++ 的庞大规模。面对这种语言复杂度不断堆叠的困境,讲者寄希望于“代码自动转换”(code transformation)能够成为打破这一僵局的有效武器。 - Java 与 C# 的规范体积已经翻了两到三倍,复杂程度直逼 C++。 - 历史沉淀下来的语法包袱如同船体上附着的藤壶,缺乏安全清理机制会导致语言不可逆地臃肿。 --- ### [24:59](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1499s) Go 语言的清洗实践:go fix、gofmt 与协议缓冲区升级 Rob Pike 接过话题,介绍了 Go 语言在迈向 1.0 版本里程碑时,如何借助工具链进行剧烈的语法清理。在 Go 1.0 锁定之前,开发团队明确希望精简语言、删减冗余特性、修复库接口并剔除某些不合理的关键字,但他们面临的巨大难题是:如何在不破坏已有用户代码的前提下大刀阔斧地重构?Go 团队给出的解决方案是编写一款名为 `go fix` 的自动化迁移工具。`go fix` 能够同时解析新旧语法结构,读取旧代码并构建抽象语法树(AST),利用针对特定语法的重写模块修复 AST,最后重新写出符合新格式的代码。由于这些模块具有幂等性,重复执行不会产生副作用,团队因此能向社区承诺只需运行一次 `go fix` 即可平滑升级。 ```mermaid flowchart LR accTitle: go fix 重构工作流 accDescr: 展示旧代码经由语法解析、AST修正并配合 gofmt 重新排版的处理过程 subgraph Parse["解析阶段"] A["旧版源码"] --> B["语法解析器"] B --> C["抽象语法树 (AST)"] end subgraph Transform["转换阶段"] C --> D["go fix 规则模块<br/>(幂等转换)"] D --> E["修正后的 AST"] end subgraph Output["输出阶段"] E --> F["gofmt 格式化排版"] F --> G["标准化新源码"] end ``` Rob Pike 强调,这一流程之所以能顺利运转,关键在于 Robert Griesemer 开发的 `gofmt` 库,它能将 AST 直接打印成规范、清晰的标准排版代码。“有人甚至说这是 Go 语言最棒的特性,他们可能说得没错;但关键在于,这让我们能够重写你的程序,并将其重新输出为理应呈现的整洁面貌。” 这种自动重构的能力极大地解放了设计者,使他们能够在 1.0 发布前对语言的每一个细节反复斟酌打磨。不仅如此,后续 Google 决定重构 Protocol Buffers 的 Go API 时,同样编写了一个 `go fix` 模块,仅用一条命令就全局替换并废弃了全公司庞大代码库中被频繁调用的旧 API。Rob Pike 对 Bjarne Stroustrup 关于自动化的看法表示赞同:“只要你敢于彻底清理、坚持立场并真正下决心丢掉旧包袱,许多此类工作实际上完全是可以自动化的。” - Go 1.0 正式发布前利用 `go fix` 大规模删减与修正不合理的语法、库及关键字。 - `gofmt` 确保了 AST 逆向输出的代码符合统一规范,避免了自动代码迁移带来的排版混乱。 - 自动化迁移曾一举完成 Google 内部全量 Go 代码中 Protocol Buffers 接口的升级。 --- ### [27:58](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1678s) 类型的显式约束:Rust 的学习门槛与领域本质复杂度 Niko Matsakis 将话题拉回观众的核心困惑:现代系统级语言(尤其是引入所有权与借用等丰富类型系统后)是否给程序员施加了过重的心智负担?Niko 承认,Rust 确实强制开发者在一开始就必须掌握所有权、借用以及各类资源管理模式,这确实带来了不小的前期认知开销;然而,在诸如 Java 或 C# 这类表面上仅使用普通引用的语言中,所有权和借用模型同样客观存在于业务逻辑中,只是它们变成了隐式规则,缺乏编译器的强制校验,极易被疏忽遗忘。 针对学习曲线,Niko 分享道,许多以前因害怕内存错误而不敢触碰 C 语言、或是没时间系统学习的系统编程初学者,在接触 Rust 后反而觉得更为顺手。因为 Rust 像导轨一样明确引导他们采用正确的资源管理模式(例如“单一所有者”法则),而在 C 语言中,这类法则往往必须通过经历惨痛的二次释放(double-free)和内存泄漏 bug 才能被动领悟。针对复杂度究竟归咎于语言还是领域的争论,Niko 给出了鲜明的断言:“我认为绝大部分复杂度本质上来源于问题领域本身,而在语言层面上将其显式暴露出来绝非错误。” - 隐式内存管理并没有消除所有权与资源借用的客观需求,反而容易引发隐蔽的生命周期漏洞。 - Rust 的编译期严格约束将隐式的心智推理转化为明确的规则,帮助初学者避免了 C 风格的内存调试泥潭。 --- ### [29:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1787s) 极致性能与资源边界:系统编程面对的物理现实 Andrei Alexandrescu 首先借用一段学术渊源打破严肃气氛,笑称提问者 Dave Ungar 是自己的“学术祖父”(因为 Craig Chambers 曾是他的硕士导师),并幽默地提到自己刚才一直在琢磨初次打招呼该说些什么才显得有趣。随后他切入正题,对比了 Smalltalk 和 Self 这类纯粹流动的动态语言与底层系统语言的根本差异。在 Andrei 看来,系统级编程语言背负着独特的重担:“你必须在同一时刻操心整座大教堂、砌墙的砖块,以及砖块内部的微观分子,这就是系统编程的冷酷现实。” 无论如何进行抽象分层或制造预制件,到底层终究无法逃避对全尺度细节的把控。 针对垃圾回收(GC)看似带来的开发便利,Andrei 用 Facebook 的实测数据予以现实层面的警示:在处理完全相同的服务器负载时,GC 版本的程序内存消耗足足是即时回收版本的 3 倍。在超大规模的数据中心运营中,系统级组件哪怕只有 1% 的能耗或效率波动,乘上数以万计的服务器基数,每年直接对应的就是数百万美元的电费账单,还不算由此带来的硬盘与内存损耗更换成本。这类细微的性能优化在学术研究中或许微不足道,但在产业界中哪怕仅仅带来 0.5% 的效率提升,背后都意味着巨大的经济回报。 - 系统级程序员心智模型必须同时覆盖从宏观架构(大教堂)到微观内存布局(分子)的全尺度范围。 - Facebook 内部对比表明垃圾回收版本比即时析构版本额外消耗多达两倍的内存资源。 - 基础设施核心组件极细微的性能提升(如 0.5% 到 1%),在超大规模数据中心可转化为每年数百万美元的能耗节约。 --- ### [33:03](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1983s) 自然语言的模糊性与强类型系统的安全屏障 Bjarne Stroustrup 赞同了 Andrei 和 Niko 的观点,并进一步反驳了“编程应该像用英语写作一样简单自然”的论调。Bjarne 尖锐地指出,自然语言是极其模糊且缺乏精确性的,在现实生活中,他经常尴尬地发现自己明明用英语讲得一清二楚,听众所理解的却完全是另一码事。将这种直觉式的自然表达方式带入系统编程是极其危险的。 为了论证严格规范的重要性,Bjarne 强调了强类型与接口约束在跨团队协作中的决定性作用,并引用了火星气候探测者号(Mars Climate Orbiter)坠毁的历史教训。该事故的程序代码本身没有语法错误,类型系统也正常运转,然而由于其类型系统过于简陋——仅仅将所有数值抽象为一个基础的 `double` 浮点数,完全无法区分公制单位(MKS)与英制单位(Imperial),最终直接导致价值 6 亿美元的航天探测器彻底损毁。Bjarne 严肃地指出:“对于我最常思考、也最为关切的应用领域——例如汽车的制动控制系统——我宁愿看到一切建立在严谨的技术精度之上,而不是寄托于虚无缥缈的直觉。” - 自然语言的语义歧义性使其无法胜任高可靠性工程规范的精确描述任务。 - 火星气候探测者号因类型系统无法区分公制与英制单位而坠毁,造成了 6 亿美元的惨痛损失。 - 在涉及汽车制动系统等攸关生命安全的关键场景下,编译期的严格技术规约远比直觉式书写更值得信赖。 ### [35:02](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2102s) 认知负担与快速原型构建 提问观众回顾了早前关于软件可靠性与成本的探讨。他提到,虽然像车载刹车系统这种软件必须通过极其详尽的测试、故障注入等手段确保万无一失,但绝大多数日常开发所面临的挑战完全不同。他注意到 Google 已经在 Go 语言中采用了自动内存回收机制。对他个人而言,编程中最常见的痛苦体验在于:大脑中经常诞生一个绝妙的构思,但在大多数系统级语言中实现它时,被迫在脑海里背负极其沉重的底层细节认知负担,导致最核心的闪光想法难以维持。 这位提问者引用了 Randy Smith 关于 Alternate Reality Kit 的名言:“如果当年不是用 Smalltalk 来写,他可能连前三行代码都写不出来。”虽然构建一个需要送往火星的航天级软件需要所有形式的验证手段,但在日常探索中,开发者迫切希望能够先快速构建出运行速度尚可的原型并验证其可行性,后续再加入额外的安全性考量,而不必因为底层的繁重细节推倒重来。 - 提问者指出在多数编程语言中实现概念时,开发者被迫承担过重的思维负担,极难维系最初的创意灵感。 - Randy Smith 曾感慨开发 Alternate Reality Kit 时,若非借助 Smalltalk 的动态表现力,项目根本无法起步。 - 提问的核心诉求在于兼顾快速原型实验与足够的运行效率,避免在概念验证期陷入严苛的类型与内存约束。 --- ### [37:03](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2223s) 垃圾回收的本质与 API 复杂度 针对提问者对自动内存回收的讨论,Rob Pike 进行了反驳与澄清。Rob Pike 首先澄清,Google 内部并非所有项目都适合用 Go 语言编写,许多底层核心基础设施因 GC 延迟等问题,依然必须依赖类似 C++ 那样对底层硬件行为提供精确控制的语言。然而,系统编程界往往对垃圾回收(GC)抱有两种误解:第一,GC 虽非万灵丹,但它是解决极大多数常见开发痛点的利器;第二,GC 在本质上并不是低性能的代名词。 Rob Pike 强调,人们对 GC 的抱怨往往局限于某种特定的 GC 实现风格,而非 GC 理念本身。合理的 GC 设计并不一定会恶化性能或无限增大内存空间。更重要的是,引入自动内存回收能让程序接口设计实现质的飞跃。Rob Pike 直言:“在典型的 Go 程序中,API 的复杂度往往只有等价 C++ 代码的一半,因为你完全不必去纠结内存管理与所有权归属。”这种心智负担的减轻,让程序变得短小精悍且易于维护。 ```mermaid flowchart TD accTitle: 内存管理机制对 API 复杂度的影响 accDescr: 对比显式内存所有权与垃圾回收在接口设计与心智负担上的差异 subgraph CXX["显式所有权机制 (如 C++)"] direction TB A["API 接口定义"] --> B["显式暴露对象所有权"] B --> C["调用方追踪生命周期"] C --> D["认知负担高、接口复杂度倍增"] end subgraph GO["自动垃圾回收 (如 Go)"] direction TB E["API 接口定义"] --> F["隐藏内存释放与归属"] F --> G["运行时自动追踪生命周期"] G --> H["接口简洁、专注核心业务逻辑"] end ``` - Rob Pike 澄清 Google 并非所有软件都使用 Go,核心基础设施仍需低延迟、细粒度的底层控制。 - 人们对 GC 的抨击常将某种实现缺陷等同于算法本身,好的 GC 实现并不必然牺牲系统性能。 - 消除“谁拥有这块内存”的追踪逻辑后,Go 语言 API 的心智负担与复杂度明显低于传统 C++。 --- ### [39:17](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2357s) 极致效率与开发便利性的权衡 Niko Matsakis 回应了关于语言效率与便利性的探讨。他提及早先 Bjarne Stroustrup 破除的一个常见迷思:开发者其实并不是所有时候都需要极致的运行效率,大家往往只是在特定场景下才需要这种效率。Rust 的核心定位是在保障完全安全的前提下,提供登峰造极的代码运行效率。然而,语言设计不应走向极端,Niko 提出一个看似反直觉的目标:“我也希望看到我们能把‘低效代码’写得极其顺畅,让开发者能够非常舒服地写出便利性优先的代码。” 在原型设计或非性能敏感阶段,开发者本就不应过度关心数据是否被多复制了两三次,或者内存由谁在何时释放。Niko 透露 Rust 团队当时正在探索可选的垃圾回收机制(Optional GC),允许用户在所有权策略中自主选择垃圾回收模式。尽管将非垃圾回收机制与垃圾回收机制融为一体存在极高的技术难度,但 Niko 认为理想的系统语言应该既能轻松写出偏向生产力的代码,又能随时根据需要渐进式调优,提供完整的控制工具链。 - Niko Matsakis 赞同 Bjarne Stroustrup 的观点:人们并非时刻追求极致效率,便利性同样不可忽视。 - Rust 追求在编写高安全性与高效率代码上保持领先,但也力求降低低效便利代码的编写门槛。 - Rust 正在研究可选的垃圾回收(Optional GC)机制,以满足混合 ownership 场景下的多元内存管理需求。 --- ### [41:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2464s) 静态类型作为抵御松散思维的防线 Bjarne Stroustrup 对提问者“希望不受类型约束先写出想法”的观点提出了截然相反的见解。Bjarne 坦言,对他而言,用严格的类型系统来表达接口恰恰是他思考问题的核心工具。许多自以为精妙绝伦的想法,一旦放入真实代码或严格的形式化框架下审视,就会暴露出结构性缺陷。静态类型系统能在第一时间拦截并暴露这些错误,成为开发者抵御自身“马虎思维(sloppy thinking)”的第一道防线。 针对动态类型与静态类型阵营的长期争论,现场引发出一阵笑声。Bjarne Stroustrup 当场抛出了一个尖锐的观察:“去年我突然顿悟了一件事:动态语言阵营之所以如此狂热地推崇单元测试(Unit Testing),正是因为他们缺乏静态类型系统。”这番言论立刻引来了台下与台上嘉宾的会心一笑与激烈反应。 > “I actually think of the type system as my first line of defense against my own sloppy thinking.” —— Bjarne Stroustrup > “I had a bit of an epiphany last year when I realized that the reason that unit testing was being driven by the dynamic language people was that they had that instead of static typing.” —— Bjarne Stroustrup --- ### [42:41](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2561s) 变化成本与二进制热补丁的历史难题 随后现场进入问答环节。一位参会观众提出了关于“变更成本”与二进制版本控制(Application Binary Versioning)的严肃问题。他指出,软件工程的成本很大程度上直接等同于支撑系统演进变更的成本。许多语言依赖抽象接口解决适配问题,但在底层 ABI(应用二进制接口)层面,对象内存布局的固化(如 C++ 隐式的 `this` 指针排布)导致任何底层库的细微改动都会破坏下游依赖,引发连锁崩溃。他质问:为什么现代语言社区缺乏针对“大规模编程(Programming in the Large)”与“发布后无痛变更”的原生语言机制? Rob Pike 顺着这一话题分享了他在 AT&T 时期的见闻。当时贝尔实验室的一大营收支柱是 5ESS程控电话交换机。这些交换机由具备极高冗余度的硬件驱动,为用户提供拨号音与号码路由服务。在全球部署的成千上万台 5ESS 交换机中,几乎没有两台的底层软件二进制是完全一致的,因为各地都在频繁下发差异化的补丁(例如法国部署的版本绝不会打上西班牙语拨号方案的补丁)。令人震惊的是,在 1980 年代,贝尔实验室的工程师竟然能在交换机持续不间断运行的同时,通过远程机制在二进制层面对系统进行持续的热补丁(Monkey Patching)。Rob Pike 感慨至今仍难以想象当时他们是如何确保电话网络在持续热修补过程中从不中断的。Bjarne Stroustrup 对此表示,虽然语言学界有一大批人长期研究软件动态演进,但他的核心精力始终聚焦在保障通信交换机与刹车系统等高可靠系统不发生故障。 - 提问者指出 C++ 等语言因内存布局与 ABI 过于固定,导致发布后代码更新极易破坏下游客户端。 - Rob Pike 回忆 1980 年代 AT&T 5ESS 交换机能够在不中断服务的情况下实现远程二进制动态热补丁。 - Bjarne Stroustrup 认为动态变更是一套庞大的技术体系,但他个人的侧重点始终在于保障安全底线和零容错任务。 ### [045:40] 动态更新与系统级性能的取舍:首行缓存即底线 Bjarne Stroustrup 首先澄清了自己的研究范畴:他的目标是保证火星探测器、Web 服务器等关键系统的可靠与高效。世上没有一种语言能够满足所有人和所有场景,诸如从 Lisp 和 Smalltalk 发展而来的高度动态、极具灵活性的语言流派从未过时,也有着强大的生命力,但这并非他在系统级编程中所讨论的重点。 紧接着,Andrei Alexandrescu 从 Facebook 的生产实践切入,解释了为何大规模系统极难接纳热补丁(hot patching)。在 Facebook,整个网站每周要发布全量代码约两次。面对海量机器、极其庞杂的依赖库交互,团队并没有采用动态热打补丁,而是借助成熟的下线系统与 BitTorrent 分发方式,平滑终止旧可执行文件、拉起新进程并逐步预热。Andrei 指出,他在 Facebook 核心 PHP 编译器团队工作了数月,编译器代码生成器的微小性能波动都会直接击穿公司的利润底线(bottom line)。热补丁本质上是通过增加间接层(indirection)实现的——原本扁平的数组被迫变成链表、树或多级间接指针,这对底层性能是致命的。 ```mermaid flowchart TD accTitle: Hot Patching Indirection vs Hardware Cache Line accDescr: 示意热补丁引入的指针间接层与底层硬件缓存行之间的冲突关系。 subgraph MemoryModel["内存布局模型"] FlatStruct["扁平连续结构体 (Struct)"] CacheLine["首个 64 字节缓存行 (Hot Cache Line)"] Indirection["多级指针与间接跳转表 (Indirection)"] end FlatStruct --> CacheLine Indirection -.->|"破坏连续布局"| CacheLine CacheLine -->|"字段乱序损耗 2% / 击穿缓存即致死"| Performance["硬件级吞吐底线"] ``` Andrei 强调,在硬件层面,连续内存(扁平数组或异构的 struct)是不可动摇的基石,而核心中的核心是结构体的第一个缓存行(first cache line)。如果仅仅调整结构体中两个字段的顺序,性能就可能当场暴跌 2%。当有人提议为了热更新而塞入指针间接层时,他当场回绝:“And you come I mean if you come and say oh we need hot patching and I'm like oh that's gonna totally ruin my first line of cache right there and I'm gonna die, right?” 对此他直言,这类方案对追求极致吞吐的系统而言根本不可行。 - Facebook 每周发布全站代码约两次,依赖 BitTorrent 传输与自动化进程启停机制进行平滑轮转。 - 结构体首个缓存行的数据排布对执行效率至关重要,仅仅调换两个字段位置便可能引发高达 2% 的整体性能损耗。 - 热补丁普遍依赖指针间接寻址,强行打破扁平连续内存,直接摧毁硬件缓存局部性。 ### [049:01] 快速崩溃重启哲学与动态打补丁的语义困境 Niko Matsakis 与其他嘉宾赞同了 Andrei 的观点,并进一步指出系统架构应当借鉴 Erlang 的核心设计范式:与其费尽心机在运行时动态修改正在跑的代码,不如贯彻“快速失败、极速重启”(fail quickly and restart fast)。现代硬件可以在数毫秒内拉起一个新服务器实例,结合增量摘除节点与流量调度,服务完全可以做到对外部无感知,根本不需要冒险进行运行期热替换。 讨论进一步深入到语义一致性难题。给运行中的程序动态加载新代码本身就需要虚函数表(vtable)等开销,而迁移已经存活的在内存数据(live data)更是难上加难。如果业务升级不仅改了逻辑,还变更了数据结构布局或数据语义——例如字段原先是两个整数表示的直角坐标,新版本改成了极坐标——自动化转换几乎是不可能完成的任务。对于大多数系统而言,理性的做法是在系统边界划清“持久化数据”与“非持久化瞬态数据”,依托现有的持久化与容灾机制进行故障隔离与冷重启。 最后,Bjarne Stroustrup 补充了传统高可用电信系统(如程控交换机)实现动态补丁的老道技巧:这些系统在出厂部署时,故意将数据结构和跳转表(jump table)预留得“稍微偏大”(slightly too big)。当需要紧急打补丁时,系统总是拥有备用插槽来切换到新逻辑,而不是仅按当前所需严丝合缝地分配空间。 - Erlang 模式倡导将机器快速摘流、崩溃重启并在几毫秒内载入新版本,在工程上远比实现复杂的运行时热替换更简洁稳健。 - 动态热补丁面临巨大的数据语义变迁障碍,旧数据难以在内存中无损就地转译为新结构。 - 经典电信高可用设备通常按“大两个规格”的尺寸预分配跳转表与结构体,留出冗余槽位供紧急补丁接管。 ### [051:19] C++ 头文件膨胀与各语言的编译耗时困局 现场提问环节,一位工程师提出了他在 C++ 实践中最痛苦的瓶颈:由于类型系统承载了大量静态分析、实体数量剧增,导致编译时间和链接时间极度漫长。他向台上提问:这是 C++ 独有的绝症,还是其他现代系统级语言(如 Rust、D)也无法幸免?如果其他语言没有,原因何在?C++ 的未来又将如何破局? Bjarne Stroustrup 直言 C++ 的编译时间确实是个大麻烦,但并非独此一家,“it's a major problem but C++ certainly not the only one and if you want really interesting, try Scala.”。不过他纠正了提问者的假设:除非深陷极其晦涩怪异的模板元编程(weird template metaprogramming),否则类型系统的模板实例化并非真正的罪魁祸首。根本原因在于 C 语言历史遗留下来的机制——同一个头文件在数以千计的编译单元中被机械地反复重编译成百上千次。Bjarne 透露,C++ 标准委员会已经意识到了这个失控的问题,他即将在三周后的委员会会议上投入大量精力推动解决方案(即 C++ Modules)。尽管标准委员会行动迟缓、往往做不出最简洁直接的方案,但他断言完全有希望把 C++ 编译速度提升 10 倍。 Niko Matsakis 随后谈到了 Rust 的现状。他坦言 Rust 编译器目前绝对谈不上飞快,但团队之前将精力全部放在了语言特性的完善与正确性上,“we also have spent zero time optimizing it, so it's hard to say”。不过,Rust 从架构上规避了 C++ 的头文件重解析陷阱,因为它按 crate(代码树整体)一次性解析整个编译单元,彻底杜绝了重复解析头文件。Niko 还提到,Mozilla 在构建庞大的 C++ 工程时,为了绕开这个痛点,干脆写脚本把大量 C++ 源文件暴力拼接(concatenate)成一个巨大的文件一起编译,速度因此大幅提升。针对外界对 Rust 编译慢的抱怨,Niko 幽默地解释了幕后的真实原因:当用户运行 `make` 构建 Rust 时,系统实际上是在用现有的编译器编译一套新的编译器,接着用新生成的编译器再自举编译一遍自身,最后还要把所有标准库完整编译一遍,相当于整整构建了三遍。 - Bjarne 指出 C++ 编译缓慢的核心元凶是头文件被重复包含与反复解析数百次,而非单纯的模板类型推导过载。 - 解决头文件重复开销后,C++ 理论上有潜力实现 10 倍以上的编译速度跃升。 - Mozilla 采取将多个 C++ 源文件拼接合并为单一大文件(Unity Build)的极端手段来对抗重复头文件解析。 - Rust 编译器从设计上采用按 crate 整体代码树解析,先天免疫了 C/C++ 的多重头文件解析问题;当前构建耗时较长主要由于自举构建机制(连续编译三轮自身及标准库)且初期尚未做专门优化。 ### [054:17] 批处理历史包袱与批处理语言的固有缺陷 Andrei Alexandrescu 随后登场,对 C/C++ 编译慢的问题进行了更为尖锐的底层剖析。他指出这是 C 语言骨子里固有的基因缺陷,并被 C++ 的模板机制成倍放大。C 语言诞生的年代内存极度匮乏,编译器根本无法一次性将源码载入内存,因此被设计成高度依赖批处理、多阶段管道(batch multistage processing)的系统。 为了证明这一历史包袱,Andrei 询问台下是否有人知道 C 语言行尾反斜杠折行(backslash line continuation)的真正由来。当年由于内存极其有限,编译器第一遍只能跑一个极其简陋的预处理器专门剔除反斜杠,接着再跑一遍处理二合字母(digraphs)和三合字母(trigraphs),最后才进入真正的解析阶段。这种机制导致 C/C++ 形成了彻底的强串行语义:代码中每一个 Token 的含义,几乎完全取决于它前面出现的所有上下文。这种严格的词法与语法依赖,从根本上锁死了现代编译器的并行化改造。 Andrei 动情地回顾道,像 Google、Facebook、Amazon 这类高流量巨头公司,面对数以千万行计的超庞大代码库,全都深陷这一泥潭。这些公司砸下庞大的计算集群,调遣业内最顶尖、最资深的工程师组团去“伺候”那套极其脆弱复杂的构建系统(baby-sit the build system),穷尽了一切工程智慧与奇技淫巧,最终发现这依然是一个无解的死局:“We've been throwing at it like all intelligence and all kind of smarts we could, and at the end of the day it was an unsolvable problem. It just takes so long to take from the source code to to the binaries.” Andrei 回忆称,正是由于在 Facebook 感受到了彻底的智力穷尽与绝望,当同事建议他去尝试 D 语言时,他花六个月深入接触,惊奇地发现 D 语言的代码解析速度极快,展现出了截然不同的现代编译架构潜力。 - C 语言受限于早期的内存容量限制,采用了多道流式批处理设计,使得 Token 的解析极度依赖前置上下文,阻碍了并行化。 - 反斜杠折行及三合字母是多阶段预处理历史遗物的典型代表。 - 顶级科技巨头在 C++ 构建流水线上投入了极其昂贵的人力与算力资源,但仍受制于串行解析本质,难以彻底解决编译墙问题。 ### [56:26](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3386s) 编译速度之痛与头文件包含爆炸 讨论首先聚焦于 C++ 饱受诟病的编译速度,以及新兴语言如何借此打动开发者。一位讲者指出,很多工程师在注意到另一门新兴语言时,最先震撼他们的是其编译解析速度之快:“无论给 C++ 砸多少钱,都根本换不来那样的编译速度;没有任何一笔钱能雇人让 C++ 代码编译得像它那么快(speeds of compilation that cannot be obtained at any with any money for C++ there's no amount of money that would pay you that you could pay someone to compile code as fast as he does)。”这种压倒性的构建速度优势成了杀手锏,促使团队抱着“试试看会发生什么”的心态去尝试新语言。 随后,Rob Pike 提到了他在 SPLASH 会议演讲中引用的具体数据。Google 曾对其超大型 C++ 代码库的编译膨胀进行过实测:虽然具体数值他记不太清,但大致是“输入给编译器的每 1 个字节源码,编译器实际要吞吐约 420 万字节的数据”。这种编译器处理文本量高达数百万倍的惊人膨胀,罪魁祸首正是 C++ 的头文件包含机制(Header Inclusion)。Rob Pike 认为,这甚至不能全怪模板元编程,而是从“每个类单独放一个头文件”的编程范式起就种下了祸根。他寄希望于 Modules(模块化)草案能真正解决这个顽疾,彻底改变 C++ 的编译速度。 作为 C++ 之父的 Bjarne Stroustrup 拿回麦克风,毫不回避地承认了这一事实。他坦承这确实是一个不断恶化且必须正视的重大问题:“我拿回麦克风主要是想说,我完全不否认这一点,这是个大问题,而且是个日益严重的问题,必须得到解决;我并不是盲目乐观,但我认为它最终很可能会被解决(this is a major problem it's a growing problem it needs to be dealt with and I am NOT sort of totally rah-rah optimistic but I think it'll probably be solved)。” ```mermaid flowchart LR accTitle: C++ 头文件膨胀机制与模块化愿景 accDescr: 对比传统包含模式下数百万倍代码膨胀与引入 Modules 后的编译简化途径。 subgraph HeaderModel["传统 C++ 头文件模式"] Src["1 字节输入源码"] --> Inc["#include 级联展开\n(单类单头文件范式)"] Inc --> Blowup["编译器解析吞吐:\n约 420 万字节 (百万倍膨胀)"] end subgraph ModuleVision["现代语言 / Modules 机制"] ModSrc["模块化源码定义"] --> Direct["直接导出元数据/预编译接口"] Direct --> Fast["数秒内完成极速构建"] end ``` - 编译膨胀倍率:Google 大型构建测试中,编译器吞吐的数据量相比实际输入的原始源码产生了约 420 万倍的膨胀。 - 根源分析:讲者们指出这主要是 C++ 将每个类分散在独立头文件并在预处理阶段文本展开导致的固有设计缺陷。 --- ### [58:23](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3503s) C++ 为何始终没有统一的 ABI 标准 现场观众提问转向了系统级编程中极其敏感的 ABI(应用程序二进制接口)议题。提问者表示自己主要也是 C++ 开发者,想请教 Bjarne Stroustrup 为何在语言规范中始终不包含 ABI,如今是否对此感到后悔;同时也想了解其他新语言的设计者在开发时,如何在可移植性限制与机器效率之间权衡二进制接口的规范。 Bjarne Stroustrup 明确表示,如果 C++ 当年能有统一定义的 ABI 当然非常好,但这从未实现,原因主要有两点: 1. **标准委员会的职责范围界定**:ABI 在历史上被认为超出了标准委员会的管辖范围。C 语言虽然也没有在标准中规范 ABI,但 C 非常幸运——每个平台上都有事实上的所有者(如操作系统厂商)来确立唯一的平台 ABI 标准,其他工具链只需遵循即可。 2. **商业竞争与历史包袱**:在 C++ 兴起的年代,微软(Microsoft)、Borland、Symantec 等各大编译器厂商都认为自己能够一统 C++ 平台。为了建立生态壁垒,厂商们各自精心设计了互不兼容的 ABI,“精心确保你绝不可能链接到敌方编译器的代码(carefully making sure you couldn't link to the enemies code)”。 Bjarne 总结道,每当委员会尝试解决 ABI 统一问题时,都会撞上两堵墙:“第一,它不被视为标准委员会章程的一部分;第二,相比于打破现有代码去跟别人兼容,大家永远更热衷于兼容自己的现有用户(people have always been more keen on being compatible with their existing users than to break all their code to be compatible everybody else)。”尽管 64 位平台上的 Itanium C++ ABI 带来了一定程度的收敛希望,但他对各方彻底握手言和并不抱太大幻想。 --- ### [01:00:42](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3642s) Rust 与 D 语言在内存布局与外部互操作中的取舍 针对提问,Niko Matsakis 与 Andrei Alexandrescu 分别阐述了 Rust 和 D 语言在 ABI 与类型布局上的哲学。 Niko Matsakis 介绍了 Rust 采用的双轨制折中方案: - **与 C 互操作的显式契约**:Rust 允许开发者显式选择采用标准的 C 语言表示(例如使用 `#[repr(C)]` 注解或将函数标记为供 C 调用的 `extern` 格式)。这为 FFI(外部函数接口)提供了确定且可靠的二进制布局。 - **保留内部激进优化的自由**:在 Rust 内部类型的默认表示中,语言规范故意不对布局做一成不变的死板承诺。编译器保留了对内存布局进行微调和重新排列字段的自由(例如省略机器字、利用空指针优化压缩枚举标签等)。Niko 强调,在“做极致硬件优化并保留未来变聪明权利”与“承诺永恒不变的跨版本 ABI 兼容”之间,存在天然的张力。 Andrei Alexandrescu 则将问题拆解为两部分:对内给程序员精准的内存布局控制,对外无缝兼容既有霸主(C/C++)。 - **向后兼容老牌霸主**:D 语言通过 `extern(C)` 和 `extern(C++)` 深入支持与 C/C++ 互操作,甚至引入了对 C++ 命名空间与名字修饰(Name Mangling)的原生支持。 - **结构体与类的布局分化**:在 D 语言内部,开发者需要精准掌控布局以榨取性能,因此 `struct` 严格遵循类似 C 的确定性字段顺序;而对于需要通过虚表和引用访问的 `class`,编译器则拥有更多自由度去重排字段。这与 C++ 中一旦涉及虚函数编译器便有权介入布局的处理思路高度一致。Andrei 总结道:“作为底线法则,新语言必须与平台上已有的既成语言良好协作(as a bottom rule new language should play well with with the existing languages on the platforms)。” --- ### [01:04:47](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=3887s) Go 语言的极简解法:纯源码构建与全家桶自洽 Rob Pike 最后介绍了 Go 语言处理 ABI 的独特方式。在 Go 的世界里,只有在必须与 C 或 C++ 打交道时,团队才不得不去面对 ABI 的烂摊子——因为各个操作系统平台的 ABI 规则千奇百怪且充斥着历史沉淀,这项对接工作异常痛苦,但为了生态不得不做。 然而,在 Go 语言自身的生态体系内,设计团队选择了一种“降维打击”式的策略:根本不去为不同版本的 Go 编译器制定 ABI 规范。 - **源码级全量重构**:Go 极度重视编译速度。Rob Pike 举例称:“在我的笔记本电脑上,包含全部标准库在内的完整构建只需要 6 秒钟,因为一切都是从源码构建的(the entire library builds on my laptop in six seconds because everything's done from source)。” - **同版本编译器规则**:Go 强制要求所有打包进最终二进制文件的依赖和代码,必须由完全相同版本的 Go 编译器统一构建。“无论当前编译器认为什么是对的,那就是对的(whatever that compiler thinks is right is right)。” 通过放弃在二进制层面对不同版本产物做 ABI 兼容的包袱,Go 彻底摆脱了传统系统级语言长期受制于 ABI 稳定性的枷锁。随后,主持人宣布讨论圆满结束,全场在轻松的调侃与热烈的掌声中落幕,相约前往会后酒会。 ## Notable quotes > [41:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2464s) I actually think of the type system as my first line of defense against my own sloppy thinking. — Bjarne Stroustrup > [19:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1190s) The users always want a simpler language with a few extra features. — Bjarne Stroustrup > [03:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=220s) It's a constraint that determines whether it's systems programming. Are you running out of memory? Are you running out of time? Are you running out of real time? Are you running out of file handles? — Bjarne Stroustrup > [12:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=724s) I think we have to distinguish sharply between type safety and security. — Bjarne Stroustrup > [03:40](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=220s) When we first announced Go, we called it a systems programming language, and I slightly regret that, because a lot of people assumed that meant it was an operating systems writing language. — Rob Pike > [41:04](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=2464s) I had a bit of an epiphany last year when I realized that the reason that unit testing was being driven by the dynamic language people was that they had that instead of static typing. — Bjarne Stroustrup > [19:50](https://www.youtube.com/watch?v=ZQR32nTVF_4&t=1190s) Whatever else we do to our languages, the users do not want their code to change. — Bjarne Stroustrup ## Mentioned Lang NEXT 2014, Bjarne Stroustrup, Rob Pike, Andrei Alexandrescu, Niko Matsakis, Dave Ungar, Craig Chambers, Gerard Holzmann, Robert Griesemer, Dennis Ritchie, Randy Smith, C++, Rust, Go, D, C, Java, C#, Smalltalk, Self, Scala, Erlang, Lisp, Simula, Plan 9, go fix, gofmt, Protocol Buffers, Alternate Reality Kit, 5ESS 交换机, 火星气候探测者号 (Mars Climate Orbiter), BitTorrent, Itanium C++ ABI, AT&T 贝尔实验室, Google, Facebook, Mozilla, Amazon, Microsoft, Borland, Symantec [Source](https://www.youtube.com/watch?v=ZQR32nTVF_4)

Source quotes

[41:04] Bjarne Stroustrup: I actually think of the type system as my first line of defense against my own sloppy thinking. [19:50] Bjarne Stroustrup: The users always want a simpler language with a few extra features. [3:40] Bjarne Stroustrup: It's a constraint that determines whether it's systems programming. Are you running out of memory? Are you running out of time? Are you running out of real time? Are you running out of file handles? [12:04] Bjarne Stroustrup: I think we have to distinguish sharply between type safety and security. [3:40] Rob Pike: When we first announced Go, we called it a systems programming language, and I slightly regret that, because a lot of people assumed that meant it was an operating systems writing language. [41:04] Bjarne Stroustrup: I had a bit of an epiphany last year when I realized that the reason that unit testing was being driven by the dynamic language people was that they had that instead of static typing. [19:50] Bjarne Stroustrup: Whatever else we do to our languages, the users do not want their code to change.

Source quotes

[41:04] Bjarne Stroustrup: I actually think of the type system as my first line of defense against my own sloppy thinking. [29:47] Andrei Alexandrescu: Systems languages have this extra burden on top of everything, which is, well, you got to worry about at the same time the cathedral, the bricks, and the molecules in the bricks. [36:55] Rob Pike: The APIs in a typical Go program are half the complexity of a C++ equivalent because you don't have to talk about the memory management, and that makes the program smaller, simpler, easy to understand, and you have less to carry in your head as a result. [12:04] Bjarne Stroustrup: I think we have to distinguish sharply between type safety and security

Original transcript

[0:00] all right so this is an interactive [0:01] panel this is one of two are going to do [0:03] so first of all thanks everybody for [0:05] coming [0:06] this panel is titled systems programming [0:10] in 2014 and beyond and so obviously if [0:14] you look at our great panel here we have [0:17] you learned a lot today about C++ rust [0:19] and go Andre hasn't talked about D yet [0:22] but that's also a systems programming [0:24] language native language compiles the [0:26] native code blah blah blah [0:29] so I don't know if we should do [0:30] introductions but why not let's really [0:32] quickly do introductions who do you want [0:36] me to introduce that's des this Rob Pike [0:41] I remember when he came to Bell Labs we [0:45] even shared an office for about three [0:46] months and he's been doing great things [0:50] at Bell Labs and then Lucent and then [0:53] went to the west coast did a lot of good [0:57] stuff with Google and and he was [1:00] physicist I remember was it Caltech yes [1:03] thanks oh this is this is BR Nestor's [1:10] trip [1:11] designer an inventor of C++ for Bell [1:14] Labs 18 T Bell Labs and many other [1:17] things besides and he's managed to stick [1:20] with C++ now for how many years have you [1:23] been working on the committee too many [1:25] which is an admirable achievement in and [1:27] of itself so and you can introduce to [1:33] b2b various area to introduce myself [1:35] because well I'm interested the [1:40] competition rust is the language that [1:44] we're going to steal a lot from [1:46] inspiration do what I say I'm gonna get [1:50] a lot of inspiration from and I actually [1:52] don't know much about about you so but [1:55] maybe you I mean I don't know [1:58] I came unprepared to this [2:01] so maybe you can introduce him yeah I [2:06] believe you are Alexi and rescue that's [2:09] very close okay [2:11] and he said Co I guess [2:13] Buju cars have a co-designer of D at [2:15] this point or resent designer advocate [2:18] for D working at Facebook for a few [2:20] years and like I think every Romanian [2:23] I've met in the last few years he wears [2:24] shorts all the time as far as I can tell [2:27] and I spend the rest of the evening [2:29] trying to hide my legs here and so being [2:34] an interactive panel the idea is you [2:36] guys you know drive questions there [2:38] weren't a lot of questions today and [2:39] realized people are probably shy or [2:41] whatever remove that mask ask questions [2:45] to people who will know the answer is in [2:47] the context is just some programming or [2:48] whatever you want to know about their [2:49] specific languages but the first [2:50] question I want to ask is what is the [2:52] system's programming language oh hey my [2:58] bad rust so obviously I know who you are [3:03] you're Nico Matt's aqus right on he is a [3:08] researcher at Mozilla and currently [3:10] working on the D programming language or [3:12] the Russ programming language well I [3:17] mean there's that's gonna be kind of a [3:18] fun thing to talk about there's some [3:19] really interesting connections but and [3:23] rust is all about type safe memory safe [3:26] without losing performance at certain [3:29] level of abstraction just like C++ gives [3:32] you the power of hardware nice levels of [3:36] abstraction but you don't lose [3:37] performance it seems to be the whole [3:38] thing with systems programming languages [3:40] which brings us to the question of what [3:43] is the system's programming language in [3:45] 2014 [3:46] C++ is used for much more than writing [3:48] operating systems D isn't used for [3:51] writing operating systems it could be go [3:53] isn't used for writing operating systems [3:55] there are also some programming [3:56] languages rust you know what's your you [4:00] know what are you gonna do [4:02] so that's the question that's a really [4:08] broad question but I think it's a really [4:09] important one because it seems like [4:11] we're all many people use the words [4:13] somewhat differently right so from our [4:15] point of view I mean the thing that [4:17] we're most interested in certainly you [4:21] know in the most selfish point of view [4:23] is writing kind of client-side [4:24] applications right so sort of the polar [4:26] opposite of what go was designed for for [4:28] example and in these kind of [4:30] applications you have high latency needs [4:32] you have high security requirements you [4:34] have a lot of requirements that I think [4:35] don't necessarily come up on the server [4:37] side though I feel like basically I [4:40] think that the definition is quite broad [4:42] and I would like to think that most of [4:47] the link I mean basically that all these [4:48] languages can be used to some extent in [4:50] all these domains I'm sure you could [4:51] write great client-side things and go as [4:52] well for example and I'm quite sure you [4:54] could write good server-side stuff and [4:56] rust so it's probably more at the edges [4:58] where you'll see the differences like [5:00] the extreme cases of each of the [5:03] different domains and so on I I think [5:13] that I mean systems programming came out [5:16] of the fields where you had to deal with [5:21] hardware and then the applications [5:24] became more complicated so you need to [5:28] deal with complexity I think if you have [5:31] any issues of significant resource [5:36] constraints you are in the systems [5:39] programming domain if you need a finer [5:42] grain control you will also be in the [5:45] systems programming domain and if you [5:48] are part of a system where part of the [5:52] system has those concerns a pro systems [5:55] programming language has advantages that [5:58] is you can do a lot of programming in [6:02] just about any language [6:04] it's a constraint that determines [6:08] whether it's systems programming are you [6:10] running out of memory are you running [6:12] out of time are you running out of real [6:15] time I [6:15] running out of file handles and then [6:20] finally there's the aspect of actually [6:22] touching hardware device drivers memory [6:26] managers and such but it's it's like [6:29] asking me to define play or game there's [6:33] something obviously is there and then by [6:36] analogy a lot of our listings are there [6:38] don't don't expect a crisp definition we [6:47] when we first announced go we called it [6:50] a systems programming language and I [6:52] slightly regret that because a lot of [6:53] people assumed that meant it was an [6:55] operating systems writing language and [6:57] what we should have called it was a [6:58] server server writing language which was [7:01] what we really thought of it as as I [7:02] said in the talk before and the [7:04] questions it's turned out to be more [7:05] generally useful than that mmm excuse me [7:08] but now what I understand is that what [7:09] we have is a cloud infrastructure [7:11] language because what we used to call [7:13] servers are now called cloud [7:14] infrastructure and so another definition [7:17] of systems programming is the stuff that [7:19] runs in the cloud I'm very glad I let [7:22] drops speak right now because my next [7:26] question was like you know going to this [7:27] itself has a system sprung a language [7:29] and then in that disappeared from the [7:30] website was the deal with that so he [7:33] kind of you know he was way ahead of me [7:35] by pre-empting that possible question I [7:39] don't know I it's a broad question it's [7:41] a fuzzy like well you know what's what's [7:44] a system what a system etc what's there [7:48] and what's not and gets into philosophy [7:49] and we get crazy before we do our ends [7:52] right but I do have a few litmus tests [7:57] for checking whether something is a [7:59] systems from your language and I think [8:01] there's a there's a simple litmus test [8:04] which says systems foreign language must [8:07] be able to allow you to write its own [8:09] memory allocator in it it shouldn't [8:11] escape into another language to do so [8:13] and it should be able to forge a number [8:16] into a pointer because that's how [8:18] hardware works this is kind of two [8:22] litmus tests that are relatively simple [8:25] the memory allocation thing is quite a [8:28] lot more [8:29] that most people think it is because for [8:32] most higher-level languages completely a [8:34] kind of a salty issue its language [8:37] designer kind of toys over a good memory [8:39] allocation strategy but for a language [8:42] in which you need to implement this as [8:43] long as well as use it it's a very salt [8:46] prone because at some point there's [8:48] gonna be a point at which a pointer that [8:50] looks like tight becomes on typed and [8:53] reused for possible another type and you [8:56] know all of this kind of manipulation is [8:57] very contrary to to the kind of type [9:00] systems that the high-level language [9:02] espouse so it is quite a hard problem [9:06] and you know there's papers on what are [9:09] the good primitives for such a thing but [9:11] ultimately fundamentally forging [9:14] pointers and making pointers look of [9:16] kind of you know changing the type of a [9:18] pointer in flight I think these are kind [9:22] of fundamental issues for assistance for [9:24] your language it's interesting you [9:27] mention that because we're almost [9:29] completed our rewrite of the go memory [9:31] allocator and to go from C so I guess we [9:34] passed that one anyway alright so of [9:45] course a slightly philosophical topic [9:50] here if you look up systems programming [9:53] in the Wikipedia you'll find that it's [9:56] defined roughly as writing the lowest [9:59] level of device drivers and is basically [10:03] useless it is very tricky when somebody [10:09] else defines your terms for you and I [10:12] mentioned it with C++ with [10:14] object-oriented programming we have an [10:16] example here with systems programming [10:18] being defined out of existence and the [10:21] other example that I remember was Simula [10:24] the language similar are the introduced [10:26] object-oriented programming to the world [10:28] and got classes and class hierarchies in [10:30] place was called similar and I met a lot [10:33] of people says no it was a [10:35] special-purpose language of simulations [10:37] there's nothing interesting there [10:39] so let's try and define what we are [10:42] doing a little bit better great so I'm [10:48] going to walk around the mic so that you [10:49] can be recorded and people can hear you [10:53] so I think what are the central [10:56] challenges of our time is being able to [11:00] write secure and robust reliable code [11:04] and and there's a lot of challenges in [11:07] that because I think it requires [11:08] cooperation from the platform as well as [11:11] from the language and I'm wondering if [11:15] you see any interesting paths for [11:18] innovation from the language space from [11:21] systems languages to support writing [11:24] more secure in our post code well yes I [11:35] do in short but I think I mean that's a [11:39] you know we could start by defining what [11:41] secure and robust and everything else [11:43] mean for me it sort of there's the base [11:45] level of security which is kind of the [11:47] properties I was talking about you know [11:48] database freedom memory safety and so [11:53] forth and you can argue about exactly [11:54] which one should be in that list but [11:55] there's a kind of basic set of things [11:57] that you would like to get from your [11:59] language most of the time at least and [12:02] that gives you a good feeling and it [12:04] gives you much more reliable software [12:06] but there's another level of robustness [12:07] above that right how that doesn't tell [12:09] you that your program is doing the right [12:11] thing it just tells you it's doing is [12:12] not doing the wrong this categories of [12:14] wrong things and so what I would like to [12:18] see and I hope to see was with rust as [12:22] we evolved is people taking advantage of [12:25] the type system to go beyond the [12:27] properties that I that I've talked about [12:29] so far to go beyond those basic [12:31] correctness properties and prove [12:32] stronger things like Express stronger [12:34] invariants about their software which [12:36] lets you basically get a bigger brain of [12:39] confidence I mean I think the simplest I [12:41] think everybody knows that when you [12:43] write something with a static type [12:44] system it's somewhat easier to refactor [12:46] it [12:46] I think well in some it's certainly user [12:49] Drew in an automated way and to get [12:50] developer tools it's also easier to find [12:52] out where [12:53] this function used and so forth I think [12:55] we can use similar techniques to say [12:59] guarantee well trying to come up with a [13:02] really crisp example but guarantee that [13:04] you know tainted data that comes from [13:07] the network is always sanitized before [13:10] it gets consumed by a routine and things [13:11] like that [13:12] those kind of more extended properties [13:13] that are really semantic and specific to [13:16] your application they may not be [13:17] something that the language chooses to [13:19] model directly but being able to model [13:21] and check that kind of thing seems to me [13:23] to be very important and I hope we can [13:25] see progress in that way yeah I think we [13:32] have to distinguish sharply between type [13:35] safety and security there are people who [13:38] go around talking as if type safety was [13:41] security security is a system property [13:44] if I'm going to steal your data I will [13:47] probably not try and break in your [13:49] computer first I'll try and steal your [13:52] computer first and then I'll head to it [13:55] my own good time that's a bit hard of a [13:58] server farms but still the point is that [14:03] it's a system property [14:05] I think type safety is the ideal and I [14:09] think it has always always been the [14:12] ideal it's just it's hard to get to we [14:17] have to do runtime checks on sizes of [14:20] array source we have a overflow problem [14:23] that's easily exploited either to crash [14:25] the system or to the security or we we [14:29] have resource problems and such so it's [14:31] the ideal and just before because we [14:33] can't get there 100% doesn't mean we [14:36] have lost and just in the languages [14:39] where you can get there 100% doesn't [14:41] mean there one it's it's a spectrum and [14:43] we want to use the techniques as Nico [14:46] said of type system and also further [14:51] analysis so to get better systems but [14:56] don't underestimate this problem I don't [14:58] think you did I don't think a lot of [15:00] people here do but I hear a lot of [15:03] overly simplified [15:05] concerns about safety and security [15:11] all right you know it's best to be last [15:14] right okay Bob I'd like to make a sort [15:17] of Dear Leader North Korean prediction [15:19] here you know the luminous path is ahead [15:23] of us well it seems to me I think I'm [15:27] gonna insert a sort of larger question [15:30] you know rust and other languages have a [15:33] few interesting ideas but I think [15:35] they're all part of a sort of a local [15:37] optimum we're in dwelling right now I [15:39] think the entire pl community is is you [15:43] know you know sort of local optimum of [15:45] sorts [15:46] I've witnessed this in I mean what I'm [15:49] saying by this is the the things we can [15:51] prove automatically and easily are not [15:57] super interesting they're good they're [16:00] not super interesting and the kinds of [16:01] types that we know how to do are [16:03] practically very hard to do such as the [16:05] rivalry bounds checking automate [16:07] eliminating on most of these and making [16:08] them sort of you know an immeasurable so [16:13] it's we know how to do it with just [16:15] practically kind of owners sometimes so [16:20] I feel we're at a local minimum I know [16:21] this from other communities they've been [16:23] stuck in local minima for four years the [16:27] speech rate your speech recognition I've [16:29] been auto research and I I left that [16:31] community exactly and when it was on the [16:33] brink of a huge breakthrough theory [16:36] being sort of part of what came out of [16:38] it but essentially the white seat we're [16:41] ripe for a sort of a real breakthrough [16:44] in in the area when programs are going [16:46] to be typed in ways that at the same [16:50] time are are interesting improve a lot [16:52] of facts but don't require a lot of [16:54] annotations where that's got that going [16:57] to come from I'm not sure but it looks [16:59] like things are kind of there's some [17:01] convergence of something going on this [17:03] is my intuition right now I think well I [17:10] agree we're kind of stuck in a rut I can [17:12] see a way out of it because I think that [17:15] quality of tooling static analysis and [17:18] otherwise [17:18] it's building up around programming [17:20] languages in general now it's pretty [17:22] exciting and I don't just mean like I [17:25] des although some of those are getting [17:27] pretty amazing but the computers are big [17:30] enough and fast enough now that we can [17:32] afford to do calculations that would [17:34] have been prohibitive a generation ago [17:36] because they would have taken too long I [17:37] mean the resources you spend our whole [17:39] program optimization you could direct in [17:42] other ways and I have seen some pretty [17:44] powerful static analysis stuff for [17:46] safety checks a long time ago now and [17:50] which would make it even more practical [17:52] today in the plan 9 kernel which was [17:55] written in C we had all these locking [17:57] primitives for you know making sure that [17:59] data structures were protected properly [18:01] and so on and Gerard Holtzman had a what [18:04] he called a protocol analyzer and he [18:06] made a version of it that could pick up [18:08] C code and recognize the calls into the [18:10] library that we were using to set [18:12] mutexes and things like that and he it [18:14] wasn't formally proof but he sort of [18:16] dynamically on static code proved that [18:20] the kernel was locked free in this case [18:22] and that's a very small example but that [18:24] was also 15 years ago now so I think [18:27] that we're just starting to scratch the [18:29] surface of what some of these tools are [18:31] going to be able to prove about our our [18:32] programs either probabilistically or [18:34] rigorously it's not really it's not a [18:42] response to I was just meant to say that [18:46] you know because the question was was [18:49] the role Assistance Program language I [18:50] think they put great upward pressure on [18:52] pretty much everything because there is [18:54] a domain in which no fat you know no [18:57] speed is enough and the more speed you [18:59] got the better it is and safety is good [19:01] to have given all the speed so I think [19:04] the pressure during the in the pressure [19:07] put the assistance from your language is [19:08] very practical upwards against the the [19:11] PL Research Committee I think it is a [19:13] good thing thank you and then I'll just [19:17] take the opportunity to to second what [19:19] Rob said about static analysis we can do [19:22] amazing things today and I think the [19:26] rich of the type system the richer the [19:29] analysis that you can get [19:32] one of the criticisms of static typing [19:35] has been that they only catch trivial [19:37] things [19:38] that's because they look at trivial type [19:40] systems Dave thank you well I've been [19:50] hoping to ask the question that would [19:52] get all of you fighting amongst [19:53] yourselves but this probably isn't it as [19:58] cycles have gotten cheaper we're doing a [20:00] lot more static analysis putting a lot [20:03] more things in the compiler hoping to [20:06] get better error messages but with all [20:09] of these languages and go maybe the [20:12] least bad I feel like I have to carry a [20:16] lot of things in my head when I use them [20:19] for example with rust and the sharing [20:21] model I have to think about who I want [20:26] to share the reference and do I want to [20:28] loan it or give it and do it muta bleah [20:31] or not and with C++ I suspect there's a [20:40] fair amount you all are so good and so [20:43] smart that you carry these things in [20:47] your head effortlessly I think I don't [20:50] know D well enough to throw a dart at it [20:53] and I don't I don't quite know go that [20:57] well to do that either but I think [21:00] you've tried to minimize it for go [21:02] because it's explicitly not for people [21:03] like yourself but do you think this is [21:08] an interesting way to think about the [21:10] languages am i way off base do you think [21:13] your languages do make you carry a lot [21:16] in your head a lot of the time I've got [21:19] all this text but there's really a [21:21] picture I'm trying to carry in my head [21:23] and it seems very left brain of [21:28] programming languages so disgust thank [21:34] you [21:39] I think this one this deserves to be on [21:42] my plate one of the reasons that the [21:47] languages are so complicated is they [21:49] carry a lot of history with them it is [21:52] really really hard to simplify a [21:55] language the users always want a simpler [21:59] language with a few extra features and I [22:02] may not have been quite as rigorous as [22:04] Rob mentioned about rejecting features [22:09] but I have certainly rejected features [22:11] up in the 99 percent of their requests [22:14] and C++ is humongous obviously too large [22:18] and it has 40 years of history with it [22:21] starting with C and in in 72 there are [22:27] features that just should never have [22:30] been there as features that should have [22:32] been there and has been been superseded [22:36] but they're still there because whatever [22:38] else we do to our languages the users do [22:41] not want their code to change one thing [22:47] that I hope for is not just code [22:51] analysis I want code transformation and [22:54] I wanted to maybe I can finally get [22:59] modernization of code code rejuvenation [23:02] or whatever you call it [23:04] that's mechanically helped so we can get [23:07] some of these things that aren't C++ [23:10] just because Denis had a bad day in the [23:13] early 70s and Dennis would agree with me [23:16] and actually has he can't be here to [23:19] defend himself but he's not being [23:21] attacked all I'm saying is that C was a [23:25] stroke of genius I said this this [23:27] morning I praised it and some of the [23:30] details were not right and you can say [23:32] that about lots of the features I have [23:35] added to C++ I could do it better today [23:39] I mean templates would have been half [23:40] the size if I was doing them today [23:43] now code analysis code transformation [23:48] can [23:48] up here furthermore I have many many [23:52] times seed the cleave and keep people [23:54] come with a new language look it's so [23:57] beautiful it's so simple it is not as [24:00] ugly as C++ look to play a guy from a [24:04] Java world here is the arm dripping out [24:08] two-thirds of the pages saying this is [24:10] what we don't need we can get Java it's [24:13] beautiful it's clean it's a signed from [24:14] first principle and it has C syntax [24:18] anyway so the point is will age comes [24:25] all of these barnacles that hangs off [24:28] the ship and till now I have not seen a [24:32] solution to that the only language is [24:34] that doesn't have this problem tend to [24:36] be languages that didn't survive c-sharp [24:40] and Java has has doubled in size tripled [24:43] in size and their specifications is [24:45] about the size of C++ I hope code [24:47] transformation will help us in this game [24:59] since I suspect most of you don't know [25:01] go very well it's probably on a topic of [25:03] code transformation mentions something [25:05] that we did excuse me we were coming up [25:09] to what we knew would be the first [25:10] version of goes it's what we have now go [25:13] 1.0 the point release has since then [25:16] involved in performance and [25:18] implementation changes in library but [25:20] the language is the same but we knew we [25:22] were going to lock it down and we wanted [25:24] to get it right but the problem was we [25:26] wanted to change a bunch of stuff we [25:27] wanted to clean up delete some features [25:30] simplify some features fix some [25:32] libraries get rid of from I think [25:34] there's a keyword even clean up things [25:36] the problem is how do you do that [25:38] without breaking our users code now we [25:40] didn't have nearly as many we still have [25:42] nearly as many users as say C++ does but [25:45] there are people we didn't want to [25:46] bother so what we did was we wrote a [25:48] program called go fix that could parse [25:51] both the old and the new things they've [25:54] had these little modules that glue it [25:55] into it and it would take your old-style [25:57] program pick it up [25:59] parse it take the [26:01] AST fix it quits the module and then [26:05] write it out of the new form and we did [26:06] some pretty fundamental change to the [26:08] language and the way it was designed to [26:10] be idempotent so if your program was [26:11] already converted the module already run [26:13] on your code didn't have to run again [26:15] and then with the release leading up to [26:18] go on [26:18] we just said run go fix on your code and [26:20] it'll be fine and one of the things that [26:22] made that possible was this amazing [26:25] library fundamentally that robert wrote [26:28] called go foamed which will take an ast [26:31] and printed out in human readable neatly [26:33] standardized formatted output which some [26:36] people say is the best feature of the [26:37] language they may be right but the thing [26:39] is this meant that we could rewrite your [26:41] programs and write them out again the [26:42] way they were supposed to look and the [26:44] way they probably looked before to be [26:45] honest but this had an amazing freeing [26:48] effect on us because we were able to [26:49] consider every single detail of the [26:51] language and if it didn't feel right fix [26:53] it literally play with it make sure was [26:56] right back out some advance so by the [26:58] time that go one happened we had [27:01] scrubbed the language clean to the best [27:02] of our knowledge turned out we've missed [27:04] a few things but but it was an [27:06] interesting process because of the [27:07] complete automation with which we were [27:10] able to update not only our code but [27:11] everybody else's code while doing that [27:13] and it got used one more important time [27:15] later we decided to change the API that [27:18] was used and go for protocol buffers [27:19] which are used on every third line of [27:22] every google source file out there and [27:25] we want to change the api and we wrote a [27:27] go fix module to do this and in [27:29] literally one command updated the entire [27:31] tree of go programs using an api retired [27:34] the old api and a stroke and we were [27:37] done and so this is an interesting [27:39] comparison to other stories about trying [27:41] to change protocol buffer api is and how [27:43] hard that's been over the massive [27:44] codebase that's there so I agree [27:46] complete with hope yarn is saying that a [27:48] lot of this is actually automatable if [27:49] you're willing to have the courage to [27:52] clean up stick to your guns and really [27:54] get rid of the old stuff [27:58] I want to step back a little bit to the [28:00] original question or somehow another [28:02] aspect of the original question that we [28:04] kind of lost I think which was okay is [28:07] this too much to keep in your head and [28:09] can you know this especially I think [28:12] when you have a richer type system was [28:13] kind of one of your main examples right [28:16] like the examples I was giving of [28:17] ownership and borrowing and everything [28:19] and I think there's an interesting [28:22] trade-off here because it is true of [28:25] course that like a language like rust [28:27] will kind of push you in a direction [28:28] where you have to learn up front and [28:33] learn these certain patterns upfront and [28:35] select which one to use and there is a [28:36] certain amount of overhead associated [28:38] with that on the other hand if you just [28:40] have say pointer like in Java or C sharp [28:43] or something like that [28:44] I would argue that a lot of times you [28:46] still have you still have these patterns [28:48] there right there is still ownership [28:50] especially when those mutability or [28:51] resources there is ownership there is [28:54] borrowing it's all in the code it's just [28:55] implicit it's not written down and it [28:57] may not have been thought about as [28:59] carefully as it should have been so I've [29:01] heard from a number of people now [29:02] actually who were learning systems [29:04] programming for the first time who were [29:06] too afraid to you see or just never had [29:08] the time or whatever and they have come [29:10] to use rust and they found that there is [29:14] some upfront learning but it's helpful [29:15] to them much compared to their attempts [29:17] to learn C because they are sort of [29:18] guided down channels they say this is we [29:21] suggest this is the proper way to manage [29:22] your resources you should have a single [29:24] owner that's kind of a lesson that you [29:26] end up learning by virtue of double [29:28] freeing too much in C code right and [29:31] having similar problems so I'm not sure [29:35] how much of the complexity is in the [29:37] languages and how much I guess I am [29:39] pretty sure actually I take that back [29:40] I feel the most of the complexity is in [29:42] the domain and exposing it at the [29:45] language level is not a mistake in that [29:47] regard Dave you should know you're my [29:53] academic grandfather Creek chambers has [29:56] been my advisors through my Master's so [29:59] it's a great honor to see I wanted to [30:01] shake your hand but I was like what the [30:02] hell am I gonna say that's gonna be [30:04] interesting to him so you know I'll [30:09] continue answering sort of the [30:11] higher level question which is you know [30:12] why do I have to keep all this detail in [30:14] my mind I'm sure thinking of things like [30:16] self and small talk which are so fluid [30:18] and so so easy to to kind of experiment [30:21] with and write in my opinion just as [30:26] justice same as Niko's I think it's um [30:29] a lot of it in hereand assistance [30:32] languages have this extra burden on on [30:35] top of everything which is well you got [30:37] to worry about at the same time the [30:39] cathedral the bricks and the molecules [30:41] in the bricks and that's the way it is [30:42] it's pretty much cut and dried and the [30:46] way you you know we can build larger [30:48] break smaller breaks nicer molecules [30:51] better molecules whatnot you know [30:54] prefabricated whatever you know you can [30:56] you can layer things anyway one but [30:59] they're the same at the end of the day [31:01] you're gonna have to worry the whole [31:02] gamut of scale there so to a good extent [31:06] it's it's cut and right that said of [31:09] course you know different languages try [31:12] to kind of carve the space silently and [31:16] you know things like garbage collection [31:19] like it's just simplify it on of things [31:21] like Rob said you know we're not gonna [31:23] be one to worry about this kind of stuff [31:24] just let the garbage collector at the [31:27] same time we just did some [31:30] experimentation at Facebook and you know [31:32] it was like good the tourists same [31:35] payload the program would consume like [31:37] three times as much memory in the [31:40] garbage collection versus the eagerly [31:42] merged version so we just can't afford [31:45] it [31:46] and in terms of efficiency when when you [31:49] talk about the razor thin margins every [31:52] you know every percent you gain in a [31:54] core component at a server level he's [31:56] gonna mean like literally millions of [31:58] dollars annually in terms of power costs [32:00] alone not to mention you know discs [32:03] failing and memory failing and you know [32:04] the a quimera [32:06] replacement so essentially we're looking [32:08] at things that probably for for a [32:09] researcher that simply don't make sense [32:12] they're not a concern they're not part [32:14] of the the thing they worry about but [32:16] for us if kind of interest you know [32:18] glorious cost is gonna reduce this your [32:21] point five percent efficiency it's gonna [32:25] reduce efficiency okay double negation [32:27] there you see what I mean right if it's [32:29] gonna increase efficiency just just by [32:31] the thin margin it's gonna be like [32:33] there's good there's gonna be a good [32:34] money in it and there's gonna be like a [32:36] very good payoff in that and people are [32:40] gonna just accept it and I think at some [32:43] at some point there's gonna be a reality [32:45] that it's a large system I mean we're [32:48] talking about large distance however [32:50] written in languages that aspire at [32:52] allowing that kind of control and at [32:55] some point there's gotta be all that [32:56] complexity laying around I just wanted [33:03] to say the same thing as SN Dre just a [33:07] lot of these things and this there's a [33:09] time scale difference but I think I'd [33:11] like to push back on this thing that you [33:14] just want to have it not remember these [33:16] things in your head just write down what [33:18] you want your head I hear often people [33:21] want programming to be as easy as as [33:28] writing in English and the problem is [33:30] English is horribly imprecise and I find [33:34] to my great embarrassment that I've said [33:36] something perfectly clearly in English I [33:38] understood it and then everybody else [33:40] understands something else and I would [33:44] like to emphasize Nico's point is that [33:46] if things in interfaces are more [33:49] precisely specified in types with [33:52] constraints with requirements and such [33:55] you get more stable interfaces you get [33:59] more things caught and you get better [34:01] communication between different groups [34:03] the classical example is the mass [34:05] climate orbiter there's nothing wrong [34:07] with the type system those nothing wrong [34:10] with the code but it was a trivial type [34:12] system at double is a double whether it [34:15] is MKS or the imperial system and we [34:19] just lost six hundred million dollar [34:21] probe I think for the kind of [34:25] applications I think of most and care [34:28] about most like the brakes on icons such [34:31] I would rather see it done at a [34:35] technical level [34:36] than an intuitive level I hope I didn't [34:41] pair caricature you too much thank you [34:52] so much I mean of course there are [34:54] different domains and things and if any [35:00] combination of language features is [35:02] sufficient to make sure the brakes work [35:04] on my car well enough compared to [35:07] putting that same amount of effort into [35:09] testing and fault injection and all of [35:12] those things I'm not aware of it but you [35:14] all maybe if Facebook cost me twice as [35:19] much to join I wouldn't mind but I don't [35:22] I don't know what what your costs are or [35:24] the some of the bugs you might have for [35:27] not having automatic reclamation I [35:29] observe that Google has gone with go the [35:32] automatic reclamation algorithm the [35:34] experience I have all the time is I have [35:38] a really neat idea in my head because [35:42] that's what I value for something to [35:44] build and I feel like when I build it in [35:48] most languages [35:50] I am slowed down so much by this stuff I [35:53] have to carry in my head it's really [35:56] hard to hold on to that shining idea you [36:02] know Randy Smith has said about the [36:04] alternate reality kit which is one of my [36:07] shining things that if he had to do it [36:09] in anything but small talk he wouldn't [36:11] have gotten the first three lines of [36:13] code written now I know that if you're [36:15] writing something that has been written [36:17] a million times before and maybe you're [36:20] sending it to Mars or something sure all [36:23] the help you can get is worthwhile but I [36:27] would love to be able to create things [36:29] that run reasonably fast and maybe later [36:33] on I can put in all this stuff to get a [36:35] little extra security but it would sure [36:37] be nice if I could try out that idea and [36:41] maybe this is just my own weird [36:42] personality [36:43] try out that idea so easily not have to [36:47] rewrite it and that's where I was coming [36:49] from with my question so thank you for [36:52] letting me Roboto know are you kidding [36:54] me come on [36:55] so do you want to retort his retort okay [36:59] what would you call that no I just want [37:03] to make a point about garbage collection [37:04] because when when we did and I also [37:07] should say not everything in Google is [37:08] written and go and a lot of it shouldn't [37:10] be because of issues like garbage [37:12] collection latency some of the core [37:14] stuff needs to be written in exactly [37:16] these sort of low what I think of as [37:17] lower level or at least more precise [37:19] descriptions of behaviors but there [37:21] isn't there two points about garbage [37:22] collection that I think are often lost [37:24] on the systems program community given [37:26] the pushback I used to get I don't get [37:28] so much anymore [37:29] one is that I we don't claim it it's the [37:32] right solution for everything but it is [37:34] a right solution for an awful lot of [37:36] stuff and for those things I shouldn't [37:38] need to pay the price that I have to pay [37:41] for the low-level things this was the [37:43] point that drove us to create go in the [37:45] first place C++ is probably the right [37:47] choice for a lot of the code at Google [37:49] but not all of it and not even maybe [37:50] even the majority of it a language [37:52] that's easier to use and you know memory [37:55] management being one of the most [37:56] important parts of that is actually [37:58] valid to have around the other point is [38:01] garbage collection is not intrinsically [38:02] slow it's an it's an idea we don't have [38:06] the best garbage that we're all I think [38:08] of a good one but it's not the best we [38:10] hope to have a great one you're working [38:11] hard on trying to make a good one [38:13] but the point is that what is often it's [38:15] a bit like what I was saying about [38:16] threads when people complain about [38:17] garbage collection they're complaining [38:19] about a certain style of garbage [38:20] collection there's waste of garbage like [38:22] that don't have those costs they have [38:24] other issues but performance isn't [38:26] necessarily made worse arenas aren't [38:28] necessarily made bigger it's just how [38:31] it's implemented and you have to [38:33] implement it you've got to get it right [38:34] but garbage collection is an idea it's [38:36] not a performance problem it's it's [38:39] something else and I just get tired of [38:43] people complaining about garbage [38:44] collection when you think of how much [38:46] better the api's look when you don't [38:49] have to worry about the questions of who [38:51] owns what and so on and this is not [38:53] meant to slag off press oh I think it's [38:54] taking a really fascinating [38:56] angle on how to deal with this but the [38:58] API is in a typical go program or half [39:00] the complexity of a C++ equivalent [39:03] because you don't have to talk about the [39:04] memory management and that makes the [39:06] program smaller simpler easy to [39:08] understand and you have less to carry in [39:09] your head as a result so I'm completely [39:11] sympathetic to the point you're making I [39:17] don't want to I don't want to pick on [39:19] garbage collection but I want to say a [39:22] couple things one I I'm one of the [39:24] things that the owner said this morning [39:26] that really stuck with me was he said it [39:28] was busting various myths right and one [39:30] of them was people want an efficient [39:32] language and he said no they don't not [39:35] most of the time right they just need it [39:36] sometimes and a lot of the times you [39:39] don't care and I kind of feel like [39:40] that's what I'm hearing from you which [39:41] is saying I don't need the utmost of you [39:45] know efficiency I don't need to examine [39:46] every assembly language instruction all [39:48] the time and a lot of times I have this [39:49] nice idea and I want to write it out and [39:51] see it run reasonably fast and maybe [39:53] later I can go tune it when I do care [39:55] and I'm completely sympathetic to that [39:57] and I I think it's tricky when you're [39:59] marketing the language I have to say [40:01] because you want to emphasize the things [40:03] that your language does best right and I [40:05] think what Russ does really well and [40:07] what I hope that we will do better than [40:08] anybody else is writing really efficient [40:11] really safe code you know that brings [40:13] those two things together I also want to [40:16] see us do really inefficient code really [40:18] well right I want to see it really nice [40:20] to write convenient code where you don't [40:22] care if you copy that memory two times [40:24] or three times or you don't care so much [40:26] if you have a garbage collector exactly [40:28] when it's going to be freed like one of [40:30] the things I didn't talk about is that [40:31] we're working on an optional garbage [40:32] collection strategy for example but you [40:34] can opt into you can say as one of those [40:36] different ownership strategies one might [40:39] be gee seed and that that's just it's [40:41] it's hard combining especially GC and GC [40:44] is a tricky problem so that's taking us [40:46] time but I think there's a big range and [40:50] I would really like to see that it's [40:51] easy to write inefficient and it's easy [40:53] to make it more efficient and then and [40:55] when you need it to be efficient from [40:57] the start that's fine we have the tools [40:59] there for you there too [41:04] I'm all in favor of you what you said in [41:07] terms of we need all the help we can get [41:10] and as you said maybe it's just me so [41:15] I'll say maybe it's just me but [41:17] expressing interfaces in terms of type [41:22] systems and tighter types actually [41:24] helped me think and I find that my great [41:28] bright idea that I started out with has [41:33] floors and running examples gets me gets [41:39] me my errors shown to me good and hard [41:43] and getting a type system put up in [41:47] front static type system gets it even [41:51] faster and forces me to think so I [41:54] actually think of the type system as my [41:57] first line of defense against my own [42:00] sloppy thinking now I think this is [42:07] getting real close to dynamic typing [42:10] versus static typing just saying you [42:14] know it's a matter in which reasonable [42:15] people are known to disagree well I'm [42:18] not going to disagree I'm just gonna say [42:20] that I had a bit of an epiphany last [42:21] year when I realized that the reason [42:23] that unit testing was being driven by [42:26] the dynamic language people was that [42:27] they had that instead of static typing [42:33] that wasn't funny so it's a fact [42:36] all right all right so great we're gonna [42:41] start doing a quick question answer so [42:46] this this is kind of going back to what [42:48] David was talking about a little bit but [42:49] but maybe not to the extreme way one [42:53] thing is that we can equate money to is [42:55] how much money it costs to facilitate [42:58] change and this directly relates to [43:00] application binary versioning right and [43:03] one of the things that I was really [43:05] inspired by what David's worth many many [43:07] years ago was how easy it was to [43:09] facilitate change so if you look at what [43:14] that implies one way to look at it is a [43:16] is a typing argument right but the other [43:20] way to look at it is is are there ways [43:22] of changing code post-release without [43:25] breaking client code and a lot of people [43:27] talk about interfaces but it's that's [43:30] one part of it but if you look out at [43:32] the layout in memory of how the objects [43:34] are laid out right you know it's the the [43:38] this pointer is always implicit in the [43:40] C++ layout whereas in the work of David [43:43] it was you could pass it and change your [43:45] identity now I'm not necessarily saying [43:48] that you know you want extreme change [43:50] ability but maybe you know in terms of [43:54] that I think that is a legitimate issue [43:57] that has money associated with it [43:59] because if every time you change your [44:00] libraries you break or you break [44:02] somebody else and your top to bottom [44:04] stack this is a big problem why isn't [44:07] there emphasis more emphasis in the [44:09] language community on mechanisms [44:13] directly designed to facilitate change [44:14] or programming in the large Rob hell [44:21] yeah I'm not sure I have an on point [44:24] answer but when I was working at 18 T [44:27] which is when Garner was working ATT the [44:30] big money maker was the 5 ESS data [44:32] switch local local machine was basically [44:36] a vac scale machine with lots of [44:37] redundancy that gives you dial tone and [44:39] digit dialing for you and every one of [44:42] those that was installed was different [44:43] because there were patches that went out [44:45] and different playful people put in [44:47] different patches right the French ones [44:48] wouldn't put in the Spanish language [44:49] patch for the Spanish dialing plan and [44:52] so somehow I have no idea how those guys [44:55] then which was like the 80s managed to [44:58] make an environment that they could [45:00] monkey patch remotely in binary all the [45:02] time and I actually I like your question [45:05] because I've been thinking lately how [45:07] the hell did they do that how did the [45:09] phones keep working well all the more [45:10] being patched on everything maybe by [45:12] honoré members and knows more about it I [45:17] remember a little bit about it but I [45:19] don't want to go there just now what I [45:22] want is to give my answer to what you [45:24] have there's a huge chunk of the [45:26] language communities that's been working [45:28] along [45:28] your lines are long you're thinking [45:30] forever and it just isn't my world I'm [45:36] much more interested in getting the [45:37] telephone switches and the brakes and [45:40] the Mars probes and the web servers [45:45] reliable and efficient that's my domain [45:48] on my first slide it said no one [45:51] language is good enough for everybody [45:53] and everything and there I think that [45:57] you find quite a few languages that's [45:59] highly dynamic highly flexible the [46:03] generation of languages starting with [46:05] Lisp and small talk they have never been [46:08] out out of fashion and they have never [46:11] had no no support it just isn't [46:15] what I'm talking about [46:21] beyond and I as a as a duo would be [46:24] really boring because kind of repeat [46:26] each other so yeah I mean essentially [46:31] here's the way I see it at Facebook we [46:35] release we read the entire Facebook site [46:37] like twice a week which is quite a [46:40] performance when you can see like with [46:41] this an unspecified number but large of [46:44] machines and there's a lot of [46:47] interacting libraries a lot of [46:49] interacting things and you know [46:51] essentially exactly it's not the [46:53] business we're in and I'll explain [46:54] exactly what I mean by that so by means [46:59] of introduction I amendment we resolve [47:01] the same problem through different means [47:02] we have you know you know upload system [47:05] BitTorrent what have you and we have a [47:07] system to kind of wind down the exec the [47:10] existing executable you know installed a [47:12] new one putting you into into run and [47:15] etc warm things up it's a combo kind of [47:17] complex but very well functioning system [47:20] but what I mean to say we're not in that [47:24] that business because and I'll tell [47:26] exactly experiments as I've been working [47:28] for months on on on the our core PHP [47:31] compiler team which is essentially like [47:33] any any change in that compiler the the [47:36] performance of the code generator by [47:38] that compiler is going to impact the [47:39] bottom line of Facebook significantly [47:42] and it's you know what the way our chief [47:46] hot patching is by in directions [47:47] essentially you add some indirection [47:50] into the mix and you have pointers you [47:52] have like you follow of things and [47:53] essentially kind of patch things at the [47:55] right level and so on so there's morning [47:57] directions in the mix meaning instead of [48:00] a race you're gonna have list trees you [48:04] know indirect pointers and at that point [48:06] we're kind of whoa because the race are [48:08] it I mean you know kind of stop there [48:11] full-stop a race are it right because [48:16] and I'm not taking a race I'm you know [48:18] talking likes trucks you know kind of [48:20] struct is like a little array that's [48:21] heterogeneous and I'm not on you wanna [48:24] watch trucks I'm talking about the first [48:26] cache line in those trucks because if [48:29] you swap two fills in a struct you got [48:31] like two percent drop in performance the [48:33] first cache line in the struct is where [48:36] it's hot that's where it happens that's [48:39] what the rubber hits the road and you [48:40] come I mean if you come and say oh we [48:42] need hot patching and I'm like oh that's [48:44] gonna totally ruin my first line of [48:47] cache right there and I'm gonna die [48:49] right [48:49] so again I said it's not a business [48:52] we're in and I'm not saying people [48:54] should work on that I'm just saying you [48:57] know we can't afford to work on that [49:01] yeah you pretty much said what I wanted [49:03] to say actually only more colorfully so [49:06] I'll leave it there so to expand a [49:10] little further I think there's a pattern [49:12] that like Erlang exemplifies but I think [49:14] people trying to recognize more now [49:15] which is like fail quickly and restart [49:19] fast if you can do that incrementally [49:21] like you know take a server don't bring [49:23] it up again and not miss any traffic as [49:25] a result you can do that in a way that [49:27] boots the new system up right away and [49:28] it's actually a lot easier to follow [49:30] that pattern as a design principle than [49:33] to try to invent ways to dynamically [49:35] update stuff while it's running modern [49:37] machines can start up a new server in a [49:38] matter of milliseconds why bother with [49:40] all the patching if you also kind of [49:44] said what I want to say but I'm gonna [49:45] repeat it to the other thing I wanted to [49:48] add is just that this I think this kind [49:50] of restart and monkey patching is [49:51] extremely semantically challenging like [49:55] in other words it real [49:56] will depend the right way to to plug in [49:59] new code is one thing that cost some V [50:01] tables that cost some other things but [50:03] to update the existing data and [50:05] especially if the layout has changed or [50:07] or changed meaning maybe it's always [50:09] been two integers but now it's Cartesian [50:12] and now then it's polar coordinates or I [50:13] don't know something else like these [50:15] kind of these kind of changes are pretty [50:18] hard so I think it's better off in terms [50:20] of for a lot of systems at least you're [50:22] better off trying to draw boundaries in [50:24] the lung the way that or long in other [50:26] systems have done and say we're going to [50:28] sail by bringing this down and bringing [50:29] it back up and we're gonna have a model [50:31] for what its persistent and what is not [50:32] that's already there for lots of other [50:34] reasons that will help us to bridge this [50:36] this gap and trying to fully automate it [50:39] it's gonna be very challenging I think [50:44] very short and I actually remembered [50:47] part of what robust the the main ideas [50:51] for being able to patch the data [50:54] structures and switches is to deploy [50:57] them with data structures that's [50:58] slightly too big and with jump tables [51:01] that are slightly too big so that if [51:04] nothing else you can always have a thing [51:06] that says switch to the new one for a [51:08] while and you you must not just ship [51:12] what fits your current system always [51:14] fits to slot as two sizes larger and [51:19] then I'm going to cut I've got three [51:27] questions I only asked one of them so if [51:29] you have three answers please only give [51:31] one of them I guess my question would be [51:34] I work mostly with C++ and one thing [51:37] that we've noticed is that compile times [51:38] take forever and link times take forever [51:40] largely because you have all of these [51:42] type system e things like we do a lot of [51:45] static analysis sort of moves into the [51:47] type system you have a lot of entities [51:48] and it takes a long time to deal with [51:50] all of them is this only a problem for [51:53] C++ do other languages have the problem [51:55] of your particular languages have the [51:57] problem and if not why not [51:58] and what is it for C++ what is the [52:00] future that [52:05] it's a major problem but secret was [52:08] certainly not the only one and she [52:10] wanted really interesting try Scala but [52:14] what you said there about the causes of [52:18] it unless you are due into two weird [52:21] template metaprogramming the instances [52:24] in the in your program are not the real [52:28] problem it's the fact that we recompile [52:31] the header files hundreds of times and [52:34] this problem is getting on manageable [52:37] and even the Standards Committee has [52:40] noticed it and and and I'm going to [52:47] spend some significant time on it in [52:50] three weeks we will see standards [52:53] committees don't work fast and they are [52:55] not good at coming up at the simplest [52:57] most straightforward solution but the [53:00] problem is not unnoticed and I see no [53:03] reason why we couldn't be 10 times [53:05] faster we can go down I'm not going to [53:12] actually don't know whether this is a [53:13] problem in rust or not because the rest [53:16] compiler isn't screaming fast but we [53:17] also have spent zero time optimizing it [53:19] so it's hard to say I know that we [53:21] avoided this C++ problem by the fact [53:23] that we parse an entire like set of [53:26] compilation unit at a time not one file [53:27] but you know the whole tree and that [53:30] lets us avoid read parsing and [53:31] everything else and I know also that [53:34] when we build C++ that's what we do now [53:36] - in Mozilla we concatenate all the [53:38] files into one big file and build that [53:39] because that also is much faster I'm so [53:42] at least that's part of the problem or [53:43] part of the solution but yeah there is a [53:46] price yeah so they say the Ross compare [53:49] ain't that fast is it I heard like [53:53] bad-mouths and you know seeing it I [53:55] would say one other thing is that when [53:59] you build rust its building itself and [54:01] then it's building itself with the [54:03] version of itself that it built and also [54:05] building all the standard libraries so a [54:06] lot of people say it takes a long time [54:08] to run make and that is true but it's [54:09] it's building everything three times you [54:11] know programs but anyhow getting back to [54:15] the question [54:17] well here's the thing I think it's a [54:18] problem that's intrinsic to C++ and it's [54:20] a problem intrinsic to C+ was because [54:22] it's a problem to see and Simplot a C+ [54:25] was because of the templates that [54:26] mentioned adds to it the problem we see [54:30] was it was designed for a batch [54:31] compilation system I'm not sure if many [54:34] of you even know the back side does [54:37] anyone know why the backslash [54:38] termination line was ever introduced [54:41] because it was run through a [54:42] preprocessor that only did that because [54:45] there's not enough memory for the whole [54:46] thing kind of you know the [54:47] pre-processing and the compilation [54:49] everything so you run the progress that [54:51] see progress through the guy that [54:52] eliminates the back slashes and then you [54:54] run the guy through the guy that does [54:56] digraphs anti-growth try grass and then [54:59] you run the primer through the guy at [55:00] least in theory and then compilers kind [55:02] of quickly modernized and did all the [55:04] all the processing at plants but [55:05] essentially it was the the whole [55:07] language C language was designed with [55:09] such batch multistage processing in mind [55:12] and it shows and the way it shows is [55:15] that every character the meaning of [55:17] every token in in in C and C++ depends [55:20] on pretty much everything as before it [55:22] and it's it's complete serial nature [55:24] we've thrown like Rob also says like all [55:29] also what I call like high traffic [55:31] companies like Google Facebook you know [55:34] Amazon and others they shared the same [55:37] problem they have a huge to process [55:39] codebase and they have a comparative [55:41] huge army of computers and an army of [55:45] Engineers the most senior engineers they [55:47] can master to kind of you know baby see [55:50] that the build system and we've been [55:53] throwing at it like all intelligence and [55:55] all kind of smarts we could and at the [55:58] end of the day it was a none solve a [55:59] problem unsolvable problem it just takes [56:01] so long to take from the source code to [56:03] the to the binaries actually people came [56:06] to me to say first day care they said oh [56:08] why don't you go play with D and kind of [56:10] you know do something and I played with [56:12] it for six months and you know nice [56:15] things happened and then I came oh [56:16] that's pretty cool and actually I notice [56:18] you can pass real fast so we we don't [56:21] know we we don't know what to do anymore [56:23] we're at the end of our wits and we [56:26] noticed that this other language can [56:27] pass so much faster so it turns out it's [56:30] it's speeds of compilation that cannot [56:32] be cannot be obtained at any with any [56:35] money for C++ there's no amount of money [56:38] that would pay you that you could pay [56:41] someone to compile code as fast as he [56:43] does and that that was a winner that was [56:46] like oh so we're gonna try this other [56:47] language I see what the hell happens so [56:50] it's a problem that infinity C++ for [56:52] historical reasons I'm sure there's you [56:55] know there's knowledge that this work on [56:57] modules going on and more but you know [57:01] fundamentally it remains the case that [57:03] for for most extend code and tools this [57:07] is a design issue yeah I actually have [57:10] some numbers on this but I can't [57:11] remember them precisely they're in the [57:13] splash talk I cited we measured how much [57:16] data went to the compiler for a large [57:18] C++ build at Google I don't remember it [57:20] exactly but I think it was some like 4.2 [57:23] million bytes per byte of input source [57:25] meet the compiler who was a million [57:28] factor blow up in the amount of source [57:29] that the compiler actually looked at [57:31] because of the header inclusion problem [57:32] it's I don't think it's a new template [57:34] something has to with putting a clasper [57:36] header file I think that's really where [57:37] the problem starts it's a huge huge [57:39] problem and modules are I hope really [57:41] going to fix it it'll make a profound [57:43] effect on the compiled ability speed of [57:45] C++ I really hope so [57:52] the reason I take this mic back is [57:55] mostly to say that I don't disagree with [57:57] that this this this is a major problem [58:03] it's a growing problem it needs to be [58:05] dealt with and I am NOT sort of totally [58:12] rah-rah optimistic but I think it'll [58:15] probably be solved [58:23] okay so I'm coming from the background [58:25] of somebody who does most of my work in [58:27] C++ as well but my question is related [58:32] to the decision to not consider a be [58:37] eyes as part of language specification [58:41] and whether for for Vienna [58:45] whether you regret that and all and for [58:49] the rest of you what your thoughts in [58:50] developing your languages were with [58:53] regard to specifying the binary [58:55] interfaces or specifying requirements [58:58] for the binary interfaces you know [59:02] within the limits of portability and the [59:05] motivations for that yes it would have [59:15] been really nice if there was binary [59:17] interface is defined for C++ it wasn't [59:21] because we were seen as beyond the scope [59:23] of the Standards Committee just as it [59:26] was beyond the scope was then this [59:27] committee for C but C was very lucky [59:30] each platform had a de facto owner and [59:35] that affects how standard for ABI and [59:39] people used this including the C++ guys [59:42] the reason C++ didn't get one of those [59:45] was that essentially everybody thought [59:48] they could own C++ on the platform and [59:52] so you had new Microsoft and Borland and [59:58] saw take each defining their ABI [60:01] carefully making sure you couldn't link [60:03] to the enemies code and each time we try [60:08] to solve this we've run into the two [60:10] problems one it is not considered part [60:12] of the standards committees charter and [60:17] two people have always been more keen on [60:20] being compatible with their existing [60:23] users than to break all their code to be [60:27] compatible everybody else there are some [60:29] hope in the 64-bit api's and the Itanium [60:32] ABI [60:35] I hope people will get their act [60:37] together but I'm not holding my breath [60:42] so we've given some thought to this and [60:46] one of the things we have done is made [60:48] it possible to specify so Rustin it has [60:51] a kind of model very similar to C so you [60:53] can essentially opt into saying I want [60:54] this representation to be the standard C [60:57] representation and there's a sort of [61:00] well-defined meaning for that and you [61:01] can say I want this function to be [61:02] callable from C and so forth and they're [61:04] completely interoperable in that way [61:07] which is very nice when using FF eyes [61:09] and so forth we've tried to reserve for [61:12] ourselves the right to optimize [61:13] representations beyond that so for [61:17] example well you could have no no it's [61:19] not worth going in details but we can [61:21] sometimes omit words and pack away [61:23] things that would be harder to do if we [61:24] were late forcing ourselves to always [61:26] follow the same rules so there's a [61:28] little bit of a tension there between [61:30] wanting to do the best optimizations you [61:32] can given the target platform and [61:34] everything else and and wanting to [61:35] reserve the right to change that in the [61:37] future when you think of something [61:38] clever that you didn't think of when you [61:40] wrote the spec and wanting to ensure a [61:42] total binary compatibility across all [61:44] time I don't know interesting question [61:48] so just to make sure I understood the [61:50] question so talking about ABI in [61:53] defining an ABI inside the language and [61:56] or with communicating with other [61:58] languages both okay so I'm gonna kind of [62:04] write [62:10] actually so there's okay so this - you [62:17] know what let me answer the question I [62:18] wish you'd asked okay so you know let me [62:23] reframe itself I'm gonna say well what's [62:26] the deal with a bi you know do you want [62:28] to specify the language very precisely [62:30] at the binary level thus encouraging to [62:34] comparison more more and the second [62:38] thing which I'm gonna add liberally from [62:40] my own hat is you know what's the deal [62:43] with the interpreting with other [62:44] languages and and so on and so forth you [62:47] know for the three of us [62:49] I think it's nice because we're kind of [62:50] new kids on the block and super sincere [62:53] kind of the established ABA standards so [62:56] for our Part D tries to kind of [62:59] interoperate with C and C++ and there's [63:01] extent cx-10c + + we introduce thing [63:04] we're interested support for namespaces [63:05] that can introduce things or use [63:07] function calls from namespace it's a [63:09] mangling issue as well as some you know [63:12] a bit of an API issue because STD [63:14] special Inc know and stuff like that but [63:17] anyhow so you know sir other languages [63:20] are concerned it's nice to play well [63:22] with the incumbent for obvious reasons [63:24] within the language I think it's nice to [63:27] to give people code writers sense of [63:31] what they're doing because layout [63:34] control is a huge performance kind of [63:39] has a huge performance benefit so it's [63:43] nice when people write the struct to [63:45] know that their fields are not gonna be [63:46] sort of by a name or something in a [63:48] final binary right there would be stupid [63:50] right and because of that it's nice to [63:56] have some level of guarantees but at the [63:58] same time it's also nice to give the [63:59] compiler writer Sankyo some freedom and [64:01] the way we went indie was I think it's [64:04] reasonable like whenever you have a [64:06] struct it's it looks like it's pretty [64:07] much C rules and when I have a class [64:10] which is I can reference access kind of [64:12] a bit more isolate and everything the [64:15] compiler has a lot more freedom to [64:17] rearrange fields this is very similar to [64:19] what C++ does which is as as soon as you [64:21] have a virtual in the mix the [64:23] bear has a lot more freedom to kind of [64:25] rearrange the fields and kind of you [64:27] know play with things because it assumes [64:29] people are gonna access it through the [64:30] virtual functions and such so I think [64:34] we're in good shape and I think it's an [64:37] interesting problem and I think as a [64:40] bottom rule new language should play [64:44] well with with the existing languages on [64:47] the platforms so with Co we won't we [64:52] only worried about this as an issue at [64:53] all when talking to C or C++ because [64:56] there you're forced to face it and we [64:58] it's actually one of the hardest things [65:00] to work on because the every platform [65:01] has its own rules and we have to encode [65:03] them and it's all quite unpleasant but [65:05] we did the work because it was necessary [65:07] for go itself we actually deliberately [65:11] don't worry about it the compilers fast [65:14] enough the library the entire library [65:15] builds on my laptop in six seconds [65:17] because everything's done from source so [65:20] we actually require that all the stuff [65:22] you're bringing into the binary be built [65:24] by the same version of the compiler and [65:25] and just therefore it doesn't matter [65:27] whatever that compiler thinks is right [65:29] is right [65:29] yes we're giving up some freedom for [65:31] control of memory although there are [65:33] actually pretty good rules you can you [65:34] can do a good job but we're also freeing [65:37] ourselves from having to worry too much [65:38] about it all right well thanks to the [65:44] panel awesome and thanks for all the [65:47] weight crisis we have to go drink beer [65:49] now sorry man I know you hate that Gaara [65:52] [Applause] [65:53] [Music]