All Projects → jackfirth → Lens

jackfirth / Lens

Licence: other
A Racket package for creating and composing pure functional lenses

Programming Languages

racket
414 projects

Labels

Projects that are alternatives of or similar to Lens

program-imperatively-using-purescript
Program imperatively using PureScript, State monad and lenses
Stars: ✭ 23 (-57.41%)
Mutual labels:  lenses
Use Profunctor State
React Hook for state management with profunctor lenses
Stars: ✭ 331 (+512.96%)
Mutual labels:  lenses
Quicklens
Modify deeply nested case class fields
Stars: ✭ 641 (+1087.04%)
Mutual labels:  lenses
putting-lenses-to-work
A presentation for BayHac 2017 on how I uses lenses at work
Stars: ✭ 73 (+35.19%)
Mutual labels:  lenses
lenses-go
Lenses.io CLI (command-line interface)
Stars: ✭ 34 (-37.04%)
Mutual labels:  lenses
Dontfeartheprofunctoroptics
Don't Fear the Profunctor Optics!
Stars: ✭ 367 (+579.63%)
Mutual labels:  lenses
futils
Utilities for generic functional programming
Stars: ✭ 21 (-61.11%)
Mutual labels:  lenses
Lambda
Functional patterns for Java
Stars: ✭ 737 (+1264.81%)
Mutual labels:  lenses
purescript-barlow-lens
Increase your magnification 🔭 and zoom deep into a record.
Stars: ✭ 32 (-40.74%)
Mutual labels:  lenses
Focal
Program user interfaces the FRP way.
Stars: ✭ 613 (+1035.19%)
Mutual labels:  lenses
concave
🧐 Lens-like state management (for React).
Stars: ✭ 13 (-75.93%)
Mutual labels:  lenses
optics.js
🔭 Lenses, Prisms and Traversals in JavaScript!
Stars: ✭ 46 (-14.81%)
Mutual labels:  lenses
Generic Lens
Generically derive traversals, lenses, and prisms.
Stars: ✭ 399 (+638.89%)
Mutual labels:  lenses
pathex
Fastest way to access data in Elixir
Stars: ✭ 242 (+348.15%)
Mutual labels:  lenses
Monocle Ts
Functional optics: a (partial) porting of Scala monocle
Stars: ✭ 657 (+1116.67%)
Mutual labels:  lenses
exercises-monocle
Scala Exercises for the Scala Optics library Monocle http://julien-truffaut.github.io/Monocle/
Stars: ✭ 12 (-77.78%)
Mutual labels:  lenses
Language Ext
C# functional language extensions - a base class library for functional programming
Stars: ✭ 3,964 (+7240.74%)
Mutual labels:  lenses
Dart functional data
Simple and non-intrusive code generator for lenses and boilerplate of data types
Stars: ✭ 39 (-27.78%)
Mutual labels:  lenses
Frunk
Funktional generic type-level programming in Rust: HList, Coproduct, Generic, LabelledGeneric, Validated, Monoid and friends.
Stars: ✭ 725 (+1242.59%)
Mutual labels:  lenses
Fsharpplus
Extensions for F#
Stars: ✭ 589 (+990.74%)
Mutual labels:  lenses

lens Build Status codecov Scribble Docs

A Racket package for creating and composing pure functional lenses.

raco pkg install lens (require lens)

What on earth are lenses?

A lens is a value that can be used to focus on a small subpiece of some larger structure. A lens splits some data structure into two pieces - a view, which is some small isolated component of the data structure, and a context, which is everything else. The context can have a new view placed into it. This makes a lens act like a pure functional getter and setter:

> (lens-view first-lens '(1 2 3))
1
> (lens-set first-lens '(1 2 3) 'a)
'(a 2 3)

Lenses are first class values and pure functional, so they can be abstracted over and functions that operate on lenses can be created. For instance, given a lens its view can be "updated":

> (lens-transform first-lens '(1 2 3) number->string)
'("1" 2 3)

Additionaly, lenses are separate values from the objects they operate on, so they can be manipulated independently of any specific data. Functions can construct lenses, and operations can combine lenses. This allows for lens composition:

> (define first-of-b-key-lens (lens-compose first-lens (hash-ref-lens 'b)))
> (define a-hash (hash 'a '(1 2 3) 'b '(10 20 30) 'c '(100 200 300)))
> (lens-view first-of-b-key-lens a-hash)
10
> (lens-set first-of-b-key-lens a-hash 'foo)
#hash((a . (1 2 3)) (b . (foo 20 30)) (c . (100 200 300)))

Lenses can also be joined together to form compound lenses that view many things:

> (define first-third-fifth-lens (lens-join/list first-lens third-lens fifth-lens))
> (lens-view first-third-fifth-lens '(1 2 3 4 5 6))
'(1 3 5)
> (lens-set first-third-fifth-lens '(1 2 3 4 5 6) '(a b c))
'(a 2 b 4 c 6)

Lenses can also be extended to operate on some new data structure:

> (define first-of-each-lens (map-lens first-lens))
> (lens-view first-of-each-lens '((1 2) (3 4) (5 6)))
'(1 3 5)
> (lens-set first-of-each-lens '((1 2) (3 4) (5 6)) '(a b c))
'((a 2) (b 4) (c 6))

See the documentation for a full API reference

So when would I want to use lenses?

Lenses are most effective when you're dealing with the "giant ball of state" problem. When you have a large amount of state you need to pass around between code written in a functional style, it's difficult to update and manage it due to the lack of mutation "magically" updating your entire object graph when a function changes a small part of it. Lenses allow code to break down and manipulate portions of this state, simplifying interactions and updates.

In particular, consider using lenses if you find yourself doing any of the following:

  • Using a giant complex piece of state that most pieces of code only care about a small part of
  • Writing struct-copy a lot
  • Converting some hairy data structure into another one, manipulating it, then turning it back
  • Wishing you could treat data X as if it were a Y, i.e. "I wish this struct was a list so I could map over it easily"
  • Creating structs that have nested struct instances inside them.

For a more in depth introduction, see The Lens Guide. For detailed API documentation, see The Lens Reference.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].