ClojureScript

Clojurescript not using custom explain-out when macro invocation fails spec

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    Clojurescript 1.10.516, Clojure 1.10

Description

This is a follow-up to https://dev.clojure.org/jira/browse/CLJS-2913

;; start with
;; clj -Srepro -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojurescript {:mvn/version "1.10.516"}}}' --main cljs.main --repl

(require '[cljs.spec.alpha :as s])
(require '[cljs.spec.test.alpha :as st])
(require '[clojure.core.specs.alpha])

;; instrumenting a function
(s/fdef foobar :args (s/cat :x int?))
(defn foobar [x] x)

(st/instrument)

;; set up an example spec printer
(set! s/*explain-out* (fn [e-data] (println "SPEC ERROR!")))

;;This works great, thanks for fixing! Note custom printer is used.
(foobar "")
;; Execution error - invalid arguments to cljs.user/foobar at (<cljs repl>:1).
;; SPEC ERROR!

;; Expected: should call custom explain-out e.g. output should include "SPEC ERROR"
;; Actual: Uses default explain-out provided by spec
(let "")
;; Execution error - invalid arguments to cljs.analyzer/do-macroexpand-check at (analyzer.cljc:3772).
;; val: "" fails spec: :cljs.core.specs.alpha/bindings at: [:args :bindings] predicate: vector?

Activity

Hide
Thomas Heller added a comment -

Macros are checked and expanded as part of the compilation on the JVM side and the generated JS code is never eval'd in that JVM. It is not possible to change this binding from CLJS directly and would need to be done outside the compilation from CLJ.

Show
Thomas Heller added a comment - Macros are checked and expanded as part of the compilation on the JVM side and the generated JS code is never eval'd in that JVM. It is not possible to change this binding from CLJS directly and would need to be done outside the compilation from CLJ.
Hide
Ben Brinckerhoff added a comment -

That's a really good point. Does this mean that error printing for specs is fundamentally unable to be configured by users for CLJS?

I wonder if there's another approach that would allow me to start up a CLJS REPL with custom error printing when macros don't match the specs.

Show
Ben Brinckerhoff added a comment - That's a really good point. Does this mean that error printing for specs is fundamentally unable to be configured by users for CLJS? I wonder if there's another approach that would allow me to start up a CLJS REPL with custom error printing when macros don't match the specs.
Hide
Michiel Borkent added a comment -

Note that in self-hosted CLJS it does work. E.g. with planck:

cljs.user=> (let "")
Syntax error macroexpanding cljs.core$macros/let at (<cljs repl>:1:1).
SPEC ERROR!
Show
Michiel Borkent added a comment - Note that in self-hosted CLJS it does work. E.g. with planck:
cljs.user=> (let "")
Syntax error macroexpanding cljs.core$macros/let at (<cljs repl>:1:1).
SPEC ERROR!
Hide
Michiel Borkent added a comment - - edited

You can set the custom printer in the JVM as follows:

$ clj -Srepro -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojurescript {:mvn/version "1.10.516"}}}' -e '(set! clojure.spec.alpha/*explain-out* (fn [e-data] (println "SPEC ERROR!")))' -m cljs.main -re node

#object[user$eval1$fn__137 0x65045a87 "user$eval1$fn__137@65045a87"]
ClojureScript 1.10.516
(require '[cljs.spec.alpha :as s])
(require '[cljs.spec.test.alpha :as st])
nil
cljs.user=> nil
cljs.user=> (require '[clojure.core.specs.alpha])
nil
cljs.user=> (let "")
Syntax error macroexpanding cljs.core/let at (<cljs repl>:1:1).
SPEC ERROR!
Show
Michiel Borkent added a comment - - edited You can set the custom printer in the JVM as follows:
$ clj -Srepro -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojurescript {:mvn/version "1.10.516"}}}' -e '(set! clojure.spec.alpha/*explain-out* (fn [e-data] (println "SPEC ERROR!")))' -m cljs.main -re node

#object[user$eval1$fn__137 0x65045a87 "user$eval1$fn__137@65045a87"]
ClojureScript 1.10.516
(require '[cljs.spec.alpha :as s])
(require '[cljs.spec.test.alpha :as st])
nil
cljs.user=> nil
cljs.user=> (require '[clojure.core.specs.alpha])
nil
cljs.user=> (let "")
Syntax error macroexpanding cljs.core/let at (<cljs repl>:1:1).
SPEC ERROR!
Hide
Ben Brinckerhoff added a comment -

Nice! I'll update the Expound documentation to include this technique.

Show
Ben Brinckerhoff added a comment - Nice! I'll update the Expound documentation to include this technique.
Hide
Ben Brinckerhoff added a comment -

I think this means this bug can be closed (as others pointed out, it's an expected behavior in CLJS), but I'll leave it to the maintainers to determine if perhaps there are any considerations here (perhaps documentation changes?). Not sure.

Show
Ben Brinckerhoff added a comment - I think this means this bug can be closed (as others pointed out, it's an expected behavior in CLJS), but I'll leave it to the maintainers to determine if perhaps there are any considerations here (perhaps documentation changes?). Not sure.

People

Vote (1)
Watch (1)

Dates

  • Created:
    Updated: