4 ms·
This seems to imply that extensive use of composition in Haskell is a notable stylistic decision rather than an entailed effect of the fundamental design choice
by ajarmst 6y ago
This seems to imply that extensive use of composition in Haskell is a notable stylistic decision rather than an entailed effect of the fundamental design choices (first-class functions, lazy evaluation, type classes) that explicitly encourage such composition and a terse, mathematical syntax that makes the composition operation obvious.
Heavy use of Composition is idiomatic in lisps, too. It’s just the syntax doesn’t rub your face in it: It’s pretty common to see form in lisp that ends in a dozen close-parentheses as we see chains of forms being passed as arguments to other forms. It would be weird if composition wasn’t idiomatic in a language with first-class functions.
The loop macro isn’t good evidence: it’s notable precisely because of its difference from typical lisp usage. I’ve heard lisp programmers claim to refuse to use loop because it clashes with the rest of the language. I’m less interested in purity, and it is so convenient sometimes...if only as a clear illustration of just how much power and potential for abuse the CL macro system provides. Amd let’s just leave CLOS and metaobject protocols under the tarp for now :-)
- eru 6y ago> It’s pretty common to see form in lisp that ends in a dozen close-parentheses as we see chains of forms being passed as arguments to other forms. That's just a chain of function applications. Function composition puts the emphasis on the fact that functions are values in their own right and can be manipulated (eg with a composition operator) as objects without regard to any values they might act on. If you want to see one Haskell equivalent of loop, https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html https://hackage.haskell.org/package/monad-loops-0.4.3/docs/C... has got you covered.
- ajarmst 6y agoI’m not convinced that chain application and composition are meaningly distinct in anything but a syntactic sense if the language in question offers first-class functions and deterministic evaluation (eg no side effects). In mathematics, composition ($f \circ g$) is invariably described in terms of chaining f(g())—in fact, the composition operator is usually defined as alias for chaining. Yes, there are subtleties I’m glossing, but I don’t think support the thesis that function chaining and composition are significantly different at this level (i.e. the level of syntax and idiom rather than the level of Category Theory).
- eru 6y agoMostly agreed. John Backus seemed to think it was a big deal. See eg 'Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs ' (http://www.ict.nsc.ru/xmlui/bitstream/handle/ICT/1256/1977-backus.pdf http://www.ict.nsc.ru/xmlui/bitstream/handle/ICT/1256/1977-b...) On the one hand, I do agree that in a language like Haskell it's almost entirely a syntax level distinction. On the other hand, syntax level conveniences and inconveniences can have a big impact on how people use a language. (Eg in Haskell if-then-else is more hassle to type out than pattern matching. A slight nudge by the language design to make users prefer the latter.) Once you have acquired the ability to see functions as objects in their own right, many more techniques become available. Think of eg parser combinators. Technically you don't need the syntactic convenience to use parser combinators. But I am not sure they are worth the hassle without those conveniences. Eg Python has enough functional machinery to support parser combinators, but its options for defining functions (def and lambda) are just so cumbersome.
- ajarmst 6y agoAnd thanks for the link to the loop monad. I didn’t know it or forgot. I don’t know whether to be delighted or appalled.
- eru 6y agoGlad to be of service. (Slight pedantry: I wouldn't call it the 'loop monad' in the same way as 'list monad' or 'IO monad'. The monad loop library provides looping combinators you can use with many monads and some you can use with all monads.)