The Mondrian Introduction to Functional Optics
Posted3 months agoActive3 months ago
marcosh.github.ioTechstory
calmmixed
Debate
40/100
Functional ProgrammingOpticsArtistic Representation
Key topics
Functional Programming
Optics
Artistic Representation
The article introduces functional optics using Mondrian's art as an analogy, sparking discussion on its usefulness and the connection between art and programming concepts.
Snapshot generated from the HN discussion
Discussion Activity
Moderate engagementFirst comment
1h
Peak period
6
2-4h
Avg / period
3.5
Comment distribution21 data points
Loading chart...
Based on 21 loaded comments
Key moments
- 01Story posted
Oct 7, 2025 at 5:35 AM EDT
3 months ago
Step 01 - 02First comment
Oct 7, 2025 at 6:38 AM EDT
1h after posting
Step 02 - 03Peak activity
6 comments in 2-4h
Hottest window of the conversation
Step 03 - 04Latest activity
Oct 8, 2025 at 2:47 AM EDT
3 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45501114Type: storyLast synced: 11/20/2025, 12:32:34 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
This is particularly useful for providing copy-on-write semantics for immutable data structures. E.g. Putting a ring on a finger creates a new finger, which creates a new hand, which creates a new arm, which creates a new body. Using an appropriate lens, such updates become much simpler to write.
People often think of optics as only "OOP accessors but for FP" but they are strictly more powerful than OOP accessors.
In the end, all an iterator is is a thing that returns the next value.
In the end, all a functor is is a thing that takes a value of type A and returns a value of type B.
In the end, all a reader is is a thing that yields up some bytes (or other locally appropriate type) when .Read is called.
What makes them interesting is what you can build on them and how they can compose together. None of these concepts are all that interesting on their own. Like everything else I mention above, the primary utility of lenses is that it turns an MxN problem, where you need to implement all combinations of both sides of the functionality, into an M+N problem, where you implement N combinations of things that implement the interface and you can have M users that can use that generic interface.
However, if you are not a functional programmer this will seem particularly useless to you. People often claim monads are functional programming's response to mutability, but this merely one of the many misunderstandings of the concept, that just because one particular solution to mutability uses a monadic interface then that must be the purpose of the monadic interface. Lenses are probably a much better fit for the position of "functional programming's answer to mutability". But even in FP's you only really need them if you're dealing with deeply nested structures a lot, and especially if you want to deal with those deeply nested structures polymorphically. If you don't have that problem, even in FP you probably won't reach for lenses as regular record updates can get you a long way. Records can be seen as de facto lenses that go one layer down into the relevant type automatically, and if that's all you need then you'll never need the lens library.
Thus, if you are used to mutable programming, lenses are going to seem particularly useless to you. What's the point of taking something that's nearly useless and then composing multiple of them together, when the resulting composition is also nearly useless? The real utility in lenses is their packaging up of a Setter; the Getter is pretty easy to deal with with just a normal closure. So if you don't need Setters because you're used to just mutating things in a conventional imperative language, then there's nothing there for you.
This is why you see lots of attempts to port monads into imperative languages with varying degrees of accuracy and utility into conventional languages and have probably never seen anyone try to port lenses into them.
If you are a functional programmer, then I would reiterate that comment about nested structures. I think one of the most popular uses of lenses in the Haskell community is for dealing with JSON, when you need to just deal with it directly for whatever reason and can't easily turn it into typed values because the JSON format in question is too chaotic. That's a bad JSON format and one should never from any language spec out such a thing but if you're forced to deal with someone else's chaos you have no choice.
This is why I don't get invited to many places.
Source: I've done a lot of Mondrian research while creating a board game where you actually make art in the Mondrian style while playing.
On a different note, I'd love to see that board game.
The point of the article was to try to explain them in simple terms through a graphical notation, so that they become more accessible and manageable by more people.
Looking at this and seeing "lens" and "prisms" is at once both familiar and extremely odd. These Mondrian shapes are just like my recursive tree maps. Familiar. But the concept of lens and prism is not at all how I thought of them as I was repeatedly generating them.
It was interesting to look at what I was doing from a more formal perspective. Thanks! Yet at the same time I wish I could understand a practical use for this. How would it make things any better in my visual representation to use these concepts?
Personally, I find the whole idea of presenting a visual representation of masses of data interesting. There was a challenge a while back about how to represent the entire catalog of ISBN for example:
https://news.ycombinator.com/item?id=43168838