clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2021-06-03T00:01:09.298200Z

Can someone please explain to me what Shaun Lebron might have been thinking about with this?

2021-06-03T00:01:24.298400Z

https://youtu.be/K0Tsa3smr1w?t=2054

alexmiller 2021-06-03T02:08:35.299200Z

(grey ... (white) ...
  (green ... (lt-green (gold) ...) 
    (blue)))

šŸ‘ 2
2021-06-03T03:07:35.300200Z

I guess my question is more about why he thinks the depth view is more meaningful than the nesting view

alexmiller 2021-06-03T03:14:16.300700Z

I think it's only when the open expression is on the left, that you indent?

alexmiller 2021-06-03T03:14:48.301300Z

and you don't with the ones in the middle? or maybe that's obvious, not sure

2021-06-03T06:26:39.303800Z

Iā€™m using test-runner (https://github.com/cognitect-labs/test-runner) for testing and made a github action for it, but it somehow constantly fails with

Syntax error (FileNotFoundException) compiling at (farmmorning/case_format_test.clj:1:1).
Could not locate farmmorning/util/case_format__init.class, farmmorning/util/case_format.clj or farmmorning/util/case_format.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
I double checked the file names, but couldnā€™t find any clues. can someone give me some advice?

borkdude 2021-06-03T07:37:35.304200Z

Could be a .gitlibs problem. Try rm -rf ~/.gitlibs

borkdude 2021-06-03T07:37:42.304400Z

and rm -rf .cpcache

dharrigan 2021-06-03T07:40:06.304600Z

Also, would you be possible to share where the github action is?

2021-06-03T07:41:38.304800Z

yep. here it is.

name: test

on:
  - pull_request

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code
        uses: actions/checkout@v2

      - uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: '11'

      - uses: DeLaGuardo/setup-clojure@3.2
        with:
          cli: '1.10.1.693'

      - name: Cache maven
        uses: actions/cache@v2
        env:
          cache-name: cache-maven
        with:
          path: ~/.m2
          key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/deps.edn') }}
          restore-keys: |
            ${{ runner.os }}-${{ env.cache-name }}-

      - name: Copy file
        run: cp -r resources dev/resources

      - name: Print paths
        run: clojure -Spath -X:test

      - name: Run test
        run: clojure -X:test

2021-06-03T07:48:29.305Z

@borkdude those commands should be run from github action, right?

dharrigan 2021-06-03T07:53:40.305300Z

I assume, the same command, clojure -X:test from your local system works flawlessly?

dharrigan 2021-06-03T07:53:47.305500Z

you're able to run tests locally?

2021-06-03T07:57:29.305700Z

yes, they can be run locally without problem.

2021-06-03T07:58:00.306Z

it fails only on github action.

dharrigan 2021-06-03T07:58:24.306200Z

Hmm, I don't have much experience with github actions, so I'm afraid I can't offer more help šŸ˜ž

šŸ™ 1
2021-06-03T06:27:07.304Z

here is the deps configuration.

:aliases {:dev     {:extra-paths ["dev/src"]}
           :test    {:extra-paths ["test"]
                     :extra-deps {io.github.cognitect-labs/test-runner
                                  {:git/url "<https://github.com/cognitect-labs/test-runner.git>"
                                   :sha "705ad25bbf0228b1c38d0244a36001c2987d7337"}}
                     :exec-fn cognitect.test-runner.api/test}}

Grigory Shepelev 2021-06-03T07:57:38.305900Z

seems like malli channel is kinda dead. asking for help

ikitommi 2021-06-03T07:58:51.306400Z

dead like in no-one answering in 20min? :thinking_face:

Grigory Shepelev 2021-06-03T07:59:17.306600Z

yes

šŸ˜‚ 4
p-himik 2021-06-03T08:51:27.306800Z

Please wait for at least a few hours before judging a channel as "dead" and reposting a question in a different one.

anonimitoraf 2021-06-03T09:20:27.307300Z

By that definition, #clojure seems to be more dead

Stefan 2021-06-03T10:08:29.312800Z

Hi all, I ran across Alex Millerā€™s article ā€œImproving Development Startup Timeā€ (https://clojure.org/guides/dev_startup_time). That seems like something I would want šŸ™‚ Iā€™m having trouble getting it to work however. When I execute (compile ā€¦) I only see the class files of that namespace, not the ones required by it. Whereas the article says ā€œtransitiveā€ which I take to mean that all namespaces it depends on should also be compiled. So I compile a few of them by hand, do a jack-in, and start my dev server, and it isnā€™t one bit faster. Now that may of course be due to other reasons, I didnā€™t profile the startup process, but Iā€™d like to make sure that Iā€™m not missing something. I added ā€œdevā€ and ā€œclassesā€ to extra-paths in deps.edn, I even added :jvm-opts ["-Dclojure.compile.path=classes"]. Any idea if Iā€™m doing something wrong?

borkdude 2021-06-03T10:10:58.314400Z

> When I executeĀ (compile ā€¦)Ā IĀ onlyĀ see the class files of that namespace, not the ones required by it That's not what I'm seeing when I compile the top level ns of an ns tree

borkdude 2021-06-03T10:12:50.316100Z

@stefan.van.den.oord

borkdude@MBP2019 ~/Dropbox/dev/clojure/babashka (master) $ mkdir classes
borkdude@MBP2019 ~/Dropbox/dev/clojure/babashka (master) $ ls classes
borkdude@MBP2019 ~/Dropbox/dev/clojure/babashka (master) $ clj
Clojure 1.11.0-alpha1
user=&gt; (compile 'babashka.main)
babashka.main
user=&gt;
borkdude@MBP2019 ~/Dropbox/dev/clojure/babashka (master) $ ls classes
babashka    bencode     borkdude    cheshire    clj_yaml    clojure     cognitect   edamame     flatland    hf          hiccup      org         rewrite_clj sci         selmer

caumond 2021-06-03T10:22:30.320700Z

Hi, I find a performance gap between the rand-int clojure function and the java native one for instance .nextIn of java.util.Random. The gap is small for small amount of iterations but increasing with the number of iterations. @alexmiller,I saw some of your posts asking for feedback on performance, so I ask if I did something wrong, or if youo think this is something which should be improved in the clojure standard library, or maybe my case is so specific that I have to use interop?

(ns poc.defrecord.slack)

(def ^java.util.Random seed (java.util.Random.))
(defn compare-rands [nb-iter]
  [{:method :java-call
    :iterations nb-iter
    :time (with-out-str  (time
                          (dotimes [_ nb-iter]
                            (.nextInt seed 100))))}
   {:method :native-rand
    :iterations nb-iter
    :time (with-out-str (time (dotimes [_ nb-iter]
                                (rand-int 100))))}])

(compare-rands 2000000)
;; =&gt; [{:method :java-call,
;;      :iterations 2000000,
;;      :time "\"Elapsed time: 35.315238 msecs\"\n"}
;;     {:method :native-rand,
;;      :iterations 2000000,
;;      :time "\"Elapsed time: 127.318862 msecs\"\n"}]
;; =&gt; [{:method :java-call,
;;      :iterations 200,
;;      :time "\"Elapsed time: 0.017836 msecs\"\n"}
;;     {:method :native-rand,
;;      :iterations 200,
;;      :time "\"Elapsed time: 0.025678 msecs\"\n"}]

caumond 2021-06-03T10:26:23.321Z

In my original code there are two call to rand-intwhich seems to increase the influence:

(ns poc.defrecord.slack)

(def ^java.util.Random seed (java.util.Random.))
(defn compare-rands [nb-iter]
  [{:method :java-call
    :iterations nb-iter
    :time (with-out-str  (time
                          (dotimes [_ nb-iter]
                            (.nextInt seed 100)
                            (.nextInt seed 100)
                            (.nextInt seed 100))))}
   {:method :native-rand
    :iterations nb-iter
    :time (with-out-str (time (dotimes [_ nb-iter]
                                (rand-int 100)
                                (rand-int 100)
                                (rand-int 100))))}])

(compare-rands 200)
;; =&gt; [{:method :java-call,
;;      :iterations 200,
;;      :time "\"Elapsed time: 0.011242 msecs\"\n"}
;;     {:method :native-rand,
;;      :iterations 200,
;;      :time "\"Elapsed time: 0.039123 msecs\"\n"}]
;; =&gt; [{:method :java-call,
;;      :iterations 2000000,
;;      :time "\"Elapsed time: 93.312348 msecs\"\n"}
;;     {:method :native-rand,
;;      :iterations 2000000,
;;      :time "\"Elapsed time: 372.539035 msecs\"\n"}]

Stefan 2021-06-03T10:27:01.321200Z

Strange. Thanks for checking!

2021-06-03T10:31:45.321400Z

rand-int calls Random/nextDouble under the hood, and does some mutiplication and casting to get an int

2021-06-03T10:31:53.321600Z

so some overhead is expected

2021-06-03T10:32:17.321800Z

Using time for benchmarks is not very reliable btw

2021-06-03T10:33:28.322200Z

I suggest using https://github.com/hugoduncan/criterium

caumond 2021-06-03T10:35:04.322500Z

Ok I will try criterium. It's true the time are not stable

caumond 2021-06-03T10:36:12.322700Z

Concerning the implementation your remark is an explanation but it may be possible to do better ?

caumond 2021-06-03T10:36:51.322900Z

I looked at the implementation it is quite straightforward

2021-06-03T10:37:51.323100Z

implementing rand-int using Random.nextInt(int bound) might be faster

2021-06-03T10:39:54.323300Z

skipping the overhead of conversion

caumond 2021-06-03T10:41:39.323500Z

You mean the double to int conversion?

2021-06-03T10:41:44.323700Z

yes

2021-06-03T10:42:09.323900Z

also Random.nextDouble looks like it does (a little) more work than Random.nextInt

2021-06-03T10:42:26.324100Z

but probably the overhead is not that large

caumond 2021-06-03T10:42:56.324300Z

Yes random functions are based on natural integer series.

caumond 2021-06-03T10:44:49.324500Z

So generating double is more time consuming

caumond 2021-06-03T10:45:25.324700Z

I know the difference is small but in my case it is doing a difference

2021-06-03T10:47:44.324900Z

if you a processing on multiple threads then using ThreadLocalRandom might also speed things up

caumond 2021-06-03T10:48:34.325100Z

I am not currently but it is im my plan so I take the advice

2021-06-03T10:48:39.325300Z

rand-int and rand use Math/random(), which uses a shared java.util.Random instance for all threads, which may cause contention

Niklas 2021-06-03T11:07:03.326800Z

I'm trying out :replace-deps with juxt/pack.alpha.git like https://github.com/juxt/pack.alpha/pull/92/files, I consistently get a few seconds slower run-times, (I run once to warmup and then average over three runs). Is that expected?

Niklas 2021-06-03T11:07:40.326900Z

this:

:pack {:extra-deps {pack/pack.alpha {:git/url "<https://github.com/juxt/pack.alpha.git>"
                                                :sha "042c61410b1851957ae5f77cfe26a255837172cc"}}
                  :main-opts ["-m"]}
is consistently faster than
:pack {:replace-deps {pack/pack.alpha {:git/url "<https://github.com/juxt/pack.alpha.git>"
                                                :sha "042c61410b1851957ae5f77cfe26a255837172cc"}}
                  :main-opts ["-m"]}

Niklas 2021-06-03T11:08:18.327100Z

I thought it would be faster since it would load less code, but maybe I'm misunderstanding it?

alexmiller 2021-06-03T11:20:47.328300Z

The first time you run it will compute and cache classpaths so make sure youā€™re accounting for that

alexmiller 2021-06-03T11:22:23.329600Z

I would generally have the same expectation as you - replace should replace the project deps so include less

alexmiller 2021-06-03T11:22:53.330400Z

You can use -Stree or -Spath to confirm that

Niklas 2021-06-03T11:40:50.330800Z

when I benchmarked I ran once to "warmup" and averaging 3 runs.

Niklas 2021-06-03T11:41:00.331Z

I'll take alook at -Stree/-Spath

Niklas 2021-06-03T11:55:45.331200Z

actually, after killing all other applications on my laptop the results look better

alexmiller 2021-06-03T14:10:58.333200Z

once all that stuff is downloaded and cached, there should be no real difference here - in both cases you're just running the program

Niklas 2021-06-03T14:14:49.333400Z

aha, so the main difference is when there is no cache?

alexmiller 2021-06-03T14:16:08.333600Z

yeah, it's just a question of how many deps you have to download

alexmiller 2021-06-03T14:16:32.333800Z

but once you download them to your .m2/.gitlibs ... that's all cached

ChillPillzKillzBillz 2021-06-03T15:25:14.335300Z

What is a good place to look for templates for clj-new?

craftybones 2021-06-03T15:36:53.335900Z

is there anyway to prevent a symbol from being unmapped via ns-unmap ?

alexmiller 2021-06-03T15:37:19.336100Z

no?

alexmiller 2021-06-03T15:37:26.336300Z

why do you want to do that?

craftybones 2021-06-03T15:38:09.336800Z

I donā€™t. Someone asked me if it could and I was almost certain that it couldnā€™t but wanted to check anyway.

craftybones 2021-06-03T15:39:05.337900Z

The person who asked me is worried about malicious code. Of course, this person hasnā€™t discovered eval yet šŸ˜„

alexmiller 2021-06-03T15:41:03.338400Z

powerful tools are also often dangerous :)

craftybones 2021-06-03T15:41:37.339200Z

Yes, of course. What is interesting is that truly dynamic systems have to allow for the change of their own environments/source, and everything from DNA to running code is susceptible to maliciousness

Ed 2021-06-03T15:55:20.341600Z

the converse is also true. Only dynamic safety is real safety. For example, unchecked array bounds have been a massively costly impact of trusting static assumptions over dynamic reality ...

borkdude 2021-06-03T15:56:57.342400Z

@srijayanth if you want to have a kind of sandbox that forbids certain vars, you could take a look at sci

user=&gt; (sci/eval-string "(ns-unmap *ns* 'inc)" {:deny ['ns-unmap]})
Execution error (ExceptionInfo) at sci.impl.utils/throw-error-with-location (utils.cljc:51).
ns-unmap is not allowed!

borkdude 2021-06-03T15:57:47.342700Z

clojail is another approach which relies on java sandboxing

2021-06-03T16:42:34.344Z

How do a type hint a vararg call for an array of Foo objects? I know to call with (into-array Foo [])

2021-06-03T16:44:03.344600Z

however I try it I seem to get a reflection warning šŸ˜•

2021-06-03T16:46:35.345700Z

Iā€™ve tried variants of things like (a and b are already type hinted) (.method a b ^"baz.bar.Foo" (into-array Foo [])

seancorfield 2021-06-03T16:48:31.346300Z

^"[Lbaz.bar.Foo;"

seancorfield 2021-06-03T16:49:10.346900Z

See (type (into-array Foo [])) for the string representation of the type.

2021-06-03T16:49:10.347Z

ah sorry thatā€™s already what I haveā€¦ I misstyped it here

2021-06-03T16:49:16.347200Z

šŸ‘€

2021-06-03T16:49:45.347500Z

hmm prints correctly

seancorfield 2021-06-03T16:49:48.347600Z

Perhaps thereā€™s some other aspect of ambiguity in the call then?

2021-06-03T16:50:00.348Z

maybe the issue is something else

seancorfield 2021-06-03T16:50:09.348100Z

Does the reflection warning provide a bit more specific information?

2021-06-03T16:53:26.349300Z

ok real code is:

(def default-context ^"[Lorg.eclipse.rdf4j.model.Resource;" (into-array Resource []))

(defn index-data! [input-files]
  (let [repo (repo/sail-repo (repo/memory-store))]
    (doseq [^File input input-files]
      (with-open [^RepositoryConnection conn (repo/-&gt;connection repo)]
        (let [^RDFFormat fmt (.orElse (Rio/getParserFormatForFileName (str input)) nil)]
          (.add conn input "<http://ignoreable>" fmt default-context))))
    repo))
Reflection warning,
swirrl/qb_tools/concept_scheme/positions.clj:89:11 - call to method add on org.eclipse.rdf4j.repository.RepositoryConnection can't be resolved (argument types: java.io.File, java.lang.String, org.eclipse.rdf4j.rio.RDFFormat, unknown).

2021-06-03T16:56:35.352500Z

hmm actually the docs are one minor version out, from what I have on my classpath :thinking_face:

seancorfield 2021-06-03T16:57:19.352700Z

Maybe the type hint on the def has to be before the symbol instead of on the value?

2021-06-03T16:57:47.352900Z

ahh thatā€™s it thanks

seancorfield 2021-06-03T16:58:08.353100Z

dev=&gt; (def example ^"[Ljava.lang.String;" (into-array String []))
#'dev/example
dev=&gt; (meta example)
nil
dev=&gt; 

2021-06-03T16:58:14.353300Z

silly mistake

2021-06-03T16:58:40.353500Z

6pm code blindness setting in šŸ˜©

chouser 2021-06-03T19:28:29.355300Z

Is there anyone here who provides hands-on introductory Clojure workshops for corporate teams, or can recommend such from personal experience?

alexmiller 2021-06-04T12:02:39.376600Z

It is as up to date as most internet information :)

seancorfield 2021-06-03T19:53:15.355600Z

Hadnā€™t Cognitect used to offer that? @alexmiller?

Ed 2021-06-03T20:03:43.356Z

I can't personally recommend him, but I like the output of Eric Normand and it sounds like he does that sort of thing: https://lispcast.com/training/

alexmiller 2021-06-03T20:37:22.356500Z

https://clojure.org/community/training

alexmiller 2021-06-03T20:37:25.356700Z

^^ resources

alexmiller 2021-06-03T20:37:47.356900Z

you can ping <mailto:sales@cognitect.com|sales@cognitect.com> - we are entertaining such requests but I don't know the full status