3 ms·
Regarding the lack of examples, the type system is strong enough that in many cases, if you write the types that you expect up front, there's only one or few po
by smallnamespace 6y ago
Regarding the lack of examples, the type system is strong enough that in many cases, if you write the types that you expect up front, there's only one or few possible implementations.
A common workflow for Haskellers is to specify type signatures and interactively edit until the compiler is satisfied. Often, the code gives you correct results on the first try.
This means the type signatures aren't simply documentation, they also strongly direct your implementation. The problem from a marketing and adoption standpoint is that this isn't visible until you've hopped into a REPL or IDE and tried it yourself.
- Silhouette 6y agoRegarding the lack of examples, the type system is strong enough that in many cases, if you write the types that you expect up front, there's only one or few possible implementations. This is a common counter-argument. It is a true statement. And, in the nicest possible way, it is also completely missing the point. When you're playing with cute mathematical code and almost everything is written in terms of totally generic types, it's cute that you get free theorems and automatic derivations of some basic functions and all that stuff. However, in the real world, 99% of the time we work with concrete types to get concrete work done, and there are going to be many possible implementations of a function of type Int -> Int, or MyDataStructure -> MyDataStructure -> MyDataStructure, or SomeWrapper SomeType -> (SomeType -> SomeOtherType) -> (SomeType -> SomeOtherType) -> SomeWrapper SomeOtherType. This remains true notwithstanding the possibility that some of that cute generic code was used to implement various small parts of the function you actually care about if you dig down far enough. This means the type signatures aren't simply documentation, they also strongly direct your implementation. The problem from a marketing and adoption standpoint is that this isn't visible until you've hopped into a REPL or IDE and tried it yourself. I would argue that the problem from a marketing and adoption standpoint is that it still isn't visible even if you do do those things, unless you're interested in writing heavily mathematical generic code rather than completing the job your boss told you to do within a reasonable timeframe.
- dragonwriter 6y ago> However, in the real world, 99% of the time we work with concrete types to get concrete work done, and there are going to be many possible implementations of a function of type Int -> Int, or MyDataStructure -> MyDataStructure -> MyDataStructure, or SomeWrapper SomeType -> (SomeType -> SomeOtherType) -> (SomeType -> SomeOtherType) -> SomeWrapper SomeOtherType. But, on the gripping hand, using types unspecific enough that that is the case is often a sign of underusing the type system. E.g., very few domains actually deal with bare numbers as domain values, and when you express concrete types specific enough, there may be more than one possible correct function, Bru very often the one actually correct function will be much more obvious, and the mistakes possible by omitting a step when using less-robust sets of types become impossible because you effectively have statically verified dimensional analysis.
- Silhouette 6y agoAs a general rule, I am all for defining specific aliases of fundamental types, type-safely if possible. I don't think this changes my argument materially, though. Real world applications of programming always come down to processing data of known, concrete types at some point. And at that point, all the power you get from saying things like there's only one possible implementation of a function f :: a -> a immediately go out of the window, because you don't have a value of type a, you have a value of type SomeConcreteTypeThatIKnowThingsAbout. In my experience, though of course yours may differ, there are very often still many plausibly correct implementations of functions working with those types and many ways to combine them that might make sense and that would satisfy the type checker. The idea that specifying the types alone is a viable substitute for proper documentation of the real meaning of the functions just falls apart at that point.
- codygman 6y ago> And at that point, all the power you get from saying things like there's only one possible implementation of a function f :: a -> a immediately go out of the window, because you don't have a value of type a, you have a value of type SomeConcreteTypeThatIKnowThingsAbout. Not if your logic is primarily in terms of domain types, invariants encoded in those domain types as is necessary and economical. > And at that point, all the power you get from saying things like there's only one possible implementation of a function f :: a -> a immediately go out of the window, because you don't have a value of type a, you have a value of type SomeConcreteTypeThatIKnowThingsAbout. Can you give an example? I can only see this being the case if your logic is done at the concrete type level.
- ashtonkem 6y ago> if you write the types that you expect up front, there's only one or few possible implementations. That does not square with the constant complaints about insufficient documentation. It also does not matter if there's only one or two valid ways to call a function if the programmer can't figure out how to do it.
- wirrbel 6y agoYeah you exemplify my point. None of what you wrote contradicts that examples could be given in the docs. But defending the lack of documentation kind of shows why haskell will not see much adoption. Also, rust for example is much more rich when it comes to examples in docs and rust people could also argue to not provide docs because of type signatures. They just decide to provide documentation and succeed in attracting people.