I’m a happy user of both Chain.jl and Accessors.jl, but I find myself missing a few things from Clojure. I’m not sure if they exist, and I just don’t know about them, or if these are actual missing capabilities.
I think one motivating example is how easy it is in Clojure to extract a value from a nested data structure and pass it to a function. For example, you might have:
(some-> data
:foo
:bar
baz)
This is a bit like unpacking a Dict in Julia and passing it to a function, like data[:foo][:bar] |> baz, but there are some extra niceties that arise from how extensively and consistently Clojure uses nil. First, the :foo keyword works like a function in Clojure and is similar to x -> get(x, :foo, nothing) in Julia. Second, some-> will short circuit and return nil as soon an intermediate value is nil. So, if we had a @chain_some macro, if might expand to something like:
if isnothing(data)
nothing
else
foo_ = data[:foo]
if isnothing(foo_)
nothing
else
bar_ = foo_[:bar]
if isnothing(bar_)
nothing
else
baz(bar_)
end
end
end
So, combining those, I guess I wish I could write something like:
@chain_some data begin
get(_, :foo, nothing)
get(_, :bar, nothing)
baz
end
This has all been focused on Dict, but in reality I have a mix of Dicts, NamedTuples, and structs. My get calls above would work for Dicts and NamedTuples, but not for structs. This seems like something that Accessors.jl could provide a generalized solution to, and I see @maybe in AccessorsExtra.jl, but that doesn’t seem to be quite what I want. I think I’m looking for something like @maybe that could do @maybe_nested data.foo[:bar], and if any intermediate value is nothing, it short circuits and evaluates to nothing.
So, putting it all together again, perhaps something like:
@chain_some data begin
@maybe_nested _.foo[:bar]
baz
end
If you’ve made it this far, thanks for sticking with me. If you have suggestions for where this might already exist in the package ecosystem, or perhaps an alternative way of doing this, I’d love to hear about it! Thanks!