This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-08-23
Channels
- # babashka (104)
- # beginners (23)
- # calva (15)
- # cider (2)
- # clojure (29)
- # clojure-europe (14)
- # clojure-nl (2)
- # clojure-norway (3)
- # clojure-spec (4)
- # clojure-switzerland (1)
- # cursive (3)
- # datomic (6)
- # emacs (17)
- # etaoin (2)
- # expound (1)
- # fulcro (4)
- # graphql (4)
- # honeysql (7)
- # introduce-yourself (2)
- # jackdaw (5)
- # malli (3)
- # meander (19)
- # nbb (3)
- # off-topic (35)
- # pathom (6)
- # pedestal (4)
- # polylith (31)
- # rdf (11)
- # re-frame (8)
- # reitit (6)
- # shadow-cljs (8)
- # specter (4)
- # squint (15)
- # vim (6)
Does any memoize/cache library implement a ttl cache that always returns fast and updates the value on the background? I mean something like this:
(defn get-value []
(let [result @cache]
(when (old? result)
(future (reset! cache (expesive-computation))))
result))
a normal ttl cache does something like
(if-not (old? result)
result
(do (reset! cache (expensive-computation))
@cache))
It's easy enough to implement something like this, and I've done it for a previous project, but I assume others would need the same thing
Guava cache does it with refreshAfterWrite
https://github.com/google/guava/wiki/CachesExplained#refresh
The HTTP caching spec calls it stale-while-revalidate
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate
user=> (vec #{1 2 3})
[1 3 2]
or use seq
into-array
or that đ
it depends on the use case. if array needed for interop it is better to use into-array
Letâs say I have this macro:
(defmacro m1 [n x]
`(def ~n ~x))
It works fine: if I run (m1 foo1 1)
, I get back #'user/foo1
, and the value of foo1
is 1. So far so good. But if I have this macro:
(defmacro m2 [n x]
`(when-not (resolve '~n)
(def ~n ~x)))
(m2 foo2)
, gives back nil
, and foo2
gives me #object[clojure.lang.Var$Unbound 0x65b01bf5 "Unbound: #'user/foo2"]
. If I change it to (when-not false ...)
it works like m1, so the when-not isnât the problem. macroexpand
didnât give me any clues - everything looks fine there. Does anyone have any idea whatâs going wrong?Trying again with a new var, to show the the before and after:
user> foo3
Syntax error compiling at (*cider-repl src/tmp:localhost:33461(clj)*:1:8275).
Unable to resolve symbol: foo3 in this context
user> (m2 foo3 3)
nil
user> foo3
#object[clojure.lang.Var$Unbound 0x70deeb77 "Unbound: #'user/foo3"]
The var is interned when the (def ...)
expression is parsed - regardless whether it's in (when false ...)
or not.
How can I get round the issue with def
? I think I tried something with bound?
previously, but it didnât seem to make any difference (perhaps because of the quoting issue).
> Do you mean (resolve ~(list 'quote n))
?
Yes.
> How can I get round the issue with def
?
What exactly are you trying to achieve?
This is the use-case I have:
I often use a macro like this: (defmacro d [n x]
(do (def n x) ~x))`, that I can wrap round expressions to store them for poking at (so a little like #spy/p from spyscope, but for def rather than printing). But sometimes I want to capture the result from multiple runs, so I want to def once, and then conj the other times.
I know I could just create a list/atom/whatever outside of the function/macro, but I wanted to get it working with âdef it, unless it already existsâ, if you see what I mean.
@U060FKQPN Iâll give that a go
Thank you for your help, both. This seems to work for the âdef unless it exists partâ:
(defmacro m4 [n x]
`(when-not (resolve ~(list 'quote n))
(intern ~(list 'quote 'user) ~(list 'quote n) ~x)))
although Iâm not sure why I need 'user
and not just user
in ~(list 'quote 'user)
(without he extra '
I get No namespace: user/user found
)you're within an unquote, so without the quote it would be evaluating the symbol user
