clojure

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

Well, you're right, there's no structural editing per say, you can use the editor of your choice. But I'm not so much talking about the editing being structural as that the source code is edited in well behaving structures.

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

2020-09-17T01:12:25.489600Z

Basically, until you add the function in the source, the function is not in the source. So I consider the add function command a structural edit of the source. And you cannot add a function that doesn't compile. And another example is renaming, you rename not by changing the name on text all over the place, renaming is also a structural command edit you run on the source, etc.

2020-09-17T01:13:33.489800Z

Maybe I shouldn't say structural, maybe it's better to call it semantic editing?

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)