12 ms·
Functional programming appeals to many of us for reasons other than these practical considerations: Functional programming feels like reasoning in algebra. As i
by Syzygies 6y ago
Functional programming appeals to many of us for reasons other than these practical considerations: Functional programming feels like reasoning in algebra. As in Modern Algebra for math majors (groups, rings, fields) and beyond.
There's a saying in mathematics that when any field matures it turns into algebra. Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order in mathematics crosses a similar threshold, as it becomes sufficiently structured to support algebraic reasoning. The subjective experience is like ice melting into a churning liquid, or a land-locked creature learning to fly. Once one has this experience, one cannot imagine thinking any other way. In the case of functional programming, programs written in other languages feel like ad hoc pre-civilization constructions, doing arithmetic by counting pebbles.
Advocates of Haskell don't tend to express this, because from the outside it can come off like trolling, but this algebraic sense of wonder is at the core of many Haskeller's experiences. We all have the example of Lisp in our minds, its "we found God" advocacy did much to hinder its adoption. Nevertheless, understanding this explains much about Haskell. The real point of lazy evaluation is that it best supports this algebraic reasoning, as carbon best supports life. The 47,000 compiler options reflect a primary goal of being a research bed for language constructs derived from mathematical category theory, despite its success as a practical language for those free to choose it.
The killer app for Haskell is parallelism. To this day it has the best implementation of parallelism; one can achieve a 7x speedup on 8 cores by adding a handful of lines to a program. This ease is a consequence of the functional model, and of considerable effort by Haskell's developers.
Idris 2 is itself a joy to learn, if one wants a smaller, cleaner Haskell without the 47,000 compiler options. One gets to learn dependent types. Alas, it doesn't offer commercial-grade parallelism.
- __jem 6y ago> Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order in mathematics crosses a similar threshold, as it becomes sufficiently structured to support algebraic reasoning. It's funny, because I think this metaphor cuts exactly the opposite direction -- code reaching sufficient complexity, the pure math approach doesn't survive an encounter with the real world. I love static analysis and think that there are core business domains that are best expressed with a rich type system, but there is a whole world of absolutely critical programming that cannot simply eliminate messiness, due to interfacing with humans and our flawed practices. With sufficient time and an expressive enough type system, even the messiest business process can be represented, but I'm not convinced that's an example of beauty but rather stubbornness.
- sli 6y ago> ... but there is a whole world of absolutely critical programming that cannot simply eliminate messiness, due to interfacing with humans and our flawed practices. I understand what you're saying, but I don't think you'll find many programmers that will argue that a programmer shouldn't use the best tool for the job.
- __jem 6y agoAgreed, except the sort of "we found God" types referenced by the parent in regards to pure functional programming.
- deleted 6y ago[deleted]
- carapace 6y agoBackus emphasized the algebra of programs in his Turing Award lecture: "Can Programming Be Liberated From the von Neumann Style? A Functional Style and its Algebra of Programs" https://amturing.acm.org/award_winners/backus_0703524.cfm https://amturing.acm.org/award_winners/backus_0703524.cfm https://dl.acm.org/doi/10.1145/359576.359579 https://dl.acm.org/doi/10.1145/359576.359579
- discreteevent 6y agoBackus: Well, because the fundamental paradigm did not include a way of dealing with real time. It was a way of saying how to transform this thing into that thing, but there was no element of time involved, and that was where it got hung up. Booch: That’s a problem you wrestled with for literally years. Backus: Yeah, and unsuccessfully. http://archive.computerhistory.org/resources/access/text/2013/05/102657970-05-01-acc.pdf http://archive.computerhistory.org/resources/access/text/201...
- carapace 6y agoVery interesting, cheers! Functional Reactive Programming seems promising. (Elm ditched it in favor of some simpler metaphor on didactic rather than technical grounds, I think.)
- nickdrozd 6y ago> In the case of functional programming, programs written in other languages feel like ad hoc pre-civilization constructions, doing arithmetic by counting pebbles. > Idris 2 is itself a joy to learn, if one wants a smaller, cleaner Haskell without the 47,000 compiler options. From a conceptual point of view, Idris makes Haskell look similarly crude.
- spekcular 6y ago> There's a saying in mathematics that when any field matures it turns into algebra. Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order in mathematics crosses a similar threshold, as it becomes sufficiently structured to support algebraic reasoning. The subjective experience is like ice melting into a churning liquid, or a land-locked creature learning to fly. Once one has this experience, one cannot imagine thinking any other way. Hi, this seems wrong to me. First, as far as I can tell, such a saying does not exist. I've never heard it, despite having a fair amount of experience with mathematics (though not as much as you), and I can't find it through Googling. Second, and more substantively, it is not the case that mathematical fields inevitably turn into algebra. One only has to look at PDE, probability, and analytic number theory to see this is the case (to give just a few examples). All are highly mature fields and essentially non-algebraic. This is not to say that ideas from algebra are not occasionally useful, just that it should be obvious to anyone who opens an introductory graduate text in PDE that the subject has not "turn[ed] into algebra." > The killer app for Haskell is parallelism. To this day it has the best implementation of parallelism; one can achieve a 7x speedup on 8 cores by adding a handful of lines to a program. This ease is a consequence of the functional model, and of considerable effort by Haskell's developers. I don't think this statement is entirely wrong, but I don't think it's entirely right either. There are plenty of languages where one can get parallelism with just a few extra lines of code; Julia comes to mind immediately. Easy parallelism is hardly a Haskell-specific, or even FP-specific, feature. I would of course agree that designing things without mutable state makes writing parallel code easier, but this can be done in many high-level languages these days. But that is a nitpick. A more substantive objection is that the sole purpose of parallelism is performance, and idiomatic Haskell is generally speaking slower, sometimes a lot slower, than the same algorithm written in C++ or similar languages. (The adjective idiomatic is important here – I'm aware that one can with enough contortions write C-like code in Haskell, but this response undercuts of the point of highlighting Haskell-specific features like immutability, laziness, etc.) In particular, a few years ago it seemed like the people implementing parallel Haskell features didn't understand or care about fundamental things like cache locality. Maybe this has changed? There is also an amusing story about the "ease" of writing parallel quicksort in Haskell [1]. > The real point of lazy evaluation is that it best supports this algebraic reasoning, as carbon best supports life. It's worth noting that Simon Peyton Jones is on record as saying that any "Haskell 2" should not be lazy [2]. [1] https://sudonull.com/post/75314-Parallel-quick-sort-on-Haskell-and-how-hard-it-was-to-write https://sudonull.com/post/75314-Parallel-quick-sort-on-Haske... [2] https://news.ycombinator.com/item?id=1924061 https://news.ycombinator.com/item?id=1924061
- adwn 6y ago> To this day it has the best implementation of parallelism; one can achieve a 7x speedup on 8 cores by adding a handful of lines to a program. Eh, you can achieve the same in Rust using rayon, this isn't exclusive to Haskell or FP. Do you have an example in Haskell, where you get an effortless speedup which wouldn't be easy in another language?
- jgilias 6y agoYeah, but Rust isn't exactly a counter example, I think. It's heavily inspired by Haskell, its type system, as well as FP in general. So, it sort of inherits (pun not intended) its parallelization capabilities from that.
- darksaints 6y agoHeavily? It's actually heavily inspired by ML (SML/OCaml), not Haskell. Most of its functional programming attributes originated in SML, and has avoided most of the things that make Haskell unique. Really it is just type classes that came from Haskell.
- pjmlp 6y agoType classes are just a way of doing module interfaces or Objective-C protocols/categories, as prior art before Haskell or Miranda came into being.
- centimeter 6y agoI was around in the very early days of rust, and it was explicitly stated in many places in the docs that the trait system, ADTs, etc. were all inspired by Haskell experience. I don't think we ever mentioned OCaml or SML. The trait system in Rust has nothing whatsoever to do with SML or OCaml and everything to do with Haskell's typeclass system. So between that and ADTs, on what grounds do you think it was "heavily inspired by ML"?
- jgilias 6y ago
- nendroid 6y agoNot all aspects of programming can be described by math. Mutations and IO are very critical parts of programming and the two areas where FP breaks down. Even the IO Monad leaks the imperative nature of the program over to the programmer. The only way pure FP can sort of work is if there are heavy frameworks abstracting IO and mutation away from the programmer. If you're not doing IO or mutating something then your caching framework, database or Haskell runtime is doing it for you. Additionally like I said earlier, Even if your database is handling mutation for you, you still end up embedding mutation commands into the strings of your pure FP function. Updating a database in haskell still necitates the haskell user to place the mutation command in a SQL string. My point is, that math is not the complete solution to the programming problem. What FP allows the programmer to do is to use the framework to segregate combinatorial logic away from mutation and IO. Your combinators will always be more composeable and modular but your IO and mutation functions will be less modular but they still have to exist.
- nimish 6y agoThe io monad is fully pure. The interpretation of the io monad? That's another story. Once you realize that mutation itself is a side effect then why not use the single most powerful idiom we have for abstraction over side effects? (Monads with do notation; for blocks in f#) For the record io is st with an opaque realworld type. And st is fully pure with a neat type trick to prevent leaking of st references.
- nendroid 6y agoI never said it's not pure. Just like how a SQL string in haskell is fully pure. Doesn't change the fact that you're using pure primitives to control a process that is fundamentally unpure. The concept leaks across the boundary.
- nimish 6y agoIt doesn't. That's the whole point of the io monad. Outside of the io monad you cannot (modulo some exceptions) indicate io.
- jjav 6y ago> algebraic sense of wonder I strongly identify with this view. Have always loved math. I remember writing a paper in middle school on how all of nature is built on math which ties closely with this quote "algebraic sense of wonder". My B.S. degree is in mathematics and I loved it. And yet... I very strongly - no, extremely - dislike functional programming. When building concrete things, I love pragmatism above all else and to me functional is the diametrical opposite of that. A CPU has registers, instructions and addressable memory. Any abstraction that strays too far from that reality is a distraction (and maintenance burden) I don't want to deal with.
- phizy 6y agoThe primary difference between computer science and mathematics proper is an overt concern for performance. Mathematical elegance and computational efficiency are not the same thing. Haskell is a pretty awesome language, but it doesn't make it easy to incrementally optimize programs.
- hobby-coder-guy 6y agoWhy isn’t anything of value actually made in Haskell if it is so much better?