Search code examples
clojureread-eval-print-loop

Why does my clojure REPL output gibberish?


I'm prototyping some really basic functionality, but the REPL is outputting totally random stuff.

Just trying to write a function to update a value in a map gives this:

fwd.core=> (fn [step] (update {:x 10 :y 10} :x 20) 20)
#object[fwd.core$eval1593$fn__1594 0x3d2da438 "fwd.core$eval1593$fn__1594@3d2da438"]

Solution

  • Funtions are first class citizens in Clojure. So you defined an anonymous function (mind you, that is close to a no-op here, since you don't hold on to it -- and you had some parens at the wrong place too (see below)) and the REPL printed it for you.

    So this is basically the .toString() representation of the object of your function the way the JVM sees it.

    Sidenote:

    To have a bit better naming for your stacktraces, you can name also anon fns like:

    user=> (fn [step] (update {:x 10 :y 10} :x 20) 20)
    #<Fn@559d19c user/eval8096[fn]>
    user=> (fn my-fancy-name [step] (update {:x 10 :y 10} :x 20) 20)
    #<Fn@451816fd user/eval8105[my_fancy_name]>
    

    edit (there are multiple problems with the function)

    As for the function itself, the inner update is a no-op too, since you are not assigning the result of the update too. The function now always returns 20.

    To call the function, you have to fix the parens:

    user=> ((fn [step] (update {:x 10 :y 10} :x step)) 20)
    Execution error (ClassCastException) at user/eval8105$fn (REPL:1).
    java.lang.Long cannot be cast to clojure.lang.IFn
    

    (The function is in the first place for the surrounding parens, so it will be called.

    This now gives an error since update expects an function - use assoc instead:

    user=> ((fn [step] (assoc {:x 10 :y 10} :x step)) 20)
    {:x 20, :y 10}