5 ms·
What's really neat about lenses to me (more of a practitioner than a theoretician) is that while the level 0 explanation of them is "they're like getters and se
by kqr 4y ago
What's really neat about lenses to me (more of a practitioner than a theoretician) is that while the level 0 explanation of them is "they're like getters and setters in your OOP language" they extend the concept much further.
Lenses can be "indirect" or "pseudo" getters or setters, for want of a better term. I.e. they can filter among many fields to set, then modify multiple fields at once, change only non-null values, replace only null values, and so on. So in a sense they're like multiple cursors at the code execution level. But they can also contain more complicated transformations if that makes your code simpler (sort of like C# properties.)
They are also first class concepts meaning you can pass these accessors around without caring about which object you will use them on.
And they compose with each other very nicely.
Those three properties make them super powerful and I really with I had them in more languages.
----
Lenses are the sort of thing where if they had been the default in more languages, people would wonder why on earth anyone would want to have the obviously inferior getters and setters of today's OOP languages.
- hither_shores 4y ago> I.e. they can filter among many fields to set, then modify multiple fields at once, and so on. These generalizations are usually referred to as "optics", with "lenses" reserved for the single-target case.
- kqr 4y agoYet ekmetts package is called "lens" and not "optic". While I agree with you in principle, I think that ship has sailed and for all practical purposes, "lenses" has come to mean both the narrower definition that is arguably correct, and optics more generally. It's a historical accident, much like a lot of people use "function" to mean all sorts of subprogram, including procedures and sometimes even methods!
- nerdponx 4y agoI would love to see some kind of table or diagram that shows all the various "optics" in some kind of structured format. Lenses are the only one that I can keep straight in my head.
- endgame 4y agohttps://raw.githubusercontent.com/wiki/ekmett/lens/images/Hierarchy.png https://raw.githubusercontent.com/wiki/ekmett/lens/images/Hi... If you need to find it again, it shows up in the README which is in the github repo and the page on Hackage.
- hither_shores 4y agoThere are infinitely many, so all is out, but the standard ones are covered here: https://oleg.fi/gists/posts/2017-04-18-glassery.html https://oleg.fi/gists/posts/2017-04-18-glassery.html Page 10 of this paper has a table with references to some more exotic optics, though it's going to be hard to parse without some category theory: https://arxiv.org/pdf/2001.07488.pdf https://arxiv.org/pdf/2001.07488.pdf
- Tarean 4y agoThe optics library is a bit stricter, using separate types with implicit conversions to give better type errors, and the subtyping diagram is here https://hackage.haskell.org/package/optics-0.4.2/docs/Optics.html#g:3 https://hackage.haskell.org/package/optics-0.4.2/docs/Optics... The lens documentation has this diagram https://i.imgur.com/ALlbPRa.png https://i.imgur.com/ALlbPRa.png These both skip over indexed versions, and some niche optics like grates aren't in the libraries yet afaik
- sfvisser 4y agoAnd you can weave effects into them just like normal functions, without losing the ability of composition. Fun stuff! In defense of OO-style access pattern, they’re a lot simpler and syntactically well integrated into most languages. The flexibility of lenses is clearly visible in types (in most current implementations). Ideally you want to hide this when you don’t need the flexibility.
- jiggawatts 4y agoNotably, this feature would be very useful in SQL or similar data processing languages. I wish these query languages had the ability to select "all key columns", "all writeable columns", "non-system-generated columns", etc... In most database or query platforms this is either impossible, or requires breaking out into another system/approach entirely. For example, it's possible to generate a SQL query to do above by querying the column metadata from INFORMATION_SCHEMA views, but this is obviously not what most people want to be doing when writing a query. Worse, even if the database platform has features like this, when it gets processed through an ORM in typical languages like Java or C#, any such features are once again lost... Lenses and optics could apply well to SQL-like query languages, because those are largely functional as well, and thanks to "JSON columns" often have nested structures where the composability of these abstractions would be more elegant than some hideous "tree query syntax" as typically seen in XPath and the like.
- avgcorrection 4y ago> What's really neat about lenses to me (more of a practitioner than a theoretician) is that while the level 0 explanation of them is "they're like getters and setters in your OOP language" they extend the concept much further. This doesn’t tell me anything since getters/setters are almost useless in my experience.
- fho 4y agoRight ... And lenses are not. Imho a better comparison would be to (safe) pointers that can point to multiple, conditional positions in a data structure. Example: in a game you want to update the health points of all enemies that are affected by an area of effect attack. With lenses you would compose a lens from multiple simpler lenses: ```enemiesAtDistanceToPoint pos radius = enemies . filtered (distanceTo pos . (< radius))``` and then you could modify those enemies: ```enemiesAtDistanceToPoint (10,20) 5 . health -= 5``` The benefit here is that you abstract the work of extracting the enemies and can reuse it elsewhere. Also note the lack of any loop to affect multiple entities.
- c-cube 4y agoWould multiple-cursors editing be an apt comparison? :-)
- fho 4y agoSomewhat, but even my pointer analogy just scratches the surface. Filtering/selecting is big, but another interesting thing is that there are lenses (which I think are called prisms?) that only provide a view of something. Eg you have a text document in Unicode, select all words marching a certain pattern, and then look as if they were encoded in ASCII. (No idea why this would useful :-) ).
- hither_shores 4y agoA "lens" that only provides a view of something is just a plain function. Prisms are first class constructors: a `Prism a b` can build a `b` from an `a`, or attempt to match on a `b` and `Maybe` get an `a` that could construct it.
- BrainVirus 4y agoGetters and setters are not a "concept" in OOP. They're just a naming convention that is occasionally built into language syntax for brevity. FP people constantly miss something fundamental about OOP. Objects only exist at runtime. Any facility that provides powerful tools to deal with objects has to be runtime-oriented and would require corresponding language support. E.g. Mirrors: https://bracha.org/mirrors.pdf https://bracha.org/mirrors.pdf
- hither_shores 4y agoThey're using "getters and setters" to refer to reading from and writing to fields, not `get => ... ; set => ...` style syntactic sugar.