4 ms·
Why not let the computer do the work? My programming flow in Ocaml has always been: (1) Hack until I've got something stable. Note: at the start of coding I t
by GregarianChild 6y ago
Why not let the computer do the work? My programming flow in Ocaml
has always been:
(1) Hack until I've got something stable. Note: at the start of coding I typically don't quite know what the right abstractions are, so a lot of code (and associated types) are in constant flux.
(2) Once program is stable, wrap it in a module, let the compiler work
out all types and put them in as module interface.
That gives me the best of all possible worlds: type annotations at abstraction boundaries but
you don't have to type them out. Writing out explicit types inhibits
fast change. I wish the languages I'm using at the moment (Scala,
Rust, C++) allowed a flow like that. Alas, full type inference stops
being possible with more expressive typing systems.
- chrisseaton 6y ago> let the compiler work out all types and put them in as module interface ... type annotations at abstraction boundaries Right - that's not global type inference. It's intra-module type-inference.
- GregarianChild 6y agoI don't understand this objection. OCaml does full program inference. I just prefer to wrap things into modules from time to time. That's a pragmatic choice I make, not a restriction on type-inference. Aside, when I decide to change where I put module boundaries, full program inference helps too: I just throw away the old module definitions, draw different boundaries and re-run inference.
- chrisseaton 6y agoI'm not objecting to anything. This is how I thought most people used inference in OCaml.
- amw-zero 6y agoYou do need to write the types for records though.
- MaxBarraclough 6y ago> Why not let the computer do the work? Because a program's types can serve as part of its documentation.
- mathgladiator 6y agoThis is under-appreciated, and as I have aged I have discovered that I prefer the verbosity over brevity. Namely, when mentoring more junior engineers who can barely write code at all.
- deleted 6y ago[deleted]
- hombre_fatal 6y agoThe other benefit of top-level/function annotations is that they ensure that your mental model of the code is consistent with what the code actually does. So many times I will accidentally return 42 or Result<Result<42>> when I mean to return Result<42>. With annotations, my error is instantly obvious. Otherwise I accidentally have a function that returns Result<Result<number>> and it may lead to a very weird error message when I use `foo().map(_ + 100)` somewhere else. That's letting the computer doing more work, not less of it. Relying too much on inference can bow back into the human doing more of the work to figure out what the types actually are in a given spot.
- lmm 6y agoSometimes an IDE hover can be the best of both worlds - the information is there when you want it (and guaranteed to be accurate since it's using the language compiler's own type inference), but not taking up space when you don't want it.
- eru 6y agoThat helps, but it's orthogonal to adding type annotations. The computer can only tell you what types your code _has_ (from inference), but not what type it _should_ have based on your intentions. Type inference can only complain when your code contradicts with itself (on a type level), but can't tell you when it contradicts with your intentions. If you don't write out your intentions, you'd have to hover over everything to see if the inferred types differ from your expectations. IDE hover types and collapsible type annotations (and alternatively also collapsible implementation) are still useful as a way to declutter your UI when reading code.
- NOGDP 6y agoIs there anything specific that you find Rust is missing in this regard?
- eru 6y agoI think Rust deliberately limits type inference to information available in a single function?
- steveklabnik 6y agoYes.