This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-16
Channels
- # ai (5)
- # announcements (47)
- # aws (11)
- # babashka (20)
- # beginners (85)
- # biff (1)
- # calva (72)
- # cider (9)
- # clj-kondo (37)
- # cljfx (9)
- # cljs-dev (1)
- # clojars (2)
- # clojure (61)
- # clojure-berlin (2)
- # clojure-europe (189)
- # clojure-nl (1)
- # clojure-norway (17)
- # clojure-uk (2)
- # clojurescript (51)
- # conjure (3)
- # cursive (4)
- # data-science (6)
- # datomic (6)
- # events (5)
- # fulcro (16)
- # gratitude (9)
- # holy-lambda (9)
- # introduce-yourself (6)
- # lsp (13)
- # malli (8)
- # membrane (2)
- # off-topic (47)
- # pedestal (11)
- # re-frame (15)
- # reitit (1)
- # releases (2)
- # rewrite-clj (6)
- # rum (4)
- # shadow-cljs (2)
- # tools-deps (3)
- # xtdb (25)
- # yada (13)
Is there a cleaner way to include a value in a map only when truthy?
(if foo
{:foo foo :bar bar}
{:bar bar})
I like this:
(cond-> {:bar bar}
foo (assoc :foo foo))
Anything about destructuring rules that could help make it even cleaner in a let binding?
(let [m (cond-> {:bar bar}
foo (assoc :foo foo))]
... )
If you want the key to automatically derive from the variable name, you could also make it a macro, though I'd say it might be a bit confusing to the user since it only makes sense if you pass in a symbol referencing a local or global var.
(defmacro assoc? [m v]
(if (symbol? v)
`(if ~v (assoc ~m (keyword (name '~v)) ~v) ~m)
(throw (ex-info "assoc? value must be a symbol referencing the value." {}))))
(let [foo 12]
(assoc? {} foo))
;;=> {:foo 12}
Though, maybe if you overload it, then it can be a convenience 2-arity:
(defmacro assoc?
([m v]
(if (symbol? v)
`(if ~v (assoc ~m (keyword (name '~v)) ~v) ~m)
(throw (ex-info "assoc? value must be a symbol referencing the value." {}))))
([m k v]
`(if ~v (assoc ~m ~k ~v) ~m)))
(assoc? {} :foo 12)
;;=> {:foo 12}
(assoc? {} :foo nil)
;;=> {}
(def foo 12)
(assoc? {} foo)
;;=> {:foo 12}
(def foo nil)
(assoc? {} foo)
;;=> {}

I've always done
(merge {:bar bar }
(when foo {:foo foo }))
I've also always wondered in what scenario I would use cond->
> I like this:
> (cond-> {:bar bar}
> foo (assoc :foo foo))
Thank you @U04V70XH6Hello Guys! I beginner of clojure. And I have question about httpkit and ring flash message middleware. I have small application with next routes
(GET "/login" [] #'auth/Login)
(POST "/login" [] #'auth/LoginCheck)
GET /login - just render form via formative
POST /login - validate form-params
Also I use middleware ring.middleware.flash
and ring.middleware.session
After submit form on GET /login, handler validate form-params
on POST /login and return next map {:status 302 :headers {"Location" "/login"} :flash {:problems {...}}}
And when I tried to get flash message on GET /login, I got nil
.
Can you help why flash messages is nil after redirect?
Thank youSome things are both functions and macros in CLJS. Where can I read about this topic to understand it better?
Thanks, @UE72GJS7J!
How does one run a jvm-opts alias in the command line? I'm trying to launch a repl like so, with an alias :jdk-17 defined in deps.edn
clj -M:repl/nrepl -O:jdk-17
I don't think -O
is a valid flag for clj, but everything after the -M flag and its args may get passed to your main function
is jdk-17 an alias that sets a jvm-opts flag? If so clj -M:repl/nrepl:jdk-17
should work
-O used to be a thing but is not anymore
Should just use with -A or -M or -X as appropriate
@UEQPKG7HQ sweet, this worked. Thanks! @U0NCTKEV8 @U064X3EF3 thanks for the info!
I am looking for a simple way to split a list as follows: (split nil nil) -> nil (split '(1 2 3) '(true false)) -> ((1) (2 3)) (split '(1 2 3) '(false true)) -> ((1 2) (3)) (split '(1 2 3) '(true true)) -> ((1) (2) (3)) Essentially, the list is split where the corresponding entry in the second parameter is true and is not split where it is false. Anybody have a neat way of doing this?
so, this is sorta like a map that takes a 2-arity fn and tags the output as split/no-split... something like that?
try map, i think you can get what you want from a map that takes in 2 lists, and then another processing step after that
As to your second comment, that is how the data is being derived. Basically, I have a list of dates. The dates have gaps between them. I need to split the list wherever the gap is larger than a particular size.
In the first example, because list2[0] is true, the list is split after list1[0]; because list2[1] is false, the next list is not split after list1[1].
Yeah, I was looking at that, but I couldn't figure out how to make the polarity of the function argument change at the right time.
partition-by is pretty big, to get it to do what you want is probably 4-5 lines of code
What I'd need is a function that changes polarity each time the list element is true.
This gets a bit close:
(defn interleave-all
"Returns a lazy seq of the first item in each coll, then the second etc."
{:added "1.0"
:static true}
([] ())
([c1] (lazy-seq c1))
([c1 c2]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2)]
(cond
(and s1 s2)
(cons (first s1) (cons (first s2)
(interleave-all (rest s1) (rest s2))))
s2 s2
s1 s1
:else nil)))))
(partition-all 2 2 (interleave-all '(1 2 3) '(false true)))
are you sure your examples are correct, cus i feel like the examples do not match the description.
(defn split [l1 l2]
(->>
(map vector l1 (concat l2 (repeat true)))
(reduce (fn [{:keys [last coll] :as acc} [k t-f]]
(let [last-run (peek coll)
coll-without-last-run (pop coll)]
(cond
(or t-f
(and (not t-f) last)) (-> acc
(update :coll conj [k])
(assoc :last t-f))
:else (let [updated-coll (conj coll-without-last-run (conj last-run k))]
(assoc acc
:last t-f
:coll updated-coll)))))
{:last false
:coll [[]]})))
i came up with this, but it follows the logic from the description, and not the examples(defn split [v1 v2]
(->> (interleave v1 (conj v2 (peek v2)))
(partition-by true?)
(remove #{[true]})
(map #(remove false? %))))
(split nil nil)
=> ()
(split '(1 2 3) [true true])
=> ((1) (2) (3))
(split '(1 2 3) [false true])
=> ((1 2) (3))
(split '(1 2 3) [true false])
=> ((1) (2 3))
My less erudite version?
(defn split-use-bool
"Split a list according to list of booleans"
[[hd & tail], bool-sq]
(let [flst (fn flst [num] (cons num '()))] ;; flst wrap num in list
(case bool-sq
((true true)) (cons (flst hd) (cons (flst (first tail)) (flst (rest tail))))
((true false)) (cons (flst hd) (flst tail))
((false true)) (cons (cons hd (flst (first tail))) (flst (second tail)))
((false false)) (cons hd tail)
"bool seq error")))
;test
(defn test-splits []
(let [lss (list 1 2 3)]
(for [fbool (list true false)
sbool (list true false)]
(prn [fbool sbool])
(split-use-bool lss [fbool sbool]))))
(test-splits)
I have a beginner's question about tooling in Clojure. What is the recommended build/package management tool? I see that the Clojure website suggests using clj, but I've also seen that many projects and resources refer to lein. The clj doesn't seem to have a convenient way to start a new project, but it does seem to have really good support for building and installing dependencies. The lein tool, on the other hand, seems to have a better user experience but seems to lack build options and package management support. I would appreciate any thoughts or guidance on this. For some context, I have read through the Learn Clojure guide and I've been reading through Clojure for the Brave and True.
One way to ease the beginner's onboarding with Deps is with something like this - https://github.com/seancorfield/deps-new - to give you project templating/bootstrapping without much effort.
both lein and clj (or tools.deps which is the library behind the clj script) have a file format for specifying dependencies and will fetch and make those dependencies available
dependencies are mostly maven artifacts, which both lein and clj support. clj adds some support for some other dependency types, most notably it can depend directly on a git repo
lein is older, is primarily a build tool, has a lot of built in build tool type functionality (packaging your project as a jar, etc) and has a large ecosystem of plugins
So is there one that is the standard?
clj is newer, is primarily a clojure process launcher, and a lot of functionality for doing build kind of tasks come from extra libraries
clj feels really nice, but it seems to be missing convenient tooling for starting a project.
you'll also want to look at tools.build which is a library that adds build tool like functionality to clj
Thanks for the guidance @U01GXCWSRMW and @U0NCTKEV8!
I was aware of clj-new but that seemed complicated to set up.
I'll give deps-new a try
if you project is light enough, you can get away without any kind of dependency file at all
to get started with clj
, you technically don't need anything to get a project started, even a deps.edn with just {}
will work
for example https://git.sr.ht/~hiredman/lions doesn't have a deps.edn at all because it doesn't use any external libraries and whatever version of clojure clj defaults too is fine
https://clojure.org/guides/deps_and_cli is a guide that demonstrates adding deps, referring to other local deps etc. And since clj/deps.edn supports git deps, pushing it to github makes it available for others too
Ah, I must have missed this.
Thanks, @U064X3EF3!
for future questions, #tools-deps is a good place to ask any deps.edn or clj related questions, and #tools-build is good for tools.build once you grow to that point (also see that guide https://clojure.org/guides/tools_build)
Okay, good to know. Sorry for posting in the wrong channel.
Not the wrong channel. You'll just get better, more in-depth answers in those other channels as you continue.
seconded - perfectly ok here (but more specialized forums exist)
Thanks, again. I'm new to the Clojure community, so I'll be sure to explore the Slack channels. If any of you have any must-use resources, I would be happy to have any recommendations.
I've been using Exercism and working on some of the Project Euler problems.
Some told me this clarified things for them, so here goes: https://clojureverse.org/t/starting-a-new-clojurescript-project-in-2022-setup-suggestions/9222/25?u=didibus
One big difference is lein includes most functionality inside itself, it's a big monolith. With clj, you're meant to install tools which are compatible with it, which are seperate programs maintained by others, such as deps-new linked above. Through installing various tools over tools.deps, and using tools.build for your build tasks, you get back all the same functionality as lein, but in a more micro-tooling kind of way.
Thanks, @U0K064KQV! That was a very helpful way to break down the differences.
I created a user configuration for Clojure CLI that adds a wide range of tools, providing the same kind of tasks as Leiningen https://practical.li/clojure/clojure-cli/install/community-tools.html https://github.com/practicalli/clojure-deps-edn
Thank you, @U05254DQM! I must say that you have a very nice collection of Clojure resources. I will be exploring that more.
Thanks. I’m always updating (Covid allowing) so let me know if there is anything missing that would be useful or anything that may need more explination.