clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
ryan echternacht 2020-09-17T01:11:34.489400Z

What's the main difference between (seq x) and (not-empty x) ? They seem to be interchangeable in all of the places I use them (mainly for testing if a sequence is/isn't empty/nil

seancorfield 2020-09-17T01:24:38.490300Z

Try (seq [1 2 3]) and (not-empty [1 2 3])

seancorfield 2020-09-17T01:24:52.490700Z

The former will give you a sequence, the latter will give you a vector.

ryan echternacht 2020-09-17T01:26:36.491800Z

oh ok. So for my usual purpose of seeing if it is/isn't empty/nil, then they are basically the same. But I can imagine when this difference would matter

seancorfield 2020-09-17T01:27:11.492300Z

not-empty is useful for when you either want nil or the original data structure.

ryan echternacht 2020-09-17T01:27:41.493200Z

usually, i'm just using it as a test, so I don't really care. but I see your point

seancorfield 2020-09-17T01:27:47.493300Z

For example (let [foo (not-empty "Hello")] foo) gives you a string, but (let [foo (seq "Hello")] foo) gives you a sequence of characters

ryan echternacht 2020-09-17T01:28:12.493700Z

(cond-> ... (not-empty x) (do-with-x))

ryan echternacht 2020-09-17T01:28:50.494300Z

Thanks!

seancorfield 2020-09-17T01:29:44.494700Z

I would use seq there -- you're only testing x

ryan echternacht 2020-09-17T01:30:25.494900Z

how come?

ryan echternacht 2020-09-17T01:30:40.495400Z

idiomatic? I feel like not-empty reads more naturally for me

seancorfield 2020-09-17T01:30:54.495600Z

Definitely not idiomatic.

ryan echternacht 2020-09-17T01:31:11.496Z

ok

ryan echternacht 2020-09-17T01:31:13.496200Z

thanks

seancorfield 2020-09-17T01:32:22.497300Z

I use it in situations like (let [field (some-> req :params :field str/trim not-empty)] (when field ... we know is it a non-empty string at this point ...))

simongray 2020-09-17T08:46:06.499900Z

How can I get the value of a private static field in a Java class?

simongray 2020-09-17T08:46:44.000700Z

Googling only returns solutions for accessing static fields or private instance fields, but not private static fields on classes.

seancorfield 2020-09-17T08:52:11.001100Z

@simongray You can use reflection and change the access to public, I think.

seancorfield 2020-09-17T08:52:26.001500Z

But I guess I would ask: why are you trying to do that?

simongray 2020-09-17T08:53:28.001600Z

There’s a bunch of Java initialisation code for a singleton instance that I need to reuse, but it’s hidden away behind a private static field.

simongray 2020-09-17T08:54:33.001800Z

Rather than duplicate the initialisation code in Clojure to make another singleton, I thought it would be easier to access the value directly.

seancorfield 2020-09-17T08:55:15.002Z

Reflection is your friend then, I suspect...

simongray 2020-09-17T08:55:31.002200Z

Yeah, not having much luck with clojure.reflect/reflect. It seems to not work for classes.

seancorfield 2020-09-17T08:59:03.002400Z

Sorry, no, I meant raw Java reflection.

dharrigan 2020-09-17T09:13:38.002900Z

This may help

dharrigan 2020-09-17T09:13:38.003100Z

https://gist.github.com/sunng87/13700d3356d5514d35ad

simongray 2020-09-17T09:34:50.003300Z

Thanks both you. I ended up just recreating the Java code myself using Clojure. It ended up being 7 lines of code + a few java class imports, so not too bad.

dharrigan 2020-09-17T09:50:42.003500Z

np 🙂

borkdude 2020-09-17T10:54:08.004300Z

Regarding the namespaced / auto-resolved keyword reading discussion we had recently, here's another interesting .cljc case:

(ns repro
  #?(:cljs
     (:require
      [clojure.string :as str])))

#?(:cljs
   (defn foo []
     {::str/test "This will break it."}))

borkdude 2020-09-17T12:20:43.004800Z

I guess that was already mentioned by lilactown

MatthewLisp 2020-09-17T14:47:47.005700Z

Hello people! Is there a more elegant way of doing this:

(if true
  :something
  (eval (do (require '[some.ns.mock :refer [mock]])
            '(mock))))

dpsutton 2020-09-17T14:49:17.007100Z

(requiring-resolve 'clojure.test/testing) i think would fit the bill

👍 1
MatthewLisp 2020-09-17T14:49:32.007500Z

*p.s: i'm avoiding doing this require on ns declaration at the beginning of the file because i only want to compile the mock ns class when i really need it

MatthewLisp 2020-09-17T14:51:07.008800Z

if i do

(if true
  :something
  (do (require '[some.ns.mock :refer [mock]])
            (mock)))
it won't compile because it says that there's no reference to mock

MatthewLisp 2020-09-17T14:52:29.008900Z

how i eval the function then?

dpsutton 2020-09-17T14:52:47.009100Z

check the docstring. that returns the function

MatthewLisp 2020-09-17T14:55:18.009300Z

i mean, the result of that is a clojure.lang.Var how to use that in order to execute the function that this var is pointing to

dpsutton 2020-09-17T14:55:56.009500Z

((requiring-resolve 'clojure.core/+)) returns 0 as it is calling clojure.core/+

MatthewLisp 2020-09-17T14:56:23.009700Z

oh, i see

borkdude 2020-09-17T14:57:11.009900Z

if you know the namespace containing that var has already been loaded, then a simple resolve also works

MatthewLisp 2020-09-17T14:58:01.010100Z

amazing

MatthewLisp 2020-09-17T14:58:08.010300Z

thanks you both 😄

MatthewLisp 2020-09-17T14:59:14.010700Z

(if true
  :something
  ((requiring-resolve 'some.ns.mock/mock)))
eval is gone 😄

ghadi 2020-09-17T15:03:37.011700Z

the require happens at runtime, but you're using (mock) at compile time

Joe Lane 2020-09-17T15:08:39.012600Z

Sounds like the mock should be injected.

borkdude 2020-09-17T15:16:00.012800Z

The question has been answered in a thread

💯 2
2020-09-17T23:44:24.004300Z

I'm using VSCode to edit an existing Clojure project, using the Calva plug-in. When I try to jack in, lein compiles the project, giving me the following error "java.lang.IllegalArgumentException: Cannot open <nil> as a Reader., compiling:(core.clj:84:32)" on this definition: (def teams-json (json/read-str (slurp (resources-path)) :key-fn keyword)) The problem seems to be in the slurp call. The function resource-path returns a string. When this function returns a static string, the compilation seems to succeed, but if there's anything else more complex (like using str to tack a directory name on the front of a resource filepath) the compiler throws this error. I checked online and there were a few references to issues with Clojure and/or Java and or lein being out of date, but I think that everything that's running is up-to-date. Does anyone have any ideas as to what's happening with the compilation?

phronmophobic 2020-09-17T23:49:21.005Z

what is (resources-path) ? the exception indicates that it's returning nil

2020-09-17T23:51:09.006800Z

(resources-path) is not run, as far as I know. This is a compiler error, not a runtime error.

phronmophobic 2020-09-17T23:51:26.007Z

(let [path (resources-path)]
   (prn "resource path: " path)
   (def teams-json (json/read-str (slurp path) :key-fn keyword)))

dpsutton 2020-09-17T23:53:53.008300Z

Sure it is. That def must be established when loading the namespace

phronmophobic 2020-09-17T23:54:06.008600Z

i'm pretty sure resources-path is being run

&gt; (slurp nil)
Execution error (IllegalArgumentException) at components/eval28033 (form-init9329007192917549923.clj:572).
Cannot open &lt;nil&gt; as a Reader

2020-09-17T23:56:16.010900Z

Yes it is. I was blind after staring at this for the last two hours. I figured it out. It's being run at compilation time, and the context for (resources-path) isn't initialized yet. Thanks for your help.

2020-09-17T23:56:18.011Z

This indicates an incorrect understanding of how clojure compiles and runs code

2020-09-17T23:57:08.011200Z

Compilation is the same as running, the compiler just saves the byte code it generates to disk instead of loading it into the jvm from memory

2020-09-17T23:57:54.011400Z

So anything like (def x (f)) will execute f while being compiled

2020-09-17T23:58:43.011600Z

(assuming you are referring to aot compilation as compiling, which is not great short hand, because clojure is always compiled)