Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alter-var-root suggestion doesn't seem to have any effect #109

Closed
orestis opened this issue Jul 6, 2018 · 3 comments
Closed

alter-var-root suggestion doesn't seem to have any effect #109

orestis opened this issue Jul 6, 2018 · 3 comments

Comments

@orestis
Copy link

orestis commented Jul 6, 2018

I'm not sure if this is actually an issue with expound, or if I'm misunderstanding how it's supposed to work.

Desired behaviour

All spec errors are handled by expound's printer, no matter if they are made on the REPL during development or at any other place.

Steps I thought I needed to do

Add the following code to the namespace that contains my -main function, which is also the namespace that CIDER loads by default.

(alter-var-root #'s/*explain-out* (constantly expound/printer))

What actually happens

When I deliberately make a mistake in the REPL, e.g. (defn a 1), I don't see expound's output, only the usual clojure.spec output.

What seems to work

Doing (set! s/*explain-out* expound/printer) interactively after I start/connect to the REPL -- then syntax errors are caught and printed by expound. I'm not sure how this would work for spec errors deep inside the code in other threads.

How does it look like

$ lein repl
nREPL server started on port 62015 on host 127.0.0.1 - nrepl://127.0.0.1:62015
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.9.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16
    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=> (require '[expound.alpha :as expound]
  #_=>          '[clojure.spec.alpha :as s])
nil
user=> (defn a 1) ;; <------------ 1. expected, no expound integration yet

CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/defn did not conform to spec:
In: [1] val: 1 fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector?
In: [1] val: 1 fails spec: :clojure.core.specs.alpha/args+body at: [:args :bs :arity-n :bodies] predicate: (cat :args :clojure.core.specs.alpha/arg-list :body (alt :prepost+body (cat :prepost map? :body (+ any?)) :body (* any?)))
 #:clojure.spec.alpha{:problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val 1, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [1]} {:path [:args :bs :arity-n :bodies], :pred (clojure.spec.alpha/cat :args :clojure.core.specs.alpha/arg-list :body (clojure.spec.alpha/alt :prepost+body (clojure.spec.alpha/cat :prepost clojure.core/map? :body (clojure.spec.alpha/+ clojure.core/any?)) :body (clojure.spec.alpha/* clojure.core/any?))), :val 1, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body], :in [1]}), :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x25f05c8d "clojure.spec.alpha$regex_spec_impl$reify__2436@25f05c8d"], :value (a 1), :args (a 1)}, compiling:(/private/var/folders/yw/d0ggvvcs5lz1fw09p76rl3_r0000gn/T/form-init4153292859114110702.clj:1:1)


user=> (alter-var-root #'s/*explain-out* (constantly expound/printer)) ;; <------------- 2. as suggested by the docs
#object[expound.alpha$printer 0x5a0e22ad "expound.alpha$printer@5a0e22ad"]
user=> (defn a 1)
CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/defn did not conform to spec:
In: [1] val: 1 fails spec: :clojure.core.specs.alpha/arg-list at: [:args :bs :arity-1 :args] predicate: vector?
In: [1] val: 1 fails spec: :clojure.core.specs.alpha/args+body at: [:args :bs :arity-n :bodies] predicate: (cat :args :clojure.core.specs.alpha/arg-list :body (alt :prepost+body (cat :prepost map? :body (+ any?)) :body (* any?)))
 #:clojure.spec.alpha{:problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val 1, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [1]} {:path [:args :bs :arity-n :bodies], :pred (clojure.spec.alpha/cat :args :clojure.core.specs.alpha/arg-list :body (clojure.spec.alpha/alt :prepost+body (clojure.spec.alpha/cat :prepost clojure.core/map? :body (clojure.spec.alpha/+ clojure.core/any?)) :body (clojure.spec.alpha/* clojure.core/any?))), :val 1, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body], :in [1]}), :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x25f05c8d "clojure.spec.alpha$regex_spec_impl$reify__2436@25f05c8d"], :value (a 1), :args (a 1)}, compiling:(/private/var/folders/yw/d0ggvvcs5lz1fw09p76rl3_r0000gn/T/form-init4153292859114110702.clj:1:1)



user=> (set! s/*explain-out* expound/printer) ;; <------------ 3. this seems to work
#object[expound.alpha$printer 0x5a0e22ad "expound.alpha$printer@5a0e22ad"]
user=> (defn a 1)

CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/defn did not conform to spec:
-- Spec failed --------------------

  (... 1)
       ^

should satisfy

  vector?

or

  (clojure.spec.alpha/cat
   :args
   :clojure.core.specs.alpha/arg-list
   :body
   (clojure.spec.alpha/alt
    :prepost+body
    (clojure.spec.alpha/cat
     :prepost
     map?
     :body
     (clojure.spec.alpha/+ any?))
    :body
    (clojure.spec.alpha/* any?)))

-- Relevant specs -------

:clojure.core.specs.alpha/arg-list:
  (clojure.spec.alpha/and
   clojure.core/vector?
   (clojure.spec.alpha/cat
    :args
    (clojure.spec.alpha/* :clojure.core.specs.alpha/binding-form)
    :varargs
    (clojure.spec.alpha/?
     (clojure.spec.alpha/cat
      :amp
      #{'&}
      :form
      :clojure.core.specs.alpha/binding-form))))
:clojure.core.specs.alpha/args+body:
  (clojure.spec.alpha/cat
   :args
   :clojure.core.specs.alpha/arg-list
   :body
   (clojure.spec.alpha/alt
    :prepost+body
    (clojure.spec.alpha/cat
     :prepost
     clojure.core/map?
     :body
     (clojure.spec.alpha/+ clojure.core/any?))
    :body
    (clojure.spec.alpha/* clojure.core/any?)))
:clojure.core.specs.alpha/defn-args:
  (clojure.spec.alpha/cat
   :name
   clojure.core/simple-symbol?
   :docstring
   (clojure.spec.alpha/? clojure.core/string?)
   :meta
   (clojure.spec.alpha/? clojure.core/map?)
   :bs
   (clojure.spec.alpha/alt
    :arity-1
    :clojure.core.specs.alpha/args+body
    :arity-n
    (clojure.spec.alpha/cat
     :bodies
     (clojure.spec.alpha/+
      (clojure.spec.alpha/spec :clojure.core.specs.alpha/args+body))
     :attr
     (clojure.spec.alpha/? clojure.core/map?))))

-------------------------
Detected 1 error
 #:clojure.spec.alpha{:problems ({:path [:args :bs :arity-1 :args], :pred clojure.core/vector?, :val 1, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/arg-list :clojure.core.specs.alpha/arg-list], :in [1]} {:path [:args :bs :arity-n :bodies], :pred (clojure.spec.alpha/cat :args :clojure.core.specs.alpha/arg-list :body (clojure.spec.alpha/alt :prepost+body (clojure.spec.alpha/cat :prepost clojure.core/map? :body (clojure.spec.alpha/+ clojure.core/any?)) :body (clojure.spec.alpha/* clojure.core/any?))), :val 1, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/args+body :clojure.core.specs.alpha/args+body], :in [1]}), :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x25f05c8d "clojure.spec.alpha$regex_spec_impl$reify__2436@25f05c8d"], :value (a 1), :args (a 1)}, compiling:(/private/var/folders/yw/d0ggvvcs5lz1fw09p76rl3_r0000gn/T/form-init4153292859114110702.clj:1:1)
user=>

Project.clj

(defproject exp-bug "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.9.0"]
                 [expound "0.7.1"]])
@j-cr
Copy link

j-cr commented Jul 21, 2018

IIRC, nrepl binds a number of vars including s/*explain-out*, so you need to set! the var in order for it to work in the repl

@bhb
Copy link
Owner

bhb commented Jul 23, 2018

@orestis thanks for reporting this! This is a common source of confusion, so I should either improve the documentation or add a function that sets up everything correctly.

Can you provide more detail about how you want to use expound in other threads? In my quick test, set! worked fine, but I suspect your use case is different. I’d like to make sure my instructions cover your case.

https://gist.github.com/bhb/910f718e2da57793bc0f5817f006f28a

@bhb
Copy link
Owner

bhb commented Dec 15, 2018

@orestis I've added some documentation about this in #142. Please feel free to reopen if you run into a case that isn't explained well in the FAQ.

@bhb bhb closed this as completed Dec 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants