clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
Gustavo Bertolino 2021-02-25T00:05:49.163500Z

I'm not sure if (iterate dec 5) 2) is a valid construction. This construction he suggested out of its context gets hard to see what he really meant. But (- n 2) makes sense a lot for me

2021-02-25T00:30:41.163800Z

After more discussion it was meant to be a joke that I didn’t pick up on. Sorry about that! 😳

dpsutton 2021-02-25T00:56:48.164300Z

the js vm can't handle integers that large

dpsutton 2021-02-25T00:58:08.164600Z

61305790721611591 > Number.MAX_SAFE_INTEGER
true

2021-02-25T01:03:20.165100Z

Oh wow!!! I had no idea.

2021-02-25T01:05:23.165300Z

the wild thing is when you are sending ids as numbers in json from a backend to the fronted and it exceeds the max safe integer

2021-02-25T01:05:33.165500Z

JavaScript represents number as 64-bit IEEE floating point, which can represent integers in the range [-2^54, +2^54] exactly, but only some integers outside of that range.

2021-02-25T01:07:37.165700Z

https://developer.twitter.com/en/docs/twitter-ids

πŸ‘ 1
jcburley 2021-02-25T05:21:09.166200Z

Wow, I’m surprised Joker (which is purely an interpreter, no JIT or compilation at all, written in Go) is even this fast:

user=> (time (nth fib 82))
"Elapsed time: 0.293 msecs"
61305790721611591

markgdawson 2021-02-25T06:51:59.169700Z

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?

2021-02-25T07:22:23.171600Z

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

2021-02-25T07:23:54.173900Z

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

2021-02-25T07:27:36.174700Z

In general installing clojure through package managers has always been terrible

2021-02-25T07:28:55.176300Z

And at odds with how clojure is usually used.

markgdawson 2021-02-25T11:55:54.188600Z

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.

zendevil 2021-02-25T15:00:27.189800Z

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?

zendevil 2021-02-25T15:00:46.190100Z

Is there a way to get all regex matches?

ghadi 2021-02-25T15:06:21.190800Z

that is not the result I'm getting

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

ghadi 2021-02-25T15:06:28.191Z

note the spaces

ghadi 2021-02-25T15:11:06.192300Z

look into greedy * vs reluctant *? qualifiers for regexes

ghadi 2021-02-25T15:11:50.193100Z

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

zendevil 2021-02-25T15:14:18.193600Z

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

zendevil 2021-02-25T15:14:35.193800Z

(defn remove-whitespace [string] (str/replace string #β€œ[ ]*” β€œβ€))

ghadi 2021-02-25T15:18:26.194900Z

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

ghadi 2021-02-25T15:18:47.195200Z

(it's not an re-seq issue)

blak3mill3r 2021-02-25T15:22:37.195500Z

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

zendevil 2021-02-25T15:27:25.196200Z

whereas

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

zendevil 2021-02-25T15:34:28.197100Z

is there a way to get all recursive matches?

alexmiller 2021-02-25T15:46:16.197400Z

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

☝️ 3
alexmiller 2021-02-25T15:46:43.197700Z

https://github.com/engelberg/instaparse is a great choice

πŸ™Œ 1
2021-02-25T15:48:11.198600Z

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

2021-02-25T15:51:00.199400Z

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.

2021-02-25T15:51:40.199500Z

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

alexmiller 2021-02-25T15:54:15.200Z

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

alexmiller 2021-02-25T15:55:20.200400Z

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

2021-02-25T16:03:16.200700Z

thanks Alex

alexmiller 2021-02-25T16:11:54.200900Z

or dynamic invocation with method handles

2021-02-25T16:12:32.201100Z

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

alexmiller 2021-02-25T16:13:49.201300Z

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

πŸ‘ 1
alexmiller 2021-02-25T16:15:23.202300Z

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

2021-02-25T16:15:53.202500Z

thanks Alex, I appreciate the help

alexmiller 2021-02-25T16:18:16.202700Z

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

alexmiller 2021-02-25T16:20:06.202900Z

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

2021-02-25T16:21:21.203100Z

ah nice. Plenty for me to get started with πŸ‘

nwjsmith 2021-02-25T17:31:07.206300Z

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

2021-02-25T17:35:22.206400Z

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

2021-02-25T17:35:45.206600Z

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

nwjsmith 2021-02-25T17:40:38.206900Z

---
name: Close pull requests
on:
  - pull_request
jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        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 <https://clojure.org/dev/dev> 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'
            })

NoahTheDuke 2021-02-25T20:54:35.207800Z

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.

NoahTheDuke 2021-02-25T20:54:42.208Z

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

NoahTheDuke 2021-02-25T20:54:48.208200Z

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?

2021-02-25T20:57:43.210Z

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

vemv 2021-02-25T22:42:33.214400Z

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

2021-02-25T22:47:15.215100Z

expanding macros makes compilation take longer

2021-02-25T22:47:35.215500Z

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

2021-02-25T22:48:31.216600Z

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

πŸ‘ 1
dpsutton 2021-02-25T22:48:50.217200Z

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

vemv 2021-02-25T22:49:09.217900Z

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

2021-02-25T22:49:55.218400Z

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

vemv 2021-02-25T22:51:43.219300Z

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

2021-02-25T23:04:48.221200Z

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
vemv 2021-02-25T23:13:00.221900Z

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

2021-02-25T23:26:55.224400Z

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
2021-02-25T23:27:22.224700Z

clojure got patched to load things differently to work around it

ghadi 2021-02-25T23:35:01.225600Z

https://cl4es.github.io/2019/02/21/Cljinit-Woes.html some background on it

alexmiller 2021-02-25T23:39:38.226Z

Fixed in Clojure 1.10.1