Live data from Hacker News

Two Vexing Problems in Functional Programming

matthewbutterick.com

21–30 of 217 posts

Re: Two Vexing Problems in Functional Programming

#21
These problems have lots of other well-known solutions.

For large objects: Persistent data structures with path-copying. Batching small mutations (and using mutation internally in a way that doesn’t leak out). Using the type system somehow to distinguish cases where copying is not necessary (experimental in certain new languages). Structuring your program around a “data store” that is mutable.

For the “references” problem: Explicit references, like by ID. Or mutable “atoms” as in Clojure, which are maybe sort of like the “mediators” in the article.

Re: Two Vexing Problems in Functional Programming

#22
post #13

In the Haskell world, folks have solutions to both of these problems: The "large-object problem" can be tackled in a principled fashion using strict state threads (aka the ST monad: https://wiki.haskell.org/Monad/ST ) or using vanilla mutable (IORef) references. The "parent-child problem" is well-addressed by lenses, also known as functional references. They are basically composable getters and setters that allow you…

You mean, Haskell developers ditch the functional idiom and use a more imperative one when they need it for performance? And yes, they do, and it works nicely. But it's not solving any problem with the functional paradigm. Anyway, none of them is a problem with the semantics of FP. They are a problem of insufficient optimization. So they will probably get solved at some point.

ST is not 'imperative'. The monadic interface can look imperative sure, but then you can also use Applicative and friends and that's back to being functional. Of course, I prefer to think of what you call 'imperative' programming as function composition where >>= is the reverse of the 'normal' composition operator. Indeed, sequential imperative commands and function composition are isomorphic.

Re: Two Vexing Problems in Functional Programming

#23
post #13

In the Haskell world, folks have solutions to both of these problems: The "large-object problem" can be tackled in a principled fashion using strict state threads (aka the ST monad: https://wiki.haskell.org/Monad/ST ) or using vanilla mutable (IORef) references. The "parent-child problem" is well-addressed by lenses, also known as functional references. They are basically composable getters and setters that allow you…

I don't fully understand how parent-child problem is addressed by lenses. How does lens helps to address the problem that a reference update is akin to changes an external state?

My understanding is that lens helps to address the large-object problem.

Re: Two Vexing Problems in Functional Programming

#24
post #15

I've been coding in functional languages for 10 years, and they have problems, but these are not them. The first problem is solved in every functional language I've used (clojure, F#, OCaml) by immutable data structures (aka purely functional data structures, which is also the name of the de facto book on the topic, which is excellent but also you don't need to know any of this to use them. [1]). I'm surprised to see…

I love the Purely Functional Data Structures book (so many cool data structures and ideas!) but does really "solve" it? For e.g. I double checked and the PFDS for an array (the author's example) would be a skew-binary random access list with O(log N) cost for random access, whereas an "imperative random access array" is O(1). Of course, the skew-binary random access list has persistence (you get to keep references to old versions of the data if you wish), while the "imperative random access array" does not, but the author's use-case sounds like he doesn't need persistence. So there is still some gap between this particular approach and the "non-functional" one.

Re: Two Vexing Problems in Functional Programming

#25
post #4

So, as the trend of forcing functional programming into imperative languages continues on its inexorable path, I just can't help but bring the old joke to mind more and more often: "Doctor, it hurts when I do this." "Well, then, don't do that." You mean, jamming a foreign paradigm into a language, where the advantages of the foreign paradigm are reduced and the disadvantages greatly magnified, hurts sometimes? Have y…

I think you're being downvoted because your tone is a bit hostile, so I'll bump you up because I think you make a good point.

I love functional idioms as well, but you have to know the cost of those idioms in a non-functional language. The first thing I did when I had to learn go was determine if I could use functional idioms (map, fold, etc.) and did some research and testing and found that, no, functional idioms are a really bad idea in go. It just isn't meant to be used that way.

For the record, I had to learn go because the team I joined used it.

Re: Two Vexing Problems in Functional Programming

#26
post #4

So, as the trend of forcing functional programming into imperative languages continues on its inexorable path, I just can't help but bring the old joke to mind more and more often: "Doctor, it hurts when I do this." "Well, then, don't do that." You mean, jamming a foreign paradigm into a language, where the advantages of the foreign paradigm are reduced and the disadvantages greatly magnified, hurts sometimes? Have y…

I don't really see how this relates to the article. The author specifically mentions that he also encountered these problems in Racket (a functional programming language). Anyway:

>I do not understand why so many of you are so vigorously adamant that you're going to program in the intersection of functional programming languages and imperative programming languages

Because it actually works pretty well? The vast majority of programming languages today are multi-paradigm for a reason. In fact, almost all functional programming languages (Lisp, Scheme, Racket, Clojure, (S)ML, OCaml, F#, Scala) are multi-paradigm. Haskell is really the odd one among functional programming languages. The same applies to lazyness by the way, to claim that functional programming is "critically based on pervasive laziness" is simply wrong.

The idea that people use FP in a language like e.g. JS only because of an ideology driven obsession and that they constantly have to fight against the language just doesn't bear out in reality.

Re: Two Vexing Problems in Functional Programming

#27

> Functional program­ming, however, suggests we should create and destroy these struc­tures willy-nilly. It really saddens me that some people completely miss the point of what FP is about. How did this happen?

I think the author somewhat explained why FP "suggests" that. In his explanation, it's because when you read tutorials that operate on "numbers and strings and simple lists" (as the author puts it), you do create and destroy those structures willy-nilly.

So when you operate on a large array (as in his example), a natural approach is to also create and destroy it.

Of course after you gain experience you learn not to do that, and techniques that let you not do that, but I don't think he is missing the point.

Re: Two Vexing Problems in Functional Programming

#28
post #4

So, as the trend of forcing functional programming into imperative languages continues on its inexorable path, I just can't help but bring the old joke to mind more and more often: "Doctor, it hurts when I do this." "Well, then, don't do that." You mean, jamming a foreign paradigm into a language, where the advantages of the foreign paradigm are reduced and the disadvantages greatly magnified, hurts sometimes? Have y…

I don't really see how this relates to the article. The author specifically mentions that he also encountered these problems in Racket (a functional programming language). Anyway: >I do not understand why so many of you are so vigorously adamant that you're going to program in the intersection of functional programming languages and imperative programming languages Because it actually works pretty well? The vast majo…

I'm not talking about using it when it's helpful. I do it myself all the time.

I'm talking about forcing it in when it hurts specifically.

It occurs to me that I may have accidentally answered myself at the end, when I referred to the concept of union vs. intersection. When you bring in helpful angles on your current paradigm from light cast by other paradigms, that's helpful. You're expanding your working set of options.

But when you get a bit of a good taste of those other paradigms, and then declare this is always the right way to do it, it may feel like you're expanding your paradigms, but now you're not. When you force sum types into a language that doesn't support them because they're just always the right answer, when you force lots of maps & filters in a language that can't do fusion and function calls are kind of expensive, when you force an algorithm in that depends on laziness to work, and so on, you are no longer working in a sort of union of paradigms. You're working in the intersection.

And that intersection sucks. A worst-of-both-worlds situation for sure.

You can tell, by the way people trying this are constantly screaming in pain about it.

When it hurts... stop.

Re: Two Vexing Problems in Functional Programming

#29
post #4

So, as the trend of forcing functional programming into imperative languages continues on its inexorable path, I just can't help but bring the old joke to mind more and more often: "Doctor, it hurts when I do this." "Well, then, don't do that." You mean, jamming a foreign paradigm into a language, where the advantages of the foreign paradigm are reduced and the disadvantages greatly magnified, hurts sometimes? Have y…

I think you're being downvoted because your tone is a bit hostile, so I'll bump you up because I think you make a good point. I love functional idioms as well, but you have to know the cost of those idioms in a non-functional language. The first thing I did when I had to learn go was determine if I could use functional idioms (map, fold, etc.) and did some research and testing and found that, no, functional idioms ar…

Tried saying it politely. Still get downvoted. Thought I'd try a bit sharper on purpose.

Despite what it may superficially sounds like, it's an attempt to reach out and help people. If it hurts, you know, think about it. Maybe don't do something that hurts so much because it "must" be good.

FP techniques in imperative languages is a tool. A good tool sometimes. But it shouldn't be an aspiration.

Re: Two Vexing Problems in Functional Programming

#30
post #7

This article explains the problems pretty well, but they are old problems and functional programmers have various solutions that the author seems unaware of. I'm not a Haskell programmer but I do know about monads and have heard of lenses.

Lenses don't help. They just make copying and updating large data structures cleaner to write. They don't solve the performance problem of copying everything.
Post reply on HN