Fork me on GitHub

in the AOT compilation the top levels defs are evaled, but their value is discarded and recomputed again when I execute the jar file?


i was trying to read some ENV vars in my top levels defs, but the env vars are only set when i call java -jar, not lein uberjar


Correct. Top-level def (and defn) forms are evaluated whenever the namespace is loaded. That happens when AOT occurs (it has to load the namespace to compile it) and it happens when you run the uberjar (again, it has to load the namespace in order to run the code).


In general, you should avoid performing any computation in a def because of that.


If you want to perform a calculation once and cache it, using (def my-sym (delay some-expression)), and then @my-sym to reference the value, will delay(!) the evaluation of some-expression until the first use of @my-sym at runtime.


That’s a bit of a hack tho’… Computing global “state” once at application startup, called from your -main function, is better (and then passing it through function call chains). Stuart Sierra’s Component library is a reasonable approach.


Oh, and if you go with the delay route, remember that (def my-other-sym @my-sym) will force a dereference at load time and thus you’ll be back in the situation you started in...


@danielstockton maybe, but i find it helps if you have some pairs on the same line and others split


that way you can train yourself to look for some common text to help you decipher a cond


but i think i agree for most cases


hello, is first doing the clojure koans and then 4clojure a good way to learn clojure properly ?


I find it's a good way, even better if you are reading Programming Clojure on the way as well.


oke, I tried to learn clojure with the brave book but that one is way to fast for me.


The exercises/challenges were to difficult


@nxqd thanks, I found the book


Is this one good :

"When things cannot be equal, they must be different"
  (not= :true true)) 
the tests are green


@adambros @cschep I found my answer. The indent spec can be a function, so pretty much anything is possible.


The last comment worked perfectly for me.


Has anyone experience with AnalyzingInfixSuggester from lucene, in a REPL? I’m running into Lock obtain timed out: NativeFSLock when I want to rebuild an instance


I want to extend a Java class that needs a mutable field in Clojure. I chose defrecord. How should I model the mutable field, with an atom?


maybe deftype is better here


How do I combine a type hint with volatile-mutable?

Alex Miller (Clojure team)17:11:15

records can’t extend Java classes

Alex Miller (Clojure team)17:11:54

if you want a typed volatile field, just stack up the meta

Alex Miller (Clojure team)17:11:45

but note that the only “types” that actually matter are double and long

Alex Miller (Clojure team)17:11:05

all other fields are always constructed as Object type

Alex Miller (Clojure team)17:11:04

so like (deftype T [^:volatile-mutable ^long f]) for a type with a mutable long field


@alexmiller out of curiosity, why only double and long? Perhaps related to the ifn permutations?

Alex Miller (Clojure team)17:11:38

they are the only primitive types Clojure uses

Alex Miller (Clojure team)17:11:33

So ^long and ^double type hints typically do something more than any other type hint (they affect the code that’s generated, not just type inference on Java calls)

Alex Miller (Clojure team)17:11:00

in records and fields, they affect the field type. in functions, they affect the parameter types.

Alex Miller (Clojure team)17:11:32

so at the jvm level, the bytecode Clojure creates pretty much only cares about long, double, and Object. (hand-waving many details)


it turned out I was implementing an interface, not extending a class. so I’m good still with deftype\


does anybody have a good technique for picking up a package version (aka from lein defproject) in a way that works both in a repl, and in an uberjar? Also, this is in a library, and the library's version would be the one I'm after) from within the library code.


How do I add the following method: public BytesRef next() throws IOException I tried: (next ^BytesRef [this] …)


but I get the following error:

   is abstract

Alex Miller (Clojure team)17:11:53

is this using any of the new Java 8 stuff for default methods perhaps?

Alex Miller (Clojure team)17:11:15

you don’t need to type-hint that btw - just (next [this] …) should be sufficient

Alex Miller (Clojure team)17:11:39

you could also be running into something weird with generic bridge methods

Alex Miller (Clojure team)17:11:21

people seem to not like this advice, but sometimes the easiest thing to do is to just write a thin Java shim


yes, that’s what I had, but it didn’t play nice with my boot project ...


I think I’m going to carve it out into its own project...

Alex Miller (Clojure team)17:11:05

what interface are you implementing here?

Alex Miller (Clojure team)17:11:48

dunno, not obvious to me why that wouldn’t be feasible



[org.apache.lucene/lucene-core "4.9.1"]
[org.apache.lucene/lucene-suggest "4.9.1"]


I suppose you can redefine deftypes in the REPL right?


ah it worked


REPL state I think

Alex Miller (Clojure team)17:11:06

I’d get rid of the type hint. and I don’t see the need for the current field?

Alex Miller (Clojure team)17:11:29

you could just reify this impl too, you don’t even need a deftype afaict


the current field is used in the payload method which I had to implement still

Alex Miller (Clojure team)17:11:24

ah, was wondering about that


do you mean reify, because I only need one instance?

Alex Miller (Clojure team)17:11:35

no, b/c I didn’t see anything stateful

Alex Miller (Clojure team)17:11:01

which you could still do with reify even, by just closing over a volatile


I’m wondering about the ‘constructor’, I guess just a normal function and then calling (TermIterator. x nil)?

Alex Miller (Clojure team)17:11:15

my personal preference is to always use the generated constructor (->TermIterator x nil)

Alex Miller (Clojure team)17:11:50

the fact that it’s generating a Java class is an implementation detail (and different in CLJS)

Alex Miller (Clojure team)18:11:02

reify version would be like:

Alex Miller (Clojure team)18:11:04

(defn term-iterator [iter]
(let [current (volatile nil)]
  (reify InputIterator
    (weight [this] 0)
    (payload [this] @current)
    (hasPayloads [this] true)
    (context [this] nil)
    (hasContext [this] false)
    (next [this]
      (when (.hasNext iter)
        (vreset! current (.next iter))
        (BytesRef. (.getBytes ^String (:term @current))))))))

Alex Miller (Clojure team)18:11:04

if you don’t need a type (and I don’t think you do), then I wouldn’t make one - it complicates everything about compilation, work at the repl, etc


cool, it worked:

(suggest s "heart att" 5) ;; (#dre.index.terms_extra.Term{:uri "x", :term "heart attack”})


this is very useful for me, because now I have my REPL experience back with this piece of code 🙂


@seancorfield thank you, that's very helpful


(never mind, was just a typo, context should be contexts)


Is there a common supertype that I can use to get rid of the reflection warning, as long it’s a seq/collection-ish thing? (.iterator items)


it seems not


Both vectors and lazy seqs do return iterators though


is there such a thing as test/simulation driven optimization, where you write generative tests or something similar for the performance sensitive parts of your code, and the compiler is able to figure out the hoth code paths and generate efficient code based on those?


kind of like a JIT, but the code would be AOT compiled based on the profiling info gained from running the tests


@luxbock I don't think anything like that exists for clojure, mostly because almost all clojure runs in JIT'd environments..


in theory could you somehow instruct the JIT to cache its optimizations during this step, and then get code that starts up and finds its hot code paths faster than otherwise?

Alex Miller (Clojure team)20:11:36

@luxbock they are working on AOT Java which maybe would be something like that


eh yes, that works! 😊

Alex Miller (Clojure team)20:11:08

although I guess that compiled binary would not be optimized for any particular profile and it could still recompile later. I don’t know.

Alex Miller (Clojure team)20:11:22

would help startup time to provide Clojure core jar in that mode though


@alexmiller top comment about JEP 295 on says "No dynamic byte code (Lambda Expressions, Dynamic Classes, etc.)". Would clojure need dynamic bytecode?


Also it mentions that this wouldn't have much if any effect on startup time, because it only bypasses the interpreted phase before the 10k invocations number is hit to trigger a compile, but it might help clojure because has to read/load so many vars.

Alex Miller (Clojure team)22:11:03

Clojure does not currently use any of those features


I believe they (JDK stewards) are still in early research phase on how to handle some of the late binding aspects of Java bytecode


(e.g. invokedynamic, which powers Lambda Expressions)




is hickory the industry standard for parsing html in clojure?