Live data from Hacker News

A few good ideas in programming languages

prydt.xyz

51–60 of 64 posts

Re: A few good ideas in programming languages

#51
post #23

Earlier quoted context omitted.

In Rust variables are not destroyed after the last borrow ends but instead when it goes out of scope. I guess that is why it us called borrow checking.

> In Rust variables are not destroyed after the last borrow ends but instead when it goes out of scope That's the problem. Once I had a tricky case, where I locked a mutex in a match expression only to read a single field to match from the mutex contents. In one of branches of the match expression I locked this mutex once again and got a deadlock. Rust compiler wasn't smart enough to realize that the temporary variab…

Rust already supports the kind of behaviour you are describing for borrows, because of non-lexical lifetimes. Code like the following now compiles:

    fn main() {
      let mut x = 42;
      let y = &x;
      println!("{y}");
      let z = &mut x;
    }
Even though y's scope overlaps with z's, and they introduce conflicting borrows, this code compiles because the compiler treats y's borrow as dead after its last use (this has been true since Rust Edition 2018, so for quite some time now). If you move the println after the mutable borrow then it fails to compile.

However values whose types have Drop are another matter. They are treated as if there's an explicit call to their drop function at the end of their lexical scope which pins their lifetime. This is intentional and desirable precisely because of the guard pattern (like for mutexes).

If you didn't have that guarantee, at worst your mutex's guard object would be immediately dropped because it's never referenced after it's created, or at best it would be very tricky to understand what the protected critical region is.

Re: A few good ideas in programming languages

#55
I know it's controversial but I really do love C++26's contract assertions.

I find they enable you, your consumers, IDEs, agents, etc understand the contracts of a method far faster, as it means you don't actually have to read the full method body. If the pre condition is correct and the post condition fails then you can be fairly sure the bug report goes to whoever owns that method, as either the precondition is wrong or the method is wrong.

Re: A few good ideas in programming languages

#56

> Borrow Checking It's very confusing name for this feature. It suggest that some sort of borrowing takes place and that it's just an optional check, which isn't the case. It should be named something like "enforced static usage analysis" instead. In my programming language I have similar mechanism. But it isn't just checking, since it affects code generation by tracking which variables are still in use and which can…

In rust it's a lot closer to optional: you can in principle compile rust without doing any borrow checking at all (and I believe in practice mrustc does not bother to implement it, because it's primarily used for bootstrapping and so assumes it is already being passed code that compiles with regular rustc).

Re: A few good ideas in programming languages

#57

Have there been any new good ideas in programming languages since LLMs came around? Or are we over that now..

Programming language innovation is measured in decades. I expect LLMs will make it easier to prototype new concepts, but adoption will still progress on a human timescale

If LLMs are writing code, won't adoption progress on LLM-timescales? Humans would seem to be out of the equation.

Re: A few good ideas in programming languages

#58

Earlier quoted context omitted.

Programming language innovation is measured in decades. I expect LLMs will make it easier to prototype new concepts, but adoption will still progress on a human timescale

The marketing pitch for these things was that they were supposed to induce "cambrian explosion of creations". That there was zero barrier to building anything anymore. This is surely true in programming languages especially, considering how fast LLMs took over software development? Surely this would mean we would get new ideas faster if that was the case? There is literally nothing stopping language designers from ge…

> So where are these prototypes?

I'm working on one, but you're not going to like it.

Re: A few good ideas in programming languages

#59

Nice list. I have a new language I'm working on (called Zena: https://zena-lang.dev/ ) with all of these in some form: If you have static types and unions, control-flow analysis and narrowing is critical for avoiding an excessive amount of casts - and if you also have pattern matching, you get very nice style where a type-check, state extraction, and branch are all one expression. Borrow checking. Zena is a GC'ed lan…

Zena looks super cool! I was wondering if you could walk me through this syntax thats part of the example loops:

``` let iterator = items.[Iterable.iterator](); // Dimensional types and formal verification make me super excited to see more of this language. You also probably mention this somewhere and I'm missing it, but any thoughts on adding pure functions / more general mutability enforcements?

Re: A few good ideas in programming languages

#60

Earlier quoted context omitted.

> In Rust variables are not destroyed after the last borrow ends but instead when it goes out of scope That's the problem. Once I had a tricky case, where I locked a mutex in a match expression only to read a single field to match from the mutex contents. In one of branches of the match expression I locked this mutex once again and got a deadlock. Rust compiler wasn't smart enough to realize that the temporary variab…

Rust already supports the kind of behaviour you are describing for borrows, because of non-lexical lifetimes. Code like the following now compiles: fn main() { let mut x = 42; let y = &x; println!("{y}"); let z = &mut x; } Even though y's scope overlaps with z's, and they introduce conflicting borrows, this code compiles because the compiler treats y's borrow as dead after its last use (this has been true since Rust…

> If you didn't have that guarantee, at worst your mutex's guard object would be immediately dropped

For named local variables it's a different story. They should remain alive until the end of their lexical scope. But for unnamed temporaries created in expressions different rules should apply - as soon as there is no reference to such temporary, it should be destroyed.

Post reply on HN