Fork me on GitHub
#clojure
<
2019-05-30
>
henrik06:05:16

Does anyone know how to set a custom entity resolver with clojure.xml/parse? I need to reroute online DTDs to local ones. Currently I'm rewriting the XML itself with regexes, which seems a bit non-idiomatic.

borkdude09:05:38

regarding performance:

user=> (defn contains [t] (contains? #{:foo :bar} t))
#'user/contains
user=> (defn contains2 [t] (or (= :foo t) (= :bar t)))
#'user/contains2
it seems that contains2 is ~twice as fast, although the idiom in contains is very common.

ivana09:05:14

it is clear, in first case it have to create additional set structure and search in it. But it is more readable and noone thinks about 2 times fast on nanoseconds

borkdude09:05:12

maybe Clojure optimizes the first case by creating the set at compile time? but maybe not

bronsa09:05:40

at load time, but yes

ivana09:05:19

Not sure about sets (they can hold values unknown on compile stage), but I guess that case t will most fastest way for this code

borkdude09:05:08

or something like this:

(defmacro one-of [x elements]
  `(or ~@(for [e elements]
           `(= ~e ~x))))

(let [x 10] (one-of x [1 2 3]))

borkdude09:05:49

you can indeed also write: (let [x 10] (case x (1 2 3) true false))

ivana09:05:11

But why you try to catch nanoseconds but not clear readable code with some? or using set?

borkdude09:05:32

case appears to be much faster:

user=> (time (dotimes [_ 10000000] (one-of :bar [:foo :bar])))
"Elapsed time: 221.057525 msecs"
nil
user=> (time (dotimes [_ 10000000] (case :foo (:foo :bar) true false)))
"Elapsed time: 61.048416 msecs"

ivana09:05:35

And I am afraid that for macro also expands in a tremendous batch of forms

ivana09:05:35

oh, I see, it will on compile time

andrewboltachev11:05:42

For my project, some modules are loaded from ~/.m2, and some from /var/maven. How can I control the exact location (e.g. force all to load from ~/.m2)?

hiredman16:05:23

What kind of os are you using?

hiredman16:05:04

/var/maven is a very non-standard thing, so either it is some setting in some tool you are using, or some non-standard packaging of some tool you are usig

noisesmith17:05:24

your maven config should be controlling where it looks for local archives

theeternalpulse17:05:44

Is the clojure syntax indescernable from edn, or is edn specifically used in the context of serialization?

dominicm17:05:28

Edn is for serialization. Clojure syntax is a superset of edn.

noisesmith17:05:21

edn is a string format

theeternalpulse17:05:41

you can essentially change a clj file to edn and it's still valid?

theeternalpulse17:05:50

or does edn have some declaration standards?

fabrao17:05:21

Hello all, how can I translate this to clojure?

table.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override 
    public void handle(MouseEvent event) {
        if (event.isPrimaryButtonDown() && event.getClickCount() == 2) {
            System.out.println(table.getSelectionModel().getSelectedItem());                   
        }
    }
});

deep-symmetry22:05:03

I suspect the reason you’re not seeing a lot of answers to this question is that it is a non-specific question about some code with no context or explanation. If you could be more clear about what specific parts you are having trouble with, it would be easier to help. After a bit of research, it looks like you are using JavaFX, which I never have, and I don’t know if anyone else on this channel has either. Because of that, I am not going to be able to put together a test environment to really try out my answer, which means it will likely contain mistakes. But with that caveat, and assuming that you are asking how to express that code using Clojure Java interop syntax, it would be something like this…

deep-symmetry22:05:18

First, I am assuming you have your table object in a Clojure local table.

deep-symmetry22:05:30

(.setOnMousePressed table
  (proxy [javax.event.EventHandler] []
    (handle [event]
      (when (and (.isPrimaryButtonDown event)
                 (= (.getClickCount event) 2))
                 (println (.. table getSelectionModel getSelectedItem))))))

deep-symmetry22:05:21

That’s not the indentation/line breaks I would really use but I adjusted it to be more readable in the narrow thread window.

deep-symmetry22:05:48

To more closely parallel your Java code (and avoid some reflection), you could type hint the event parameter, which would look like (handle [^javafx.scene.input.MouseEvent event] …)

deep-symmetry22:05:21

And you could shorten this code by importing the EventHandler and MouseEvent classes in your Clojure namespace so you would not have to fully-qualify them in your code.

dominicm17:05:35

You can change anything you edn and it's valid edn?

noisesmith17:05:54

@theeternalpulse I'm pretty sure there's things in clojure that the edn standard doesn't' accept

dominicm17:05:52

#() is the easy one

dominicm17:05:01

Also ' behaves differently in edn

noisesmith17:05:08

haha, just as I was about to paste this

user=> (clojure.edn/read-string "#()")
RuntimeException No dispatch macro for: (  clojure.lang.Util.runtimeException (Util.java:221)

dpsutton17:05:17

and java interop, yes?

noisesmith17:05:31

user=> (clojure.edn/read-string "`(foo ~bar)")
RuntimeException Invalid leading character: `  clojure.lang.Util.runtimeException (Util.java:221)

dominicm17:05:45

Well, java interop is valid edn

dominicm17:05:49

Because symbols

dpsutton18:05:19

ah you're right

noisesmith18:05:32

interop seems fine

user=> (clojure.edn/read-string "(java.util.Date.)")
(java.util.Date.)
user=> (clojure.edn/read-string "Math/PI")
Math/PI
user=> (clojure.edn/read-string "(. Math PI)")
(. Math PI)

noisesmith18:05:27

another big one:

user=> (clojure.edn/read-string "::foo")
RuntimeException Invalid token: ::foo  clojure.lang.Util.runtimeException (Util.java:221)

noisesmith18:05:46

edn can't have a current namespace, so auto-namespaced symbols don't make sense

dominicm18:05:39

I kinda wish edn had a facility for namespaces :(

noisesmith18:05:10

it does, just not a "current namespace"

user=> (clojure.edn/read-string ":foo/bar")
:foo/bar

theeternalpulse18:05:57

neat info, I wasn't sure, I was watching an older rich video and he ploped some clojure code and showed it as edn, so I wasn't sure if there was some connection outside of serialization to the language

noisesmith18:05:17

it's intentional that everything that is valid edn (or nearly so) is valid in clojure source (as syntax or literal)

noisesmith18:05:30

but it doesn't extend to everything in the other direction

noisesmith18:05:26

on the other hand, metadata (and the ^ metadata shorthand) does work on edn, and transfers to the read value

noisesmith18:05:40

user=> (clojure.edn/read-string "^:foo []")
[]
user=> (meta *1)
{:foo true}

ghadi18:05:29

regexes and #'var

dominicm18:05:41

I also miss regex (in config files)

jaihindhreddy13:06:08

Clojure reader accepts more syntax than EDN but almost all of that is just syntax sugar and after read becomes data that can be put in EDN (excluding #=()). Rich Hickey mentioned this in one of his talks AFAIR, emphasising the fact that eval deals in data structures and not text, and the LISPs give users the ability to extend the language by participating in this eval right after reading. Clojure for Java Programmers part 1 if memory serves me right.

csd18:05:20

I ran into a weird issue just now where I was wrapping with-redefs in a fn. When I tried to execute the function, the with-redefs would fail for a function that I was rebinding but succeed for an atom that I was rebinding. After relocating with-redefs so that it wrapped the fn instead, everything works. I'm actually struggling to put this into a toy example, for whatever reason. Clearly there is something going on I don't understand. Just wondering if there is any obvious "gotcha" that I ran into.

noisesmith18:05:49

was the fn called by something lazy that might escape the context of the with-redefs form?

csd18:05:46

i don't think it would be evaluated lazily. here's what was calling fn:

(defn with-props
  "Temporarily rebinds props and calls `f`"
  [props-map f]
  (let [old-props (atom {})]
    (doseq [[k v] props-map]
      (swap! old-props assoc k (.getProperty props/properties k))
      (.setProperty props/properties k v))
    (f)
    (doseq [[k v] @old-props]
      (.setProperty props/properties k v))))

noisesmith18:05:52

and where is the with-redef? - oh it's inside f

csd18:05:59

basically i had been calling

(with-props {} 
  (fn [] 
    (with-redefs [my vars]
      (do-stuff))))

noisesmith18:05:51

yeah, my question was if any of (do-stuff) might be lazy, or otherwise execute after with-redefs exits

noisesmith18:05:03

(eg. if it uses other threads)

csd18:05:38

oh. that's exactly what it is 🙂

csd18:05:09

was writing to a channel, and the consumer of the channel had the var i was trying to redef

csd18:05:12

of course

noisesmith18:05:24

also - with-redefs is a really blunt tool - it's redefining those vars in all your other threads!

noisesmith18:05:46

if two threads both use with-redefs, you have a race condition that could lose the original pre-redef values

noisesmith18:05:10

a (grabs bindings) a (stashes bindings) a (sets bindings) b (grabs bindings) a (resets bindings) b (stashes bindings) b (sets bindings) b ("resets" bindings)

noisesmith18:05:22

that last step actually sets the bindings from a, not the original bindings

noisesmith18:05:43

I wouldn't use with-redefs outside tests, and even then I'd be sceptical

noisesmith18:05:04

(that is, if your tests use threads at all it's still likely to cause problems)

csd18:05:19

fortunately it's (mostly) single threaded test code, but point taken

borkdude19:05:30

where can I find in which places in defn or fn metadata can be expected? on the fn name, on arguments… where else?

noisesmith20:05:20

at the end of the function body for multi-arity

noisesmith20:05:58

user=> (defn foo ([]) {:extra true})
#'user/foo
user=> (-> #'foo meta :extra)
true

noisesmith20:05:06

since there's no single argument list to put the meta on

noisesmith20:05:09

err.. but a hash-map before the function bodies also works

user=> (defn bar {:also :OK} ([]) {:extra true})
#'user/bar
user=> (-> #'bar meta :also)
:OK
user=> (-> #'bar meta :extra)
true

borkdude20:05:21

so those are the normal hashmaps as metadata, but in which positions can people put metadata? (defn ^String bar ...), (defn bar ^String ([] ...)? I’d like to have a comprehensive overview

hiredman20:05:19

metadata can be expected anywhere

borkdude20:05:38

good point 🙂

hiredman20:05:41

type hints (a specific kind of metadata) can only go certain places

hiredman20:05:05

and only certain metadata is copied from the read forms to evaluated obejcts

cupello20:05:36

Hi! Could someone explain to me why (every? vector? nil) evaluates to true?

noisesmith20:05:02

@lucelios "is every member of an empty set a vector?" - this is considered true in classical logic

😲 4
cupello20:05:38

hmmm nice! thanks for the clarification!

dpsutton20:05:06

colloquially you can think you need a counter example to disprove the universal. There are no counter examples in empty collections.

👍 4