             "but got " ~ndims " instead"))))
 
 (defmacro with-check-shape [ndims [m-sym m] & body]
+  "Binds m-sym to m, with a type hinting indicating NDArray. Executes body
+  after running with-check-ndims and with-check-indices. Note that
+  body will have to adhere to the format expected by with-check-indices.
+  See (source with-check-indices) for more details
+  
+  Usage:
+  
+  (with-check-shape 2 [m (mp/construct-matrix (NDArray.) [ [1 2 3]])] row col
+    (println (.get m row col)))
+  
+  Note that explicit type hinting is not required if row and col are symbols,
+  this macro will automatically cast 'row and 'col to long types"
   `(let [~(with-meta m-sym {:tag NDArray}) ~m]
      (with-check-ndims ~ndims ~m-sym
        (with-check-indices ~ndims ~m-sym

        (aget shape dimension-number)))))

(defn- all?
  ([coll]
   (every? true? coll))
  ([f coll]
   (every? true? (mapv f coll))))

(defn- make-index-type-hints [syms]
  (vec
    (mapcat (fn [sym]
              `[~sym (long ~sym)])
            syms)))

(defn- in-bound? [^long idx ^long len]
  (and (>= idx 0) (< idx len)))

(defmacro with-check-indices [ndims m & args]
   (let [row-sym (gensym "row_")
         col-sym (gensym "col_")
         indexes-sym (gensym "indexes_")

             "\n"))))))

(defmacro with-check-ndims [ndims m & body]
  "macro to check the dimensionality of the m against ndims.
  If it is equal, the body will be executed. Otherwise, a runtime error
  will be thrown."
  `(if (= ~ndims (.dimensionality ~m))
     (do ~@body)
     (error
