Re: strange typecheck error
Many thanks to you Bill - it works! .Bill Smith at Fri, 1 Jan 2010 10:44:37 -0800 (PST) wrote: .S Happy New Year to you, Alex. .S I reproduced the problem as follows: .S user= (loop [x (byte 0) count 0] .S (if ( count 10) (recur 0 (inc count .S java.lang.RuntimeException: java.lang.IllegalArgumentException: recur .S arg for primitive local: x must be matching primitive (NO_SOURCE_FILE: .S 57) .S user= .S If the compiler detects that a loop binding evaluates to a primitive, .S it insists that the corresponding recur argument be a reducible to a .S primitive as well. You can short-circuit that logic with a type hint, .S like this: .S user= (loop [x #^Object (byte 0)] .S (if ( x 10) (recur (inc x .S nil .S user= .S It's ugly but it works. If you change line 65 in your example from .S char (.read ireader)] to char #^Object (.read ireader)], the .S compile error should go away. The example in my previous posting .S didn't have that problem because 0 by itself is an Integer object, not .S an int primitive. -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/http://xtalk.msk.su/~ott/ http://alexott-ru.blogspot.com/ -- 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: strange typecheck error
Happy New Year to you, Alex. I reproduced the problem as follows: user= (loop [x (byte 0) count 0] (if ( count 10) (recur 0 (inc count java.lang.RuntimeException: java.lang.IllegalArgumentException: recur arg for primitive local: x must be matching primitive (NO_SOURCE_FILE: 57) user= If the compiler detects that a loop binding evaluates to a primitive, it insists that the corresponding recur argument be a reducible to a primitive as well. You can short-circuit that logic with a type hint, like this: user= (loop [x #^Object (byte 0)] (if ( x 10) (recur (inc x nil user= It's ugly but it works. If you change line 65 in your example from char (.read ireader)] to char #^Object (.read ireader)], the compile error should go away. The example in my previous posting didn't have that problem because 0 by itself is an Integer object, not an int primitive. On Dec 31 2009, 12:45 pm, Alex Ott alex...@gmail.com wrote: Hello Bill .Bill Smith at Thu, 31 Dec 2009 09:20:16 -0800 (PST) wrote: .S I tried out your example with a couple of files and it appeared to .S work. Is it supposed to fail, or is this an example of what you had .S to do to work around the problem you mentioned? Yes, this is working variant if you'll replace '(.read ireader)' in 'recur' on line 80 with 'res', then it will fail. .S It's certainly ok for a function to return different data types. I .S guess the simplest example of that would be the identity function. thanks for identity example, i'll look to it P.S. Happy New Year to you, and rest of clojure community -- With best wishes, Alex Ott, MBAhttp://alexott.blogspot.com/ http://xtalk.msk.su/~ott/http://alexott-ru.blogspot.com/ -- 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: strange typecheck error
Nikolay Petrov at Wed, 30 Dec 2009 18:13:13 + wrote: NP Is process char returns char or String? I want to return either String, either Integer, depending on condition... -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/http://xtalk.msk.su/~ott/ http://alexott-ru.blogspot.com/ -- 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: strange typecheck error
Hello I'm sorry, i tried to prepare shorter example, and mixed loops recurs. Full example is attached. This is code, that implements something like 'strings' command on Unixes, but for UTF-8 encoding The problem is, that i need to return from function 'read-utf-char', either String, either Integer, depending on condition. Or this is not allowed by Clojure? I mostly programming in Scheme, that allows such tricks .Bill Smith at Wed, 30 Dec 2009 11:28:54 -0800 (PST) wrote: .S Sorry, I'm confused by the code sample. I see several loops but no .S corresponding recurs. -- 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(ns test1 (:import (java.io File InputStream FileInputStream InputStreamReader)) (:import (java.nio.charset Charset)) (:use [clojure.contrib.def :only (defvar-)]) ) (defn is-ascii? [#^Integer n] (or (and (= n 32) (= n 126)) ;; 0x20-0x7e (== n 9) ;; \t, \n, \v, \f, \r (== n 10) (== n 13) )) (defvar- utf-8-locale (Charset/forName UTF-8)) (defvar- latin-1-locale (Charset/forName ISO-8859-1)) ;; (defn- clear-strbuf [#^StringBuffer strbuf] (.delete strbuf 0 (.length strbuf))) (defn- append-from-strbuf [lst #^StringBuffer strbuf #^Integer n] (if (= (.length strbuf) n) (let [str (.toString strbuf)] (clear-strbuf strbuf) (cons str lst)) (do (clear-strbuf strbuf) lst))) (defn- detect-utf-n [#^Integer char] (cond ( char 0xC0) 0 (= (bit-and char 0xE0) 0xC0) 1 ;; 2-bytes seq (= (bit-and char 0xF0) 0xE0) 2 ;; 3-bytes seq (= (bit-and char 0xF8) 0xF0) 3 ;; 4-bytes seq :else 0)) (defn- read-utf-char [#^InputStreamReader istream #^Integer char #^Integer utf-n] (let [barr (make-array Byte/TYPE (+ 1 utf-n))] (aset-byte barr 0 char) ;; loop over rest of characters, checking their validity (loop [cnt 0] (if (= cnt utf-n) (String. barr utf-8-locale) ;; if we read all characters (let [ch (.read istream) ;; read rest of characters ncnt (+ 1 cnt)] (if (= (bit-and ch 0xC0) 0x80) (do (aset-byte barr ncnt ch) (recur ncnt)) ch)) (defn- extract-text-utf-8 Performs text extraction for UTF-8 encoding [#^InputStream istream #^Integer n ] (let [#^InputStreamReader ireader (new InputStreamReader istream latin-1-locale) #^StringBuffer strbuf (new StringBuffer) ] (loop [lst '() char (.read ireader)] (let [utf-n (detect-utf-n char)] (cond (== char -1) (reverse (append-from-strbuf lst strbuf n)) (is-ascii? char) (do (.append strbuf (Character/toChars char)) (recur lst (.read ireader))) ( utf-n 0) (let [res (read-utf-char ireader char utf-n)] (if (string? res) (do (.append strbuf res) (recur lst (.read ireader))) ;; TODO: don't forget to fix this (.read istream) - res issue (recur (append-from-strbuf lst strbuf n) (.read ireader :else (recur (append-from-strbuf lst strbuf n) (.read ireader))) (defn analyse-stream Performs analysis of given file and extract text in given charset [#^InputStream stream #^Integer n #^String locale-name] (extract-text-utf-8 stream n)) (defn analyse-file Performs analysis of given file and extract text in given charset [#^File file #^Integer n #^String locale-name] (analyse-stream (new FileInputStream file) n locale-name)) -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/http://xtalk.msk.su/~ott/ http://alexott-ru.blogspot.com/
Re: strange typecheck error
I tried out your example with a couple of files and it appeared to work. Is it supposed to fail, or is this an example of what you had to do to work around the problem you mentioned? It's certainly ok for a function to return different data types. I guess the simplest example of that would be the identity function. user= (identity 5) 5 user= (identity x) x Here is another one: user= (defn return-string-or-num [flag] (if flag x 0)) #'user/return-string-or-num user= (return-string-or-num :t) x user= (return-string-or-num nil) 0 Here is an example of using that function with recur: user= (loop [x 0 count 0] (println x= x x is a (class x) count= count) (if ( count 10) (recur (return-string-or-num (even? count)) (inc count x= 0 x is a java.lang.Integer count= 0 x= x x is a java.lang.String count= 1 x= 0 x is a java.lang.Integer count= 2 x= x x is a java.lang.String count= 3 x= 0 x is a java.lang.Integer count= 4 x= x x is a java.lang.String count= 5 x= 0 x is a java.lang.Integer count= 6 x= x x is a java.lang.String count= 7 x= 0 x is a java.lang.Integer count= 8 x= x x is a java.lang.String count= 9 x= 0 x is a java.lang.Integer count= 10 nil user= -- 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: strange typecheck error
Hello Bill .Bill Smith at Thu, 31 Dec 2009 09:20:16 -0800 (PST) wrote: .S I tried out your example with a couple of files and it appeared to .S work. Is it supposed to fail, or is this an example of what you had .S to do to work around the problem you mentioned? Yes, this is working variant if you'll replace '(.read ireader)' in 'recur' on line 80 with 'res', then it will fail. .S It's certainly ok for a function to return different data types. I .S guess the simplest example of that would be the identity function. thanks for identity example, i'll look to it P.S. Happy New Year to you, and rest of clojure community -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/http://xtalk.msk.su/~ott/ http://alexott-ru.blogspot.com/ -- 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: strange typecheck error
Is process char returns char or String? --Original Message-- From: Alex Ott Sender: clojure@googlegroups.com To: Clojure ML ReplyTo: clojure@googlegroups.com Subject: strange typecheck error Sent: Dec 30, 2009 19:53 Hello all I have strange problem with type inference in Clojure. I have following code (simplified version of real code), (defn- process-char [#^InputStream istream] (let [ch (.read istream)] (if (= ch 10) AAA ch))) (defn- process-text [#^InputStream istream] (loop [char (.read istream)] (let [result (process-char istream)] (cond ;; .. some additional conditions (string? result) (loop (.read istream)) (number? result) (loop result) ... Main idea, that in some function, i read characters in sequence, and check their values, and in some conditions, i need to re-submit already readed character into loop, but when i use code above, i get following error: java.lang.IllegalArgumentException: recur arg for primitive local: char must be matching primitive [Thrown class java.lang.RuntimeException] but if i replace (loop result) with (.read istream), then it works without any problems I checked type of result, and it's Integer - same type, that 'char' var in loop will get after reading from stream. If need, i can submit somebody full test case -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/http://xtalk.msk.su/~ott/ http://alexott-ru.blogspot.com/ -- 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 Sent from my BlackBerry® wireless device -- 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: strange typecheck error
Sorry, I'm confused by the code sample. I see several loops but no corresponding recurs. On Dec 30, 11:53 am, Alex Ott alex...@gmail.com wrote: Hello all I have strange problem with type inference in Clojure. I have following code (simplified version of real code), (defn- process-char [#^InputStream istream] (let [ch (.read istream)] (if (= ch 10) AAA ch))) (defn- process-text [#^InputStream istream] (loop [char (.read istream)] (let [result (process-char istream)] (cond ;; .. some additional conditions (string? result) (loop (.read istream)) (number? result) (loop result) ... Main idea, that in some function, i read characters in sequence, and check their values, and in some conditions, i need to re-submit already readed character into loop, but when i use code above, i get following error: java.lang.IllegalArgumentException: recur arg for primitive local: char must be matching primitive [Thrown class java.lang.RuntimeException] but if i replace (loop result) with (.read istream), then it works without any problems I checked type of result, and it's Integer - same type, that 'char' var in loop will get after reading from stream. If need, i can submit somebody full test case -- With best wishes, Alex Ott, MBAhttp://alexott.blogspot.com/ http://xtalk.msk.su/~ott/http://alexott-ru.blogspot.com/ -- 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: strange typecheck error
On Dec 30, 12:53 pm, Alex Ott alex...@gmail.com wrote: If need, i can submit somebody full test case I think this might help because it's hard to tell what you are trying to do without a little more context. Some odd things that stand out to me: 1) You call loop, but you should be calling recur. E.g. (loop result) 2) Why are the arguments streams and not readers? 3) You do nothing with the 'char' variable binding. My guess is you just made some typos while trying to create a simple example. -- 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