Re: strange typecheck error

2010-01-02 Thread Alex Ott
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

2010-01-01 Thread .Bill Smith
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

2009-12-31 Thread Alex Ott


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

2009-12-31 Thread Alex Ott
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

2009-12-31 Thread .Bill Smith
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

2009-12-31 Thread Alex Ott
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

2009-12-30 Thread Nikolay Petrov
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

2009-12-30 Thread .Bill Smith
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

2009-12-30 Thread rzeze...@gmail.com


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