Fork me on GitHub
#clojure
<
2022-01-10
>
didibus02:01:54

Does a Cider repl change out ? I'm trying to have a test that sets System/out so I can assert something got printed, but it seems no matter what clojure println prints somewhere else. So I suspect something is binding out for every thread in my REPL maybe?

didibus02:01:58

The thing that is printing is doing so inside a go block, so I can't bind out from inside it in my test. But I thought setting the global System/out of alter-var-root on out should have worked, but neither did.

hiredman02:01:50

Not only does a cider repl have its own *out*, it must as a consequence of being client/server

hiredman02:01:00

The stdout of the repl server process is basically never the same as the out of the repl client

didibus02:01:34

Ok, thanks. I might pass on that unit test then, too complicated haha, and don't like having a test that only works when ran in the test-runner

didibus05:01:25

I'm not too sure, but I've noticed when I run clojure -X:test setup with the exec-fn of the cognitect test runner, it seems to load the user namespace. I do have a user.clj in my src folder, but I would not expect it to be loaded, except it does and what's inside it gets evaluated. I'm not sure if it is loaded by the CLI and exec-fn machinery, or if it is loaded by cognitect test-runner, or something else. Anyone knows?

didibus05:01:17

I'm thinking maybe test-runner loads all namespaces automatically to be able to run the :patterns regex?

seancorfield05:01:43

@didibus That's built into Clojure itself. It always tries to load the user namespace, no matter how you run it.

didibus05:01:32

Hum... :thinking_face: I thought only clojure.main did so, and a few other tools as a similar convention

seancorfield06:01:40

seanc@Sean-win-11-laptop:~/clojure$ cat > src/main.clj
(ns main)
(defn x [_] (println 'x))
(defn -main [& _] (println 'main))
seanc@Sean-win-11-laptop:~/clojure$ clojure -X main/x
user-loaded
x
seanc@Sean-win-11-laptop:~/clojure$ clojure -M -m main
user-loaded
main
seanc@Sean-win-11-laptop:~/clojure$

seancorfield06:01:54

after

seanc@Sean-win-11-laptop:~/clojure$ cat > src/user.clj
(println 'user-loaded)

didibus06:01:22

That would use clojure.main no? To load it without clojure.main you need to gen-class your own main

didibus06:01:44

But I guess the CLI probably loads things using clojure.main so maybe everything it setups is slowly something that can be assumed to be "standard" as it becomes the preferred way to launch Clojure apps.

seancorfield06:01:31

The -X invocation uses the exec.jar but that may well use clojure.main itself I guess.

didibus06:01:20

I changed how my project is setup, probably not great to have user.clj in src anyways. Moved it out somewhere else and adding the path to specific aliases made it work.

didibus06:01:01

Relevant blog post: https://engineering.collbox.co/post/where-should-my-user-dot-clj-go/ Did the same, put in in a dev folder, and made an alias. Its better anyways

lassemaatta06:01:55

Also, with larger projects, where user.clj might grow over time to require a bunch of namespaces, it might be a good idea to move most of the content to another auxiliary namespace (e.g. dev.clj) and thus postpone loading it until you explicitly ask for it. An example from the duct template: https://github.com/duct-framework/duct/blob/master/lein-template/resources/leiningen/new/duct/base/user.clj. I've seen some cases where opening a repl takes ages, because user.clj pulls in everything when you only wanted to just quickly run some unit tests. (disclaimer: not sure if this applies to deps.edn as much as leiningen)

didibus19:01:04

It would apply only if user.clj is in your src folder. Which you can avoid if you move it elsewhere. Then you can decide in what profile to include it being loaded automatically or not. That was my use case, I did not want it loaded when running tests.

didibus19:01:29

But thanks, ya that's another way to do it. But I like the auto-load feature when at REPL, because I use it to setup things I want at the REPL

seancorfield06:01:44

Yeah, you don't want user.clj in src because it'll end up in JAR files etc.

👍 1
eskos08:01:42

I’m not saying this is perfect, but with Leiningen at least it’s quite easy to set up a per-profile source directory; eg src/clj{,c|s}/ , test/clj{,c|s} and dev/clj{,c|s}/ and I’d have my user.clj in that last one mentioned. Last time I used this scheme though it ended up being kinda unnecessary though since my user.clj was pretty much (ns user (:require [my.main.ns :refer :all])) and nothing else… 🙂

avfonarev12:01:56

Sorry if the question is ill addressed, but I only use Java for Clojure. What is the current way of installing Java on Apple M1 machines? Is it still brew install java11 ?

javahippie12:01:36

If you switch the config as described in the post, you can make sure that you have an ARM compatible JDK installed on your machine.

avfonarev12:01:56

@U0N9SJHCH Thanks, that's an option I've not heard of.

javahippie12:01:38

Also provides some selection of JDK vendors for you and lets you switch between them:

👍 1
dharrigan13:01:42

As far as I'm aware, it's only from JDK17 onwards is Arm fully supported.

javahippie14:01:51

Azul should have ported it back?

javahippie14:01:17

But you are right, it‘s not in the list

avfonarev15:01:35

@U11EL3P9U Thanks, I've missed that 17 has arm support

dharrigan15:01:40

I originally ran with Azul since they were the first to release with Arm support, then when Adoptium came out with their cut of openjdk, I switched to them.

ghadi15:01:21

brew install temurin will give you mac/arm64

Al Z. Heymer15:01:51

Is there an "intelligent" way to differentiate behaviour on different log-levels with clojure.tools.logging? i.e. currently I would do this:

(cond
  (log/enabled? :trace) (log/trace "foo")
  (log/enabled? :debug) (log/debug "bar")
But I think it would read much smoother if I could just do
(case log/*log-level*
  :trace (log/trace "foo")
  :debug (log/debug "bar")
(Using unilog/slf4j btw)

ghadi15:01:59

IIRC log calls are already predicated on whether the level is enabled, so there's no need to check levels in your program

ghadi15:01:54

(do (log/trace lots of detail) (log/debug less detail) ....) should give you what you want

Al Z. Heymer15:01:04

well... yes, but I want to omit the debug-log, whenever I am on trace. Therefore I would like to differentiate. So e.g. I want to select keys in a map on debug, but print the full map on trace

Al Z. Heymer15:01:57

I mean my current way works fine, it just feels bloated to "Do I trace? Yes? Ok. Trace. No? Ok, do I debug? Yes? Ok. Debug."

Alex Miller (Clojure team)16:01:24

I think the assumption built into tools.logging (and most logging libs) is that levels are additive

Alex Miller (Clojure team)16:01:11

but categories (often tied to namespaces) are independent so you could turn a particular logging namespace on/off independently of level

Drew Verlee18:01:44

Is there a way to have core async or something similar function like the network layer between browser runtimes and server ones? I would imagine this means the buffer is somehow persisted outside memory of either. I want to essential abstract the http & transport layer. I don't need something as powerful as an actual server.

p-himik18:01:50

Just in case - if you think there's a chance you might need to know whether a request was successful or not, do not abstract the transport layer. That's exactly why CORBA has failed. You can't completely abstract away HTTP given its distributed nature and the fact that networks fail.

Drew Verlee18:01:12

good thought. the goal here is for faster development between components, abstracting some of the elements of the network so we can later focus on them specifically.

👍 1
raspasov09:01:56

This is a hard problem. Many attempts have been made to solve it over many years, in different languages/frameworks but none are ideal or truly simple. There's sente (I have not used it myself, only looked at it) for Clojure(Script), but it does involve a server, it does not try to paper over the problem or pretend there's no server https://github.com/ptaoussanis/sente

Drew Verlee02:01:02

Maybe some more context would help. I have a locally running browser app and a locally running cljs node app. I need them to talk. I don't think it's too complex in essence, ill need to write to some persistent storage and have both watch for messages on it. Recreating the network is hard. But i want to abstract it, that means flawless happy instant communication.

Drew Verlee02:01:44

i think i can just catch the re-frame events and push them into a file then have the server app read them. The work will likely be abstracting the server entry point to look for this file in the context when im running locally.

Joshua Suskalo18:01:50

there is also aleph and chord

Jacob Rosenzweig18:01:13

Are there any good documentation frameworks that put the schema front-and-center on the doc page? I feel like a lot of clojure docs will bury the spec for a map away. Sometimes I even have to dig through the source just to see how they destructure the map that comes in.

Joshua Suskalo18:01:29

this isn't good for web docs but cider will show you the spec of functions when you look up documentation on a symbol

Norman Eckstein19:01:23

I have 3 free Manning book giveaways for someone who is interested in => Privacy-Preserving Machine Learning, Evolutionary Deep Learning, Feature Engineering Bookcamp

dpsutton19:01:50

this does not seem relevant to #clojure. Do you mind deleting this from here? We have an #off-topic channel that is suitable for this if this is not some kind of self-promotion bit

Norman Eckstein19:01:06

Hey, well I only had good intentions

Norman Eckstein19:01:14

I thought the most people are in that channel

Norman Eckstein19:01:38

I bought the books and there was the manning free christmas giveaway buy one, get one free for a friend

dpsutton19:01:30

No worries! It's a nice gesture. But it's not on topic for clojure so repost in off topic and thanks for your generosity!

👍 1
respatialized19:01:13

is there a default way to make data.xml discard XML namespace information? What I currently get:

(clojure.data.xml/parse-str "<svg width=\"100\" xmlns=\"\"><circle cx=\"3\" cy=\"3\"/></svg>" :namespace-aware false)

;; => {:tag :xmlns.http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg/svg,
;; :attrs {:width "100"},
;; :content
;; ({:tag :xmlns.http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg/circle,
;;   :attrs {:cx "3", :cy "3"},
;;   :content ()})}
What I'm hoping for:
;; => {:tag :svg,
;; :attrs {:width "100"},
;; :content
;; ({:tag :circle,
;;   :attrs {:cx "3", :cy "3"},
;;   :content ()})}
I can walk the whole thing using xml-zip to convert them if I have to, but was wondering if the parse fn had an option that I may have overlooked to avoid that step.

p-himik20:01:43

Interesting. What you expect is exactly what I'm getting:

(clojure.data.xml/parse-str "<svg width=\"100\" xmlns=\"\"><circle cx=\"3\" cy=\"3\"/></svg>" :namespace-aware false)
=>
#xml/element{:tag :svg,
             :attrs {:width "100", :xmlns ""},
             :content [#xml/element{:tag :circle, :attrs {:cx "3", :cy "3"}}]}
But I'm using 0.2.0-alpha6 - maybe that's why.

respatialized20:01:18

strange. clojure -X:deps list indicates that I'm on that version as well. I'm on JDK11, Clojure 1.10.3. Thanks for helping out with a repro attempt!

p-himik20:01:33

Sure thing. FWIW, same Clojure version but JDK 17. Although I doubt that JDK would affect things here.

respatialized20:01:52

I'm able to parse as I intend to with another library, eximia - so for the time being I'll use that. However, I can file a bug report if needed about this discrepancy.

p-himik20:01:02

Before you file a bug report - have you actually tried running your code in a clean environment, with no dependencies but the XML library? Given that it works for me perfectly, it makes it seem like there's something wrong with your environment. Perhaps you're using a different alias when running that REPL session?

Alex Miller (Clojure team)20:01:18

% clj -Sdeps '{:deps {org.clojure/data.xml {:mvn/version "0.2.0-alpha6"}}}'
Clojure 1.10.3
user=> (require '[clojure.data.xml])
nil
user=> (clojure.data.xml/parse-str "<svg width=\"100\" xmlns=\"\"><circle cx=\"3\" cy=\"3\"/></svg>" :namespace-aware false)
#xml/element{:tag :svg, :attrs {:width "100", :xmlns ""}, :content [#xml/element{:tag :circle, :attrs {:cx "3", :cy "3"}}]}

Alex Miller (Clojure team)20:01:03

those are records we're seeing in the output whereas you're just seeing plain maps. not sure if that's due to an older data.xml version or if your repl/editor is affecting your printing

respatialized21:01:31

Is there a version of loaded-libs that outputs the version of the loaded libraries?

p-himik22:01:48

Try (System/getProperty "java.class.path"). If there's only one org/clojure/data.xml and it points to the right version, there is one other possibility - one of your dependencies bundles data.xml classes or sources within its own JAR. Or it might be on the classpath of the project you're working on - maybe just in a place you didn't know about, like some extra src or maybe somehow outdated but not updated classes.

noisesmith00:01:58

there's an easy way to look for a compiled version of a namespace

Clojure 1.10.1
(ins)user=> (require '[ :as io])
nil
(ins)user=> (io/resource "clojure/core__init.class")
#object[java.net.URL 0x420bc288 "jar:file:/home/justin/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/core__init.class"]

👍 1
noisesmith00:01:40

that checks for the compiled version of clojure.core, it would return nil if it couldn't be found on classpath

noisesmith00:01:52

you can also check for "clojure/core.clj" etc. to see if the source file comes from the artifact you expect - but in my experience bad bundling of compiled namespaces are much more common than bad bundlings of source