3 ms·
"Rust puts things in the signature that aren't there in many other places." I expect this sort of thing scales up as you are putting more in the type signature
by jerf 4y ago
"Rust puts things in the signature that aren't there in many other places."
I expect this sort of thing scales up as you are putting more in the type signature. Simple manifestly-typed languages like C or Go can't say much in their type signature compared to Rust, so it is harder to notice as a principle, though I think it's still present if you examine it hard enough. (A good example of how learning another language can be the best way to advance in your "core" language.)
Haskell is an interesting supporting case for your core thesis; it can put a lot more in its type signature than most languages, but it also has inference, even pretty good inference considering how strong and complex the type system is. However, community practice is (and has been for a long time) to put type annotations on all your top-level functions, to a large degree for the same reason you are talking about. Haskell can get away without annotations to a large degree, but you'll be chugging along changing this & tweaking that, and suddenly your entire program explodes into a mess of type error messages attributed to all your code everywhere because of some change you made. Explicit annotations contain the blast radius of such changes and keep the compiler messages pointing at something much closer to the vicinity of what you actually changed and somehow broke. At the top expression level, type inference is treated more as a tool for determining the top-level types than a solution on its own terms.
- FullyFunctional 4y ago100% In fact much of "debugging" when I was writing Haskell was to increasingly hand type-annotate stuff to catch where my assumptions were flawed. Definitely, top-level exported entries almost all get an explicit signature is it's part of the documentation. Rust's level of type inference feels very natural to me and I don't miss what additional inference Haskell provided.
- dllthomas 4y ago> Rust's level of type inference feels very natural to me and I don't miss what additional inference Haskell provided. The biggest place I miss Haskell's inference is the repl; When futzing with a new library I very much appreciate being able to glue things together in ghci and ask what the type is. I don't know how to get something quite that general quite that easy in rust, although 'let _: () = my(expression)` is often good enough.
- FullyFunctional 4y agoI again agree completely, especially when learning, but even today I will occasionally prototype stuff in ghci. There is irust which seems to work well. I haven't used it enough find the limitation (eg. can you define new types at the prompt? I haven't tried).
- steveklabnik 4y ago> I expect this sort of thing scales up as you are putting more in the type signature. Yep, I would agree with this. On my mental list of "stuff to blog about someday" is a post along these lines. For me, most Rust code fits into a sort of sweet spot, with enough types to make things helpful, but not so many that it causes pain. Other people have different preferences and/or goals when it comes to these sorts of things. Incidentally, I was porting some Haskell code to Rust the other day, and ran into some of these differences. Oops, there's a lot more to this signature than I originally considered! This caused me to completely change the API of the code, given that what's natural for Haskell isn't always natural for Rust.
- asib 4y agoI always explicitly annotate when writing Haskell, but I often like to remove types on functions (one at a time) to see what Haskell infers because it sometimes gives me a more general type that I prefer. But then I'll manually add in that annotation.