6 ms·
"In type checking, only the signature of functions are considered. There’s no relying on the implementation for determining if callers are correct (like you can
by smabie 6y ago
"In type checking, only the signature of functions are considered. There’s no relying on the implementation for determining if callers are correct (like you can do in Scala, or Haskell)"
What does this mean?
- twic 6y agoYou can know the exact parameter and return types of a function by reading its signature. You can't do that in Scala, because of type inherence. This is legal Scala: def twice(x: Int) = { x * 2 } But you can't know the return type without reading the function body. That example is not so bad. I routinely used to confront things like: def applyComputation(x: Int) = { determineComputation().compute(x) } And now you're off on an adventure to work out the return type. EDIT There's sort of a deviation from this with "impl trait" returns. There the signature says that the function returns some type which implements a certain trait, but you can't tell exactly what.
- jfim 6y agoIt's been a while since I've written any Scala, but if I recall correctly it's frowned upon to use type inference for return values in method signatures.
- twic 6y agoYes, inference. My phone is very keen to use the word "inherence", which I didn't even know was a word. In Scala it's frowned on. In Rust it's not possible.
- MrBuddyCasino 6y ago> it's frowned upon to use type inference for return values in method signatures The language shouldn't allow it in the first place. Its a symptom or not balancing power with complexity and shows up elsewhere in Scala. They "were so preoccupied with whether or not they could that they didn't stop to think if they should."
- logicchains 6y agoOCaml also does global type inference like this, and it generally works out fine (unlike Haskell, it's not idiomatic to write a type signature for every single top level function in OCaml). Maybe because the type system is more principled compared to Scala.
- momentoftop 6y agoOcaml and the MLs have a very strong commitment to global type inference, much stronger than Haskell's. Scala has no commitment. That said, you do see a lot of types in Ocaml code. Ocaml source files typically have an accompanying signature file (with extension ".mli" rather than ".ml"). The signature file gives explicit types for all of the definitions (fields) in the structure file. Often, you need to write these signature files because you want to hide implementation details from the user and so give narrower types than the ones inferred by the compiler. You can and do write Ocaml without ".mli" files, and there, you are relying heavily on global type inference, and built-in Ocaml tools to tell you what your most general ".mli" file would look like. You can and do get the compiler to write them for you and then add your restrictions and documentation. As such, Ocaml programmers are very used to reading these signatures as the entry point to understanding a library. This doesn't work so well in Haskell, because Haskell doesn't have global type inference, and annotations are sometimes mandatory. Consider the expression show (read "1") Without saying what type "read" is supposed to return here, there's no way to know what this code is supposed to do.
- MrBuddyCasino 6y ago> Ocaml tools to tell you what your most general ".mli" file would look like Thats a nice idea! Can those tools do automatic refactorings to use the generalized type?
- momentoftop 6y agoAh, sadly I haven't come across any refactoring tools for Ocaml. But in Emacs with Merlin, I regularly hit "C-t C-t" on a module identifier, and it brings up the signature in another window, whether there is an ".mli" file or not.
- Erlich_Bachman 6y agoSo basically is Rust like C/C++ this way? In C++ you also have to know exact types of arguments and return types?
- twic 6y agoIt's like pre-C++14 C++. C++14 added automatic return type deduction!
- valenterry 6y ago> But you can't know the return type without reading the function body Use a good IDE like IntelliJ. It has shortcuts to show ot for you and it will show you the return type automatically in the editor if you want (using different font-style to distinguish it from the actual code). It can even be configured where to show it and where not.
- smabie 6y agoWhy is this a problem? It's trivial for any editor to just display the return type. How is the lack of type inference a feature? Type inference makes a statically type language so much better. For example, in OCaml it is rare to ever implicitly define the return type of a function, and it's never caused my any problems. If I need to see the return type, I just C-c C-t and it's displayed for me.
- logicchains 6y agoIn modern C++, you can write: template<typename T, typename U> auto myFn(T x, U y){ return x + y; } Note the return type of the function is not specified; it could return anything, depending on what the type of x + y is. In Rust you can't do that; you must specify the return type of the function.
- jasode 6y agoThat's not a good C++ example for comparison because that's using templates. The whole point of templates is to have "code that generates other code". Therefore, omitting the types as much as possible lets the compiler deduce types so the programmer doesn't have to manually write multiple redundant versions with different types. With normal functions, one parameterizes values but templates lets you parameterize types so explicitly putting a return type defeats the purpose of templates. In the context of the Rust blog, the comment about type signatures seems to be about ABI Abstract Binary Interface backward compatibility of libraries and not templates generating code.
- logicchains 6y agoIt also works without templates: auto add(int a, int b){ return a + b; } But yes there's usually less reason to do it for a normal function.
- skohan 6y agoThis is one thing which makes it almost unbearable for me to go back to programming in Javascript. The signature gives precisely zero information about the types being used, so if a library is not well documented, you often have to go to the source to figure out what's being expected and returned.