Adding type hint causes compiler error

2009-07-05 Thread philip.hazel...@gmail.com

Hi,

The following code works as expected:

(import 'javax.imageio.ImageIO 'java.io.File
'java.awt.image.BufferedImage)
(defn bi-get-pixels
  [bi]
  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
nil
(bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
test.png")))

But if *warn-on-reflection* is true, it generates four warnings. If we
try to shut it up with a type hint:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
nil

Exception in thread "main" java.lang.IllegalArgumentException: More
than one matching method found: getPixels (imagio-test.clj:7)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
...
Caused by: java.lang.IllegalArgumentException: More than one matching
method found: getPixels
at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
at clojure.lang.Compiler$InstanceMethodExpr.
(Compiler.java:1159)
at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
810)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
... 34 more

The problem here is that getPixels has three forms: (
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html )
 double[]   getPixels(int x, int y, int w, int h, double[] dArray)
  Returns a double array containing all samples for a
rectangle of pixels, one sample per array element.
 float[]getPixels(int x, int y, int w, int h, float[] fArray)
  Returns a float array containing all samples for a rectangle
of pixels, one sample per array element.
 int[]  getPixels(int x, int y, int w, int h, int[] iArray)
  Returns an int array containing all samples for a rectangle
of pixels, one sample per array element.

In each case, if the final argument is NULL it is ignored, and if not
the array is populated with the return data from the call (generating
an error if it's not large enough).

Is it possible to specify which invocation of getPixels I intend
without passing an array? I've tried putting #^ints in some likely-
looking places, but nil can't be type-hinted and the others seem to
have no effect. I've also tried splitting the .. up:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (let [rast (.getData bi)
#^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
pi))

But this doesn't work either. I could do manual reflection on Raster
to get the correct method and .invoke it, but that seems far more
complicated than necessary. Any other ideas?

-Phil
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Adding type hint causes compiler error

2009-07-05 Thread Mark Triggs

Hi Phil,

Part of me hopes there's a nicer way of doing this, but I was able to
get it working using:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (let [raster (.getData bi)
pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
   (cast (Class/forName "[I") nil))]
(vec pixels)))

Cheers,

Mark


On Jul 5, 10:18 pm, "philip.hazel...@gmail.com"
 wrote:
> Hi,
>
> The following code works as expected:
>
> (import 'javax.imageio.ImageIO 'java.io.File
> 'java.awt.image.BufferedImage)
> (defn bi-get-pixels
>   [bi]
>   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
> (bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
> test.png")))
>
> But if *warn-on-reflection* is true, it generates four warnings. If we
> try to shut it up with a type hint:
>
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
>
> Exception in thread "main" java.lang.IllegalArgumentException: More
> than one matching method found: getPixels (imagio-test.clj:7)
>         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
> ...
> Caused by: java.lang.IllegalArgumentException: More than one matching
> method found: getPixels
>         at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
>         at clojure.lang.Compiler$InstanceMethodExpr.
> (Compiler.java:1159)
>         at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
> 810)
>         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
>         ... 34 more
>
> The problem here is that getPixels has three forms: 
> (http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html)
>  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
>           Returns a double array containing all samples for a
> rectangle of pixels, one sample per array element.
>  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
>           Returns a float array containing all samples for a rectangle
> of pixels, one sample per array element.
>  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
>           Returns an int array containing all samples for a rectangle
> of pixels, one sample per array element.
>
> In each case, if the final argument is NULL it is ignored, and if not
> the array is populated with the return data from the call (generating
> an error if it's not large enough).
>
> Is it possible to specify which invocation of getPixels I intend
> without passing an array? I've tried putting #^ints in some likely-
> looking places, but nil can't be type-hinted and the others seem to
> have no effect. I've also tried splitting the .. up:
>
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (let [rast (.getData bi)
>         #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
>     pi))
>
> But this doesn't work either. I could do manual reflection on Raster
> to get the correct method and .invoke it, but that seems far more
> complicated than necessary. Any other ideas?
>
> -Phil
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Adding type hint causes compiler error

2009-07-05 Thread Kevin Downey

On Sun, Jul 5, 2009 at 5:18 AM,
philip.hazel...@gmail.com wrote:
>
> Hi,
>
> The following code works as expected:
>
> (import 'javax.imageio.ImageIO 'java.io.File
> 'java.awt.image.BufferedImage)
> (defn bi-get-pixels
>  [bi]
>  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
> (bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
> test.png")))
>
> But if *warn-on-reflection* is true, it generates four warnings. If we
> try to shut it up with a type hint:
>
> (defn bi-get-pixels
>  [#^BufferedImage bi]
>  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
>
> Exception in thread "main" java.lang.IllegalArgumentException: More
> than one matching method found: getPixels (imagio-test.clj:7)
>        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
> ...
> Caused by: java.lang.IllegalArgumentException: More than one matching
> method found: getPixels
>        at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
>        at clojure.lang.Compiler$InstanceMethodExpr.
> (Compiler.java:1159)
>        at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
> 810)
>        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
>        ... 34 more
>
> The problem here is that getPixels has three forms: (
> http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html )
>  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
>          Returns a double array containing all samples for a
> rectangle of pixels, one sample per array element.
>  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
>          Returns a float array containing all samples for a rectangle
> of pixels, one sample per array element.
>  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
>          Returns an int array containing all samples for a rectangle
> of pixels, one sample per array element.
>
> In each case, if the final argument is NULL it is ignored, and if not
> the array is populated with the return data from the call (generating
> an error if it's not large enough).
>
> Is it possible to specify which invocation of getPixels I intend
> without passing an array? I've tried putting #^ints in some likely-
> looking places, but nil can't be type-hinted and the others seem to
> have no effect. I've also tried splitting the .. up:
>
> (defn bi-get-pixels
>  [#^BufferedImage bi]
>  (let [rast (.getData bi)
>        #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
>    pi))

you change (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)
to something like (.getPixels rast (int 0) (int 0) (.getWidth bi)
(.getHeight bi) nil)

>
> But this doesn't work either. I could do manual reflection on Raster
> to get the correct method and .invoke it, but that seems far more
> complicated than necessary. Any other ideas?
>
> -Phil
> >
>



-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Adding type hint causes compiler error

2009-07-06 Thread philip.hazel...@gmail.com

On Jul 5, 10:31 pm, Mark Triggs  wrote:
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (let [raster (.getData bi)
>         pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
>                            (cast (Class/forName "[I") nil))]
>     (vec pixels)))

This still generates a single reflection warning, but #^ints before
the cast fixes it. That gave me an idea:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (vec (.. bi (getData)
   (getPixels 0 0 (.getWidth bi) (.getHeight bi)
  #^ints (identity nil)

Which does the right thing with no warnings.

Thanks for the help,

-Phil

>
> Cheers,
>
> Mark
>
> On Jul 5, 10:18 pm, "philip.hazel...@gmail.com"
>
>  wrote:
> > Hi,
>
> > The following code works as expected:
>
> > (import 'javax.imageio.ImageIO 'java.io.File
> > 'java.awt.image.BufferedImage)
> > (defn bi-get-pixels
> >   [bi]
> >   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> > nil
> > (bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
> > test.png")))
>
> > But if *warn-on-reflection* is true, it generates four warnings. If we
> > try to shut it up with a type hint:
>
> > (defn bi-get-pixels
> >   [#^BufferedImage bi]
> >   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> > nil
>
> > Exception in thread "main" java.lang.IllegalArgumentException: More
> > than one matching method found: getPixels (imagio-test.clj:7)
> >         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
> > ...
> > Caused by: java.lang.IllegalArgumentException: More than one matching
> > method found: getPixels
> >         at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
> >         at clojure.lang.Compiler$InstanceMethodExpr.
> > (Compiler.java:1159)
> >         at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
> > 810)
> >         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
> >         ... 34 more
>
> > The problem here is that getPixels has three forms: 
> > (http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html)
> >  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
> >           Returns a double array containing all samples for a
> > rectangle of pixels, one sample per array element.
> >  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
> >           Returns a float array containing all samples for a rectangle
> > of pixels, one sample per array element.
> >  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
> >           Returns an int array containing all samples for a rectangle
> > of pixels, one sample per array element.
>
> > In each case, if the final argument is NULL it is ignored, and if not
> > the array is populated with the return data from the call (generating
> > an error if it's not large enough).
>
> > Is it possible to specify which invocation of getPixels I intend
> > without passing an array? I've tried putting #^ints in some likely-
> > looking places, but nil can't be type-hinted and the others seem to
> > have no effect. I've also tried splitting the .. up:
>
> > (defn bi-get-pixels
> >   [#^BufferedImage bi]
> >   (let [rast (.getData bi)
> >         #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
> >     pi))
>
> > But this doesn't work either. I could do manual reflection on Raster
> > to get the correct method and .invoke it, but that seems far more
> > complicated than necessary. Any other ideas?
>
> > -Phil
>
>
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Adding type hint causes compiler error

2009-07-06 Thread Jarkko Oranen



On Jul 6, 1:26 pm, "philip.hazel...@gmail.com"
 wrote:
> On Jul 5, 10:31 pm, Mark Triggs  wrote:
>
> > (defn bi-get-pixels
> >   [#^BufferedImage bi]
> >   (let [raster (.getData bi)
> >         pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
> >                            (cast (Class/forName "[I") nil))]
> >     (vec pixels)))
>
> This still generates a single reflection warning, but #^ints before
> the cast fixes it. That gave me an idea:
>
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (vec (.. bi (getData)
>            (getPixels 0 0 (.getWidth bi) (.getHeight bi)
>                       #^ints (identity nil)
>
> Which does the right thing with no warnings.
>
> Thanks for the help,
>
> -Phil

(ints nil) might also work
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Adding type hint causes compiler error

2009-07-06 Thread philip.hazel...@gmail.com

On Jul 6, 12:25 pm, Jarkko Oranen  wrote:
> (ints nil) might also work

It does indeed. This seems to be as good a solution as could be hoped
for, thank you.
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---