one thing I’ve noticed. functional languages such ...
# arrow
m
one thing I’ve noticed. functional languages such and Haskell and F# have really nice type inference that’s very unintrusive and code looks almost dynamically typed (in F# almost always, idk about Haskell but it seems even better than in F#). Clojure is dynamically typed etc. why in Kotlin everybody is trying to type constraint the shit out of the code? why is everyone suggesting specifying types everywhere and creating types for everything? why not to rely on type inference in Kotlin too? in F# for example you specify type explicitly only if compiled can’t infer it
s
If you don’t do that you’ll get the inferred type of just String for both username and for password, effectively meaning that you can pass either of them to the same function which would expect only one of them. If anything it’s just so that you can’t make a mistake. Not sure what you mean with the rest of your message, for me type inference means you don’t explicitly write the type out and let the compiler pick the type for you. But it’s still of that type, doesn’t change anything.
m
I know what type inference is 😄
If you don’t do that you’ll get the inferred type of just String for both username and for password, effectively meaning that you can pass either of them to the same function which would expect only one of them.
if you have tests that’s probably not going to happen but ok what am talking about is that FP Kotlin community is relying on types way to much compared to what you see in other, also type safe, languages
for example, it was recommended by Arrow docs to even specify
Unit
return type of functions and they showed you how to disable IDE telling you that specifying
Unit
return type is not needed
s
Why write a test for what a type can achieve? The tests may miss something, your type won’t be accepted in a function which expects a different type. Keeping the public API of a class fully typed out comes with a few benefits, like not rogue changing your public if you change the implementation and accidentally return something else, and makes it easy for another dev to at a glance see what a function returns without having to look at the implementation to figure out what the return type is (or use the IDE somehow to do it). If it’s in the function signature it’s the clearest and fastest way to get that information. Hence the explicitApi mode exists too. For returning Unit I mean I’d normally not do it if the function is defined as a normal function, but if it’s defined as an expression
fun foo() = ...
, then I’d also want the
Unit
to be there, otherwise we’re back at trying to figure out if something actually returns here and what its type is. Where’s that part of the arrow docs btw?
m
Why write a test for what a type can achieve? The tests may miss something, your type won’t be accepted in a function which expects a different type.
Keeping the public API of a class fully typed out comes with a few benefits, like not rogue changing your public if you change the implementation and accidentally return something else
all of this can be mitigated/solved with having comprehensive test suite. and no, am not talking writing type specific tests
and am pretty sure that there are great libraries and code written Python and Clojure, for example but I guess that it comes down to preference
Would be nice with some examples of Haskell variants where you believe the types are inferred in a way that makes specifying them redundant. The little Haskell I've done has been with explicit typings everywhere. Haskell Language Server also suggests adding type signatures to your functions
j
In my experience this is about local VS global type inference. Kotlin is local as in each function needs a fully specified type when called, the compiler won't try to infer types by looking further than a function call (this is loosened up a little with builder inference and probably some other special cases). Haskell is globally inferred, or better put: haskell typechecks the whole program and thus has more options to infer a type. You can absolutely run haskell like a dynamically typed language, however it is good practice to add type signatures manually because it helps readability. Ghc also sometimes infers overly generic types and it may fail infer types when more complex features are involved, so annotating at least the top level functions is good practice.
Also types are additional documentation and specifying the types explicitly helps understanding. Sufficiently complex functions should always have fully specified types, even if they are local and possibly not exported. It just helps anyone reading code. Exported functions should always have fully specified types. Where this gets annoying for me is when I need to add types at function call sites, this happens in kotlin more often than in haskell due to differences in inference algorithms.