Hacker News new | ask | show | jobs
by mumblemumble 1020 days ago
It's also nice for making certain kinds of code more readable and maintainable in a way that isn't perfectly emulated by anything in OOP.

Here's a nice talk on the subject: https://www.youtube.com/watch?v=sfYA0HCWgqQ

and slides: https://fsharpforfunandprofit.com/pipeline/

This "looser" way of doing things tends to be more popular in the F# community, which isn't terribly fond of those rigid crystalline structures that you get in other corners of the FP community. Though I'd also point out that, even in Haskell, ways of programming that lead to incomprehensible and resistant-to-change code are often viewed as a sign of inexperience by more seasoned developers. There's a lot of truth in this joke: http://pages.cpsc.ucalgary.ca/~robin/class/449/Evolution.htm

1 comments

I use Lean 4 quite a lot these days, and I appreciate how the developers embrace syntax extension and metaprogramming solutions rather than trying to encode complicated control flow using ascii art operators (it's like Lisp meets the ML family). I suppose programming with dependent types is enough of a challenge, so why make it even harder? They've got a sophisticated "do" notation with imperative constructs, mutable variables (that are translated into something StateT-like), and pretty seamless monad lifting. They've also got pipeline operators, including things like `x |>.foo a b c` for `X.foo x a b c` if `x` has type `X` (type-directed field notation is wonderful).

Many times you don't even use currying, since it's not always worth the effort making a particular argument be the last one. Instead you might write `xs.map (f · x)`, where `(f · x)` is short for `fun a => f a x`.

The language also has an interesting GC that lets you write functional algorithms that have good memory performance -- objects with exactly one reference can be mutated (using so-called FBIP, "functional but in-place"). There's an Array type whose theoretical representation is a linked list but whose run-time representation is a dense array with O(1) pushing, popping, and writing. Makes it easy to write performant code without resorting to sophisticated functional data structures.