Hacker News new | ask | show | jobs
by sacado2 2211 days ago
> Maybe I’m doing something wrong, but my Go code is often littered with casts between different integer sizes and signedness.

It can actually be a feature, and one of the things that brought me to go, as you can define your own integer (or float, or string, etc.) types, thus making them incompatible with each other:

    type distance int
    type speed int
    func distFor(d distance, t time.Time) speed { ... }
    ...
    x = distFor(x, t) // Oops, that's probably a bug!
Not many languages let you do this, especially back then. But yeah, not great for exploratory programming.
1 comments

This is probably the biggest thing I wish was easier to do in Rust. You can make "newtypes" by wrapping the value in a tuple (that gets compiled away), but it's a fair amount of boilerplate or macros to make the newtype useful. Once you have what you need, it's fine, but it's even less convenient for exploratory programming ;-)
> but it's a fair amount of boilerplate or macros to make the newtype useful.

As mentioned in the docs, you can use the Deref facility to have the newtype implement everything that the original type does. Rust just gives you the choice of doing this vs. wrapping with a custom set of impls.

I'm not sure why I didn't recall that :-P Of course you are correct!
Oh, Rust does not have elegant strong typedefs? Bummer. Are they at least planned? It's such a boon for type correctness/safety.
I'm sorry but that does not look like an elegant first-class language construct, more like a pattern workaround.
I have to admit that I felt that way about it too. In fact, I think everybody felt that way about it at first. It was a work-around. The reason it was never changed, though, was that people didn't find anything significantly better. Rust is already a big language. It doesn't necessarily need new constructs.

However, as the OP of this thread, I have to admit that I often feel conflicted about it. Using the Deref trait certainly feels like another hack (and some people really dislike it). Basically Deref is what's used to dereference a reference. It's invoked automatically when you are calling a trait function on a variable. So if you have a variable that's a struct that implements a trait, it will bind to the function on that trait. If your variable contains a reference to the struct, then the compiler is smart enough to see if the struct implements the trait and then automatically uses the Deref train to derefernce the reference and bind to the function.

So if you want to delegate from one type to exactly one other type, you can do it simply by implementing the Deref trait on the first type and having it convert to the second type. It's kind of elegant, but also kind of hacky :-) There are people who feel that Deref should only be used for objects that are actually memory references. Other people feel that it's OK to use it when one type is masquerading as another type (as we are doing when we put a data structure inside a tuple to make it a "new type").

On the plus side, it gives you really fine grained control without adding new constructs to the language. You can make a "new type" that incurs no runtime overhead (in speed or space) and you can choose whether to delegate all of the function calls to the contained type, or to control them explicitly. The former is really, really easy (essentially 5 lines of boilerplate) and the latter is extremely easy to read and reason about. I have to admit that it's hard to justify adding a new construct for something that is not actually broken (except when you first look at it ;-) ).

And, really, to me this is Rust in a nutshell. It's got a lot of really elegant and intelligent decisions going into its implementation, but all of them look incredibly unlikely when you first look at them. The result is that the learning curve is quite high and the road to fluency long. Often newbies (which I probably still qualify for) ask, "Why the heck is it done this way". When you get the answer, it make sense, but it's often not as satisfying as you had initially hoped :-) Still, like others who push past that point, I've got to say that I really enjoy writing Rust code. It's strange.

What specific problems do you see with it?