Re: I've found a constellation of related bugs in primitive function support when type-hinting *return types*.

2016-08-09 Thread Sean Corfield
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*.

2016-08-09 Thread Alex Miller
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*.

2016-08-09 Thread Timothy Baldridge
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 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.
>



-- 
“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*.

2016-08-09 Thread Fluid Dynamics
=> (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.