You should read the article, because it’s pretty much a direct rebuttal with justifications to this exact argument. You’ve really just re-stated what the article disputes.
Which isn’t to say you’re wrong, I’d just be interested in your response to the arguments.
The article doesn’t make a persuasive case at all. It immediately backs off by acknowledging that 99% of type inference is fine, because it’s really only complaining about function signature inference, which is an extreme case that only a few obscure ML variants like Ocaml and F# support.
It’s like saying all american movies are terrible, and then clarifying that you’ve only seen White Chicks
I don’t want to infer types from my code. I’d rather infer the code from the types. Types are the spec, they are small and low in expressiveness, code is big and has infinitely more degrees of freedom than types. The bug surface area is smaller with types.
So it makes sense to use the types (simple, terse, constrained) to generate the code (big, unconstrained, longer to write, bug-prone). Inferring types from code is like building a complex machine without plans, and then using an X-ray diffractometer to extract plans from the physical object.
This is the argument.
This comes back to a perennially forgotten/rediscovered fundamental truth about coding: It is much easier to write code than read code
This is immediately followed by the next part that in any sufficiently large organization, you spend more time reading code than writing code.
Put it all together? Fractional second gains in writing that have meaningful expenses when it comes to reading aren’t worth it once you’re operating at any kind of scale.
If you and your buddy are making little hobby projects. If you have a 3 person dev team. If you’re writing your own utility for personal use… I wouldn’t expect these features to become evident at that scale.
Again, it isn’t saying that it’s something intrinsically wrong, it’s just that there is a trade off and if you really think about it, under most professional environments it’s a net negative effect on efficiency.
I agree if we’re talking at the granularity of function signatures, but beyond that I don’t. Every language supports type inference when chaining expressions. Inference on local variables is often a way of breaking up large expressions without forcing people to repeat obvious types.
As for inferring code from types, scrub the symbol names off any production java code and see how much sense it makes. If you really go down this path you’re quickly going to start wanting refinement types or dependent types. Both great research fields, but the harsh reality is that there’s no evidence that either field is production ready, or that either solves problems in readability.
The best technologies for reading code are all about interactive feedback loops that allow you to query and explore. In some languages that is type-based, with features like dot-completion, go-to-definition, and being able to hover to see types and doc comments. And just knowing whether the code compiles provides useful information.
In other languages, like Python and JavaScript, that feedback loop is value-based, and in some ways far richer and more powerful, but it suffers from being unavailable in most contexts. Most importantly, the lack of error messages is not a very useful signal.
I am obviously no authority, but my honest opinion is that type inference is completely orthogonal to the questions that actually matter in code readability, so blaming it is silly.
My response to the article is that you’re sacrificing gains in language because some people use outdated tools. Code has more context than what is just written. Many times you can’t see things in the code unless you dig in, for example responses from a database or key value store, or literally any external api. Type inference in languages that have bad IDE support leads to a bad experience, hence the author’s views on ocaml. But in a language like Kotlin it’s absolutely wonderful. If needed you can provide context, but otherwise the types are always there, you can view them easily if you’re using a decent IDE, and type inference makes the code much more readable in the long run. I would say that a majority of the time, you do not care about the types in any application. You care about the data flow, so having a type system that protects you from mismatched types is much more important that requiring types to be specified.
Does type inference provide a practical benefit to you beyond saving you some keystrokes?
What tools do you use for code review? Do you do them in GitHub/gitlab/Bitbucket or are you pulling every code review directly into your IDE? How frequently do you do code reviews?
Yes. Type-inference typically *knows better than me* what the types should be.
I frequently ask the compiler what code I need to write next by leaving a gap in my implementation and letting the compiler spit out the type of the missing section.
I’ve never used Haskell, so I can barely read this as-is.
But sure: I have no idea, and I expect that’s your point.
You as the writer, you don’t know either? What if I could understand Haskell, is there an option to communicate that information to me? Or is the argument that nobody but the compiler and god need know? That having an awareness of the types has no value?
@Windex007
> You as the writer, you don’t know either?
Not until the compiler tells me.
> Or is the argument that nobody but the compiler and god need know? That having an awareness of the types has no value?
No, I want to know, because knowing the types has value. If the compiler has inference, it can tell me, if not, it can’t.
I recognize that truly functional languages are their own beasts, with tons of amazing features provided by a ton of academic backing.
I will absolutely concede that I can’t speak to them with a shred of competence. I don’t know about the trade-offs and relative value propositions for pretty much anything in that space, let alone specifically w/ explicit typing.
Does type inference provide a practical benefit to you beyond saving you some keystrokes?
it’s more readable! like, that’s literally the whole point. It’s more readable and you don’t have to care about a type unless you want or need to.
What tools do you use for code review? Do you do them in GitHub/gitlab/Bitbucket or are you pulling every code review directly into your IDE? How frequently do you do code reviews?
I use GitHub and Intellij. I do code reviews daily, I’m one of two staff software engineers on my team. I rarely ever need to know the type, and if I do Github is perfect for 90% of use cases, and for the other 10% I literally click the PR button in intellij and open up the pull request that way. It’s dead simple.
So you’re saying that for you, not only do you generally not see value is knowing types, but that them being explicitly defined is DETRIMENTAL to your ability to read the code?
For me, it’s like if I whip open a recipe book and see tomato sauce, dough, cheese, and pepperoni are the ingredients. Before the recipe details specifically how they are combined, I have a pretty good context from which to set expectations based on that alone. It’s a cheap way to build context.
But I don’t think you’re all lying. And you are very likely not all incompetent either. I wish I could sit down with you and have you show me examples of code where explicit types are detrimental to readability, so I could examine if there are cases that exist but are somehow being mitigated by a code style policy that I’m taking for granted.
You should read the article, because it’s pretty much a direct rebuttal with justifications to this exact argument. You’ve really just re-stated what the article disputes.
Which isn’t to say you’re wrong, I’d just be interested in your response to the arguments.
The article doesn’t make a persuasive case at all. It immediately backs off by acknowledging that 99% of type inference is fine, because it’s really only complaining about function signature inference, which is an extreme case that only a few obscure ML variants like Ocaml and F# support.
It’s like saying all american movies are terrible, and then clarifying that you’ve only seen White Chicks
This is the argument.
This comes back to a perennially forgotten/rediscovered fundamental truth about coding: It is much easier to write code than read code
This is immediately followed by the next part that in any sufficiently large organization, you spend more time reading code than writing code.
Put it all together? Fractional second gains in writing that have meaningful expenses when it comes to reading aren’t worth it once you’re operating at any kind of scale.
If you and your buddy are making little hobby projects. If you have a 3 person dev team. If you’re writing your own utility for personal use… I wouldn’t expect these features to become evident at that scale.
Again, it isn’t saying that it’s something intrinsically wrong, it’s just that there is a trade off and if you really think about it, under most professional environments it’s a net negative effect on efficiency.
I agree if we’re talking at the granularity of function signatures, but beyond that I don’t. Every language supports type inference when chaining expressions. Inference on local variables is often a way of breaking up large expressions without forcing people to repeat obvious types.
As for inferring code from types, scrub the symbol names off any production java code and see how much sense it makes. If you really go down this path you’re quickly going to start wanting refinement types or dependent types. Both great research fields, but the harsh reality is that there’s no evidence that either field is production ready, or that either solves problems in readability.
The best technologies for reading code are all about interactive feedback loops that allow you to query and explore. In some languages that is type-based, with features like dot-completion, go-to-definition, and being able to hover to see types and doc comments. And just knowing whether the code compiles provides useful information.
In other languages, like Python and JavaScript, that feedback loop is value-based, and in some ways far richer and more powerful, but it suffers from being unavailable in most contexts. Most importantly, the lack of error messages is not a very useful signal.
I am obviously no authority, but my honest opinion is that type inference is completely orthogonal to the questions that actually matter in code readability, so blaming it is silly.
My response to the article is that you’re sacrificing gains in language because some people use outdated tools. Code has more context than what is just written. Many times you can’t see things in the code unless you dig in, for example responses from a database or key value store, or literally any external api. Type inference in languages that have bad IDE support leads to a bad experience, hence the author’s views on ocaml. But in a language like Kotlin it’s absolutely wonderful. If needed you can provide context, but otherwise the types are always there, you can view them easily if you’re using a decent IDE, and type inference makes the code much more readable in the long run. I would say that a majority of the time, you do not care about the types in any application. You care about the data flow, so having a type system that protects you from mismatched types is much more important that requiring types to be specified.
Maybe I’m missing something:
Does type inference provide a practical benefit to you beyond saving you some keystrokes?
What tools do you use for code review? Do you do them in GitHub/gitlab/Bitbucket or are you pulling every code review directly into your IDE? How frequently do you do code reviews?
@Windex007 @snowe
Yes. Type-inference typically *knows better than me* what the types should be.
I frequently ask the compiler what code I need to write next by leaving a gap in my implementation and letting the compiler spit out the type of the missing section.
Can you explain why you wouldn’t know what a type should be?
@Windex007
lexer :: Parser LexState (Vector Int, Vector Token)
lexer = do
(positions, tokens) <- _ nextPositionedToken
…
What goes where the underscore is in the above snippet?
I’ve never used Haskell, so I can barely read this as-is.
But sure: I have no idea, and I expect that’s your point.
You as the writer, you don’t know either? What if I could understand Haskell, is there an option to communicate that information to me? Or is the argument that nobody but the compiler and god need know? That having an awareness of the types has no value?
@Windex007
> You as the writer, you don’t know either?
Not until the compiler tells me.
> Or is the argument that nobody but the compiler and god need know? That having an awareness of the types has no value?
No, I want to know, because knowing the types has value. If the compiler has inference, it can tell me, if not, it can’t.
I recognize that truly functional languages are their own beasts, with tons of amazing features provided by a ton of academic backing.
I will absolutely concede that I can’t speak to them with a shred of competence. I don’t know about the trade-offs and relative value propositions for pretty much anything in that space, let alone specifically w/ explicit typing.
it’s more readable! like, that’s literally the whole point. It’s more readable and you don’t have to care about a type unless you want or need to.
I use GitHub and Intellij. I do code reviews daily, I’m one of two staff software engineers on my team. I rarely ever need to know the type, and if I do Github is perfect for 90% of use cases, and for the other 10% I literally click the PR button in intellij and open up the pull request that way. It’s dead simple.
So you’re saying that for you, not only do you generally not see value is knowing types, but that them being explicitly defined is DETRIMENTAL to your ability to read the code?
For me, it’s like if I whip open a recipe book and see tomato sauce, dough, cheese, and pepperoni are the ingredients. Before the recipe details specifically how they are combined, I have a pretty good context from which to set expectations based on that alone. It’s a cheap way to build context.
But I don’t think you’re all lying. And you are very likely not all incompetent either. I wish I could sit down with you and have you show me examples of code where explicit types are detrimental to readability, so I could examine if there are cases that exist but are somehow being mitigated by a code style policy that I’m taking for granted.