This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-04-09
Channels
- # aleph (1)
- # asami (5)
- # babashka (4)
- # beginners (8)
- # biff (19)
- # calva (2)
- # cider (14)
- # clojure (17)
- # clojure-dev (3)
- # clojure-europe (3)
- # clojurescript (2)
- # community-development (9)
- # conjure (1)
- # core-typed (2)
- # datomic (6)
- # emacs (20)
- # gratitude (1)
- # helix (5)
- # kaocha (4)
- # nbb (1)
- # releases (3)
- # testing (17)
Are people using the contextual-eval
from The joy of Clojure?
It's pretty cool, but I found it broken for things that cannot serialise into a valid CLJ, Java objects, exceptions, that sort of things.
For instance it may try to eval this:
(clojure.core/let [e (quote #error {
:cause "error"
:data {:thrown true}
:via
[{:type clojure.lang.ExceptionInfo...] e)
Are there any work-arounds? Can it be fixed somehow? It's such a useful thing but only works for CLJ values and blows up when anything non-CLJ (even including exceptions) get into the lexical scope.
Ref: https://gist.github.com/leobm/6061734.Instead of embedding the values, I would use eval to create a function and call it:
(defn contextual-eval [ctx expr]
(let [f
(eval
`(fn [~@(keys ctx)]
~expr))]
(apply f (vals ctx))))
> (contextual-eval {'a (Exception. "hi")
'b 2}
'(str (.getMessage a) " " b))
;; "hi 2"
You can also do something like save the values in a dynamic variable and then grab the values inside of the eval from the dynamic variable, but I think wrapping in a function is more explicit and less brittle.
Thanks @U7RJTCH6J, just what I needed!
I have a deeply nested set of forms like reduce->let->reduce->let->reduce->let->reduce that needs to propagate the innermost reduced
to the top.
When I don't have let
, it seems that the combination transduce
+ reduced
over a composition of mapcat
transducers is a reasonable solution.
But it doesn't work that well with let
s.
I'm pretty sure there was a macro for it somewhere but struggling to find it.
Any ideas? Maybe a better approach altogether?
for
with interspersed :let
and :when
fits perfectly in terms of structure.
But it's not suitable because (first (for ...))
will do a lot more work than needed.
Good to know my encyclopedic knowledge of the ecosystem isn't wasted (yet) (we should get a LLM to do that)
@U2FRKM4TW you have a gist to share? Hard to picture the problem in my head.
Sure, here's something I came up with on the spot. Although it's in Python, specifically to demonstrate that there it's a no-brainer, and that I had to rewrite some similar code in Clojure. :)
def find_red_item(items):
for item in items:
net = build_network(item)
nodes = find_affected_nodes(net)
for n in nodes:
max_depth = get_max_depth(n, net)
for d in range(max_depth):
es = get_relevant_edges(net, n, d)
for e in es:
if get_attr(e, 'color') == 'red':
return item, n, e