JKWA
Here’s why lawful lenses matter (even in Elixir):
Couldn’t fit optics in my book, but I can build them into Funx.
Most Liked
LostKobrakai
I certainly feel like lenses could get a lot more attention on elixir, but does a blogpost in favor of them need to start with dunking on elixirs built in lenses? – especially given most of the critic stated could be mitigated by a single Enum.map?
garfield = %{
name: "Garfield",
weight: 20,
owner: %{
name: "Jon"
}
}
invalid_owner_age_path = [:owner, :age] |> Enum.map(&Access.key!/1)
get_in(garfield, invalid_owner_age_path)
# ** (KeyError) key :age not found in: %{name: "Jon"}
put_in(garfield, invalid_owner_age_path, 40)
#** (KeyError) key :age not found in: %{name: "Jon"}
update_in(garfield, invalid_owner_age_path, fn curr -> curr + 1 end)
# ** (KeyError) key :age not found in: %{name: "Jon"}
There’s also reasons why elixir doesn’t allow you to access structs when using bare keys. Structs in elixir are not treated as “data containers”, but as user defined datatypes, which might want to be used as a scalar. If you want that user defined datatype to be accessible like other map data you can implement the Access behaviour, which can then take into account that structs internals. The reason for a behaviour over a protocol is iirc due to performance reasons, potentially even ones of the past, but I’m not sure. You can certainly see how Access wants to be a protocol in spirit. Sadly this means this is less likely to be implemented that e.g. an Enumerable especially for library code.
But it’s always possible to access struct keys without Access implemented by forcing map key access using Access.key or Access.key!, just like Map.get works on structs.
lud
Access is not a protocol, you will not find defimpl Access. You should search for “def fetch”!
garrison
As someone unfamiliar with the surrounding theory, I found the framing in terms of Elixir’s stdlib to be pedagogically helpful. Of course the points you make about Access are also useful context and could be incorporated.
The difference between behavio(u)rs and protocols is that of extensibility, right? So by turning Access into a protocol you are essentially saying that “other people” can decide whether my struct can be accessed like a map. Not just the user themselves, but any third party that invokes defimpl in the user’s dependency tree.
Does that actually make semantic sense?
TBH this question may be too theoretical. What’s the canonical example of a struct that should implement Access?
Popular in Blog Posts
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









