Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

`&` is a reference.

`'a` is a label for a memory area, like goto labels in C but for data. You can read it as (memory) pool A. Roughly, when function entered, memory pool is created, then destroyed at exit.

`'static` is special label for static data (embedded constants).

`()` is nothing, like void in C.

`&()` is an reference to nothing (an address) like `void const *` in C.

`&&()` is an reference to reference to nothing, like `void const * const *` in C.

`& 'static & 'static ()` is like void `const * const *` to a built-in data in C.

`& 'a & 'b ()` tells compiler that second reference is stored in pool 'a, while data is stored in pool 'b. (First reference is in scope of current function.)

`_` is a special prefix for variables to instruct compiler to ignore warning about unused variable. Just `_` is a valid variable name too.

  static UNIT: &'static &'static () = &&();

  fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
Let's say that `&'a` is from a function `a()`, while `&'b` is from a function `b()`, which called from the function `a()`.

The trick here is that we relabel reference from pool `'b`, from an inner function, to pool `'a` from outer function, so when program will exit from function `b()`, compiler will destroy memory pool `'b`, but will keep reference to data inside until end of the function `a()`.

This should not be allowed.



Thank you very much for spending time explaining this. It makes more sense with that kind of description. I'm still not sure how long it would take someone like myself to be comfortable and proficient with the syntax.

I guess stated another way, I don't generally have issues reading code from a wide swath of languages. If someone plopped me in front of a rust codebase I'd be at the mercy of the manual for quite a long time.

Thank you again, sincerely.


Rust decided to spend very little budget on syntax. The issue though, is that where it took said syntax from is very wide.

& is used for references in a lot of languages.

() is a tuple, same syntax as Python

'a isn't even novel: it was taken from OCaml, which uses it for generic types. Lifetimes are generic types in Rust, so even though it's not for an identical thing, it's related enough to be similar.

_ to ignore a name for something has a long tradition in programming, sometimes purely as a style thing (like _identifier or __identifier), but sometimes supported by the language.

fn name(args) -> {} as function syntax is not SUPER unusual. The overall shape is normal, though the choice between "fn," "fun," "func," or "function" varies between languages. The -> comes from languages like Haskell.

<> for generics is hotly debated, but certainly common among a variety of langauges.

the "static name: type = value;" (with let instead of static too) syntax is becoming increasingly normalized, thanks to how it plays with type inference, but has a long history before Rust.

So this leads to a very interesting thing, where like, it's not so much that Rust's syntax is entirely alien in the context of programming language syntax, but can feel that way unless you've used a lot of things in various places. And that also doesn't necessarily mean that just because it's influenced from many places that this means it is coherent. I think it does pretty good, but also, I'd refine some things if I were making a new language.


> I'd refine some things if I were making a new language.

Which parts would you change?


About a year ago I wrote this: https://steveklabnik.com/writing/too-many-words-about-rusts-...

I do think there's some good criticism of doing this, though, and so even a year later it's not clear to me it's a pure win.

I am sympathetic to the vague calls to action by Aria et al. to improve the syntax for various unsafe features. I understand why we ended up where we ended up but I think overall it was a mistake. I am not sure I agree with her specific proposals but I do agree with the general thrust of "this was the wrong place to provide syntactic salt." (my words, not hers, to be clear)

Ideally `as` wouldn't be a thing. Same deal, this is just one of those things that's the way it is due to history, but if we're ignoring all that, would be better to just not have it.

I am still undecided in the : vs = debate for structs.

I am sad that anonymous lifetimes in structs died six years ago, I think that would be a massive help.

Probably tons of other small things. Given the context and history, I think the Rust Project did a great job. All of this is very minor.


That blog post says that "Rust doesn’t have named parameters, and possibly never will". Could you clarify why that is the case? In my experience, named arguments in all but the simplest - i.e. unary and some binary - function calls give a massive boost to readability. And for Rust specifically, they would also provide an easy, unambiguous way to "overload" functions, similar to Swift (I'm putting "overload" in quotes here because it's not really overloading, as parameter names simply become part of the function name). So, why weren't they considered, or if they were considered, why were they rejected so emphatically that you don't anticipate them showing up even in the future?


Part of it is that it's not just named parameters: you should have a good story for default parameters too, and I think one or two others? Variadrics feels similar but separate. Oh, anonymous structs would allow you to emulate them while not adding the feature directly.

Therefore, it ends up being a really huge thing, with lots of design space. This is combined with the fact that

> they would also provide an easy, unambiguous way to "overload" functions

Not everyone sees this as a good thing.

Being slightly controversial, plus being really large, plus there being a lot of other things to do, would make me surprised if they ever land.

Here's a link from eight years ago with a link to lots of other related proposals: https://internals.rust-lang.org/t/pre-rfc-named-arguments/38...


> About a year ago I wrote this: https://steveklabnik.com/writing/too-many-words-about-rusts-...

The = on functions idea is particularly interesting by comparison with Scala, which has shifted towards requiring = over time.


FWIW, as a high performance C++ dev who likes Rust but considers unsafe the biggest issue by far, it's encouraging to see important folk within the project believe there are issues. Too often as a relative Rust outsider it feels like the attitude is "but the unsafe situation is okay because you'd barely ever actually need it!". Hope that unsafe continues to improve!


I appreciate the kind words, but haven't been a part of the project for a while now. I hope they share this opinion, but I don't know.


Ah okay, didn't know that. Good luck wherever you are!


To be fair, even for someone who is comfortable in Rust, the example is definitely on the rather confusing side of the language. (Not entirely surprising--it's a bug about a soundness hole in the language, which invariably tends to rely on overuse of less commonly used features in the language).

In particular, explicit use of lifetimes tends to be seen as somewhat more of a last resort, although the language requires it more frequently than I like. Furthermore, the soupiest of the syntax requires the use of multiple layers of indirection for references, which itself tends to be a bit of a code smell (just like how in C/C++, T * tends to be somewhat rare).


> If someone plopped me in front of a rust codebase I'd be at the mercy of the manual for quite a long time.

This is not a representative sample of Rust. That's explicitly triggering edge cases which requires abuse of syntax you wouldn't normally see.

Check out this for something more realistic that anyone should understand https://github.com/ratatui-org/ratatui/blob/main/examples/ca...


I write rust professionally and really like it, but I do think that its noisy syntax is a flaw. I'm not sure how I would clean this up, but it really can be inscrutable sometimes.


You will never actually encounter code like this in practical use.

And even if not, this example isn’t particularly hard to decompose and understand once you have a basic grasp of the independent underlying bits (generics, lifetimes, borrows). It’s just combining all of them pathologically into an extremely terse minimal reproduction.

It’s like saying you could never understand Java because someone linked to an AbstractClientProxyFactoryFactoryFactoryBean.


For an anecdota it took me roughly a year. I was trying it several times. I still use .clone() a lot but it is getting better. :)

The real question what is the use of Rust for you. Do you work on anything where Rust could be a value?


I think that's the best description of a lifetime I've seen so far.


If memory safety needs this level of fuckery to get going, it's not worth it for vast majority of software. Maybe stick to a GCed language until we can come up with a sane way to do it. These examples look cryptic as hell.


It's cryptic because it is a reduced test case to show off a bug. 99.9% of code doesn't look like this.

Just because "int ((foo)(void ))[3]" is a valid C declaration doesn't mean that all of C code looks like that.


This is basically the Rust equivalent of the obfuscated C code contest and indicates little to nothing about the actual Rust people write.


> this level of fuckery to get going

C++ has the same level of fuckery without memory safety. I don't think there is an extreme level of fuckery in Rust. I wish they got more influence from the ML languages than C++ but it is not unbearable.


It's a level of fuckery required to trigger a compiler bug. You don't see code like this in real code bases.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: