Jonathan Goodwin
pling.jondgoodwin.com · Personal blog · on HN since 2018
Jonathan Goodwin writes about programming language design, memory safety, lifetimes, and type theory while building the Cone language.
What HN saysHN links it for discussion of Cyclone's influence on Rust, borrowed references, and ownership; the author joins the comments about Cone's partly built borrow checker.
18HN people shared it
5linked it in comments
17stories submitted
388story points
2 years agolast shared
2018people per year2026
Most-shared posts
- 1The Fascinating Influence of Cyclone (2019)6 people · 40 points · first shared 2019 · 4 comments on HN
- 2The Power of Lifetimes5 people · 121 points · first shared 2019 · 7 comments on HN
- 3Compiler Performance and LLVM3 people · 123 points · first shared 2019 · 18 comments on HN
- 4Can a compiler guarantee multi-owner memory safety?2 people · 3 points · first shared 2018 · discussion on HN
- 5Weakening Cycles So That Turing Can Halt1 people · 96 points · first shared 2020 · 68 comments on HN
- 62030 Programming Language Predictions1 people · 3 points · first shared 2020 · discussion on HN
- 7The Rise of Type Theory1 people · 2 points · first shared 2020 · discussion on HN
- 8Interior references and shared mutable1 people · first shared 2019
- 9When sum types inherit1 people · first shared 2020
What HN people wrote when they linked it
jondgoodwin · 2019-04-04
Yes, borrowed references being lifetime-constrained means that I have a "borrow checker" that ensures that. It is only partially implemented.
You are correct that Cone supports a static, shared, mutability permission, including on borrowed references into resizable arrays. The short safety answer is array resizing is only possible when you have a unique reference to the array, so you can't run into the trouble you describe. I wrote a post about it.[1]
You left out an important clause I specified in my criteria: "with no chance of exception". Terminating the program in the event of dereferencing a reference does not meet the safety requirements I set for Cone references.
Yes, only borrowed reference have lifetime constraints. I did not mention the allocator-based reference in that quote because of context. Cone does support a distinction between move vs. copy types. Unlike with Rust, the distinction is typically inferred from the definition of the type. Currently, all memory is "pinned", but that may become more flexible in the future.
The safety strategy for Cone involves versatility: giving the programmer a curated collection of permissions and memory allocators, each with distinct advantages and disadvantages. The safety of certain options can be completely determined statically, making them inflexible but fast. Others will use a mix of static and runtime mechanisms, which offer greater flexibility but incur a runtime cost.
That said, I admit I am somewhat…
hu3 · 2020-08-03
Rust also borrowed concepts from Cyclone:
> The inspiration for safe borrowed references comes in two ways from the Cyclone programming language, a joint development effort by AT&T and Cornell University. The notion of a borrowed reference is adapted from Cyclone’s polymorphic restricted alias pointers. Additionally, Cyclone’s safe memory management focused on regions (which are usually arenas). In order to ensure memory safety, Cyclone pointers could be annotated with a named region qualifier preceded with a back-tick (making them look very much like Rust’s apostrophe-based lifetime annotations).
source: https://pling.jondgoodwin.com/post/lifetimes/
epcoa · 2024-10-11
> I was familiar with Ada, but I wasn't aware that it had an ownership system like Rust that could guarantee memory safety.
The point for bringing up Ada was more that a non-academic "memory-safe" language without GC existed for decades (predating Linux). Old school Ada doesn't use the ownership system, and true doesn't give all the compile-time safety guarantees of Rust but it does give some (and rust in practice cant't either, run the output of grep unsafe | wc on the linux/rust source tree), it also provides some affordances lacking in safe rust. Memory-safety is not some binary or univariate concept that you seem somewhat close to implying. You could have written Linux in Ada from day one and been "safer" than C (imagine that universe).
Related:
https://pling.jondgoodwin.com/post/cyclone/ (which is also referred to in the aforementioned paper).
> I think that's enough to demonstrate that Rust's ownership system is substantially novel
Well, where did anyone say it wasn't, but it certainly wasn't novel in pushing safety as a first class concept for a low level systems language. The fact that it is as (deservedly) successful as it is must be due to other factors. I'm not saying Ada did it first as some kind of gotcha, but Ada did it first and it does not rule the world.
Also, interesting comments from the creator of Rust.
https://www.reddit.com/r/rust/comments/t9972l/comment/hztbsni
https://www.reddit.com/r/rust/comments/le7m54/comment/gmb4zgc
I'll reiterate, I'm…
AndyKelley · 2019-04-08
I'm jealous of that self hosted compiler! For Zig I've mandated that we have to forever maintain both the stage1 C++ compiler as well as the self-hosted one (which is not feature complete yet).
Also I have some bad news for you...
> One major caveat: after the above stages have finished, a C compiler still needs to run to generate the final binary, which usually takes up the most time. The LLVM backend will (hopefully) reduce this.
Nope. LLVM is about 80% of the time that it takes to compile Zig code. Other language authors have found similar results. See for example http://pling.jondgoodwin.com/post/compiler-performance/
Anyway, Godspeed. I'll be watching Muon with interest :-)
Edit: one more question, if I may:
> No undefined behavior. Undefined behavior can lead to various, hard-to-spot, bugs. In Muon, all behavior, including platform-specific behavior, is defined.
> The compiler currently outputs C code.This means that we inherit C's undefined behavior model, which goes against the goals listed above! An LLVM backend is in the works which will avoid any undefined behavior.
> High performance. Strive for parity with C.
How are these things to be reconciled? First of all LLVM IR and C have basically the same undefined behavior model. In both C and LLVM IR it's possible to output well-defined code. But more confusing to me is how it's supposed to be fast, if everything is defined?
For example: https://godbolt.org/z/7d8RLG
export fn add1(a: i32, b: i32) bool…
chubot · 2020-08-12
FWIW I found this post thought provoking in thinking about data models of languages.
https://news.ycombinator.com/item?id=13293290
---
About first class variants:
https://lobste.rs/s/77nu3d/oil_s_parser_is_160x_200x_faster_than_it_wa…
https://github.com/rust-lang/rfcs/pull/2593
Another way I think of this is "types vs. tags": https://oilshell.zulipchat.com/#narrow/stream/208950-zephyr-asdl/topic… (Zulip, requires login)
Basically variant can types stand alone, and have a unique tag. Tags are discriminated at RUNTIME with "pattern matching".
But a variant can belong to multiple sum types, and that's checked statically. This is modeled with multiple inheritance in OOP, but there's no implementation inheritance. Related: https://pling.jondgoodwin.com/post/when-sum-types-inherit/
So basically in the ASDL and C++ and Python type system I can model:
- a Token type is a leaf in an arithmetic expression
- a Token type is a leaf in an word expression
But it's not a leaf in say what goes in a[i], or dozens of other sum types. Shell is a big composition of sublanguages, so this is very useful and natural. Another construct that appears in multiple places is ${x}.
So having these invariants modeled by the type system is very useful, and actually C++ and MyPy are surprisingly more expressive than Rust! (due to multiple inheritance)
Search for %Token here, the syntax I made up for including a first class variant into…