README.md



# optic
 #

Copyright (c) 2019 John Krukoff

__Version:__ 0.1.0

__Authors:__ John Krukoff ([`github@cultist.org`](mailto:github@cultist.org)).


### Overview ###

![Camera Lenses](lenses.jpg)

This is an Erlang/OTP library for retrieving and modifying nested values, in
the spirit of [Haskell's
lens library](https://en.wikibooks.org/wiki/Haskell/Lenses_and_functional_references). Functional selectors for deeply nested values are
constructed by composing "optics", each of which specifies a way to focus on a
particular kind of value.

For example, say we had a list of deserialized JSON entities representing pets
for sale that we wanted to modify.

```

> Pets = [#{
    <<"id">> => 628178654,
    <<"name">> => <<"spot">>,
    <<"status">> => <<"available">>,
    <<"category">> => #{
      <<"id">> => 3216199393,
      <<"name">> => <<"dog">>
    }}].
```

We could then update all pets to a new status by:

```

> optic:put([optic_lists:all(), optic_maps:key(<<"status">>)],
            Pets,
            <<"sold">>).
{ok,[#{
  <<"id">> => 628178654,
  <<"name">> => <<"spot">>,
  <<"status">> => <<"sold">>,
  <<"category">> => #{
    <<"id">> => 3216199393,
    <<"name">> => <<"dog">>
  }}]}
```


### Getting Started ###

This library is published to [hex.pm](https://hex.pm) as [optic](https://hex.pm/packages/optic). If you're using [rebar3](https://www.rebar3.org/) as your build tool, it can be added
as a dependency to your rebar.config as follows:

```

{deps, [{optic}]}.
```


### Usage ###


#### Optics ####


#### Examples ####


### Contributing ###

Please fork the repo and submit a PR. Tests are run via:

```

rebar3 eunit
```

Documentation is autogenerated using edown and edoc via:

```

rebar3 as markdown edoc
```

The application has only been tested with Erlang/OTP 21 on Windows 10. Reports
of success (or failure!) on other versions and operating systems are
appreciated.


### Lineage ###

I first encountered lenses via the[Datum](https://github.com/fogfish/datum) library, but wanted a
version that supported traversables instead of lenses in order to support
updating multiple elements. As lenses are a special case of traversables, this
allowed for using a single type to represent both.

There are a number of good introductions to lenses, [this](https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial)
was the most accessible for me.

This library was initially conceived with the intention of making it easy to
modify deeply nested JSON, so JSON related data structures were the first
implemented.


### Attribution ###
Image by Bill Ebbesen
CC BY-SA 3.0 [`https://creativecommons.org/licenses/by/3.0/deed.en`](https://creativecommons.org/licenses/by/3.0/deed.en)


## Modules ##


<table width="100%" border="0" summary="list of modules">
<tr><td><a href="http://github.com/jkrukoff/optic/blob/master/doc/optic.md" class="module">optic</a></td></tr>
<tr><td><a href="http://github.com/jkrukoff/optic/blob/master/doc/optic_generic.md" class="module">optic_generic</a></td></tr>
<tr><td><a href="http://github.com/jkrukoff/optic/blob/master/doc/optic_lists.md" class="module">optic_lists</a></td></tr>
<tr><td><a href="http://github.com/jkrukoff/optic/blob/master/doc/optic_maps.md" class="module">optic_maps</a></td></tr>
<tr><td><a href="http://github.com/jkrukoff/optic/blob/master/doc/optic_proplists.md" class="module">optic_proplists</a></td></tr>
<tr><td><a href="http://github.com/jkrukoff/optic/blob/master/doc/optic_tuples.md" class="module">optic_tuples</a></td></tr></table>