This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-11
Channels
- # beginners (109)
- # boot (61)
- # cider (8)
- # clara (3)
- # cljs-dev (67)
- # cljsrn (5)
- # clojure (96)
- # clojure-argentina (1)
- # clojure-brasil (2)
- # clojure-greece (10)
- # clojure-russia (114)
- # clojure-spec (51)
- # clojure-uk (45)
- # clojurebridge (2)
- # clojurescript (139)
- # cursive (18)
- # data-science (1)
- # datascript (2)
- # datomic (13)
- # dirac (2)
- # emacs (5)
- # events (1)
- # javascript (2)
- # jobs (1)
- # juxt (3)
- # off-topic (62)
- # om (10)
- # onyx (12)
- # perun (7)
- # ring-swagger (7)
- # specter (21)
- # test-check (5)
- # untangled (16)
- # utah-clojurians (1)
- # yada (2)
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...
Hope that helps @jasonjckn ?
@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.
Is this one good :
"When things cannot be equal, they must be different"
(not= :true true))
the tests are green@adambros @cschep https://github.com/clojure-emacs/clojure-mode/issues/337 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?
records can’t extend Java classes
neither can deftypes
if you want a typed volatile field, just stack up the meta
but note that the only “types” that actually matter are double and long
all other fields are always constructed as Object type
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?
they are the only primitive types Clojure uses
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)
in records and fields, they affect the field type. in functions, they affect the parameter types.
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:
Method
dre/index/terms_extra/TermIterator.next()Lorg/apache/lucene/util/BytesRef;
is abstract
is this using any of the new Java 8 stuff for default methods perhaps?
you don’t need to type-hint that btw - just (next [this] …)
should be sufficient
you could also be running into something weird with generic bridge methods
people seem to not like this advice, but sometimes the easiest thing to do is to just write a thin Java shim
what interface are you implementing here?
TermIterator?
this one: https://lucene.apache.org/core/4_9_1/suggest/org/apache/lucene/search/suggest/InputIterator.html
the method next
is from BytesRefIterator
: https://lucene.apache.org/core/4_9_1/core/org/apache/lucene/util/BytesRefIterator.html?is-external=true#next()
dunno, not obvious to me why that wouldn’t be feasible
gist more of the code?
Dependencies:
[org.apache.lucene/lucene-core "4.9.1"]
[org.apache.lucene/lucene-suggest "4.9.1"]
I’d get rid of the type hint. and I don’t see the need for the current field?
you could just reify this impl too, you don’t even need a deftype afaict
ah, was wondering about that
no, b/c I didn’t see anything stateful
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)
?
my personal preference is to always use the generated constructor (->TermIterator x nil)
the fact that it’s generating a Java class is an implementation detail (and different in CLJS)
reify version would be like:
(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))))))))
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”})
cool, thanks @alexmiller !
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
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)
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?
@borkdude what about Iterable?
@luxbock they are working on AOT Java which maybe would be something like that
http://openjdk.java.net/jeps/282 is one of the starting points around that
although I guess that compiled binary would not be optimized for any particular profile and it could still recompile later. I don’t know.
@alexmiller interesting
would help startup time to provide Clojure core jar in that mode though
@alexmiller top comment about JEP 295 on https://news.ycombinator.com/item?id=12807906 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.
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