Adding type hint causes compiler error
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
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
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
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
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
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 -~--~~~~--~~--~--~---