On Sun, 25 Jan 2009, John Chambers wrote:

It's unclear from your mail what you actually tried to do, but here are
a few comments that may be relevant.

The syntactic form for() is indeed implemented as a primitive
function.   Some primitives can and are used as generic functions, but
`for` is not currently one of them.

> setGeneric("for")
Error in genericForPrimitive(f) :
 methods may not be defined for primitive function "for" in this
version of R

Allowing methods for it would be possible in a future version.  This
would be a little odd, since the syntax does not look like a function
call. Still, it's an interesting idea, and I don't know of anything
offhand to prevent its implementation.

I would VERY STRONGLY prefer NOT to go down this road as it would
significantly complicate code analysis and compilation at no great
benefit I can see.  Allowing the current for() code to accept an
iterator object of some sort is reasonable and would not create any
issues.  Figuring out what such an iterator should be is a little
harder and depends in part on whether we would want to support things
more general than vector-like objects, such infinite and mutable
collections.

luke

 The natural interpretation would
be for the signature of the generic to be the second argument
(primitives don't intrinsically have argument names, so we would make
one up, `seq` is used in the documentation, although something like
`object` would be more suggestive).

Your comments about coercing are unclear and you showed no examples of
what supposedly went wrong.  In fact, that approach works fine:

> setClass("foo",representation(bar="list"))
[1] "foo"
> setAs("foo","list",function(from)f...@bar)
> xx = new("foo", bar = list(1,2,3))
> as(xx, "list")
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

> for(i in as(xx, "list")) dput(i)
1
2
3

Of course, this is not exactly defining methods for the iterator, but
would be a sensible workaround in practice.

Along the same lines, if one asks how the underlying ideas fit naturally
into R, as opposed to making R behave more like other languages, here's
my take on that.  The `for` operator is defined to work on vectors of
various kinds.  If a new class is supposed to be "like" a vector, then
the two natural choices are to define a method to coerce it to a vector
(as in the example above) or to make it a subclass of "vector" (or of a
specific vector class):

> setClass("baz", contains = "vector")
[1] "baz"
> yy = new("baz", list(1,2,3))
> for(i in yy) dput(i)
1
2
3

Which choice works best depends on what the "real" meaning of the class
is (there's discussion of these and other alternatives in section 9.3 of
"Software for Data Analysis").


John Chambers

Stavros Macrakis wrote:
Inspired by Rudolf Biczok's query of Fri, Jan 23, 2009 at 1:25 AM, I
tried to implement iteration in a generic way using S4. (Though I am
admittedly still struggling with learning S4.)


setClass("foo",representation(bar="list"))

[1] "foo"

x<-new("foo",bar=list(1,2,3))


Given this, I would not expect for(i in x)... to work, since R has no
way of knowing that x...@bar should be used as is.  What would it do if
the representation included two lists?  What if list(1,2,3) is used by
the class foo to represent something else?

But I did hope that I could put in place some definitions so that the
*class* could define an iterator.

First I tried overloading `for` to allow the definition of iterator
classes, but as a primitive function, `for` cannot be overloaded.

Then I tried to see how the Containers package handles iterators:


library(Containers);.jinit();.jpackage("Containers")
ah = MaxHeap(); ah$insert(3)
for (i in ah) print(i)

[1] NA

as.list(ah)

[[1]]
[1] NA

Bit it appears that the Containers package's Iterators don't interface
with R's `for` or type conversion system.

So I gave up on iterators, but thought I'd try automatic conversion to lists.

So I defined an automatic conversion from foo to list, since `for`'s
seq argument is specified as "An expression evaluating to a vector
(including a list...)":

    setAs("foo","list",function(from)f...@bar)

This and various variants (using "numeric" or "vector" instead of
"list") all give errors.  Is there perhaps some 'sequence' superclass
that I am ignorant of?

I *was* able to overload lapply:


setMethod("lapply","foo",function(X,FUN,...) lapply(x...@bar,FUN,...))
lapply(x,dput); NULL

1
2
3
NULL

but of course that doesn't affect `for` and other places that expect sequences.

Is there in fact some generic way to handle define iterators or
abstract sequences in R?

          -s

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



        [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


--
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
   Actuarial Science
241 Schaeffer Hall                  email:      l...@stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to