Fork me on GitHub
#clojure
<
2023-03-06
>
Carsten Behring09:03:50

Just today I got this issue back: https://clojurians-log.clojureverse.org/tools-deps/2021-09-16 Using a very recent clojure CLI: Clojure CLI version 1.11.1.1200 Same error:

Error building classpath. Could not acquire write lock for 'artifact:org.bytedeco:opencv:4.5.5-1.5.7'
java.lang.IllegalStateException: Could not acquire write lock for 'artifact:org.bytedeco:opencv:4.5.5-1.5.7'
same workaround to get it fixed:
clj  -Sthreads 1

Carsten Behring10:03:21

I have it reproducible, every time doing:

rm -rf ~/.m2/repository/org/bytedeco/opencv* && clj
with a deps.edn:
{:deps {org.deeplearning4j/deeplearning4j-nlp {:mvn/version "1.0.0-M2.1"}}}
using
Clojure CLI version 1.11.1.1200

Carsten Behring10:03:42

workaround is, as before:

clj -Sthreads 1
In the prevoius thread (https://clojurians-log.clojureverse.org/tools-deps/2021-09-16), it seems to have gone away with a later Clojure CLI (1.10.3.981). Either this was not true, or it came back.

Alex Miller (Clojure team)12:03:57

Also check with -Sforce to make sure you have a fresh classpath computation, but please put on Ask Clojure and I will take a look when I have a chance, might not be today

Eugen16:03:40

hi, any updates for https://github.com/edn-format/edn/issues/43 ? I've tried "viewing" an edn config file from nginx and it prompt for download

Alex Miller (Clojure team)16:03:03

what would the recommended type be?

Eugen17:03:24

there is a suggestion for application/edn

Alex Miller (Clojure team)18:03:47

I will talk to Rich and look into it again

borkdude16:03:22

Hello. If you want to greet people and chat about random stuff, please do that in #off-topic. This channel is reserved for discussions and questions about #clojure :)

tomd16:03:23

Or #C0218CKTVEK

Noah Bogart18:03:10

A couple of the special forms listed on the https://clojure.org/reference/special_forms are in fact macros wrapping the concrete special form: let -> let*, fn -> fn* . Is there an available full list of the concrete/actual special forms? The ones built into the reader/compiler that exist before core.clj is loaded.

Noah Bogart18:03:02

oh of course, thanks

ag18:03:12

does anyone know if http://clojuredocs.org can take search path params? e.g.,Can I open Find page using a path like: , or it always has to be FQN, i.e.,

ag19:03:39

Yeah, I just found it. Thank you!

šŸ‘ 2
p-himik19:03:19

Struggling to understand something in the context of tools.namespace.repl. I have code like this:

(defonce ^:dynamic *env* nil)

(defmethod some-other-ns/do-stuff :x [_]
  (println *env*))

(defn load-env []
  (into {} ...))

(defn load []
  (binding [*env* (load-env)]
    (some-other-ns/call-do-stuff-on-some-deeply-nested-data)))
On the first call to load all is fine. But calling load after t.n.repl/refresh shows that *env* is now nil. Where did that binding go, given that (load-env) can never return something but a map?

p-himik19:03:13

Not reloading the NS with *env* fixes the issue, but I would still like to understand where it came from in the first place.

hiredman20:03:21

Because it is a different var

hiredman20:03:52

Refresh blows away the existing vars so you get a new var with the same name

hiredman20:03:13

But previously compiled code that may still be running is using the old var

p-himik21:03:15

But that defmethod is the "old code" that apparently sees the old var - since it's in the same NS, shouldn't it start seeing the new var right away? And defonce doesn't prevent the new var from appearing, right? `But that

hiredman21:03:03

Depends on this that and the other

hiredman21:03:25

Which namespace the code is doesn't come into it, what comes into it is when the code that is running looked up the var by name

hiredman21:03:42

Which generally only happens when code is loaded (there is a static init that looks up vars by name and then stores the var it finds in a static field of most fn classes generated by the compiler)

hiredman21:03:37

So it is a temporal difference (code loaded at different times coexisting) not a spacial one (different namespaces or whatever)

p-himik21:03:44

I see, thanks. Still feels itchy because I haven't traced it with a debugger to the exact root cause, of course. :) But that can wait, given that not reloading that particular ns works just fine.

hiredman21:03:05

The refresh is an epoch, a line in time that for things to work correctly code shouldn't cross, but for some reason you are having code survive across the line

hiredman21:03:39

I mean, I dunno, could be something else, but seems most likely

p-himik21:03:51

Right, makes sense.

FlavaDave21:03:57

I am trying to use the cli to return the value of a var. Originally, I was inclined to do something like clj -X com.namespace/foo But, it is pretty clear that that is only going to work with functions. Can anyone think of a way to do this?

Alex Miller (Clojure team)21:03:09

By returning a value do you mean an exit code or printed return?

FlavaDave21:03:43

printed return

Alex Miller (Clojure team)21:03:17

I mean you can use -M -e to evaluate and print the result of any expression

FlavaDave21:03:07

I got (ClassNotFoundException) after running clj -M -e com.namespace/foo

FlavaDave21:03:29

So I just wanna make sure we are on the same page, In com.namespace i have (def foo "bar") and I am just trying to return "bar"

seancorfield22:03:12

With -e you'd still need to require the ns. -e "(requiring-resolve 'com.namespace/foo)"

seancorfield22:03:34

(and you may need (deref ..) wrapped around that since requiring-resolve returns a Var)

seancorfield22:03:07

Like so:

(~/clojure)-(!2007)-> clojure -Tnew app :name flava/dave
Creating project from org.corfield.new/app in dave

Mon Mar 06 14:02:46
(~/clojure)-(!2008)-> cd dave/

Mon Mar 06 14:02:49
(~/clojure/dave)-(!2009)-> vi src/flava/dave.clj

Mon Mar 06 14:03:03
(~/clojure/dave)-(!2010)-> cat src/flava/dave.clj
(ns flava.dave
  (:gen-class))

(def foo "bar")

(defn greet
  "Callable entry point to the application."
  [data]
  (println (str "Hello, " (or (:name data) "World") "!")))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (greet {:name (first args)}))

Mon Mar 06 14:03:06
(~/clojure/dave)-(!2011)-> clojure -M -e "(requiring-resolve 'flava.dave/foo)"
#'flava.dave/foo

Mon Mar 06 14:03:26
(~/clojure/dave)-(!2012)-> clojure -M -e "(deref (requiring-resolve 'flava.dave/foo))"
"bar"

Mon Mar 06 14:03:37
(~/clojure/dave)-(!2013)->

Noah Bogart23:03:22

In other languages, you can put a reference to a parent object on a child and traverse up and down the relationships pretty easily. This is less doable in clojure without incurring additional memory costs and losing updates when either side changes. How do folks deal with this?

p-himik23:03:07

Store relationships as separate data. In other words, normalize the data.

āž• 4
šŸ‘ 2
phronmophobic23:03:49

@U2FRKM4TW's suggestion is a good one. Depending on the use case, you can also use things like zippers!

šŸ‘ 2
phronmophobic23:03:59

There are also in-memory dbs that can help.

šŸ‘ 4
Noah Bogart23:03:23

Normalization is smart. Iā€™m considering zippers but they feel very low level for the kind of operations Iā€™m working with.

phronmophobic23:03:22

What kind of operations are you working with?

Noah Bogart01:03:36

lol Iā€™m working with source code traversal, which is the bread and butter of zippers, namely rewrite-clj. But rewrite-clj is a little slow and I find zippers to be hard to work with/conceptualize, so Iā€™m exploring other options for fun.

opqdonut06:03:12

in functional programming you usually use write a recursive transformation and use the call stack as the parent pointer

opqdonut06:03:46

that can be a bit awkward sometimes of course, but for tree rewriting it definitely works

borkdude12:03:27

zippers add quite a bit of overhead. you can also do what those other languages do: use mutable references

āž• 4
borkdude12:03:56

I ran into a similar problem when trying to port a markdown parser from JS to Clojure

cddr19:03:01

In analysing sports games, we originally had something that used a zipper. Currently experimenting with something that promises to be much faster based on a kind of doubly linked list of events allowing for lazily looking outwards in either direction from current context. That's an interesting point about normalisation. Will need to think about that.