presented by Bayle Shanks
Haskell has typeclasses, but many libraries, even core libraries, don't make full use of them to acheive genericity. Example: the popular (non-core) Parsec parsing library was written to use Haskell strings, and the user couldn't just use it with bytestrings.
Example: there is a typeclass whose sole member is a function which is a generalization of "map". There is another one whose sole member is a function that gives you a sort of default value. I would have called these functions "map" and "default", and called the classes "Mappable" and "Defaultable". Haskell calls the functions "fmap" and "pure", and calls the corresponding typeclasses "Functor" and "Pointed".
If a body of codes refers to a particular datatype, you can't swap in another type that holds extra information. You can do that if the code always uses typeclasses instead of types. But Haskell's syntax is much cleaner if you use types.
You aren't allowed to make your code completely type-agnostic by only using typeclasses; Haskell would be unable to decide which type to actually use. The obvious solution would be to allow typeclasses to specify default types, but Haskell doesn't support this (except for a few core types, which are exceptions).
Code is cluttered with verbose, explicit type conversion function calls, like "fromJust".
In Python, for example, you can do "if list:", and the list value is treated as True iff the list is nonempty. This is a little different from type coercion, but it has the same effect. There is a protocol (__nonzero__) for user-defined classes to define how they want to be "coerced" to boolean.
In Haskell, you have to do this explicitly.
Haskell code is often filled with intermediate values and functions which are bound to one-off symbols. These one-off symbols are given short, non-explanatory names like x', x, x, f, g.
Python: arr[1] = 64 print (arr[1])
Haskell: arr' = arr [(1, 64)] print (arr ! 1)
(these aren't equivalent, but they are analogous)
---
Python: both trees and tables ("dictionaries")
---
WONTFIX
---
WONTFIX
---
$
---
CAN'T REPRODUCE
---
---
---
---
4
pos
def
key
partial
Haskell: partial
Python: def, key
java vs python vs arc vs oot
motif: cripple for readability, but with well-known exceptions
ex: mostly hygenic macros ex: infix fns
motif: syntactic sugar
motif: general operations
In imperative languages, attribute or array lookup is supposed to be:
whereas functions/procedures do not have these restrictions; in this situation, having different syntaxes is useful.
(even though some languages, for example Python, allow default behavior to be overriden by arbitrary functions, blurring the distincting; but the semantic convention still holds)
But in lazy functional languages, neither of these distinctions holds; nothing is supposed to have side effects, and lookup is not in general guaranteed to be fast b/c the evaluation of the contents of a container or struct might have been deferred