funcool / cats

Category Theory and Algebraic abstractions for Clojure and ClojureScript.
http://funcool.github.io/cats/latest/
BSD 2-Clause "Simplified" License
940 stars 66 forks source link

Error printing return value of try monad in REPL #232

Open mwelt opened 5 years ago

mwelt commented 5 years ago

Using cats in CIDER + nREPL yields:

;; CIDER 0.22.0snapshot (package: 20190326.1752), nREPL 0.6.0
;; Clojure 1.10.0, Java 1.8.0_201

user> (require '[cats.monad.exception :as exc])
(exc/try-on 1)
nilError printing return value (IllegalArgumentException) at clojure.lang.MultiFn/findAndCacheBestMethod (MultiFn.java:179).
Multiple methods in multimethod 'simple-dispatch' match dispatch value: class cats.monad.exception.Success -> interface clojure.lang.IDeref and interface clojure.lang.IPersistentMap, and neither is preferred
alexanderjamesking commented 5 years ago

I see this too:

user> (require '[cats.monad.either :as either])
nil
user> (either/left "foo")
IllegalArgumentException Multiple methods in multimethod 'simple-dispatch' match dispatch value: class cats.monad.either.Left -> interface clojure.lang.IPersistentMap and interface clojure.lang.IDeref, and neither is preferred  clojure.lang.MultiFn.findAndCacheBestMethod (MultiFn.java:178)
user> (either/right "foo")
IllegalArgumentException Multiple methods in multimethod 'simple-dispatch' match dispatch value: class cats.monad.either.Right -> interface clojure.lang.IPersistentMap and interface clojure.lang.IDeref, and neither is preferred  clojure.lang.MultiFn.findAndCacheBestMethod (MultiFn.java:178)
mwelt commented 5 years ago

After a little more trial and error if found the following.

It works if you dereference the values with "@" like so:

user> @(exc/try-on 1)
1
user> @(exc/try-on (/ 1 0))
ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:163)

I guess its intended that way.

dchelimsky commented 4 years ago

This is a side-effect of adding IDeref to a defrecord in order to support ref-like syntax for unwrapping monadic values.

I don't know if this is a good solution, but I was able to get around it like this:

user> (defmethod clojure.pprint/simple-dispatch cats.monad.exception.Failure [f]
  (pr f))
#multifn[simple-dispatch 0x12668380]
user> @(#'cats.monad.exception/->Failure (ex-info "oops" {}))
Execution error (ExceptionInfo) at user/eval15705 (form-init5393967084257662022.clj:136).
oops

This is what printed to the *cider-error* buffer:

1. Unhandled clojure.lang.ExceptionInfo
   oops
   {}
                      REPL:  136  user/eval15705
                      REPL:    1  user/eval15705
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  368  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
                  AFn.java:   22  clojure.lang.AFn/run
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  834  java.lang.Thread/run