Re: I've found a constellation of related bugs in primitive function support when type-hinting *return types*.
I can’t reproduce any of this on Clojure 1.9.0 Alpha 10 – it all works exactly as expected. On 8/9/16, 2:50 PM, "Fluid Dynamics"wrote: => (defn foo [x] (doto (double-array 1) (aset 0 x))) => [(foo 3.0) (type (foo 3.0))] [[3.0] [D] ; As expected, a double array with the value passed in. ; Maybe a good idea to hint this function as always returning a double array. => (defn foo ^doubles [x] (doto (double-array 1) (aset 0 x))) Reflection warning, NO_SOURCE_PATH:1:24 - call to aset can't be resolved. => [(foo 3.0) (type (foo 3.0))] [[3.0] [D] ; Hmm, that reflection is not going to help performance any. (Why wasn't it occurring before?) Maybe hint x as well? => (defn foo ^doubles [^double x] (doto (double-array 1) (aset 0 x))) => [(foo 3.0) (type (foo 3.0))] AbstractMethodError Method user$foo.invokePrim(D)Ljava/lang/Object; is abstract ; What the f---?! => (defn foo [^double x] (doto (double-array 1) (aset 0 x))) => [(foo 3.0) (type (foo 3.0))] [[3.0] [D] ; OK, now at least we have a primitive function taking a double, and not generating a reflection warning, though it's expected to return generic objects. Why don't we wrap it with a *second* function that knows it's really returning a double array, and hope the JIT inlines it so we won't get doubled function call overhead? => (defn bar [^double x] (foo x)) => (bar 3.0) [3.0] ; So far, so good. Now add the return type hint to bar: => (defn bar ^doubles [^double x] (foo x)) => (bar 3.0) AbstractMethodError Method user$bar.invokePrim(D)Ljava/lang/Object; is abstract ; WHAT?!?!?!?!?! ; IMPOSSIBLE ; How can changing bar's return type hint introduce the bug back into foo when foo was working earlier and we didn't recompile foo?!?!?!?!?! ; WTF WTF WTF!!! ; ; OK so what if we hint foo as a primitive function that takes a double and returns an object? => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (f x)) => (bar foo 3.0) AbstractMethodError Method user$bar.invokePrim(Ljava/lang/Object;D)Ljava/lang/Object; is abstract ; Even more impossible! (foo 3.0) continues to work, so the function is intact in memory, but passing it to bar magically breaks it?! ; OK, what if we explicitly invoke foo's correct method, which takes a double and returns an object? => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (.invokePrim f x)) => (bar foo 3.0) AbstractMethodError Method user$bar.invokePrim(Ljava/lang/Object;D)Ljava/lang/Object; is abstract ; Still not working! ; OK, let's hide it *another level deep* => (defn bar [^clojure.lang.IFn$DO f] => (fn ^doubles [^double x] => (f x))) => ((bar foo) 3.0) NoSuchMethodError clojure.lang.IFn$DO.invokePrim(D)[D user$bar$fn__9962.invoke (NO_SOURCE_PATH:-1) ; ?!?!?!?!?!?!??!?!?!?!?! ; Time to give up and file a bug report. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: I've found a constellation of related bugs in primitive function support when type-hinting *return types*.
What Clojure version are you using? On Tuesday, August 9, 2016 at 5:01:21 PM UTC-5, Fluid Dynamics wrote: > > => (defn foo [x] (doto (double-array 1) (aset 0 x))) > => [(foo 3.0) (type (foo 3.0))] > [[3.0] [D] ; As expected, a double array with the value passed in. > ; Maybe a good idea to hint this function as always returning a double > array. > => (defn foo ^doubles [x] (doto (double-array 1) (aset 0 x))) > Reflection warning, NO_SOURCE_PATH:1:24 - call to aset can't be resolved. > I don't see that. I'm guessing you did (set! *warn-on-reflection* true) prior to the start of this? With reflection warnings on, I see: Reflection warning, NO_SOURCE_PATH:5:24 - call to static method aset on clojure.lang.RT can't be resolved (argument types: [D, int, unknown). (Note that this message has improved so I am guessing you're using an older version). The reflection part here is the "unknown" bit - basically the type of x. > => [(foo 3.0) (type (foo 3.0))] > [[3.0] [D] > ; Hmm, that reflection is not going to help performance any. (Why wasn't > it occurring before?) Maybe hint x as well? > => (defn foo ^doubles [^double x] (doto (double-array 1) (aset 0 x))) > => [(foo 3.0) (type (foo 3.0))] > AbstractMethodError Method user$foo.invokePrim(D)Ljava/lang/Object; is > abstract > ; What the f---?! > I don't see this on Clojure 1.8. > => (defn foo [^double x] (doto (double-array 1) (aset 0 x))) > => [(foo 3.0) (type (foo 3.0))] > [[3.0] [D] > ; OK, now at least we have a primitive function taking a double, and not > generating a reflection warning, though it's expected to return generic > objects. Why don't we wrap it with a *second* function that knows it's > really returning a double array, and hope the JIT inlines it so we won't > get doubled function call overhead? > => (defn bar [^double x] (foo x)) > => (bar 3.0) > [3.0] > I see the return of a double array here (prob changes in printing since whatever version you're on): #object["[D" 0x49c2faae "[D@49c2faae"] > ; So far, so good. Now add the return type hint to bar: > => (defn bar ^doubles [^double x] (foo x)) > => (bar 3.0) > AbstractMethodError Method user$bar.invokePrim(D)Ljava/lang/Object; is > abstract > I don't see this in current Clojure. I just see the returned double array as before. > ; WHAT?!?!?!?!?! > ; IMPOSSIBLE > ; How can changing bar's return type hint introduce the bug back into foo > when foo was working earlier and we didn't recompile foo?!?!?!?!?! > ; WTF WTF WTF!!! > ; > ; OK so what if we hint foo as a primitive function that takes a double > and returns an object? > => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (f x)) > => (bar foo 3.0) > AbstractMethodError Method > user$bar.invokePrim(Ljava/lang/Object;D)Ljava/lang/Object; is abstract > You shouldn't do this, but it also does not fail for me on 1.8. > ; Even more impossible! (foo 3.0) continues to work, so the function is > intact in memory, but passing it to bar magically breaks it?! > ; OK, what if we explicitly invoke foo's correct method, which takes a > double and returns an object? > => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (.invokePrim f x)) > => (bar foo 3.0) > AbstractMethodError Method > user$bar.invokePrim(Ljava/lang/Object;D)Ljava/lang/Object; is abstract > Still works on 1.8. > ; Still not working! > ; OK, let's hide it *another level deep* > => (defn bar [^clojure.lang.IFn$DO f] > => (fn ^doubles [^double x] > => (f x))) > => ((bar foo) 3.0) > NoSuchMethodError clojure.lang.IFn$DO.invokePrim(D)[D > user$bar$fn__9962.invoke (NO_SOURCE_PATH:-1) > Still doesn't fail. > ; ?!?!?!?!?!?!??!?!?!?!?! > ; Time to give up and file a bug report. > Please try Clojure 1.8. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: I've found a constellation of related bugs in primitive function support when type-hinting *return types*.
It's impossible to read what you've written here. Can you give us a minimum failing use case? Thanks. Timothy On Tue, Aug 9, 2016 at 3:50 PM, Fluid Dynamicswrote: > => (defn foo [x] (doto (double-array 1) (aset 0 x))) > => [(foo 3.0) (type (foo 3.0))] > [[3.0] [D] ; As expected, a double array with the value passed in. > ; Maybe a good idea to hint this function as always returning a double > array. > => (defn foo ^doubles [x] (doto (double-array 1) (aset 0 x))) > Reflection warning, NO_SOURCE_PATH:1:24 - call to aset can't be resolved. > => [(foo 3.0) (type (foo 3.0))] > [[3.0] [D] > ; Hmm, that reflection is not going to help performance any. (Why wasn't > it occurring before?) Maybe hint x as well? > => (defn foo ^doubles [^double x] (doto (double-array 1) (aset 0 x))) > => [(foo 3.0) (type (foo 3.0))] > AbstractMethodError Method user$foo.invokePrim(D)Ljava/lang/Object; is > abstract > ; What the f---?! > => (defn foo [^double x] (doto (double-array 1) (aset 0 x))) > => [(foo 3.0) (type (foo 3.0))] > [[3.0] [D] > ; OK, now at least we have a primitive function taking a double, and not > generating a reflection warning, though it's expected to return generic > objects. Why don't we wrap it with a *second* function that knows it's > really returning a double array, and hope the JIT inlines it so we won't > get doubled function call overhead? > => (defn bar [^double x] (foo x)) > => (bar 3.0) > [3.0] > ; So far, so good. Now add the return type hint to bar: > => (defn bar ^doubles [^double x] (foo x)) > => (bar 3.0) > AbstractMethodError Method user$bar.invokePrim(D)Ljava/lang/Object; is > abstract > ; WHAT?!?!?!?!?! > ; IMPOSSIBLE > ; How can changing bar's return type hint introduce the bug back into foo > when foo was working earlier and we didn't recompile foo?!?!?!?!?! > ; WTF WTF WTF!!! > ; > ; OK so what if we hint foo as a primitive function that takes a double > and returns an object? > => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (f x)) > => (bar foo 3.0) > AbstractMethodError Method user$bar.invokePrim(Ljava/ > lang/Object;D)Ljava/lang/Object; is abstract > ; Even more impossible! (foo 3.0) continues to work, so the function is > intact in memory, but passing it to bar magically breaks it?! > ; OK, what if we explicitly invoke foo's correct method, which takes a > double and returns an object? > => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (.invokePrim f x)) > => (bar foo 3.0) > AbstractMethodError Method user$bar.invokePrim(Ljava/ > lang/Object;D)Ljava/lang/Object; is abstract > ; Still not working! > ; OK, let's hide it *another level deep* > => (defn bar [^clojure.lang.IFn$DO f] > => (fn ^doubles [^double x] > => (f x))) > => ((bar foo) 3.0) > NoSuchMethodError clojure.lang.IFn$DO.invokePrim(D)[D > user$bar$fn__9962.invoke (NO_SOURCE_PATH:-1) > ; ?!?!?!?!?!?!??!?!?!?!?! > ; Time to give up and file a bug report. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
I've found a constellation of related bugs in primitive function support when type-hinting *return types*.
=> (defn foo [x] (doto (double-array 1) (aset 0 x))) => [(foo 3.0) (type (foo 3.0))] [[3.0] [D] ; As expected, a double array with the value passed in. ; Maybe a good idea to hint this function as always returning a double array. => (defn foo ^doubles [x] (doto (double-array 1) (aset 0 x))) Reflection warning, NO_SOURCE_PATH:1:24 - call to aset can't be resolved. => [(foo 3.0) (type (foo 3.0))] [[3.0] [D] ; Hmm, that reflection is not going to help performance any. (Why wasn't it occurring before?) Maybe hint x as well? => (defn foo ^doubles [^double x] (doto (double-array 1) (aset 0 x))) => [(foo 3.0) (type (foo 3.0))] AbstractMethodError Method user$foo.invokePrim(D)Ljava/lang/Object; is abstract ; What the f---?! => (defn foo [^double x] (doto (double-array 1) (aset 0 x))) => [(foo 3.0) (type (foo 3.0))] [[3.0] [D] ; OK, now at least we have a primitive function taking a double, and not generating a reflection warning, though it's expected to return generic objects. Why don't we wrap it with a *second* function that knows it's really returning a double array, and hope the JIT inlines it so we won't get doubled function call overhead? => (defn bar [^double x] (foo x)) => (bar 3.0) [3.0] ; So far, so good. Now add the return type hint to bar: => (defn bar ^doubles [^double x] (foo x)) => (bar 3.0) AbstractMethodError Method user$bar.invokePrim(D)Ljava/lang/Object; is abstract ; WHAT?!?!?!?!?! ; IMPOSSIBLE ; How can changing bar's return type hint introduce the bug back into foo when foo was working earlier and we didn't recompile foo?!?!?!?!?! ; WTF WTF WTF!!! ; ; OK so what if we hint foo as a primitive function that takes a double and returns an object? => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (f x)) => (bar foo 3.0) AbstractMethodError Method user$bar.invokePrim(Ljava/lang/Object;D)Ljava/lang/Object; is abstract ; Even more impossible! (foo 3.0) continues to work, so the function is intact in memory, but passing it to bar magically breaks it?! ; OK, what if we explicitly invoke foo's correct method, which takes a double and returns an object? => (defn bar ^doubles [^clojure.lang.IFn$DO f ^double x] (.invokePrim f x)) => (bar foo 3.0) AbstractMethodError Method user$bar.invokePrim(Ljava/lang/Object;D)Ljava/lang/Object; is abstract ; Still not working! ; OK, let's hide it *another level deep* => (defn bar [^clojure.lang.IFn$DO f] => (fn ^doubles [^double x] => (f x))) => ((bar foo) 3.0) NoSuchMethodError clojure.lang.IFn$DO.invokePrim(D)[D user$bar$fn__9962.invoke (NO_SOURCE_PATH:-1) ; ?!?!?!?!?!?!??!?!?!?!?! ; Time to give up and file a bug report. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.