Fork me on GitHub

Has anyone installed Clojure from the guix package manager (i.e. guix install clojure). When I do that on ubuntu and run clojure, it gives me a repl. But it seems to ignore deps.edn files in the current directory. Anyone have any clues what could cause that kind of behaviour?


Whatever the clojure script is it installs isn't the tools.deps one


Clojure didn't have an official launcher like the tools.deps scripts have become for a long time, so many packagers in linux distributions included their own launcher scripts


In general installing clojure through package managers has always been terrible


And at odds with how clojure is usually used.


Thanks @hiredman, It was fine with the official installer scripts. But guix has nice advantages, so it would be nice to see something working. Thanks for the pointer to the repo, now that I know where it is maybe at some future time I'll have a go at a patch to make guix do something more similar to the installer script.


given that the only "global" install required for clojure is a jvm, and everything else is determined by per-project config and cached, I don't think guix helps much with clojure


and of course you can use deps.edn clojure with a jvm installed by guix


I’m using re-seq to get all the sequences that match a regex in clojure like so:

(re-seq #"(.*)\&(.*)" "((a & b) & c)")
And I’m getting the following result:
(["(a&b)&c" "(a&b)" "c"])
Whereas I expect the sequence to contain all such regex matches like so:
(["(a&b)&c" "(a&b)" "c"] ["(a&b)&c" "(a" "b)&c"])
How to fix this and what am I doing wrong?


Is there a way to get all regex matches?


that is not the result I'm getting

(re-seq #"(.*)\&(.*)" "((a & b) & c)")
=> (["((a & b) & c)" "((a & b) " " c)"])


(.*)\&(.*) tantalizing regex


note the spaces


look into greedy * vs reluctant *? qualifiers for regexes


as an aside, parsing nested things is not something regexes can do well


@ghadi I have a (remove-whitespace …) wrapped around the string


(defn remove-whitespace [string] (str/replace string #“[ ]*” “”))


there is only one possible match here with greedy qualifiers (the default *)


(it's not an re-seq issue)



(re-seq #"(.*?)\&(.*?)" "(a & b) & c")
> gives
(["((a&" "((a" ""] ["b)&" "b)" ""])


is there a way to get all recursive matches?

Alex Miller (Clojure team)15:02:16

I think regexes are a bad tool for this job - you want a parser

☝️ 9

Also instaparse is awesome once you get the hang of it. Well worth taking a few moments to learn.

Sam H15:02:00

does anyone know why this isn't possible:

(let [math-class (resolve 'Math)]
  (. math-class floor 5.677))
I'm trying to get a java class and then call a static method on it.

Sam H15:02:40

maybe I'm going about this incorrectly. I want to specify a java class in an edn file and then load that at run time and call static methods on that class

Alex Miller (Clojure team)15:02:15

math-class is not going to get eval'ed there - the . special form expects a literal class name

Alex Miller (Clojure team)15:02:20

you really need to use Java reflection if you want to do this dynamically

Sam H16:02:16

thanks Alex

Alex Miller (Clojure team)16:02:54

or dynamic invocation with method handles

Sam H16:02:32

can you point me to any docs / examples for me to read up on this?

Alex Miller (Clojure team)16:02:49

for reflection - Class/forName, then .getMethod(s), then invoke

👍 3
Alex Miller (Clojure team)16:02:23

for dynamic invoke - start from MethodHandles/lookup, then .findStatic with a MethodType/methodType

Sam H16:02:53

thanks Alex, I appreciate the help

Alex Miller (Clojure team)16:02:16

or you could build a Clojure expression and eval it :)

Alex Miller (Clojure team)16:02:06

(eval (list '. 'java.lang.Math 'floor 1.2))

Sam H16:02:21

ah nice. Plenty for me to get started with 👍


I'm not sure how much of a distraction they really are, but maybe PRs on Clojure and the contrib libs could be auto-closed with GitHub Actions? Something like


name: Close pull requests
  - pull_request
    runs-on: ubuntu-latest
      - uses: actions/github-script@v3
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            await github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: 'Hi, this project does not accept pull requests (please see  for more info on contribution process).'
            await github.issues.update({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'closed'

Noah Bogart20:02:35

i asked a variation of this question in #testing, but seemed broad enough to warrant discussion: i have defined a bunch of helper functions for use in my test suite. They do validation before passing code into the game engine (the same validation the game's UI does). When the validation fails, the line number in the error points to the helper function instead of the line in the test, so I converted the helper functions to macros so that the failure correctly points to the test's file and line.

Noah Bogart20:02:42

However, this makes the compilation time of my test suite balloon significantly. switching the two primary helper functions to macros makes my total test suite go from 40 seconds to 70 seconds

Noah Bogart20:02:48

i realize this is somewhat the nature of macros, but it still seems pretty intense. is there any way to get both correct line numbers and short test compilation times?


Yes, when the verification fails capture a stacktrace, them walk up the trace to your test code, and report that line number


I don't understand why the scenario described above is slower? Macros don't appear to be a slow mechanism (you can (time (macroexpand ...)) to verify this claim), and macro-emitted code should be fast as well (for one thing it elides would-be function calls) I do have experience assessing a certain slowness in the clojure compiler itself (and have asked about it here, gathering the fact that it intentionally emits simple code that is easy for the JVM to optimize). Not sure how macros play a role (if at all) in the equation


expanding macros makes compilation take longer


I imagine the slow down includes the time to compile the tests


this is really visible with complex macros, like if you use the go macro in core.async

👍 3

i'm surprised by the claim that compilation of a namespace goes from 40 to 70 seconds. that seems incredibly high to me

Noah Bogart14:02:01

Y'all got to chatting about this after I got off the computer for the day! One of the macros is used 1500 times and the other over 3000, lol


yes 30s seems a disproportionate cost for changing a defn to a defmacro. I'd assume from the OP that the defn was doing something fairly straightforward


it is, but if the macros contain calls to other macros you can easily inflate things


even if the would-be defn also contained the same calls to other macros?


It could depend on how often the would-be defn "bar" is invoked from other parts of the program. If bar is invoked 50 times, then when bar is a defn, the macro-expansions inside of it occur one time when loading the code. When bar is a defmacro, then bar and everything inside of it will be expanded 50 times when loading the code.

👀 3

oh TIL, both that one and go's specific slowness. ty both!


there was a performance regression in some jvm version, maybe 2 years ago by now? where code loaded while running static initializers (java feature) wouldn't get jit compiled, and clojure loads user.clj via a static init, so if you had a user.clj, and that user.clj loaded core.async, the macro expansion would run significantly slower

👀 3

clojure got patched to load things differently to work around it

Alex Miller (Clojure team)23:02:38

Fixed in Clojure 1.10.1

Noah Bogart14:02:01

Y'all got to chatting about this after I got off the computer for the day! One of the macros is used 1500 times and the other over 3000, lol