Live data from Hacker News

Thoughts on Rust, a few thousand lines in

rcoh.me

101–110 of 183 posts

Re: Thoughts on Rust, a few thousand lines in

#101
post #31

Earlier quoted context omitted.

String slicing using byte indices has to exist in some form, since it is the only thing that is efficient (O(1)). But, I guess it could have used syntax other than somestring[...].

It could slice on bytes and return a slice of bytes since the String type is a wrapper over Vec .

If you want to just slice on bytes without any String semantics, why not use Vec then? String implies that it is, well, a string.

Re: Thoughts on Rust, a few thousand lines in

#102

Earlier quoted context omitted.

> for Optional promotion You'll see the same in Rust fn example(name: Option ) -> Option { let name = name?; Some(name.len()) } Or fn example(name: Option ) { if let Some(name) = name { println!("{}", name.len()); } } A main difference is the requirement to use `Some`, which allows for the flexibility to apply to any enum. > but since `self.` is implicit To make sure I'm following, do you mean that Rust's `self.` is…

That all makes sense. I've only done a couple days of Rust, so my recollection is spotty. The shadowing makes sense because if a local variable was moved out, then you're not really shadowing it anymore. Is my understanding of that correct? > do you mean that Rust's `self.` is implicit in Swift? Swift's `self.` is implicit in Swift – in most contexts, to access a property the `self.` is not required. `self.name = "Jo…

> The shadowing makes sense because if a local variable was moved out, then you're not really shadowing it anymore. Is my understanding of that correct?

This is kind of a philosophical corner: can you shadow something that isn't there anymore? Once you've moved out of something, if you attempt to use the old name, then you'll get a compiler error different from "no such variable", so it's still there in some sense.

Pragmatically, I think you are on the money.

Re: Thoughts on Rust, a few thousand lines in

#103

Earlier quoted context omitted.

The obvious follow up question would be: so why is slicing a string a byte-wise operation and not a character-wise operation? If a string is an array of characters, why does it let me refer to individual bytes without explicitly casting it to a byte array? How often comparatively do you want the nth byte compared to the nth character? I would suspect that's pretty rare.

> How often comparatively do you want the nth byte compared to the nth character? I would suspect that's pretty rare. It's exactly the opposite of what you expect. Getting the nth codepoint is often (not always) semantically incorrect since a codepoint isn't necessarily one character. Multiple codepoints might combine to form one character. (In Unicode, these are called grapheme clusters.) Byte offsets are used a ton…

I still think that using the common [] operator for this is a mistake. Strings shouldn't offer [] at all, and instead should provide methods like codepoints(), bytes(), grapheme_clusters() etc for indexing, slicing, and iterating.

The reason being that the behavior of [] for string varies widely in different languages, and so this is something that's best made explicit, both to force the author of the code to consider whether their assumptions are valid and reasonable for what they're trying to do, and to give additional context to anyone else reading the code.

As it is, I suspect a common class of bugs for Rust will be with people assuming that [] slices codepoints, because it seems to work that way for ASCII.

Re: Thoughts on Rust, a few thousand lines in

#104
post #87
post #70

Earlier quoted context omitted.

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 p…

Panics are not unsafe. Panic exists in Rust because they are safe. If you don't want a panic on index, just don't index. Indexing into a UTF-8 string doesn't serve any reasonable consistent purpose anyway, because it is an abstraction of text that doesn't provide support to the notion that a "character" is more fundamental than a word or paragraph, etc. Rust's string slicing exists solely to make ASCII text easy to h…

I think that's too extreme. There are many legitimate reasons to slice non-ASCII text - for example, to split it on newlines.

Re: Thoughts on Rust, a few thousand lines in

#105
post #88

Earlier quoted context omitted.

i admire you: you change your occupation every couple of days, as well as the languages you've replaced rust for :)

Could you site this? I've looked at ilovecaching's comment history (at least up to ~60 days ago) and they seem consistent on being a networking programmer who uses C++. Was there a particular comment you found which would indicate this isn't the truth?

nb: you mean "cite".

why would you make me do this? you can doxx people on your own dime... still, for posterity:

https://news.ycombinator.com/item?id=18328964 "...now I am working full time as a Rust developer"

https://news.ycombinator.com/item?id=18310666 "As a long time Erlang developer..."

https://news.ycombinator.com/item?id=18265199 "As someone who has worked two jobs now writing, deploying, and operating Erlang clusters, I recommend switching to Rust."

https://news.ycombinator.com/item?id=18251478 "Becoming a professional Haskell and Erlang developer really shifted my view on OOP"

https://news.ycombinator.com/item?id=18185795 "I've been using Rust in production for a little over half a year, and my team and I have run into very few issues. [...] We're all extremely glad we chucked C++ and Go and switched to Rust. "

https://news.ycombinator.com/item?id=18171917 "I am exclusively using Go and Rust at home and at work, and I find myself equally productive in both."

you get the point.

Re: Thoughts on Rust, a few thousand lines in

#106

Earlier quoted context omitted.

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.

Modern Python uses whatever representation is sufficient to ensure 1-unit-per-codepoint for a given string (which it can do on creation, since strings are immutable). So you get ASCII, UTF-16 sans surrogate pairs, or UTF-32.

This is great for high-level code, but painful to work with from native code, because it usually needs some specific encoding to call into other libraries, and it's usually UTF-8 - so you need to re-encode all the time.

Re: Thoughts on Rust, a few thousand lines in

#107
post #89

One thing Rust doesn't seem to be doing very well yet is guard clauses, specifically when handling Option . I've seen and appreciated the use of guard clauses in many languages, as a good way to quickly check for a few conditions at the top of a function, and return early if those conditions aren't met. Since it seems that Option are recommended in Rust, there's a lot of time you want to quickly return if `Some(x)` i…

Related to the discussion in the second link, it sounds like Mr Pearce got to coin the phrase 'flow typing' to describe this situation but this is something people have been talking about for a long time.

Pseudocode:

    if (foo is a String) {
       foo.someStringMethod();
    }
Flip that around a little bit:

    if (foo is not a String) {
        return "error";
    }
    foo.someStringMethod();
And you've got a guard clause that's fundamentally the same kind you're asking for. I've wanted this structure in a language for a very long time. I was happy to see it pop up in Kotlin and would love to see it in Rust as well.

Re: Thoughts on Rust, a few thousand lines in

#108
post #50

Earlier quoted context omitted.

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

I'm not sure I'd consider that lib any safer than the average serialization library when things like this happen: https://github.com/serde-rs/json/issues/464

Re: Thoughts on Rust, a few thousand lines in

#109
post #57
post #50

Earlier quoted context omitted.

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

Hi -- OP here. I actually do it in the tests (but for TOML): https://github.com/rcoh/angle-grinder/blob/master/tests/inte... https://github.com/rcoh/angle-grinder/blob/master/tests/stru...

[deleted]

Re: Thoughts on Rust, a few thousand lines in

#110

Earlier quoted context omitted.

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.

One nitpick: `.chars`[1] gives you an iterable[2] of `char`s[3], each of which is always a 4 byte representation of a valid unicode character. This means that `"asdf".chars().collect()` will have a different size to `"asdf"` and `"asdf".chars().as_str()`. `.chars()` will never give you an incomplete codepoint, but it will give you incomplete characters, as you could have many c̶̼̟̏ó̷̘̉n̴̖̞̏̇t̸̡̃ĭ̸̻̬n̴̯͉̂͑ṵ̴̑a̷̛̫̳ẗ̸͕́i̷̱̫̓̋ǫ̸̑ǹ̶̼̅s̸̩̾̌ to represent what visually are a single char.

[1]: https://doc.rust-lang.org/std/string/struct.String.html#meth...

[2]: https://doc.rust-lang.org/std/str/struct.Chars.html

[3]: https://doc.rust-lang.org/std/primitive.char.html

Post reply on HN