This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-01
Channels
- # announcements (7)
- # babashka (72)
- # beginners (62)
- # biff (1)
- # calva (9)
- # cider (8)
- # clj-kondo (35)
- # clj-otel (8)
- # cljsrn (11)
- # clojure (98)
- # clojure-europe (25)
- # clojure-germany (1)
- # clojure-norway (9)
- # clojure-uk (2)
- # clojured (3)
- # clojurescript (12)
- # conjure (3)
- # core-logic (4)
- # cursive (18)
- # datalevin (9)
- # datomic (5)
- # defnpodcast (2)
- # exercism (1)
- # graalvm (5)
- # gratitude (6)
- # hyperfiddle (3)
- # interop (12)
- # jobs (1)
- # joyride (34)
- # lsp (22)
- # meander (14)
- # missionary (16)
- # nbb (88)
- # off-topic (4)
- # pathom (20)
- # podcasts-discuss (1)
- # polylith (13)
- # portal (10)
- # re-frame (6)
- # releases (2)
- # remote-jobs (2)
- # rewrite-clj (3)
- # shadow-cljs (3)
- # spacemacs (6)
- # vim (24)
Why can't I use require
in a function like so?
(comment
(do
(require '[clojure.set :as c-set])
(c-set/union #{1} #{2}))
)
(comment
(->> ["1" "2"]
(reduce (fn [acc v]
(require '[clojure.set :as c-set])
(c-set/union acc #{v}))
#{})))
The first one works, but the second gives me:
; Syntax error compiling at (lab/sandbox_playground.clj:31:18).
; No such namespace: c-set
IIRC, aliases are resolved to namespaces when the form is read, but c-set
alias is defined in the ns later, on eval
When I copy/paste your second block of code in my REPL it works fine: (doesn't work indeed)
clj꞉myapp.core꞉>
(comment
(->> ["1" "2"]
(reduce (fn [acc v]
(require '[clojure.set :as c-set])
(c-set/union acc #{v}))
#{})))
nil ;; output
Is that because it's in the REPL and not from file?
(I probably evaluated the comment
😉)
tl;dr you cannot introduce new aliases and use them unless you're in a top level form or top level do
but you can get around this by just using (resolve 'clojure.set/foo)
and then use that
Awesome. And why is it called Gilardi scenario? There is nothing on the Internet, that I have found, that tells me that!
After the man, the legend, @U06C3GHJR who probably described it first?
Ah yes, here it is confirmed: https://clojurians.slack.com/archives/C03S1KBA2/p1604003087391900
If someone runs into troubles unpacking the blog post about the Gilardi scenario, like I did, here is how to make the OP code work:
(comment
(->> ["1" "2"]
(reduce (fn [acc v]
(require '[clojure.set :as c-set])
((resolve 'c-set/union) acc #{v}))
#{})))
I'm new to this. 😃 Yeah, that works too:
(comment
(->> ["1" "2"]
(reduce (fn [acc v]
((requiring-resolve 'clojure.set/union) acc #{v}))
#{})))
Asked the question here for easier googling by future me: https://ask.clojure.org/index.php/11922/how-to-require-a-symbol-from-within-a-function Please answer 😃 🙏
I got another solution as an answer to that question. It was a bit unclear from the prose of the answer if it worked, but I tried it and it does work. A bit to my surprise...
Hiya! Here's my take: Macro expansion happens early in the process of evaluating the form. Macros take arguments and return "expanded" code. In this case, the expanded code is "nil", but in the process of producing that nil, there is a side-effecting function call to require
(the function). The clever trick hooks into the evaluation machinery at a time early enough ("macro expansion time") to allow the alias reference to be properly resolved when it is compiled a bit later.
Where the clever trick is a little bit iffy is that the task of understanding Clojure code is simpler if macros are purely functional: transforming "arguments in" (which may include "code as data" (e.g., &body
)) to "code out". Calling functions for side effects inside a macro is not in keeping with a purely functional (easier to understand and test) style.
However, in this case, the workaround macro is very simple and is intentionally used only for its single side effect. The potential for producing confusing/hard to debug behavior is very small.
Awesome. Thanks, @U06C3GHJR! It makes sense and I now learned about a part of the process that I had the wrong ideas about.
I now wonder why the answerer said this when I informed about my use case: > Sorry, but my hack with a pseudo-macro will not be useful in this case, even though it gives the good result in the REPL.
I tested it, and it does work in the Joyride script where I ran into the Gilardi scenario to begin with. clj-kondo doesn't like it though, but that is probably a configuration issue.
I'm surprised to be honest that it works in SCI. A better solution is to just use require + resolve imo
Can I do that change now, you mean, and be future compatible? Maybe move this part of the discussion to #joyride...
I'm not planning to use the pseudo macro thing for this. But I am curious about why it wouldn't work. Given what I now know about it, thanks to @U06C3GHJR, it seems it should work? At least in real Clojure and ClojureScript. SCI might be a different story, even though it is amazingly true to the ”real” things.
Is there any way to know whether a var is a macro? Something like fn?
but for macros e.g. (macro? #'or)
.
(:macro (meta #'or)) ;; => true
this flag should be true for any macro https://github.com/clojure/clojure/blob/b1b88dd25373a86e41310a525a21b497799dbbf2/src/jvm/clojure/lang/Var.java#L243-L245
you can also use isMacro method of Var it defined just three lines below my link but then you make your code depend on internal implementation details
Has anyone tried using Clojure in Excel using https://exceljava.com/docs/index.html ? Looks like an interesting idea

i am looking for clojure(or a clojure like languange) for python, i might prefer to use python data structures, and also to have easy interop, and easily intergrated with python projects
any suggestions has someone used any of them? or some other clojure-like language for python
I tried both, but just toyed with them. Hylang is not really Clojure, its just a Lisp syntax for Python, everything else is Python, so the way you do things is the same as Python. If you're used to Python semantics and programming constructs over those of Clojure, its a good choice if you just want Lispyness. The Lisp has some limits, for example let
doesn't exist, you only get function scope and global scope, no let scope, just like in Python but unlike in other Lisps.
libpython-clj is my preferred one, but that's because I much prefer Clojure proper, and that lets you use Python libs from Clojure proper. Its straightforward, everything I tried worked, but I suspect some more esoteric Python libs might have issues, not sure.
Since you said you prefer Python data structure, and want easy integration with Python, HyLang is your best bet.
thank you didibus i tried only libpython-clj, one test project, worked nicely clojure like. but i was curious if i can give the code i made with libpython-clj to a python programmer, to use it as library
I'd be surprise if you could, I think with libpython-clj you only get one way interop, Clojure can use Python, but not the other way around.
In theory, there's also GraalVM polyglot stuff, and if you run Python there, it could make use of other things like Clojure, but you have to run everything with GraalVM including the Python, so it is not standard CPython
Hey.
I found a macro when-class
in clojure.core. It's not documented but it's probably used to find out whether a class exists. Can I use it and not import some classes?
it is not documented because it is private. And I don't know how private macro can be used in user code
Oh. Well I simply found it and didn't even try to call. But even then I could copy the source code. And what I wanted to know if it would be safe to use it.
I don't know why it wouldn't ) it is just 4 lines of code so even in case of problems debugging should not be a massive headache
Maybe. I was expecting the answer to be something similar to "the class may not be loaded if nobody imported it" or something like that. Because it's possible that the class may be marked as if it doesn't exist before anybody loads it. But I don't need this function now. Simply curious.
you can use class without explicit import. Upon symbol lookup clojure will try to load it for you
So does it mean that the macro will load the class?
I decided to use it. I need to parse some EDN and I'm migrating from joda time. This is my internal representation that I then use to bind serialization/deserialization methods.
(def serializers (merge {"mm/instant" [java.time.Instant java-time/instant]
"mm/local-date-time" [java.time.LocalDateTime java-time/local-date-time]}
(when-class "org.joda.time.DateTime"
{"clj-time/date-time" [org.joda.time.DateTime time-coerce/to-date]})))
what are the best tools for creating interactive documentation for clojure libraries? I’d like to be able to publish docs to github pages so that people can play around with examples in a browser. It seems like a couple options are: • klipse • scittle I also looked at Clerk and it seems like it doesn’t exactly get me there? It looks like you can publish notebooks but I don’t see that mentioned anywhere in the readme
https://www.maria.cloud/ offers a very nice experience. Not sure how it's implemented, but might be worth checking out. But sorry, I think this is just clojurescript.
@U0AQ1R7FG You can achieve this with SCI + your library in the configuration. Let me know if you need any help with that. Possibly you can also use nextjournal's clojure-mode for the code editing.
And when combining all of this with clerk, it would be quite cool. Maybe a more out of the box experience would help. cc @U5H74UNSF
This comes pretty close: https://twitter.com/hashbrown490/status/1530668983552077824 (read the thread, it's done with SCI btw)
@U0AQ1R7FG An example: https://nextjournal.com/try/borkdude/confetti It would be cool if you could have your own library in there (sicmutils is included here and you can play around with it) and just front-end, no backend, so it can be hosted on github pages (although maybe you could have the front-end load notebooks from a gist or so)
@U04V15CAJ thank you, this is very helpful!
You can set up a build task to push them to a static site (e.g. gh pages), that's what Clerk does for its own docs. They're not normally interactive in the sense that someone can open the rendered notebook and play with the code. Nextjournal is a better fit for that.
clerk notebooks can be as interactive as scittle (as they also have access to sci which scittle is built on), and example is https://snapshots.nextjournal.com/clerk/build/814589de0fdc0cda80894d717a5d3a7f36332447/index.html#/notebooks/slideshow.clj. If your goal is to let folks interact with changing code samples, we’re not there (yet).
Hello folks, could anyone please answer this question of mine?
(new java.util.Queue)
=> Syntax error (IllegalArgumentException) compiling new at (/private/var/folders/w_/vx0dsld95z72bz6ml4txpgcw0000gp/T/form-init15671582189914750444.clj:1:1).
No matching ctor found for interface java.util.Queue
So I can’t instantiate a Java queue. I am just assuming that I have to give a type parameter. I actually want to instantiate Queue<AsyncContext>
type. But I couldn’t find from anywhere
how I would specify the type parameter part (`AsyncContext` ). Please share your knowledge with me 🙂java.util.Queue
is an interface, you can't instantiate it. You have to find a concrete class implementing that interface that satisfies your needs and instantiate that instead.
generics (the <AsyncContext>
part) are erased in Java, meaning everything is really a plain Object under the hood
Thanks folks! Indeed.
(new java.util.concurrent.ConcurrentLinkedQueue)
this was what I needed!
Have a nice day! @U2FRKM4TW @U050ECB92
I assume then there is really no syntax for type parameter in Clojure ?
Got it 🙂 thanks again! Learned something new.
Is the reason the clojure.error/source is "NO_SOURCE_FILE" because i'm evaluating individual expressions at the repl? I'm not blocked on anything i'm just trying to sharpen my error reading skills and that bit seems obscure.
Yes, correct.
how does it know the line and column but not the source?
#:clojure.error{:phase :execution,
:line 306,
:column 7,
:source "NO_SOURCE_FILE"}
licenses=> (def x 1)
#'build.licenses/x
licenses=> (meta #'x)
{:line 16,
:column 1,
:file "NO_SOURCE_PATH",
:name x,
:ns #object[clojure.lang.Namespace 0x6634558a "build.licenses"]}
I think the main REPL uses a LineNumberingPushbackReader, IIRC...
https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L368-L374 -- so it depends on how you start the REPL, but the default is to use LNPR.