aero
question incoming: I have a custom reader that reads a file if a certain profile is used. Now that file is usually not present and only supplied in production environments:
:cljdoc/version #profile {:prod #slurp "CLJDOC_VERSION"
:default "dev"}
I think because everything is implemented using reader tags the file is being read regardless of what profile is being used, causing an exception in non-production environments.
Does anyone have advice around dealing with this situation?of course Deferred is the answer: https://github.com/juxt/aero#deferreds
I have something that makes aero lazy
Deferreds aren't always perfect.
what deficiencies are you thinking of ? i use Deferred
s for just about everything on the backend which isn't a pure fn...
#join[#state 1, #state 2]
That will 💥
what op is #join
@dominicm?
Same as (str #state 1, #state 2)
dyu mean where #state 1
and #state 2
are Deferred
?
Yeah
so you see exceptions when you stringify two Deferred
s ? that's weird, i've never seen anything like that
although i suppose it would be rare for me to stringify more than one Deferred
without having combined them first
You can't really do anything with a deferred if your result is non-walkable
what do you mean by non-walkable @dominicm ? we commonly have opaque objects in deferreds, so presumably you mean something else ?
I'm thinking the other way round, a string isn't walkable. Anything that creates an opaque object, cannot take a deferred as a return value.
do you have some example code ? i return Deferred<String>
all the time without any trouble, so i think i'm misunderstanding something
Implement #state as something that returns deferred<string>
❯ replme aero
[Rebel readline] Type :repl/help for online help info
user=> (require '[aero.core :as aero])
nil
user=> (defmethod aero/reader 'state
#_=> [_ _ value]
#_=> (aero/deferred value))
#object[clojure.lang.MultiFn 0x474c9131 "clojure.lang.MultiFn@474c9131"]
user=> (aero/read-config (java.io.StringReader. "#join [#state 1 #state 2]"))
"aero.core.Deferred@c23667ddaero.core.Deferred@ec3736c9"
That's not what you wanted as a result! 😄Same thing was true for #ref, but I made it specialer
The problem is that deferred is really a patch over the eagerness of aero. What you need is a lazy resolution mechanism. I based my solution around macros & functions. Macros (e.g. #profile) can lazily operate on what they're given. Functions have everything they're given pre-resolved. This should remove any need for deferred.
oh, wow, now i understand - :rolling_on_the_floor_laughing: - you are talking about aero.core.Deferred
and i am talking about manifold.deferred.IDeferred
!
which, looking at the conversation history, is entirely my fault - looks like i dyslexed into the Deferred
i was familiar with 😊
so now i understand what you are talking about, i think it's quite similar to a problem i had with our own app-context factory - in cljs i had factory fns which returned a promise of something, say a file-area, and i wanted other components to depend on that file-area
in order to do this i made the app-context factory return a Promise<app-context> - and once everything is Promise based it's fine to compose promises
Yep. But the root of the problem is deeper.
It's a major rewrite though, and it's living in a hacked up alternative branch
But the tests pass 😁
https://github.com/ztellman/aleph/issues/441 since yada is based on aleph (IIRC) this might be interesting for juxt folks... cc @dominicm et al
@malcolmsparks more so 😊
Yeah, pinged you because I wasn't sure how often Malcolm is around here 🙂
He lurks
I just answer quicker because I'm addicted to my phone