Live data from Hacker News

Thoughts on Rust, a few thousand lines in

rcoh.me

61–70 of 183 posts

Re: Thoughts on Rust, a few thousand lines in

#61

One thing I don't like about Rust is how taking a slice of a string can cause a runtime panic if the start or end of the slice ends up intersecting a multi-byte UTF-8 char. I would prefer it if this feature didn't exist at all rather than cause runtime panics. https://play.rust-lang.org/?gist=e02ce5e9aacfee3a2b4917d5624...

Go indexes bytes on strings, even though there's a builtin type called Rune which delimits utf-8 codepoints. This is yet another footgun. Is there a language that doesn't handle this poorly? https://play.golang.org/p/CkBp0w8T621

UTF-8 is at odds with efficient array indexing. I like pythons approach where bytes and strings are distinct types, though I have no idea what it is doing under the hood.

Re: Thoughts on Rust, a few thousand lines in

#62
post #50

Rust is one of the few times where the language/ecosystem does precisely what I wished it would do. For instance, being able to partially destructure JSON into a struct in a typesafe manner is just awesome.

This sounds really useful, you don't happen to have an example of this do you? Thanks in advance!

I’m basically talking about Serde. Read the section titled “Parsing JSON as strongly typed data structures”. What’s nice is that you don’t have to include all the fields in the JSON in the struct. Serde will only give you the ones defined by the struct.

https://github.com/serde-rs/json/blob/master/README.md

Re: Thoughts on Rust, a few thousand lines in

#63
post #43

Earlier quoted context omitted.

Why not this? fn main() { let a = "ab早".as_bytes(); let a = &a[..3]; println!("Hello, world!"); }

It's not clear to me what you're suggesting; is it that String shouldn't have supported indexing in the first place? That code does work, but you have a &[u8] not a &str.

But neither AsciiString. It has a as_str method, but it's still a kludge.

This example was basically a suggestion to throw0u1t: if they want to cut in the middle of the utf-sequence for whatever reason, they can [edit:] do it without extra crates.

What I don't understand is why slices are indexed in bytes and not in objects. If String has an ability to check that we're cutting in the middle of the character sequence, why doesn't it provide an ability to take 3 fully formed characters.

Re: Thoughts on Rust, a few thousand lines in

#64
post #56

Earlier quoted context omitted.

It's not clear to me what you're suggesting; is it that String shouldn't have supported indexing in the first place? That code does work, but you have a &[u8] not a &str.

I think he's suggesting that slicing on strings should be by character, and if you want to slice on bytes, you should explicitly ask to treat the string as a byte array. It makes more sense semantically, and it's safe.

Slicing on characters is a linear time operation and indexing is meant to be cheap.

Re: Thoughts on Rust, a few thousand lines in

#65

> the escape hatch suggested on the internet, `partial_cmp(...).unwrap_or(Ordering::Less)` This is often a Bad Idea, as you get unstable sorts and you are right back to the same problem. - Explanation: How do I get the minimum or maximum value of an iterator containing floating point numbers? — https://stackoverflow.com/a/50308360/155423 - Example: https://play.integer32.com/?version=stable&mode=debug&editio... See a…

To me this feels quite pedantic. Being able to do less than on NaNs and just having it do something vaguely sensible (as in your linked solution) is a far more common requirement than need to handle NaNs specially.

You could even say the reason NaN exists is so that you don't have to check for NaN constantly. Rust is being technically correct but practically really annoying, for basically no benefit.

Re: Thoughts on Rust, a few thousand lines in

#66

Earlier quoted context omitted.

Yes, the literal < in the language induces a partial order by convention. What I'm getting at in my comment is that you can define a sensible total ordering.

The challenge becomes what code to emit when you see those operators: native target comparisons, or the software implementation of your total ordering? The latter is safe and slow and the former is fast and IMO idiomatic. So since no one needs this often enough to emit the soft-float comparison code, we should emit the fast code. If folks need different behavior they should use different types. This is similar to the…

[deleted]

Re: Thoughts on Rust, a few thousand lines in

#67

One thing I don't like about Rust is how taking a slice of a string can cause a runtime panic if the start or end of the slice ends up intersecting a multi-byte UTF-8 char. I would prefer it if this feature didn't exist at all rather than cause runtime panics. https://play.rust-lang.org/?gist=e02ce5e9aacfee3a2b4917d5624...

Go indexes bytes on strings, even though there's a builtin type called Rune which delimits utf-8 codepoints. This is yet another footgun. Is there a language that doesn't handle this poorly? https://play.golang.org/p/CkBp0w8T621

In Rust, you're supposed to use `unicode-segmentation`[1] if you need to split on logical character (grapheme cluster in the Unicode standard). Otherwise, the iterators `.bytes` emits raw bytes, and `.chars` emits UTF-8 codepoints.

Basically, string indexing is a lot harder than it seems at first glance, depending on what you want.

Re: Thoughts on Rust, a few thousand lines in

#68
post #63

Earlier quoted context omitted.

It's not clear to me what you're suggesting; is it that String shouldn't have supported indexing in the first place? That code does work, but you have a &[u8] not a &str.

But neither AsciiString. It has a as_str method, but it's still a kludge. This example was basically a suggestion to throw0u1t: if they want to cut in the middle of the utf-sequence for whatever reason, they can [edit:] do it without extra crates. What I don't understand is why slices are indexed in bytes and not in objects. If String has an ability to check that we're cutting in the middle of the character sequence,…

> What I don't understand is why slices are indexed in bytes and not in objects.

Slicing is an O(1) operation, and that would be an O(n) operation.

Re: Thoughts on Rust, a few thousand lines in

#69
post #48

let foo = "..."; let foo = parse(foo); let foo = escaped(foo); ... doSomethingWith(foo); I don't see how this is helpful for avoiding the bug described. The most common bug with this type of code is mistaking which form "foo" represents at a given line of code, or that form changing as the code evolves. For example, if one programmer writes let foo = "..."; let foo = parse(foo); ... doBarWithFoo(foo); and another pro…

I think the example only really works if `parse` and `escaped` return something other than a string. If that was the case, the type system will save you.

Re: Thoughts on Rust, a few thousand lines in

#70
post #56

Earlier quoted context omitted.

I think he's suggesting that slicing on strings should be by character, and if you want to slice on bytes, you should explicitly ask to treat the string as a byte array. It makes more sense semantically, and it's safe.

Slicing on characters is a linear time operation and indexing is meant to be cheap.

That seems like taking it too far. It's like using pointer arithmetic to index a linked list on the assumption that the nodes happen to be allocated contiguously in memory. I mean, I guess the thinking is, indexing a Unicode string isn't cheap, but indexing strings used to be cheap once upon a time, when strings were encoded in fixed one-byte-per-character representations, so let's pretend that's still the case and panic if it doesn't work out.... That's weirdly antithetical to Rust's purported focus on safety.

Also, you can get the same performance from an operation that returns a byte array instead of a string. If that kind of performance is what you want, then a Unicode string is simply not the right type to use.

Post reply on HN