Welcome! Please see the About page for a little more info on how this works.

+1 vote
in REPL by

Providing an eduction to the repl will print the result in list format:

=> (eduction (map identity) [#'+ 2 3]) (#'clojure.core/+ 2 3)

This should not eval to 5, because an eduction is not a seq. However, when I try, then I expect to get the eduction returned, but instead I get an unexpected error from the reader in the REPL:

=> (eval (eduction (map identity) [#'+ 2 3])) Execution error (IllegalArgumentException) at user$eval183/<clinit> (REPL:1). No matching ctor found for class clojure.core$map$fn__5880

The stack trace for this seems to show that the error occurs in the reader:
`
java.lang.ExceptionInInitializerError

at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at clojure.lang.Compiler$ObjExpr.eval(Compiler.java:5000)
at clojure.lang.Compiler.eval(Compiler.java:7180)
at clojure.lang.Compiler.eval(Compiler.java:7136)
at clojure.core$eval.invokeStatic(core.clj:3202)
at clojure.core$eval.invoke(core.clj:3198)
at user$eval181.invokeStatic(NO_SOURCE_FILE:1)
at user$eval181.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:7181)
at clojure.lang.Compiler.eval(Compiler.java:7136)
at clojure.core$eval.invokeStatic(core.clj:3202)
at clojure.core$eval.invoke(core.clj:3198)
at clojure.main$repl$read_eval_print__9110$fn__9113.invoke(main.clj:437)
at clojure.main$repl$read_eval_print__9110.invoke(main.clj:437)
at clojure.main$repl$fn__9119.invoke(main.clj:458)
at clojure.main$repl.invokeStatic(main.clj:458)
at clojure.main$repl_opt.invokeStatic(main.clj:522)
at clojure.main$main.invokeStatic(main.clj:667)
at clojure.main$main.doInvoke(main.clj:616)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:40)

Caused by: java.lang.IllegalArgumentException: No matching ctor found for class clojure.core$map$fn__5880

at clojure.lang.Reflector.invokeConstructor(Reflector.java:288)
at clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1317)
at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:853)
at clojure.lang.LispReader.read(LispReader.java:285)
at clojure.lang.LispReader.read(LispReader.java:216)
at clojure.lang.LispReader.read(LispReader.java:205)
at clojure.lang.RT.readString(RT.java:1879)
at clojure.lang.RT.readString(RT.java:1874)
at user$eval183.<clinit>(NO_SOURCE_FILE:1)
... 27 more

`

The source code at clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1317) suggests that it's processing a list form where the first element ends with a dot character. This is unexpected

1 Answer

+2 votes
by

In general, not every object is eval-able. When eval'ing something like this, a class gets generated that's something like (fn* [] <eduction-object>). To create the class, that eduction object needs to get stored in the bytecode. In this case, the transducer function can't be directly stored in the bytecode - the Compiler in this case makes a hail mary and does a print-dup to a string like "#=(clojure.core$map$fn__596.)" Then that value is attempting to be read back during the eval but the class is not available with that constructor. That's the read error you're seeing.

It's the same kind of exception you often get when returning objects rather than forms from a macro and in fact you can replicate the error with macros too (this is a common macro error):

(defmacro foo [] (eduction (map identity) [#'+ 2 3]))
(foo)

I don't know that I would expect this to work - as you say, eductions are collections, but not seqs or lists.

by
This makes sense, thank you. I was really curious about the `clojure.core$map$fn__596.` and where it was coming from.
...