Search code examples
clojure

Use of make-array


Building a function in Clojure that returns a 2D matrix with all initial values set to zero, for which I intended to use make-array.

(def m (make-array Integer/TYPE 3 3))

however what I get in return isn't the instance of the array (expected [[0 0 0] [0 0 0] [0 0 0]]) but got #object["[[I" 0x10014d2 "[[I@10014d2"]. I can properly access values in the m matrix via (get-in) and change them using (assoc-in), but ultimately I need to return the matrix, not the type of the object. Is there a way to do it?

PD. I'm new to stackoverflow and to Clojure.


Solution

  • It is really a matter of how your REPL is configured to display values. I get something similar in my REPL (launched with lein repl):

    user=> (def m (make-array Integer/TYPE 3 3))
    #'user/m
    user=> m
    #object["[[I" 0x4d632ca0 "[[I@4d632ca0"]
    

    However, closer inspection shows that m is a Java array of Java integer arrays:

    user=> (-> m class)
    [[I
    user=> (-> m class .getComponentType)
    [I
    user=> (-> m class .getComponentType .getComponentType)
    int
    

    Based on this answer we can configure the repl to display values differently:

    user=> (clojure.main/repl :print pprint)
    user=> m
    [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    

    But you may consider representing your matrix with vectors because they are immutable:

    user=> (def m2 (reduce #(vec (repeat %2 %1)) 0 [3 3]))
    #'user/m2
    user=> m2
    [[0 0 0] [0 0 0] [0 0 0]]