Fork me on GitHub
#clojure
<
2021-02-25
>
M4rkD06:02:59

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?

hiredman07:02:23

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

hiredman07:02:54

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

hiredman07:02:36

In general installing clojure through package managers has always been terrible

hiredman07:02:55

And at odds with how clojure is usually used.

M4rkD11:02:54

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.

noisesmith17:02:22

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

noisesmith17:02:45

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

zendevil15:02:27

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?

zendevil15:02:46

Is there a way to get all regex matches?

ghadi15:02:21

that is not the result I'm getting

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

blak3mill3r15:02:37

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

ghadi15:02:28

note the spaces

ghadi15:02:06

look into greedy * vs reluctant *? qualifiers for regexes

ghadi15:02:50

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

zendevil15:02:18

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

zendevil15:02:35

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

ghadi15:02:26

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

ghadi15:02:47

(it's not an re-seq issue)

zendevil15:02:25

whereas

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

zendevil15:02:28

is there a way to get all recursive matches?

alexmiller15:02:16

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

☝️ 3
manutter5115:02:11

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

shan15: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.

shan15: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

alexmiller15:02:15

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

alexmiller15:02:20

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

shan16:02:16

thanks Alex

alexmiller16:02:54

or dynamic invocation with method handles

shan16:02:32

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

alexmiller16:02:49

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

👍 1
alexmiller16:02:23

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

shan16:02:53

thanks Alex, I appreciate the help

alexmiller16:02:16

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

alexmiller16:02:06

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

shan16:02:21

ah nice. Plenty for me to get started with 👍

nwjsmith17:02:07

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

nwjsmith17:02:38

---
name: Close pull requests
on:
  - pull_request
jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/[email protected]
        with:
          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'
            })

NoahTheDuke20: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.

NoahTheDuke20: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

NoahTheDuke20: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?

hiredman20:02:43

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

vemv22:02:33

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

hiredman22:02:15

expanding macros makes compilation take longer

hiredman22:02:35

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

hiredman22:02:31

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

👍 1
dpsutton22:02:50

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

NoahTheDuke14: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

vemv22:02:09

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

hiredman22:02:55

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

vemv22:02:43

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

andy.fingerhut23:02:48

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.

👀 1
vemv23:02:00

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

hiredman23:02:55

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

👀 1
hiredman23:02:22

clojure got patched to load things differently to work around it

alexmiller23:02:38

Fixed in Clojure 1.10.1

NoahTheDuke14: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