How to evaluate multiple keys?
;; Evaluating a specific key of an env (nodely/eval-key simple-env :c)
How can I in effect ask for multiple keys? Let's say I only know at runtime which ones I need. Wouldn't it be much more efficient to evaluate all at once? Do I need to create a node dynamically that I evaluate?
Hey @jtrunick, there is no official support for that in the API. You can always define some resulting node that is an aggregation of all the nodes you want.
{:a ... :b ... :c ... :final (>leaf [?a ?b ?c])}
Or using eval-node (or similar): (eval-node (>leaf [?a ?b ?c]) {:a ... :b ... :c ...} ...)
We're thinking of including something like this: https://github.com/nubank/nodely/pull/56 in the api, for a different set of reasons (it can help with some kinds of timeout logic). Some (most) engines rely on this Lazy Env structure that is a map with all the nodes prepared for execution and you can schedule execution by trying to fetch the key with (get env k). You could hypothetically schedule multiple keys for evaluation this way if you have access to the Lazy Env. I wouldn't recommend it though, I think doing one of the above is easier and does not expose you to implementation detail.
OK, I was thinking of going the latter route as you suggested above (using eval-node). So it sounds clear that doing a reduce operation with eval-key is going to be less performant. In my case, I want to be able to handle a list of n keys, so it sounds like I either use >leaf and generate symbols '?a '?b or possibly build the underlying data structure myself. Either way, it's doable and any engine strategy would be compatible. Thanks @sovelten
You don't need to overcomplicate this: eval will accept an env and a key, and return an env with that key and all of its dependencies evaluated. This means that you can write something like:
(-> env
(eval <k1>)
(eval <k2>)
((juxt <k1> <k2>)))
and you'll evaluate k1 and k2 by only doing the distinct evaluations for k2; k1's evaluations are still in the env you feed into the second eval
Consequently you can generalize this to n key by using the env as a memo to reduce and eval as your reducing function, once you're reduced you can fetch all of the keys out of the memo, they'll each be evaluated
@aredington Doesn't it block on (eval <k1>)? I want whatever parallelism I can get.
(-> env
(eval <k1>) ; <-- blocks?
(eval <k2>)
((juxt <k1> <k2>)))