Using :clojure.spec.alpha/invalid inside clojure.core macros throw exception

298 views
Skip to first unread message

Daniel Dinnyes

unread,
Sep 17, 2019, 5:34:04 PM9/17/19
to Clojure
I am using Clojure 1.10.0

Basic example for the issue is:

(let [x 42] :clojure.spec.alpha/invalid)

This will result in the following exception:

2. Unhandled clojure.lang.Compiler$CompilerException
1. Caused by clojure.lang.ExceptionInfo
Call to clojure.core/let did not conform to spec.
    #:clojure.spec.alpha{:problems
                        [{:path [:body],
                          :pred clojure.core/any?,
                          :val :clojure.spec.alpha/invalid,
                          :via [],
                          :in [1]}],
                        :spec
                        #object[clojure.spec.alpha$regex_spec_impl$reify__2509 0x3358b4c5 "clojure.spec.alpha$regex_spec_impl$reify__2509@3358b4c5"],
                        :value ([x 42] :clojure.spec.alpha/invalid),
                        :args ([x 42] :clojure.spec.alpha/invalid)}

Couple of workarounds I've been told:

(let [x 42] (identity :clojure.spec.alpha/invalid))

(def invalid :clojure.spec.alpha/invalid))
(let [x 42] invalid)

Also, interestingly the error is only with the let macro (and some others in clojure.core), special forms (like if) are seemingly unaffected:

(let [x 42] (if (= 42 x) :clojure.spec.alpha/invalid))

Therefore I assume this is unintended, is a bug, and hopefully be fixed in the future.

Regards,
Daniel

Peter Hull

unread,
Sep 18, 2019, 4:06:24 AM9/18/19
to Clojure

On Tuesday, 17 September 2019 22:34:04 UTC+1, Daniel Dinnyes wrote:
(let [x 42] :clojure.spec.alpha/invalid)

That's an interesting one. It's failing the spec on the let's body, which is just 'any?' , so this is initially surprising. 
However s/valid? is implemented as, approximately, (not (invalid? (conform spec value)))
and (conform any? value) evaluates to value
(invalid? v) is implemented as (identical? ::invalid v)
so
(valid? any? ::invalid)
(not (invalid? (conform any? ::invalid)))
(not (identical? ::invalid (conform any? ::invalid)))
(not (identical? ::invalid ::invalid))
(not true)
false

Whether this is a bug or not I can't say - it seems to be an inevitable consequence of the way spec is implemented.
Pete

David Bürgin

unread,
Sep 18, 2019, 3:48:39 PM9/18/19
to clo...@googlegroups.com

Peter Hull

unread,
Sep 18, 2019, 4:11:08 PM9/18/19
to Clojure


On Wednesday, 18 September 2019 20:48:39 UTC+1, David Bürgin wrote:
This is a known issue, see
https://clojure.atlassian.net/projects/CLJ/issues/CLJ-1966
2016!

Andy Fingerhut

unread,
Sep 18, 2019, 6:56:58 PM9/18/19
to clo...@googlegroups.com
I do not know the specifics of this issue, but just because it was reported in 2016 does not necessarily imply that the Clojure spec developers believe it is a bug, rather than something than an unexpected corner case that some spec users wish would behave differently.

Also, Rich Hickey and Alex Miller (and perhaps others I am unaware of) are actively working on developing spec version 2.

Andy

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/6bfbcf08-eaf2-4bd4-ba96-f16f627f4380%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages