This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-12
Channels
- # adventofcode (1)
- # announcements (1)
- # atom-editor (4)
- # aws (4)
- # babashka (7)
- # beginners (46)
- # biff (14)
- # calva (11)
- # cljdoc (2)
- # clojure (78)
- # clojure-art (1)
- # clojure-austin (1)
- # clojure-europe (50)
- # clojure-nl (2)
- # clojure-norway (22)
- # clojure-spec (2)
- # clojure-uk (2)
- # clojurescript (72)
- # conjure (6)
- # core-typed (6)
- # eastwood (4)
- # events (1)
- # figwheel-main (11)
- # fulcro (1)
- # guix (1)
- # helix (13)
- # jobs (2)
- # jobs-discuss (4)
- # kaocha (2)
- # malli (5)
- # off-topic (7)
- # pathom (22)
- # pedestal (9)
- # re-frame (29)
- # reagent (7)
- # releases (2)
- # remote-jobs (1)
- # rewrite-clj (12)
- # shadow-cljs (44)
- # sql (13)
- # squint (2)
- # xtdb (17)
Hi, I'm looking for 'completely new to programing' guides for clojure. I made a website with a bb script and a fresh team member wants to hack on it
Hi, I started programming with Clojure as my first programming language, and I can suggest clojure for the brave and true book. Everything there is very nice and simply explained and full of jokes, so I really enjoyed working with this book :)
Now I made a blog post that mentions the book https://benjamin-asdf.github.io/faster-than-light-memes/intro-to-clojure.html#org1a44cb0
Hello All, I have a weird problem. I am trying out sicmutils.
(ns rand.filetry
(:require
[sicmutils.env :as e :include-macros true]
Deps entry:
sicmutils/sicmutils {:mvn/version "0.20.0"}
I have a macro as defined below:
(defmacro def-literal-function [label]
(->> label
(list 'symbol)
(list 'e/literal-function)
(list 'def (symbol label))))
When I run this macro it creates a literal-function defined in the global scope. e.g.
clj꞉rand.filetry꞉>
(def-literal-function "theta")
#'demo.clerktry/theta
clj꞉rand.filetry꞉>
(theta 't)
(theta t)
However if I need to run over a vector of labels e.g.
(def labels ["theta_1" "theta_2" "theta_3"])
(doseq [label labels]
(def-literal-function label))
This doesn't work in the same way.... as
clj꞉rand.filetry꞉>
theta_1
; Syntax error compiling at (..\Clojure\sicmutils-main\demo\.calva\output-window\output.calva-repl:0:0).
; Unable to resolve symbol: theta_1 in this context
What am I doing wrong? Why can't I access the values created by the macro?What's the result and output of the doseq
? You are using position_labels
there, and not labels
(which I think its your intention?)
yes that was a typo in my code. I've updated my code to fix this. It is not a typo issue in the original code. This is but an excerpt of the rest...
output of the doseq is just nil
Not an expert here at all, but I'm wondering... When you call (def-literal-function label)
, that would give the symbol label
to your macro, right? So maybe you are just creating a literal function named label
three times?
but when I am passing label to the def-literal-function it is a string. Not a function yet...
Yeah, I am not reading that code correctly. Let's wait for someone more macro-savvy to look at it. 😃
@U022LK3L4JJ You're trying to mix macro expansion and runtime values. You can see why it won't work with this simplified version:
user=> (def f "foo")
#'user/f
user=> (macroexpand '(def-literal-function f))
(def f (e/literal-function (symbol f)))
user=>
As pez said, you're defining a literal function called label
three times.
As @U04V70XH6 suggests - use macroexpand
to figure out if your macro does what you think it does!
And when asking for help with a macro, including example input from (macroexpand '(your-macro your-args))
is very helpful. Is the output what you wanted? Not? Why not?
@U04V70XH6 I am a newbie... (still 😄) So I destructured labels into label in doseq. Here label is a string. I am passing a string to the macro. The only difference between calling the macro with the string directly and the non-working code is the doseq. How do I get around this problem? Any ideas?
Macros are expanded first, so the argument is the symbol label
. There are no runtime values at that point. Once the macro is expanded, then the doseq
is evaluated. You are not passing a string to the macro, you are passing a symbol.
In my limited understanding I thought the whole point of macros is so that you can generate dynamic code to execute at runtime... so if I can't pass a string to macros, what is the right way of doing this?
In real world Clojure, macros are not used much, and their execution model can be very confusing when you're learning Clojure.
@U022LK3L4JJ If it helps at all, think of macros being "evaluated" (expanded) at compile-time and then the compiled code is executed (at runtime). The doseq
, the binding to label
, and the value of labels
are all runtime things. They happen after your macro has been expanded.
You could try to write a macro that you pass multiple (string) arguments that expands to multiple def
expressions (wrapped in a do
), so you could write (def-literal-functions "theta_1" "theta_2" "theta_3")
What would be a clean way of getting the nth element from index 0? For example
(func [0 1 2 3 4 5 6] 1)
#_=> [1 2 3 4 5 6]
(func [0 1 2 3 4 5 6] 2)
#_=> [2 4 6]
(func [0 1 2 3 4 5 6] 3)
#_=> [3 6]
You might be looking for take-nth
: https://clojuredocs.org/clojure.core/take-nth
(->> coll (drop n) (take-nth n))
or as a function:
(defn drop-take-nth [n coll]
(->> coll (drop n) (take-nth n)))
-----
Examples:
(drop-take-nth 1 [0 1 2 3 4 5 6])
;;=> (1 2 3 4 5 6)
(drop-take-nth 2 [0 1 2 3 4 5 6])
;;=> (2 4 6)
(drop-take-nth 3 [0 1 2 3 4 5 6])
;;=> (3 6)
Perhaps (map [0 1 2 3 4 5 6] your-indices)
?
I didn't either until I started pondering your question. So thank you for the opportunity to learn!
In case you're wondering why that works, vectors implement IFn
so they can be "invoked" with an argument, and they treat that argument as an index into themselves. Maps also implement IFn
and when "invoked" with an argument, they look that argument up as a key in themselves (and return the associated value).
Also sets:
user=> (let [v [1 2 3]] (v 1))
2
user=> (let [m {:a 1 :b 2}] (m :a))
1
user=> (let [s #{:a :b}] (s :b))
:b
user=>
Are there any resources which summarize which exception classes to throw in which situations?
I always throw ExceptionInfo (`ex-info`) and give the context as a map whenever I can. If you care about interop from Java it's probably more complicated than that though (and I honestly don't know).
Hmm, no, I don't care about Java interop. Is that a common approach - to just throw ex-info
like that?
My impression is that it's quite ubiquitous 🙂
Not exactly a scientific experiment but a quick search on http://grep.app shows that throw (ex-info...
is https://grep.app/search?q=throw%20%28ex-info&filter[lang][0]=Clojure than https://grep.app/search?q=throw%20.%2AException&regexp=true&filter[lang][0]=Clojure
That's roughly been my experience as well

What a relief! I thought I was going to have to start committing the exception hierarchy bits to memory.
is there a way to use :keys
to destructure a map without explicitly naming all the keys? I am reading over https://clojure.org/guides/destructuring and it gives multiple examples of the :keys
shortcut but only with explicit bindings. I've seen the & args
idiom used before in functions but that doesn't seem to work in my case. I've tried a couple variations and I either get nil
or an exception nth is not supported on PersistentHashMap
What do you want to accomplish? Destructuring’s whole point is to introduce an explicit binding based on the shape of the input data. If you don’t want a name introduced what do you want out of destructuring?
You don't have to name all the keys. You just name whatever ones you need. Are you trying get explicit names for some keys and then have another binding for all the ones you didn't name?
But it seems like when I use :keys
I have to match the actual key names exactly? That makes sense bc maps are unordered but if I just want keys by position should I not use a map?
I’m not following. :keys
is useful to destructure associative objects like maps. Where there is a key and a value. You can destructure by position just do that (which does not use keys)
Yeah that's what I want @U11BV7MTK. sorry for the confusion
You don't have to use :keys
to destructure a map. It's just sugar for keeping the same name.
(let [m {:a 1 :b 2}]
(let [{:keys [a b]} m]
(println a b)) ;; => 1 2
(let [{a :a b :b} m]
(println a b)) ;; => 1 2
(let [{c :a d :b} m]
(println c d))) ;; => 1 2
;; => nil
@U03QBKTVA0N Just be aware that if you try to use sequence destructuring on a hash map, there's no order to the key/value pairs, so "first" and "second" make no sense really.
Also, a little confusingly, if you destructure a rest argument from var-args as a map, it treats it as a pair of key/values.
(defn foo [& {:keys [a b]}]
[a b])
(foo :a 1 :b 2)
;;=> [1 2]
This applies to any sequence, so you can treat an ordered sequence as key/value pairs.
(let [{:keys [a b]} (seq [:a 1 :b 2])]
[a b])
;;=> [1 2]
But this only works for sequences, not for vector for example, but it will for list or sequences.Hello, I'm getting this error.
(clojure.core/load "/min/src/min/core")
Execution error (FileNotFoundException) at user/eval6006 (REPL:1).
Could not locate min/src/min/core__init.class, min/src/min/core.clj or min/src/min/core.cljc on classpath.
when calling the following from the projects root directory in clj
:
user=> (require '[min.src.min.core] :verbose)
Project structure
├── deps.edn
└── src
└── min
├── core.clj
└── db.clj
If the file is src/min/core.clj
then the namespace will be min.core
-- src
is one of the classpath roots and namespaces are relative to the classpath in terms of how they match filesystem paths.
(assuming you are running clj
in the folder containing deps.edn
, which you should be @U01HBARPCFL)