This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-20
Channels
- # admin-announcements (1)
- # announcements (1)
- # beginners (115)
- # calva (31)
- # cider (25)
- # clj-kondo (47)
- # cljdoc (23)
- # cljs-dev (5)
- # clojars (1)
- # clojure (60)
- # clojure-australia (1)
- # clojure-europe (23)
- # clojure-nl (3)
- # clojure-norway (2)
- # clojure-spec (3)
- # clojure-uk (18)
- # clojurescript (49)
- # community-development (1)
- # cursive (4)
- # datahike (2)
- # datascript (3)
- # datomic (36)
- # deps-new (2)
- # emacs (2)
- # events (9)
- # fulcro (6)
- # graphql (2)
- # gratitude (13)
- # holy-lambda (1)
- # introduce-yourself (10)
- # macro (2)
- # malli (5)
- # meander (9)
- # news-and-articles (5)
- # nextjournal (1)
- # off-topic (32)
- # pathom (17)
- # pedestal (13)
- # polylith (4)
- # protojure (4)
- # reagent (4)
- # sci (27)
- # shadow-cljs (2)
- # show-and-tell (2)
- # specter (3)
- # tools-deps (7)
- # xtdb (16)
Does anyone have a nice way of handling destructuring of (for example) a map, using a when-let
form so that if the destructured values are nil, not to eval the body of the form?
how about
(defmacro when-let-destruct [bindings & body]
(let [local? (->> bindings (partition 2) (map first)
(tree-seq (fn [x] (and (not (string? x)) (seqable? x))) seq)
set)]
`(let ~bindings
(when (and ~@(->> bindings destructure (partition 2) (map first) (filter local?) distinct))
~@body))))
(macroexpand-1 '(when-let-destruct [{:keys [a b]} {:a 1 :c 2}] (+ a b))) ;; => (clojure.core/let [{:keys [a b]} {:a 1, :c 2}] (clojure.core/when (clojure.core/and a b) (+ a b)))
(when-let-destruct [{:keys [a b]} {:a 1 :c 2}] (+ a b)) ;; => nil
(when-let-destruct [{:keys [a b]} {:a 1 :b 2}] (+ a b)) ;; => 3
???(when-let [{:keys [a]} {:a {:b 1} :c 2}]
(str "The value is '" a "'")) ;; "The value is '{:b 1}'"
(when-let [{:keys [d]} {:a {:b 1} :c 2}]
(str "The value is '" d "'")) ;; "The value is ''"
In the second example, I don't want the body to eval. I understand the when-let
form does the let
part first, as can be seen from expanding the macro out...
(clojure.core/let [temp__4165__auto__ {:a {:b 1}, :c 2}]
(clojure.core/when temp__4165__auto__
(clojure.core/let [{:keys [d]} temp__4165__auto__]
(str "The value is '" d "'"))))
I donโt know about a nice way, but perhaps you could do something with some->
, or else wrap a let
with when-let
Happy Friday ๐