Live data from Hacker News

Two Vexing Problems in Functional Programming

matthewbutterick.com

11–20 of 217 posts

Re: Two Vexing Problems in Functional Programming

#11
Relational systems (e.g. SQL) solve the parent-child problem by making references explicit -- instead, keys are used to reference children in a well-known collection.

That is, if you're trying to emulate sharing of mutable structures (i.e. pointers) in a functional language -- that is, reflecting changes to children across multiple parents -- model the pointers explicitly (as integer keys) and put the shared structures in a map, which is necessary to interpret a parent in full.

This seems to be what the article is getting at with its "mediator" concept, albeit in very abstract terms. The author seems to find this distasteful, wanting to "hide" these relationships, but I disagree -- the difference between value and reference semantics is very important; making the difference explicit is a good thing.

Re: Two Vexing Problems in Functional Programming

#12
The a-ha moment for me was that functional programming - in most real world applications - is less about "no state" and "no side effects", and more about "properly managed state" and "properly managed side effects". This is one of the things I really like about Elixir/Erlang/OTP - of course your application needs to manage state, but it's well contained and well managed, avoiding a lot of common pitfalls.

Re: Two Vexing Problems in Functional Programming

#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 to read or update deep into nested structures.

Re: Two Vexing Problems in Functional Programming

#14
You should not approach problems in functional languages with imperative techniques. It's fitting a square peg in a round hole. The approaches & data structures aren't always the same.

In my experience with FP you start with more of a top down approach in contrast to the bottom up approach discussed in the blog post.

There are many good resources on this. I've referenced a few below. Of course there are many more.

[1] https://www.amazon.com/Pearls-Functional-Algorithm-Design-Ri...

[2] https://www.amazon.com/Purely-Functional-Data-Structures-Oka...

[3] https://www.amazon.com/Algorithm-Design-Haskell-Richard-Bird...

[4] https://www.amazon.com/Structure-Interpretation-Computer-Pro...

Re: Two Vexing Problems in Functional Programming

#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 this critique without a mention of this.

The second problem seems to be due to trying to do OO in FP. The thing is you don't have a glyph, you have a whole system which contains glyphs. So you can't do an update on a glyph because it won't update the system.

This is a common frustration when you're used to OO and can be really annoying in FP but it's also part of the design modelling that FP forces you to do: the problem was that he was modeling in the small and not the large.

The solution is not the 1, 2, or 3 from the article (1 and 2 are bad, 3 is not as bad but not FP), but is straightforward. When you want to update a glyph, you use a function like `updateGlyph(pathToGlyph, functionToExecuteOnGlyph)`. That's at the top-level, and it allows you compose your lower level `updateGlyph` functions.

[1] https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.64...

Re: Two Vexing Problems in Functional Programming

#16
post #3

I found that a fast immutable in memory database like Datascript solves both problems quite nicely.

Came here to say this. The author wasn't actually describing problems with functional programming, he was describing his troubles due to naive implementations.

Naive implementations will always, by definition, not be great. But instead of spending the time, energy, and money on crafting a custom solution each time, use off-the-shelf libraries that do the job. DataScript, Storm, etc. are great for this.

Re: Two Vexing Problems in Functional Programming

#18
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.

Re: Two Vexing Problems in Functional Programming

#19
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…

There's genuinely good things that came from FP that creeped into popular languages:

* Algebraic data types

* Pattern matching (with exhaustiveness)

* Lambdas / Closures

* Type inference

Post reply on HN