[ANN] Clojure 1.9.0 is now available!

856 views
Skip to first unread message

Alex Miller

unread,
Dec 8, 2017, 2:35:39 PM12/8/17
to Clojure

Clojure 1.9 is now available!


Clojure 1.9 introduces two major new features: integration with spec and command line tools.


spec (rationaleguide) is a library for describing the structure of data and functions with support for:

  • Validation
  • Error reporting
  • Destructuring
  • Instrumentation
  • Test-data generation
  • Generative test generation
  • Documentation

Clojure integrates spec via two new libraries (still in alpha):

This modularization facilitates refinement of spec separate from the Clojure release cycle.

The command line tools (guidereference) provide:

  • Quick and easy install
  • Clojure REPL and runner
  • Use of Maven and local dependencies
  • A functional API for classpath management (tools.deps.alpha)

The installer is available for Mac developers in brew, for Linux users in a script, and for more platforms in the future.

For more information, see the complete list of all changes in Clojure 1.9 for more details.


Contributors


Thanks to all of the community members who contributed to Clojure 1.9 (first time contributors in bold):

  • Adam Clements
  • Andy Fingerhut
  • Brandon Bloom
  • Cameron Desautels
  • Chad Taylor
  • Chris Houser
  • David Bürgin
  • Eli Lindsey
  • Gerrit Jansen Van Vuuren
  • Ghadi Shayban
  • Greg Leppert
  • Jason Whitlark
  • Johan Mena
  • Jozef Wagner
  • Lee Yen-Chin
  • Matthew Boston
  • Michael Blume
  • Michał Marczyk
  • Nicola Mometto
  • Ruslan Al-Fakikh
  • Steffen Dienst
  • Steve Miner
  • Yegor Timoshenko
  • Zhuang XiaoDan

Alex Miller

unread,
Dec 8, 2017, 2:52:00 PM12/8/17
to Clojure
I will also mention that if you have visited any of these docs in the past, they have all been rewritten as well:
And if you're on a Mac, you can grab the new tools + 1.9 with just:  brew install clojure

Alex Miller

unread,
Dec 8, 2017, 2:53:05 PM12/8/17
to Clojure
whoops, last one should have been: https://clojure.org/reference/deps_and_cli

Jozef Wagner

unread,
Dec 8, 2017, 3:03:49 PM12/8/17
to Clojure
Congratulations on the long awaited release and thanks to Rich, Stu, Alex and all contributors! I'm glad and proud to be part of it!

Jozef 

Sergey Didenko

unread,
Dec 8, 2017, 4:11:29 PM12/8/17
to clo...@googlegroups.com
Congratulations!

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rick Moynihan

unread,
Dec 8, 2017, 4:54:26 PM12/8/17
to clo...@googlegroups.com

Wow great news... Thanks to everyone who made it happen!!

R.


Congratulations!


For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
R.

Didier

unread,
Dec 8, 2017, 5:13:26 PM12/8/17
to Clojure
Awesome Job!

Now looking forward to spec improving and eventually getting out of alpha!

Jose Figueroa Martinez

unread,
Dec 8, 2017, 5:17:38 PM12/8/17
to Clojure
Excelent news! Thank you all for your effort.

It feels like christmas but earlier :-D

"We wish you a merry christmas and a happy new Clojure!"

José FM

Rostislav Svoboda

unread,
Dec 8, 2017, 8:54:23 PM12/8/17
to clo...@googlegroups.com
Hi, first of all: thanks for the 1.9.0!
And now issue: it looks like the 1.9.0 is slower than 1.8.0. Is there
any --turbo switch to flip?

Bost


time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000
1000)))'
#'user/Σ
500000500000
1.31user 0.04system 0:00.65elapsed 205%CPU (0avgtext+0avgdata
101872maxresident)k
0inputs+64outputs (0major+21822minor)pagefaults 0swaps

time clj -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (*
1000 1000)))'
#'user/Σ
500000500000
2.03user 0.05system 0:00.92elapsed 226%CPU (0avgtext+0avgdata
108284maxresident)k
0inputs+64outputs (0major+25522minor)pagefaults 0swaps



time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000 1000
10)))'
#'user/Σ
50000005000000
1.72user 0.08system 0:00.88elapsed 204%CPU (0avgtext+0avgdata
199204maxresident)k
0inputs+64outputs (0major+46108minor)pagefaults 0swaps

time clj -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (*
1000 1000 10)))'
#'user/Σ
50000005000000
2.63user 0.09system 0:01.27elapsed 214%CPU (0avgtext+0avgdata
210056maxresident)k
0inputs+64outputs (0major+50405minor)pagefaults 0swaps



time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000 1000
100)))'
#'user/Σ
5000000050000000
2.17user 0.23system 0:01.59elapsed 151%CPU (0avgtext+0avgdata
729756maxresident)k
0inputs+64outputs (0major+178749minor)pagefaults 0swaps

time clj -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (*
1000 1000 100)))'
#'user/Σ
5000000050000000
2.95user 0.28system 0:01.87elapsed 172%CPU (0avgtext+0avgdata
739368maxresident)k
0inputs+64outputs (0major+182736minor)pagefaults 0swaps



time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000 1000
1000)))'
#'user/Σ
500000000500000000
9.34user 0.27system 0:08.75elapsed 109%CPU (0avgtext+0avgdata
744520maxresident)k
0inputs+64outputs (0major+183953minor)pagefaults 0swaps

time clj -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (*
1000 1000 1000)))'
#'user/Σ
500000000500000000
10.52user 0.25system 0:09.29elapsed 115%CPU (0avgtext+0avgdata
752244maxresident)k
0inputs+104outputs (0major+189351minor)pagefaults 0swaps

Andy Fingerhut

unread,
Dec 8, 2017, 11:26:01 PM12/8/17
to clo...@googlegroups.com
Rostislav:

I haven't run a bunch of benchmarks to double-check this in detail, but just running a '(println "Hello")' shows a difference between 1.8 and 1.9, which is purely Clojure startup time.  I don't see anything in your results that suggests the time difference is getting large with more computation, do you?

If it is all extra startup time, that could be due to loading spec and def'ing extra Clojure 1.9 Vars during initialization.

Andy


> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an

> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.

Alex Miller

unread,
Dec 9, 2017, 12:23:08 AM12/9/17
to Clojure

On Friday, December 8, 2017 at 7:54:23 PM UTC-6, Bost wrote:
Hi, first of all: thanks for the 1.9.0!
And now issue: it looks like the 1.9.0 is slower than 1.8.0. Is there
any --turbo switch to flip?

I think to be a better comparison, I would do clj -Spath to grab your classpath and in both cases start with "java -cp <classpath> ..." to get an apples to apples comparison. The clj script is fast compared to Clojure startup but it is checking and comparing files time for multiple files to determine whether it can use the cached classpath. 

Second I don't think you're doing enough work or enough timings here to necessarily get past the JVM hotspot compilation overhead and see times that are worth comparing. If you want to benchmark the time for the reduce, I would add criterium and exclude the startup time. My expectation would be that the times are pretty similar as little has changed that should affect what you're doing here.

Startup time through clojure.main (which you're doing in both cases) does currently have a side effect of loading spec and the core specs which adds about 0.1-0.2 s. Startup time on AOT'ed code NOT going through clojure.main can usually avoid these.

 
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Rostislav Svoboda

unread,
Dec 9, 2017, 6:10:58 AM12/9/17
to clo...@googlegroups.com
To give you a bit of an explanation - I'd like to use
clojure/clojurescript for scripting... I was reading the:
http://blog.brunobonacci.com/2017/08/10/lumo-vs-planck-vs-clojure-vs-pixie/
and got curious how does the 1.9.0 behave when talking about startup times.
(Oh BTW notice that lumo and planck compute wrong results, how lovely :)

> If it is all extra startup time, that could be due to loading spec and def'ing extra Clojure 1.9 Vars during initialization.

It really looks like it is the startup time. Unfortunately:

> start with "java -cp <classpath> ..." to get an apples to apples comparison

makes not much of a difference. Anyway, thank you for the (correctly
computing :-) 1.9.0!


Bost


time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000 1000
10)))'
#'user/Σ
50000005000000
1.47user 0.07system 0:00.79elapsed 194%CPU (0avgtext+0avgdata
197744maxresident)k
0inputs+64outputs (0major+45783minor)pagefaults 0swaps

time java -cp /home/bost/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar:/home/bost/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar:/home/bost/.m2/repository/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24.jar
clojure.main -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ
(* 1000 1000 10)))'
#'user/Σ
50000005000000
2.30user 0.04system 0:00.95elapsed 246%CPU (0avgtext+0avgdata
213724maxresident)k
0inputs+64outputs (0major+49720minor)pagefaults 0swaps



time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000 1000
100)))'
#'user/Σ
5000000050000000
2.10user 0.13system 0:01.49elapsed 150%CPU (0avgtext+0avgdata
730068maxresident)k
0inputs+64outputs (0major+178898minor)pagefaults 0swaps

time java -cp /home/bost/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar:/home/bost/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar:/home/bost/.m2/repository/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24.jar
clojure.main -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ
(* 1000 1000 100)))'
#'user/Σ
5000000050000000
3.10user 0.25system 0:01.90elapsed 176%CPU (0avgtext+0avgdata
740780maxresident)k
0inputs+64outputs (0major+182178minor)pagefaults 0swaps



time java -jar /home/bost/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar
-e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ (* 1000 1000
1000)))'
#'user/Σ
500000000500000000
9.31user 0.24system 0:08.64elapsed 110%CPU (0avgtext+0avgdata
743596maxresident)k
0inputs+64outputs (0major+183306minor)pagefaults 0swaps

time java -cp /home/bost/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar:/home/bost/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar:/home/bost/.m2/repository/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24.jar
clojure.main -e '(defn Σ [n] (reduce + (range (inc n)))) (println (Σ
(* 1000 1000 1000)))'
#'user/Σ
500000000500000000
9.72user 0.25system 0:08.51elapsed 117%CPU (0avgtext+0avgdata
749604maxresident)k
0inputs+64outputs (0major+185270minor)pagefaults 0swaps
>> > clojure+u...@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/clojure?hl=en
>> > ---
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "Clojure" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an
>> > email to clojure+u...@googlegroups.com.
>> > For more options, visit https://groups.google.com/d/optout.
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+u...@googlegroups.com.

Georgi Danov

unread,
Dec 9, 2017, 9:38:17 AM12/9/17
to Clojure
is the new clj CLI going to be alternative to Lein? For example can I run repl with middleware?

also, if I use lein repl, is deps.edn taken into account? I love that feature

Alex Miller

unread,
Dec 9, 2017, 11:00:39 AM12/9/17
to Clojure
> is the new clj CLI going to be alternative to Lein?

No, it’s not intended to replace lein. clj is about building classpath and launching programs, not building or deploying artifacts.

> For example can I run repl with middleware?

No.

> also, if I use lein repl, is deps.edn taken into account? I love that feature

No, although that is presumably something that could be made.

Sean Corfield

unread,
Dec 9, 2017, 2:35:30 PM12/9/17
to clo...@googlegroups.com

also, if I use lein repl, is deps.edn taken into account? I love that feature

 

It shouldn’t be hard for someone to write a Leiningen plugin that uses tools.deps to read the cascade of deps.edn files and provide support for resolve/classpath aliases etc. I’ve already done this for Boot: https://github.com/seancorfield/boot-tools-deps

 

Also, since you’re interested specifically in REPL behavior and dependency handling, you might be interested to see that Boot lets you start a REPL with a set of dependencies loaded, without needing a project folder or build file:

 

                boot -d some/thing repl

 

That loads the latest version of some/thing (as if you’d specified [some/thing “RELEASE”] as a dependency) and then starts a REPL.

 

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

 


From: clo...@googlegroups.com <clo...@googlegroups.com> on behalf of Georgi Danov <georgi...@gmail.com>
Sent: Saturday, December 9, 2017 6:38:16 AM
To: Clojure
Subject: Re: [ANN] Clojure 1.9.0 is now available!
 
is the new clj CLI going to be alternative to Lein? For example can I run repl with middleware?

also, if I use lein repl, is deps.edn taken into account? I love that feature

Message has been deleted

Isaac Tsang

unread,
Dec 25, 2017, 9:40:50 AM12/25/17
to Clojure
I think is better to add AOT cache to speed up startup time.

Mamun

unread,
Dec 26, 2017, 5:42:38 PM12/26/17
to Clojure
Congratulation. I am getting one problem for defmacro spec with defmethod. Here it is

(defmulti mycomp (fn [v] v))
(defmacro defcomp [m]
 
`(defmethod mycomp ~m
     [_]

     ~m
    )
  )

(defcomp :test) ;; Throwing exception

;; Expand macro
(defmethod mycomp :test [_] :test)
;; it is working




Here is error details

  Call to clojure.core/fn did not conform to spec: In: [0 0] val:
   (com.mxsys.psql.component/_) fails spec: :clojure.core.specs.alpha/arg-list
   at: [:args :bs :arity-1 :args] predicate: (cat :args (*
   :clojure.core.specs.alpha/binding-form) :varargs (? (cat :amp #{(quote &)}
   :form :clojure.core.specs.alpha/binding-form))), Extra input In: [0 0] val:
   com.mxsys.psql.component/_ fails spec: :clojure.core.specs.alpha/arg-list at:
   [:args :bs :arity-n :args] predicate: vector?

Br,
Mamun







On Friday, December 8, 2017 at 8:35:39 PM UTC+1, Alex Miller wrote:

Gary Verhaegen

unread,
Dec 26, 2017, 5:59:23 PM12/26/17
to clo...@googlegroups.com
The spec is correct; your code is wrong and I don't know how you got your expansion there.

$ lein try org.clojure/clojure 1.9.0
nREPL server started on port 55018 on host 127.0.0.1 - nrepl://127.0.0.1:55018
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_144-b01
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (defmulti mycomp (fn [v] v))
#'user/mycomp
user=> (defmacro defcomp [m]
  #_=>   `(defmethod mycomp ~m
  #_=>      [_]
  #_=>      ~m
  #_=>     )
  #_=>   )
#'user/defcomp
user=> (defcomp :test)

CompilerException java.lang.RuntimeException: Can't use qualified name as parameter: user/_, compiling:(null:1:1)
user=> (macroexpand '(defcomp test))
(. user/mycomp clojure.core/addMethod test (clojure.core/fn [user/_] test))
user=>

The problem is that you have not protected the _, so it gets expanded to the local namespace (user/_ in my case here, com.mxsys.psql.component/_ in yours). You want:

user=> (defmacro defcomp [m] `(defmethod mycomp ~m [~'_] ~m))
#'user/defcomp
user=> (defcomp :test)
#multifn[mycomp 0x545609d8]
user=> (macroexpand '(defcomp :test))
(. user/mycomp clojure.core/addMethod :test (clojure.core/fn [_] :test))
user=>

Notice how the underscore is escaped as ~'_ to escape from the syntax quote and place a literal underscore symbol.

Mamun

unread,
Dec 26, 2017, 6:08:52 PM12/26/17
to Clojure
Thanks

It is working with (defmethod mycomp ~m [~'_] ~m))
_ is also clojure valid symbol identifier.
I miss that point.


Br,
Mamun

Luc

unread,
Dec 28, 2017, 7:13:30 PM12/28/17
to Clojure
Hi,

I am baffled. I switched a project from 1.8 to 1.9.0 upgrading also other dependencies
(latest version fo core.async, ...) via lein ancient.

As usual I ran an AOT pass to make sure I don't have anything fishy before running the code.

I got  this from the AOT pass:

java.lang.UnsupportedOperationException: Can't type hint a primitive local

Oupse... I Reverted to 1.8 w/o reverting the dependency changes. it AOTed w/o a glitch.

I narrowed it at:

(:ns ....)
(defprotocol GatewayJob
  (start-job! [this] "Start the given job")
  ...)

(:ns ....)
(defrecord NoopJob [name job-controller-channel env job-state parameters job-output]
  impl/GatewayJob
  (start-job! [this]
   ...
    (try
      ....
      (catch Exception e#
         (reset! job-state :failed) (>!! job-controller-channel [this :new-state :failed :error e#])
        (log/error (format "NoopJob job died unexpectedly !") e#) ))) <- Here

error is a macro which expands here to:

(clojure.tools.logging/log* logger__458__auto__ :error nil (clojure.core/print-str "NoopJob job died unexpectedly !"))

The (try (catch...) compiles w/o problems outside of the protocol implementation. It bombs a soon as it is
embedded in a protocol implementation. 3 instances in three different namespaces same behavior and same
code pattern (try .. catch .. reset! >!! ...

I have been toying with this for an hour but I need some new direction(s) to eventually nail it.
I dived in the list of changes of 1.9 but my search didn't come up with anything relevant yet.

Anything changed in the defrecord macro expansion that could explain this ?
Something related to core.async ? (it works with 1.8 w/o reverting the other dependencies however)
A malpractice in the code structure that was tolerated so far ?

I looked at the macro expansion of the defrecord but did not find anything wrong on the surface.

Note that I did not yet attempt to run this project from source. That's forthcoming but I would expect
it to crash at runtime..

Any idea is welcomed.

Thank you,
Luc P.

Alex Miller

unread,
Dec 28, 2017, 8:02:51 PM12/28/17
to Clojure
What’s the full stack trace on the original exception? (Or if same repros without aot)?

Gary Verhaegen

unread,
Dec 29, 2017, 8:09:25 AM12/29/17
to clo...@googlegroups.com
Can you try deleting code until the error disappears, and try to get to a minimal reproducing case that way? Does it still happen if the protocol and record are in the same ns? Does it still happen if you remove the reset! and >!! forms?

Is that whole code within a custom macro? The name e# for the exception seems to suggest this is part of a syntax-quote?

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.

Luc

unread,
Dec 29, 2017, 7:17:47 PM12/29/17
to Clojure
Hi Alex,

here it is, I did not get through the compiler source code yet, it might be obvious to you:

java.lang.UnsupportedOperationException: Can't type hint a primitive local, compiling:(yabug/jobs/noop.clj:21:9)
Exception in thread "main" java.lang.UnsupportedOperationException: Can't type hint a primitive local, compiling:(yabug/jobs/noop.clj:21:9)
    at clojure.lang.Compiler.analyze(Compiler.java:6792)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$VectorExpr.parse(Compiler.java:3253)
    at clojure.lang.Compiler.analyze(Compiler.java:6775)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3881)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3881)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6991)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
    at clojure.lang.Compiler$TryExpr$Parser.parse(Compiler.java:2334)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
    at clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:8431)
    at clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:7937)
    at clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:7813)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6420)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5460)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4022)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7001)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3813)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7005)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6330)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
    at clojure.lang.Compiler.analyze(Compiler.java:6773)
    at clojure.lang.Compiler.analyze(Compiler.java:6729)
    at clojure.lang.Compiler.compile1(Compiler.java:7604)
    at clojure.lang.Compiler.compile(Compiler.java:7676)
    at clojure.lang.RT.compile(RT.java:413)
    at clojure.lang.RT.load(RT.java:458)
    at clojure.lang.RT.load(RT.java:426)
    at clojure.core$load$fn__6548.invoke(core.clj:6046)
    at clojure.core$load.invokeStatic(core.clj:6045)
    at clojure.core$load.doInvoke(core.clj:6029)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5848)
    at clojure.core$compile$fn__6553.invoke(core.clj:6056)
    at clojure.core$compile.invokeStatic(core.clj:6056)
    at clojure.core$compile.invoke(core.clj:6048)
    at user$eval164$fn__173.invoke(form-init6735162608711470447.clj:1)
    at user$eval164.invokeStatic(form-init6735162608711470447.clj:1)
    at user$eval164.invoke(form-init6735162608711470447.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:7062)
    at clojure.lang.Compiler.eval(Compiler.java:7052)
    at clojure.lang.Compiler.eval(Compiler.java:7052)
    at clojure.lang.Compiler.load(Compiler.java:7514)
    at clojure.lang.Compiler.loadFile(Compiler.java:7452)
    at clojure.main$load_script.invokeStatic(main.clj:278)
    at clojure.main$init_opt.invokeStatic(main.clj:280)
    at clojure.main$init_opt.invoke(main.clj:280)
    at clojure.main$initialize.invokeStatic(main.clj:311)
    at clojure.main$null_opt.invokeStatic(main.clj:345)
    at clojure.main$null_opt.invoke(main.clj:342)
    at clojure.main$main.invokeStatic(main.clj:424)
    at clojure.main$main.doInvoke(main.clj:387)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.lang.Var.applyTo(Var.java:702)
    at clojure.main.main(main.java:37)
Caused by: java.lang.UnsupportedOperationException: Can't type hint a primitive local
    at clojure.lang.Compiler$LocalBindingExpr.<init>(Compiler.java:5999)
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:7183)
    at clojure.lang.Compiler.analyze(Compiler.java:6752)

Will get this up and running this weekend to see if it can be reproduced at runtime and post the result here.
I need to revive some setups, it's a project that had been put on ice for a while.

Thank you, Happy New Year,
Luc

Alex Miller

unread,
Dec 29, 2017, 8:00:05 PM12/29/17
to clo...@googlegroups.com
On Fri, Dec 29, 2017 at 6:17 PM, Luc <lprefo...@softaddicts.ca> wrote:
 
here it is, I did not get through the compiler source code yet, it might be obvious to you:

java.lang.UnsupportedOperationException: Can't type hint a primitive local, compiling:(yabug/jobs/noop.clj:21:9)
Exception in thread "main" java.lang.UnsupportedOperationException: Can't type hint a primitive local, compiling:(yabug/jobs/noop.clj:21:9)

What's the code here? ^^

 

Luc

unread,
Dec 29, 2017, 8:05:35 PM12/29/17
to Clojure
I went through the compiler code, it has to do with a bad local binding expression.

It crashes in the same way in the REPL with this minimal defrecord:


(defrecord NoopJob [name job-controller-channel env job-state parameters job-output]
  impl/GatewayJob
  (start-job! [this]
    (log/error "NoopJob job died unexpectedly !")))

No try catch, no core.async, ...
So there's something going on in log/error macro expansion versus the defrecord expansion.

I attached two files, the macro expansions of defrecord and the log/error macro.

Alex if you prefer I can open a ticket. If nothing obvious comes out that's were it will end up anyway.
I'll toy with the combined macro expanded code this weekend to see if I can narrow this a bit more.

I have been using the same logging API for years now (since 2009). I really want to know what's broken.
I have two dozen projects to upgrade to 1.9 :) It's bizarre at best.

Thank you,
Luc P.
defrecord-macroexpand.txt
log-macroexpand.txt

Luc

unread,
Dec 29, 2017, 8:08:05 PM12/29/17
to Clojure
The call to the log/error macro. Theres an interaction with the expanded code from the defrecord macro and this macro.
I posted both expansions in a message 30secs ago. Ill play with these this weekend to see if I can narrow it down further.

Gary Verhaegen

unread,
Dec 30, 2017, 6:37:26 AM12/30/17
to clo...@googlegroups.com
What version of clojure.tools.logging are you using?
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
<defrecord-macroexpand.txt>
<log-macroexpand.txt>

Luc

unread,
Jan 2, 2018, 5:03:00 PM1/2/18
to Clojure
Hi,

finally got some time to dig deeper. The minimal code to reproduce this has shrunk:

(defprotocol Anonymous
  (start-job! [this]))

(defrecord NoopJob []
  Anonymous
  (start-job! [this]
    (yabug.services.logger/environment)))

The environment macro was called by log/error but not by the other severity level macros.
The error macro within a defrecord is the only case where it fails.

This is the environment macro definition:

(defmacro environment
  "Expands to code that generates a map of locals: names to values"
  []
  (clojure.pprint/pprint (macroexpand `(zipmap '~(keys &env) [~@(keys &env)])))
  `(zipmap '~(keys &env) [~@(keys &env)]))

I added the macroexpand in the macro to get what it expands to in the context of the defrecord
at compile time.
Outside of the defrecord the compiler does not complain (let, ...)). The protocol by itself does not seem
to be a significant factor. I got this at different places under different protocols.

This is the 1.9 macro expansion outputted at compile time before ending up with exception while evaluating
the resulting code:

(clojure.core/zipmap
 '(__hash __meta this __hasheq __extmap)
 [__hash __meta this __hasheq __extmap])

This is the 1.8 macroexpansion of this macro which is a bit shorter, there's seem to be less context generated by the defrecord macro
expansion:

(clojure.core/zipmap '(__meta this __extmap) [__meta this __extmap])

The expansion of the defrecord context is slightly bigger but nothing hits me when I compare both expanded vectors at the end.
I am assuming that this the expression that the compiler cannot evaluate in 1.9 since it the error originates from the VectorExpr
class.
Is there anything obvious on with the evaluation of the last vector in the 1.9 expansion that would explain this error ?
I don't see it.

Just to make things more puzzling the expansion literally works in the 1.9 REPL:

=> (defrecord NoopJob []
     impl/GatewayJob
     (start-job! [this]
       (clojure.core/zipmap
         '(__hash __meta this __hasheq __extmap)
         [__hash __meta this __hasheq __extmap])))
yabug.jobs.noop.NoopJob

Grr...

Will sleep on it and toy with it tomorrow by expanding a bit the test cases. It's nearly 22:00 Morocco time here.
I need a break and some sleep.

Luc P.

On Saturday, 30 December 2017 01:00:05 UTC, Alex Miller wrote:

Alex Miller

unread,
Jan 2, 2018, 5:15:15 PM1/2/18
to Clojure
What’s GatewayJob look like?

Nicola Mometto

unread,
Jan 2, 2018, 5:22:18 PM1/2/18
to clo...@googlegroups.com
The code that caused this issue is
https://github.com/clojure/clojure/commit/a1c3dafec01ab02fb10d91f98b9ffd3241e860c0?diff=unified#diff-03234b041c0917ec98f2ad9477a0a014R260
But this is not a bug in the clojure code nor a regression, in fact
you can reproduce this in any clojure version with the following code:

(defmacro m [] `[~@(keys &env)])
(defprotocol p (f [_]))
(deftype t [^int x] p (f [_] (m)))


This is happening for the same reason why (let [x (int 1)] (identity
^int x)) throws the same error, the fix in your case is to use (map
#(with-meta % {}) (keys &env))

Luc

unread,
Jan 3, 2018, 6:01:11 AM1/3/18
to Clojure
Should have posted this instead, same protocol.


(defprotocol Anonymous (start-job! [this]))

;; Clojure 1.8.0
=> (defrecord NoopJob []
     Anonymous
     (start-job! [this]
       (yabug.services.logger/environment)))

(clojure.core/zipmap '(__meta this __extmap) [__meta this __extmap])
yabug.jobs.noop.NoopJob


On Tuesday, 2 January 2018 22:15:15 UTC, Alex Miller wrote:
What’s GatewayJob look like?

Luc

unread,
Jan 3, 2018, 6:08:44 AM1/3/18
to Clojure
Thank you,

I was not searching strictly for a bug or regression, a malpractice was also something I wanted to ear about.
The let form generates this in both 1.8 & 1.9. No idea why the defrecord compiles in 1.8 but that could be related
to the way it is expanded in each version. I don't see the point of going down further on this path.

I will change the macro code here accordingly.

Luc P.
Reply all
Reply to author
Forward
0 new messages