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...@x, y = x...@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...@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

Index: src/main/eval.c
===================================================================
--- src/main/eval.c     (revision 50047)
+++ src/main/eval.c     (working copy)
@@ -1046,6 +1046,17 @@
     PROTECT(val = eval(val, rho));
     defineVar(sym, R_NilValue, rho);
 
+    /* deal with the S4 case, try to dispatch to as.list */
+    if( TYPEOF(val) == S4SXP ){
+       SEXP expr ; 
+       /* probably should use DispatchOrEval here */
+       PROTECT( expr = lang2(install("as.list"), val ));
+       PROTECT( ans = eval( expr, rho ) ) ;
+       val = ans ;
+       UNPROTECT(3); /* expr, ans and val from above*/
+       PROTECT(val);
+    }
+    
     /* deal with the case where we are iterating over a factor
        we need to coerce to character - then iterate */
 
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to