From romain.francois at dbmail.com  Tue Oct 13 11:09:53 2009
From: romain.francois at dbmail.com (Romain Francois)
Date: Tue, 13 Oct 2009 11:09:53 +0200
Subject: [Rd] for loop over S4
Message-ID: <4AD443E1.9080402@dbmail.com>

Hello,

Consider this :

> setClass("track", representation(x="numeric", y="numeric"))
[1] "track"
> o <- new( "track", x = 1, y = 2 )
> for( i in o ){
+ cat( "hello\n")
+ }
Error: invalid type/length (S4/1) in vector allocation



This happens at those lines of do_for:

	n = LENGTH(val);
	PROTECT_WITH_INDEX(v = allocVector(TYPEOF(val), 1), &vpi);

because allocVector( S4SXP, 1) does not make sense.



What about detecting S4SXP and attempt to call as.list, similarly to 
what lapply does ?

> as.list.track <-  function(x, ...){ list( x = x at x, y = x at y ) }
> lapply( o, identity )
$x
[1] 1

$y
[1] 2


That would make for loops more generic, and make it possible to 
implement custom "iterators". I'm attaching a patch to eval.c that does 
just that. For example :

 > setClass("iterator", representation(to="integer"))
[1] "iterator"
 > o <- new( "iterator", to = 4L )
 > setGeneric( "as.list" )
[1] "as.list"
 > setMethod( "as.list", "iterator", function(x, ...) {
+         seq_len( x at to )
+ })
[1] "as.list"
 >
 > for( i in o ){
+         cat( i, "\n" )
+ }
1
2
3
4

Obviously that is the cheap way of doing it, something better would be 
to abstract a bit more what is an "iterator".



For example in java iterators implement just two methods : hasNext() 
that indicates if there is a next object and next() that returns the 
next object.


For the long story, one motivation for this is actually to deal with 
java iterators (with the devel version of rJava, and this patch), you 
might do something like this:

 > v <- new( J("java/util/Vector") )
 > v$add( new( J("java/awt/Point"), 10L, 10L ) )
[1] TRUE
 > v$add( new( J("java/lang/Double"), 10 ) )
[1] TRUE
 > for( item in v ){
+   print( item$getClass()$getName() )
+ }
[1] "java.awt.Point"
[1] "java.lang.Double"

Where the as.list method for java object references returns a list that 
is filled by iterating over the object if it implements the Iterable 
interface.

The drawback here is that one has to first fully retrieve the list, by 
iterating in java, and then process it in R, by iterating again in R.

Romain


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/BcPw : celebrating R commit #50000
|- http://tr.im/ztCu : RGG #158:161: examples of package IDPmisc
`- http://tr.im/yw8E : New R package : sos

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: loop.txt
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20091013/e592ddd1/attachment.txt>


[Rd] for loop over S4
Romain Francois