This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-23
Channels
- # announcements (1)
- # babashka (29)
- # beginners (53)
- # berlin (1)
- # cider (14)
- # clj-kondo (18)
- # cljsrn (16)
- # clojure (141)
- # clojure-france (4)
- # clojure-italy (8)
- # clojure-norway (1)
- # clojure-uk (57)
- # core-async (7)
- # cursive (3)
- # data-science (2)
- # datomic (12)
- # duct (5)
- # fulcro (27)
- # hoplon (37)
- # immutant (1)
- # jobs (2)
- # jobs-discuss (7)
- # kaocha (2)
- # leiningen (3)
- # music (17)
- # nyc (1)
- # off-topic (22)
- # pathom (27)
- # re-frame (33)
- # reitit (23)
- # shadow-cljs (20)
- # tools-deps (15)
- # vim (29)
Are nested let
s idiomatic? Seems that it’s the right thing to do to keep bindings at their appropriate scope, but I haven’t seen a lot of it in example code I’ve stumbled across.
nested lets are unidiomatic, each binding can refer to all preceding bindings
instead of nesting bindings when you have side effects, use the idioimatic no-op binding _
or don't use side effects :)
yeah, I was figuring referring to prior bindings and side-effects were the two reasons someone would nest a let inside a let, and covering each case
that said, (let [x (foo) _ (bar)] x)
is a peeve of mine - just move (bar) out of th binding block into the body :/
Also, if you think you still need nested let
s, maybe consider breaking your function into smaller pieces.
hey people, I'm using deps.edn clojure and I want to get the alias variable on repl
like
clj -A:test
I want to know what variable contains the :test keywordI believe that the '-A:test' argument is not passed to the JVM process. It is 'consumed' by the clj
or clojure
command before the JVM process is started.
You could define the alias :test
inside of your deps.edn file to pass additional arguments to the Java process command line, using a key/val pair like :jvm-opts ["-Dmy.custom.jvm.property=true"]
thanks
There is also the :main-opts
key inside of deps.edn that an alias can have, causing additional command line arguments to be added to the Java command line.
@d.ian.b If it helps, you can think of clj
running in two phases: the first phase figures out the desired classpath (download libraries as needed), the list of desired JVM options, and the list of desired Clojure "main" options -- and those are all cached (into .cpcache
) -- and the second phase takes all that cached data and runs java ...
with appropriate options. So, by the time Clojure is running, nothing about the original clj
invocation is available.
(if you run the same command a subsequent time, it can just reuse the cached data -- so startup is much faster that time)
aw, thanks!
Hey! I am trying to write a macro but i am failing. The macro below works fine. But I would like to use it without the do
form.
(defmacro validate
"Validate data against a spec, if OK execute forms. Else log code and spec error message.
`code` - Unique random string, used to locate the execution place in src code.
`spec` - Clojure spec.
`data` - Data to validate against the spec.
`forms` - Forms to evaluate if spec validation is OK."
[code spec data forms]
`(if (s/valid? ~spec ~data)
(~@forms)
(do
(timbre/error ~code)
(timbre/error (s/explain-str ~spec ~data)))))
(validate "pe8DJKuyoIzFPUaC5mWHIdq" ::company/company company
(do
(println "gabba gabba hey")
(+ 1 1)))
Trying things like this but i get unbound fn failures.
(defmacro validate
[code spec data & forms]
`(if (s/valid? ~spec ~data)
(do ~(map (fn [form] ~form) ~forms))
(do
(timbre/error ~code)
(timbre/error (s/explain-str ~spec ~data)))))
so that the list that is the result of the map function gets spliced in, rather than just dumping a list
Dont really get it, trying this but still failing ~@(map (fn [form] ~@form) ~@forms)
the first @ means everything in the following list is unquoted, so you shouldn’t be unquoting ( and ~ @) anything inside that list
Still dont get it right
(defmacro validate
[code spec data & forms]
`(if (s/valid? ~spec ~data)
(do (map (fn [form] form) ~@forms))
(do
(timbre/error ~code)
(timbre/error (s/explain-str ~spec ~data)))))
user=> (defmacro foo [& forms]
#_=> `(do ~forms))
#'user/foo
user=> (clojure.pprint/pprint
#_=> (macroexpand-1 '(foo 1 2 3)))
(do (1 2 3))
nil
user=> (defmacro foo' [& forms]
#_=> `(do ~@forms))
#'user/foo'
user=> (clojure.pprint/pprint
#_=> (macroexpand-1 '(foo' 1 2 3))
#_=> )
(do 1 2 3)
nil
the above macros are broken in that they may evaluate spec and data multiple times, writing it as not a macro would be simpler and avoid that kind of thing
hi 🙂 Is there something like cond->
that short circuits? I have a value and want to execute the right expression depending on which 1-arity predicate returns true for it, out of a hard-coded set of such predicates …
… and it seems a little verbose to use cond
when the value is going to be fed into each of these predicates in turn
@fappy Something like
(foo-> x
pred1 do-thing1
pred2 do-thing2
pred2 do-thing2
;; ...
)
which expands to this:
(if (pred1 x)
(do-thing1 x)
(if (pred2 x)
(do-thing2 x)
(if (pred3 x)
(do-thing3 x)
;; ...
)))
Is that what you mean?I'd recommend looking through the options available in this library, although I do not know off the top of my head whether any of them match what you are asking for: https://github.com/Engelberg/better-cond
I get the sense that there is a good reason why cond->
does not short circuit, but I don’t know what it is
yeah, it applies threadings if the test preceding it is truthy
(condp #(%1 %2) :foo
string? "it's a string"
keyword? "it's a keyword"
symbol? "it's a symbol"
fn? "it's a function"
"something else!")
from https://clojuredocs.org/clojure.core/condp#example-542692d2c026201cdc326f6cJust to "prove" the answer, that macro-expands to this:
(let*
[pred__44187 (fn* [p1__44183# p2__44184#] (p1__44183# p2__44184#))
expr__44188 :foo]
(if (pred__44187 string? expr__44188)
"it's a string"
(if (pred__44187 keyword? expr__44188)
"it's a keyword"
(if (pred__44187 symbol? expr__44188)
"it's a symbol"
(if (pred__44187 fn? expr__44188)
"it's a function"
"something else!")))))
(actually, our condq
would work here but it wouldn't be any better than condp
: (condq #(%1 :foo) string? "it's a string" ,,,)
🙂 )