Reputation: 2312
I would like to understand why I cannot add a return type annotation to this dot product function in clojure.
(defn dot3
"3d vector dot product"
^double [^doubles [u0 u1 u2]
^doubles [v0 v1 v2]]
(+ (* u0 v0) (* u1 v1) (* u2 v2)))
In the log below you can see that an annotation for a subtract works just fine and if I remove the ^double
return type annotation it also works. But, the above code produces an error when called:
user=> (dot3 [4 5 6] [1 2 3])
ClassCastException user$dot3 cannot be cast to clojure.lang.IFn$OOD user/eval3487 (form-init8441686871120943013.clj:1)
Thanks in advance,
--Roger
thunder 13:17:21 clojure> lein version
Leiningen 2.5.0 on Java 1.8.0_25 Java HotSpot(TM) 64-Bit Server VM
thunder 13:17:28 clojure> lein new test123
Generating a project called test123 based on the 'default' template.
The default template is intended for library projects, not applications.
To see other templates (app, plugin, etc), try `lein help new`.
thunder 13:18:09 clojure> cd test123
thunder 13:18:14 test123> lein repl
nREPL server started on port 57240 on host 127.0.0.1 - nrepl://127.0.0.1:57240
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (defn vsub3
#_=> "3d vector subtraction"
#_=> ^doubles [^doubles [u0 u1 u2]
#_=> ^doubles [v0 v1 v2]]
#_=> [(- u0 v0) (- u1 v1) (- u2 v2)])
#'user/vsub3
user=> (vsub3 [4 5 6] [1 2 3])
[3 3 3]
user=> (defn dot3
#_=> "3d vector dot product"
#_=> ^double [^doubles [u0 u1 u2]
#_=> ^doubles [v0 v1 v2]]
#_=> (+ (* u0 v0) (* u1 v1) (* u2 v2)))
#'user/dot3
user=> (dot3 [4 5 6] [1 2 3])
ClassCastException user$dot3 cannot be cast to clojure.lang.IFn$OOD user/eval3487 (form-init8441686871120943013.clj:1)
user=> (defn dot3
#_=> "3d vector dot product"
#_=> [^doubles [u0 u1 u2]
#_=> ^doubles [v0 v1 v2]]
#_=> (+ (* u0 v0) (* u1 v1) (* u2 v2)))
#'user/dot3
user=> (dot3 [4 5 6] [1 2 3])
32
Upvotes: 1
Views: 111
Reputation: 20194
The type annotation you have provided is incompatible with the way you specify your arguments to the function.
Destructuring is preventing the proper code from being compiled. It turns out that this is a bug in current Clojure versions, but will be fixed with the 1.7 release.
The following version works properly:
(defn dot3
"3d vector dot product"
^double [^doubles u
^doubles v]
(+ (* (aget u 0) (aget v 0))
(* (aget u 1) (aget v 1))
(* (aget u 2) (aget v 2))))
user=> (dot3 (double-array [4.0 5.0 6.0]) (double-array [1.0 2.0 3.0]))
32.0
Upvotes: 1