This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-06-15
Channels
- # beginners (56)
- # boot (4)
- # cider (22)
- # clara (10)
- # cljs-dev (50)
- # cljsrn (27)
- # clojure (27)
- # clojure-conj (4)
- # clojure-dev (3)
- # clojure-italy (17)
- # clojure-nl (12)
- # clojure-norway (3)
- # clojure-spec (10)
- # clojure-uk (137)
- # clojurescript (132)
- # cursive (4)
- # datascript (2)
- # datomic (109)
- # devcards (2)
- # editors (1)
- # emacs (4)
- # euroclojure (2)
- # events (4)
- # figwheel (1)
- # fulcro (15)
- # jobs (1)
- # jobs-discuss (4)
- # juxt (3)
- # leiningen (2)
- # off-topic (21)
- # onyx (13)
- # other-languages (8)
- # pedestal (6)
- # re-frame (22)
- # reagent (5)
- # reitit (1)
- # ring-swagger (3)
- # shadow-cljs (75)
- # sql (6)
- # tools-deps (2)
- # vim (1)
- # yada (8)
Here is an example of an intended use for the macro I asked about above. I was looking for a way to evaluate an expression in-place once at compile time such that I didn’t need to bind it to a symbol with def
. In this case, I didn’t want the extra overhead of calling .toString
on several java objects everytime I performed a comparison. I also wanted to let the java api decide what constant to use:
(defmacro inline [form] (eval form))
(condp = status-string
(inline (str QueryExecutionState/FAILED))
(do-something :im-a-failure)
(inline (str QueryExecutionState/CANCELLED))
(do-something :my-show-was-cancelled)
(inline (str QueryExecutionState/SUCCEEDED))
(do-something :lottery-as-retirement-investment-succeeded))
macroexpansion of (inline (str QueryExecutionState/FAILED))
is:
(macroexpand '(inline (str QueryExecutionState/FAILED)))
"FAILED"
It would be interesting if this could be profiled with and without the inline-compilation, and determine whether the Java compiler is smart enough to inline this automatically when it uses it at runtime. I might steal this idea!
i'm having trouble understanding when (inline (str QueryEx../FAILED))
wouldn't be just whatever value of QueryEx../FAILED
It would be, as the macroexpansion shows
The intent is to evaluate at compile time
i have no idea what problem you're solving so i'm not saying its wrong. just curious
Yes, it’s just an optimization. Avoiding both the pointer chasing and any repeated execution of the form.
i think you could get the same "memoization" from just putting them in a let above the defn of this and reusing them like that. and if you are optimizing pointer derefence of strings in clojure your life must be extremely hard
the emitter will put those in a variable anyways i bet, right? so you don't save a lookup anyways
optimizing the dereference isn’t what motivated me, but optimizing the arbitrary computation in the form did. And not wanting to have to name yet another thing
(let [failed (expensive-computation)]
(cond status
failed (react-whatever)))
could something like this help you get the same?Is there any way to supply a predefined vector of keys to a destructuring bind of a map? Something like:
(def test-keys [:one :two])
(let [{:keys test-keys} {:one 1 :two 2 :three 3}] (str one " " two))
That's a nonsense example, in reality I've a much larger vector of keys I'd like to supply
It fails the spec test in Clojure 1.9 which asserts the argument to keys has to be a vector
@oliver.mooney let
is a macro, so the only ways to do what you want are either to write another macro wrapping it, or use eval
@sundarj thanks for the pointer, I was wondering if I'd have to write a macro and my macro-fu is... lacking 😅
you might find https://github.com/clojure/tools.macro interesting
Thanks, I've been looking at that and Riddley too, not the first time I've felt the need for macros but they never go quite how I expect
Anyone can recommend a good arcticle/tutorial on deps.edn? I'm struggling to get things working, so I might be missing something...