Most active commenters
  • JoshTriplett(6)
  • Rusky(3)

←back to thread

517 points bkolobara | 26 comments | | HN request time: 0.001s | source | bottom
Show context
veber-alex ◴[] No.45042068[source]
I find the Zig example to be shocking.

It's just so brittle. How can anyone think this is a good idea?

replies(5): >>45042182 #>>45042784 #>>45043157 #>>45045393 #>>45046983 #
1. kouteiheika ◴[] No.45043157[source]
Every language has questionable design decisions that lead to brittle code, although some more than others.

Like, how can anyone think that requiring the user to always remember to explicitly write `mutex.unlock()` or `defer mutex.unlock()` instead of just allowing optional explicit unlock and having it automatically unlock when it goes out of scope by default is a good idea? Both Go and Zig have this flaw. Or, how can anyone think that having a cast that can implicitly convert from any numeric type to any other in conjunction with pervasive type inference is a good idea, like Rust's terrible `as` operator? (I once spent a whole day debugging a bug due to this.)

replies(2): >>45043445 #>>45050774 #
2. veber-alex ◴[] No.45043445[source]
You are right, but it doesn't mean we can't complain about it :)

As a side note, I hate the `as` cast in Rust. It's so brittle and dangerous it doesn't even feel like a part of the language. It's like a JavaScript developer snuck in and added it without anyone noticing. I hope they get rid of it in an edition.

replies(3): >>45043464 #>>45043857 #>>45045791 #
3. JoshTriplett ◴[] No.45043464[source]
> As a side note, I hate the `as` cast in Rust. It's so brittle and dangerous it doesn't even feel like a part of the language. It's like a JavaScript developer snuck in and added it without anyone noticing. I hope they get rid of it in an edition.

Rust language hat on: I hope so too. We very much want to, once we've replaced its various use cases.

replies(2): >>45043819 #>>45044497 #
4. bigstrat2003 ◴[] No.45043819{3}[source]
As a Rust user, I hope that "as" never goes away. It's way too useful to get rid of, e.g. deliberately truncating numbers to a smaller number of bits. Can you do that in other ways? Absolutely. But they are all less ergonomic than "as". At most I would be ok with restricting "as" to an unsafe block, though that isn't a perfect solution because unsafe isn't really meant to apply to such cases.
replies(1): >>45044125 #
5. jcranmer ◴[] No.45043857[source]
As much as I hate 'as' and try to avoid it, it also covers several things that are impossible otherwise (integer <-> float casts are impossible without it, e.g.). I've found that sometimes just being able to express a coerce-to-type-damn-the-consequences is useful.

Another painful bugbear is when I'm converting to/from usize and I know that it is really either going to be a u64 or maybe u32 in a few cases, and I don't care about breaking usize=u128 or usize=u16 code. Give me a way to say that u32 is Into<usize> for my code!

6. JoshTriplett ◴[] No.45044125{4}[source]
I'm hoping that we provide ergonomic alternatives for all the individual use cases. The brevity of `as` is a major reason we haven't removed it yet.

We have `.into()` for lossless conversions like u32 to u64.

We need to fix the fact that `usize` doesn't participate in lossless conversions (e.g. even on 64-bit you can't convert `usize` to `u64` via `.into()`).

We need to fix the fact that you can't write `.into::<u64>()` to disambiguate types.

And I'm hoping we add `.trunc()` for lossy conversion.

And eventually, after we provide alternatives for all of those and some others, we've talked about changing `as` to be shorthand for `.into()`.

replies(4): >>45045654 #>>45045700 #>>45047402 #>>45048310 #
7. 1718627440 ◴[] No.45044497{3}[source]
How are people supposed to use a language, that changes syntax?
replies(1): >>45044618 #
8. sunshowers ◴[] No.45044618{4}[source]
Rust's edition system allows the language frontend to be changed every few years.
replies(1): >>45045205 #
9. JoshTriplett ◴[] No.45045205{5}[source]
In particular, note that new Rust compiles code with both old and new editions. Upgrading Rust does not require you to move to the new edition. And one project can pull in crates from multiple editions.

(Imagine if Python 3 let you import Python 2 modules seamlessly.)

replies(1): >>45045661 #
10. Rusky ◴[] No.45045654{5}[source]
A method call like `.trunc()` is still going to be abysmally less ergonomic than `as`. It relies on inference or turbofish to pick a type, and it has all the syntactic noise of a function call on top of that.

Not to mention this sort of proliferation of micro-calls for what should be <= 1 instruction has a cost to debug performance and/or compile times (though this is something that should be fixed regardless).

replies(2): >>45046657 #>>45046754 #
11. 1718627440 ◴[] No.45045661{6}[source]
That's nice, but I think at some point they will cut the old implementation, as otherwise they would end with hundreds of versions.

And it doesn't exactly help to compile newer software on an older OS.

replies(2): >>45045713 #>>45046004 #
12. ChadNauseam ◴[] No.45045700{5}[source]
> We need to fix the fact that you can't write `.into::<u64>()` to disambiguate types.

This confused me too at first. You have to do `u64::from(_)` right? It makes sense in a certain way, similar to how you have to do `Vec::<u64>::new()` rather than `Vec::new::<u64>()`, but it is definitely more annoying for `into`.

replies(1): >>45046726 #
13. sunshowers ◴[] No.45045713{7}[source]
No, there's a commitment to not cut old editions. A new edition/frontend comes out every 3 years, so Rust (and maybe humanity) is probably going to be completely dead long before it has hundreds of versions.
14. Starlevel004 ◴[] No.45045791[source]
As someone working with bitfields and enums-to-ints a lot, you can take ``as`` out of my cold dead hands.
15. steveklabnik ◴[] No.45046004{7}[source]
To elaborate on what sunshowers said, because editions only impact the early parts of the compiler, most of the code isn’t edition specific, which makes maintenance easy.
16. int_19h ◴[] No.45046657{6}[source]
The compiler doesn't have to implement a call as a call; having "magic functions" calls to which are special-cased by the code generator is an old and time-honored tradition.
replies(1): >>45046828 #
17. JoshTriplett ◴[] No.45046726{6}[source]
Yeah, you either need `u64::from` or `let x: u64 = expr.into()` or similar.

It does "make sense" but it's obnoxious, and we should have something better.

replies(1): >>45048428 #
18. JoshTriplett ◴[] No.45046754{6}[source]
> A method call like `.trunc()` is still going to be abysmally less ergonomic than `as`. It relies on inference or turbofish to pick a type, and it has all the syntactic noise of a function call on top of that.

If `as` gets repurposed for safe conversions (e.g. u32 to u64), there's some merit to the more hazardous conversions being slightly noisier. I'm all for them being no noisier than necessary, but even in my most conversion-heavy code (which has to convert regularly between usize and u64), I'd be fine writing `.into()` or `.trunc()` everywhere, as long as I don't have to write `.try_into()?` or similar.

> Not to mention this sort of proliferation of micro-calls for what should be <= 1 instruction has a cost to debug performance and/or compile times (though this is something that should be fixed regardless).

I fully expect that such methods will be inlined, likely even in debug mode (e.g. `#[inline(always)]`), and compile down to the same minimal instructions.

replies(1): >>45046825 #
19. Rusky ◴[] No.45046825{7}[source]
> I'd be fine writing `.into()` or `.trunc()`

Yes, this is specifically what I'm disagreeing with.

> I fully expect that such methods will be inlined, likely even in debug mode (e.g. `#[inline(always)]`), and compile down to the same minimal instructions.

That's the cost to compile time I mentioned.

replies(1): >>45047031 #
20. Rusky ◴[] No.45046828{7}[source]
Yes, that's how it should work. It is not how it works in today's rustc.
21. JoshTriplett ◴[] No.45047031{8}[source]
Many things in the language theoretically go through a trait as well, except that we have special cases in the compiler to handle those traits more efficiently. If this were a performance issue, there's no reason we couldn't do the same for `.trunc()` or `.into()`.
22. muvlon ◴[] No.45047402{5}[source]
> We need to fix the fact that you can't write `.into::<u64>()` to disambiguate types.

Yes, that would be great. In the meantime, if you can't wait but want something like this, you can DIY it via an extension trait.

It's very easy to write it yourself, this is all it takes:

  pub trait To {
      fn to<T>(self) -> T where Self: Into<T> {
          <Self as Into<T>>::into(self)
      }
  }
Now whenever this trait is in scope, you get to simply do .to::<u64>() and it does exactly what Into does. If you prefer adding a tiny dependency over copy-pasting code, I've also published a crate that provides this: https://crates.io/crates/to_method
23. tczMUFlmoNk ◴[] No.45048310{5}[source]
> And eventually, after we provide alternatives for all of those and some others, we've talked about changing `as` to be shorthand for `.into()`.

Whoa, that could be awesome. It's always felt a bit unfortunate that you can't write `val.into::<SomeExplicitType>::()`—because the type parameter is on the trait, not the method. Of course, `SomeExplicitType::from` works, but sometimes that slightly upsets the flow of code.

Having just `val as SomeExplicitType` might be really nice for that common case. I do wonder if it'd feel too magic… but I'm optimistic to see what the lang team comes up with.

24. estebank ◴[] No.45048428{7}[source]
If only we had type ascription on expressions... ducks
25. vjerancrnjak ◴[] No.45050774[source]
I would like a language where your call stack can't be bigger than two/three.

You can call functions inside your function Main, but these function can't call any functions anymore (exception being flat helper functions defined inside your function).

I think it would save a huge chunk of time by just having all programs really nice and flat. You'd naturally gravitate towards mechanisms that make programs flat.

replies(1): >>45051874 #
26. dboreham ◴[] No.45051874[source]
Also allows founding of: The Flat Program Society.