4 ms·
IMHO it's tooling. The industry has spend decades to help you to deal with the kind of mess OO tends to produce. The tooling isn't anywhere close when you have
by thomasz 6y ago
IMHO it's tooling. The industry has spend decades to help you to deal with the kind of mess OO tends to produce. The tooling isn't anywhere close when you have to deal with a mess of functions returning functions that return functions.
- samus 6y ago> a mess of functions returning functions that return functions. That is just a curried function with three arguments. The bigger problem is that programmers still have to understand how Hindley-Milner type inference works to figure out type errors. This gets worse when you add in type classes, dependent types and (Yog-Sothoth help you) lenses. Your point is still true. For any language, it is important to have an IDE ecosystem in place. The tooling must enable developers to move beyond fighting the unruly or boring parts of the language and instead leverage it to work on the domain.
- thomasz 6y agoNo, not necessarily. Curried functions have their own problems because they are missing the vital parameter names. But that's not what I meant. Think of the classic memoization example (written without a compiler at hand...) let createMemoizer f = let cache = Dictionary<_,_>() let f' = fun x -> match cache.TryGetValue(x) with | (true,value) -> value | (false, _) -> let result = f x do cache.[x] <- result result f' The signature is ```createMemoizer (f:'a->'b) -> 'a->'b```, which is not very telling, especially if it is returned by yet another function, so that even the createMemoizer name is lost. In classic OO, I'd just get a Memoizer object that carries vital documenation and what not with itself, as it is passed around. It's no even that much longer, it's just not as elegant to use. class Memoizer<TINPUT,TOUTPUT> { Dictionary<T,TOUTPUT> cache = new Dictionary<T,TOUTPUT>(); Func<TINPUT,TOUTPUT> f; /* ... */ public TOUTPUT Invoke(TINPUT parameter) { if (!cache.TryGetValue(parameter, out var result)) { result = f(parameter); cache[parameter] = result; } return result; } }