[ANN] Clojure 1.10.0-RC5

467 views
Skip to first unread message

Alex Miller

unread,
Dec 11, 2018, 4:37:42 PM12/11/18
to Clojure
1.10.0-RC5 is now available. Please test, particularly if your library/application uses interop calls and reflection...

You can try it with clj using:

clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.0-RC5"}}}'

Changes in 1.10.0-RC5:
  • CLJ-2454 - fix IllegalAccessException from invoking matching reflective call
You can read the full 1.10 changelog here: https://github.com/clojure/clojure/blob/master/changes.md

Sean Corfield

unread,
Dec 11, 2018, 5:28:30 PM12/11/18
to Clojure
And as you can no doubt imagine, we are already testing it at World Singles Networks (albeit on OpenJDK 8).

Sean

Mars0i

unread,
Dec 12, 2018, 1:44:46 AM12/12/18
to Clojure
I have a couple of small apps that use interop pretty heavily because the Java library I'm using is very inheritance-based.  There are no  problems running with RC5 (although spec did find a syntax error that had passed in 1.9).  I don't use reflection explicitly, but turning on *warn-on-reflection* generates a bunch of warnings in one of the apps, so I guess it's using reflection to figure out types at runtime.

Alex Miller

unread,
Dec 12, 2018, 7:42:47 AM12/12/18
to clo...@googlegroups.com
Thanks for the feedback! I assume the spec one was a bad import statement?

On Dec 12, 2018, at 12:44 AM, Mars0i <mars...@logical.net> wrote:

I have a couple of small apps that use interop pretty heavily because the Java library I'm using is very inheritance-based.  There are no  problems running with RC5 (although spec did find a syntax error that had passed in 1.9).  I don't use reflection explicitly, but turning on *warn-on-reflection* generates a bunch of warnings in one of the apps, so I guess it's using reflection to figure out types at runtime.

--

Avi Flax

unread,
Dec 12, 2018, 11:36:12 AM12/12/18
to Clojure
My test suite passes just fine. My project uses Java interop for various things, including watching the filesystem for changes (via JNA), clipboard IO, image processing, etc. Also some spec and core.async in there too.

Alex Miller

unread,
Dec 12, 2018, 11:43:32 AM12/12/18
to clo...@googlegroups.com
Thanks for the feedback!!

Mars0i

unread,
Dec 12, 2018, 5:22:19 PM12/12/18
to Clojure

On Wednesday, December 12, 2018 at 6:42:47 AM UTC-6, Alex Miller wrote:
Thanks for the feedback! I assume the spec one was a bad import statement?

Yes, exactly.

Mark

unread,
Dec 13, 2018, 12:24:49 PM12/13/18
to Clojure
Hi Alex -

Not sure if this is a bug or spec'd behavior.  When combining the reader literal for comments with the reader literal for metadata, I get unexpected behavior:  
(meta #_^:hello [])
yields a compilation error.  I get the same error in 1.9.0.

Alex Miller

unread,
Dec 13, 2018, 1:16:21 PM12/13/18
to clo...@googlegroups.com
Metadata attaches to the form following it, so I would read this (with my Clojure Reader hat on) as:

(                   read list begin
  meta          read symbol
  #_              read and discard next form 
    ^              read meta and form, then apply meta to form
      :hello     read keyword
      []            read vector
    ...             apply :hello as meta to []
  ...               discard [] with metadata  
)                   end list

which would yield a final form: (meta), which should throw an arity exception. So looks correct to me.

--
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 a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/K74chBn4Pis/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark

unread,
Dec 13, 2018, 2:24:05 PM12/13/18
to Clojure
Ah. Makes sense. Thanks

Rostislav Svoboda

unread,
Jan 29, 2019, 3:23:50 PM1/29/19
to clo...@googlegroups.com
Could anybody explain please why I can't get a sample of falses or
quoted nils / falses here?

foo.core> (clojure-version)
"1.10.0"
foo.core> (require '[clojure.spec.gen.alpha :as gen]
'[clojure.spec.alpha :as s])
nil
foo.core> (gen/sample (s/gen #{'nil}))
Error printing return value (ExceptionInfo) at
clojure.test.check.generators/such-that-helper (generators.cljc:320).
Couldn't satisfy such-that predicate after 100 tries.


Other interesting and/or relevant cases are:

foo.core> (gen/sample (s/gen #{'n}))
(n n n n n n n n n n)
foo.core> (gen/sample (s/gen #{true}))
(true true true true true true true true true true)
foo.core> (gen/sample (s/gen #{'true}))
(true true true true true true true true true true)
foo.core> (gen/sample (s/gen #{false}))
Error printing return value (ExceptionInfo) at
clojure.test.check.generators/such-that-helper (generators.cljc:320).
Couldn't satisfy such-that predicate after 100 tries.
foo.core> (gen/sample (s/gen #{'false}))
Error printing return value (ExceptionInfo) at
clojure.test.check.generators/such-that-helper (generators.cljc:320).
Couldn't satisfy such-that predicate after 100 tries.
foo.core> (gen/sample (s/gen #{nil}))
Error printing return value (ExceptionInfo) at
clojure.test.check.generators/such-that-helper (generators.cljc:320).
Couldn't satisfy such-that predicate after 100 tries.


Thanx

Alex Miller

unread,
Jan 29, 2019, 3:40:33 PM1/29/19
to Clojure
Sets are treated as predicate functions which are valid when they produce a logically true value. Sets with logically false values nil or false will fail this check. This is not a spec thing, but a general thing to be aware of in Clojure when using sets as functions.

If you want nils, use (s/gen nil?). 
If you want falses, use (s/gen false?). 
If you want either, the simplest thing is probably (s/gen (s/nilable false?)), but keep in mind that the s/nilable generator is constructed to only produce nils 10% of the time, so you'll get 10% nils, 90% falses.

You could also use the more cumbersome (s/gen (s/nonconforming (s/or :n nil? :f false?))) which should give you about 50/50 mix.

Rostislav Svoboda

unread,
Jan 29, 2019, 5:23:18 PM1/29/19
to clo...@googlegroups.com
Hi Alex,

> Sets are treated as predicate functions which are valid when they produce a logically true value.

So then my question boils down to:
Why is then (boolean (quote nil)) => false and (boolean (quote
anything)) => true?
And this boils down to:
Why a type of quoted symbol (type (quote nil)) is nil and not
clojure.lang.Symbol as is it the case for (type (quote anything))?
Here the source says:
(defn type
"Returns the :type metadata of x, or its Class if none"
{:added "1.0"
:static true}
[x]
(or (get (meta x) :type) (class x)))

And if I put few println's here, I see that in both cases (type (quote
nil)), (type (quote anything)) the input arg x is nil, IOW the
information "the arg x has a type of quoted symbol" is lost here. IOW
the clojure.core/type eagerly reports the type of e.g.:
(type (quote true)) => java.lang.Boolean
(type (quote "foo")) => java.lang.String
(type (quote nil)) => nil
(type (quote 1)) => java.lang.Long
etc. when I expect clojure.lang.Symbol, as for:
(type (quote anything)) => clojure.lang.Symbol

Hmm... *if* this type-hiding is a bug then I guess it's crawling too
deeply to fix it, right? :)
Anyway, thank you for your response, Alex!

Bost
> --
> 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.

Alex Miller

unread,
Jan 29, 2019, 5:45:44 PM1/29/19
to clo...@googlegroups.com
On Tue, Jan 29, 2019 at 4:23 PM Rostislav Svoboda <rostisla...@gmail.com> wrote:
Hi Alex,

> Sets are treated as predicate functions which are valid when they produce a logically true value.

So then my question boils down to:
    Why is then (boolean (quote nil)) => false and (boolean (quote
anything)) => true?

nil, false, and true are the only three special "symbols" that the Clojure reader reads as something other than a symbol. They are read as respectively nil and boolean false and true. nil's "type" is nil (there is no type to represent nil). false and true's type is java.lang.Boolean. Moreover, the false and true values are exactly the static constants java.lang.Boolean/FALSE and java.lang.Boolean/TRUE.

quote's purpose is to read (with the Clojure reader, converting from string to value) but NOT evaluate. For these three values, they all evaluate to themselves, so quote has no effect.

For something like (type (quote anything)), (quote anything) will read the string "anything", and construct the symbol anything, with type clojure.lang.Symbol. The quote prevents evaluation. 

Skipping some important details, every value in Clojure evaluates to itself except for the two special cases of symbols and lists. Symbols evaluate by looking up their associated value in the current namespace. Lists evaluates its elements, then invokes the first element as a function while passing the rest of the elements as arguments.

So, no bug here. Everything is going as planned. :)
 
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/K74chBn4Pis/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

Alex Miller

unread,
Jan 29, 2019, 5:48:58 PM1/29/19
to clo...@googlegroups.com
You can see the special cases of nil, false, and true in the LispReader here if you're curious:


Rostislav Svoboda

unread,
Jan 30, 2019, 12:42:35 PM1/30/19
to clo...@googlegroups.com
Hi Alex,

> You can see the special cases of nil, false, and true in the LispReader here if you're curious:
> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L393-L413

I think it's not the special case of nil, false and true what's
causing me headache. I'm having difficulties wrapping my head around
following:

;; First quoting doesn't change the type:
user=> (= (type 42) (type (quote 42)))
true
;; But consequent quoting changes the type. Ugh ???
user=> (= (type 42) (type (quote (quote 42))))
false

My conclusion: a state has been introduced to the computation.
(presumably by the quote)
Or am I missing here something?

Bost

Alex Miller

unread,
Jan 30, 2019, 1:03:43 PM1/30/19
to clo...@googlegroups.com
On Wed, Jan 30, 2019 at 11:42 AM Rostislav Svoboda <rostisla...@gmail.com> wrote:
Hi Alex,

> You can see the special cases of nil, false, and true in the LispReader here if you're curious:
> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L393-L413

I think it's not the special case of nil, false and true what's
causing me headache. I'm having difficulties wrapping my head around
following:

;; First quoting doesn't change the type:
user=> (= (type 42) (type (quote 42)))
true

(quote 42) is read as (quote 42). It then evaluates the list by invoking quote. quote is a special form that returns the value you pass it, without evaluation, so it evaluates to a long, whose type is java.lang.Long.
 
;; But consequent quoting changes the type. Ugh ???
user=> (= (type 42) (type (quote (quote 42))))
false

(quote (quote 42)) is going to be read by the Clojure reader just like that: as the list (quote (quote 42)). The outer list is evaluated by invoking quote, which is a special form that returns the value, without evaluation. Here, that value is the list (quote 42) - that is, literally a list containing the symbol quote and the long 42. If you check the type of that you'll find it's a list (clojure.lang.IPersistentList). 

user=> (quote (quote 42))
(quote 42)
user=> (type (quote (quote 42)))
clojure.lang.PersistentList
 
My conclusion: a state has been introduced to the computation.
(presumably by the quote)
Or am I missing here something?

You seem to be missing the basic model for how Clojure reads and evaluates source, so I would suggest reading up on that a bit more. 

 


Bost

Rostislav Svoboda

unread,
Jan 31, 2019, 7:50:32 AM1/31/19
to clo...@googlegroups.com
Hi Alex,

> quote is a special form that returns the value you pass it, without evaluation

Aah! "without evaluation" is the key! Now it makes sense. Yea you
mentioned it before already, but it takes twice the effort to undo and
re-comprehend an acquired misconception. Thank you so much!

Would you mind if I add this example to
http://clojuredocs.org/clojure.core/quote ?
It's basically your explanation in the REPL.

;; Quote returns the argument you pass it, without evaluation. So:
;; In the expression `(quote 42)` the argument is the number 42 and...
user> (= (quote 42) 42)
true ;; ... it is returned without any evaluation and...
user> (= (type (quote 42)) (type 42) java.lang.Long)
true ;; ... as expected, without changing it's type.

;; In the expression `(quote (quote 42))` the argument is the list of
two elements
;; `(quote 42)` and...
user> (= (quote (quote 42)) (list (read-string "quote") (read-string "42")))
true ;; ... and it is returned without any evaluation and...
user> (= (type (quote (quote 42))) (type (list "1st-elem" "2nd-elem"))
clojure.lang.PersistentList)
true ;; ... again, without changing it's type.


Bost

Alex Miller

unread,
Jan 31, 2019, 8:36:48 AM1/31/19
to clo...@googlegroups.com
Go for it. Not sure the type stuff is adding anything in the context of quote examples here beyond the other explanation though.

Andy Fingerhut

unread,
Jan 31, 2019, 12:20:17 PM1/31/19
to clo...@googlegroups.com
Sometimes text in comments in ClojureDocs.org examples can be more useful than the examples.  They are effectively longer (unofficial) doc strings.

Andy

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.
Reply all
Reply to author
Forward
0 new messages