Gabriel Baud-Bovy
2005-May-10 19:00 UTC
Fwd: Re: [Rd] Implementation of the names attribute of attribute lists
Hi Martin, Thanks for your reply. I am responding on r-devel to provide some examples of outputs of the function that I had list in the post-scriptum of my previous email (BTW, did my post went through the list? I subscribed only after mailing it). You wrote:>Just to ask the obvious: > > Why is using str() not sufficient for you and instead, > you use 'print.object' {not a good name, BTW, since it looks like a > print() S3 method but isn't one} ?Would printObject or printSEXP a better name?>The very few cases I found it was insufficient, >certainly dput() was, possibly even using it as >dput(. , control = ....).As I wrote in my email, I might have reinvented the wheel. I did not know str! The output of str and print.object is quite similar for atomic and list objects. I might look at this function to change the argument names of the print.object function. However, the output of str is quite different for language expressions and does not show as well the their list-like strcuture since it respects the superficial C-like syntax of the R language (at the textual level). In contrast, print.object prints all R objects in a much more uniform way. For me, at least, it is both simpler because it handles recursive R-objects with a similar format and closer to the internal Lisp-like SEXPR structures representing the R objects. It has, I think, a pedagogic value in particular for language objects and can be useful when "computing on the language". The goal was really to be simple, clear and close the true and elegant internal representation of the R objects. Examples Atomic object x<-matrix(1,2,2) dimnames(x)<-list(c("1","2"),c("a","b")) printObject(x,print.attr=T) - <double>=1,1,1,1 + [[attributes]] <list> - [dim] <integer>=2,2 + [dimnames] <list> - <character>='1','2' - <character>='a','b' str(x) num [1:2, 1:2] 1 1 1 1 - attr(*, "dimnames")=List of 2 ..$ : chr [1:2] "1" "2" ..$ : chr [1:2] "a" "b" Note: I have chosen not to represent the names attribute of the attribute list since I don't know how it is internally represented as I said in my previous email. > x<-list(first=pairlist(a="a",b=as.name("b")),second=2) > printObject(x) + <list> + [first] <pairlist> - [a] <character>='a' - [b] <symbol>=b - [second] <double>=2 > str(x) List of 2 $ first :Dotted pair list of 2 ..$ a: chr "a" ..$ b: symbol b $ second: num 2 > dput(x) structure(list(first = list(a = "a", b = b), second = 2), .Names = c("first", "second")) Closure example foo<-function(x,y)x+y printObject(foo) + <closure> + [[formals]] <pairlist> - [x] <symbol>='' - [y] <symbol>='' + [[body]] <language> - <symbol>=+ - <symbol>=x - <symbol>=y + [[env]] <environment>=<environment: R_GlobalEnv> str(foo) function (x, y) - attr(*, "source")= chr "function(x,y)x+ydput(foo) dput(foo) function (x, y) x + y Function calls: printObject(quote(2+2)) + <language> - <symbol>=+ - <double>=2 - <double>=2 printObject(expression(2+2)) + <expression> + <language> - <symbol>=+ - <double>=2 - <double>=2 dput(expression(2+2)) expression(2 + 2) printObject(quote(expression(2+2))) + <language> - <symbol>=expression + <language> - <symbol>=+ - <double>=2 - <double>=2 dput(quote(expression(2+2))) expression(2 + 2) statement<-quote(function(x,y){z<-(x+y)/2;z}) printObject(statement) + <language> - <symbol>=function + <pairlist> - [x] <symbol>='' - [y] <symbol>='' + <language> - <symbol>={ + <language> - <symbol>=<- - <symbol>=z + <language> - <symbol>=/ + <language> - <symbol>=( + <language> - <symbol>=+ - <symbol>=x - <symbol>=y - <double>=2 - <symbol>=z - <character>='function(x,y){z<-(x+y)/2;z}' dput(statement) function(x, y) { z <- (x + y)/2 z } The output of printObject makes it easy to identify and eventually change an element of an expression (it easy to count the argument in each function call). For eample, to replace a division by a multiplication statement[[3]][[2]][[3]][[1]]<-as.name("*") One additional point, to wrap the names of the elements of recursive objects, I have used double brackets [[]] to distinguish between a SEXP inside the SEXPR (this also used for attributes) and single brackects for generic vectors. For pairlist, I also use single brackets because it is writtin in the Manual that they are converted in generic vector of type pairlist when accessed from R. The print.object function allows also to use the "typefun" function (but this is a detail). Regards, Gabriel>From: Martin Maechler <maechler@stat.math.ethz.ch> >Date: Tue, 10 May 2005 17:30:32 +0200 >To: Gabriel Baud-Bovy <baud-bovy.gabriel@hsr.it> >Subject: Re: [Rd] Implementation of the names attribute of attribute lists >X-Mailer: VM 7.18 under Emacs 21.3.1 >Reply-To: Martin Maechler <maechler@stat.math.ethz.ch> >CC: maechler@stat.math.ethz.ch >X-Virus-Scanned: by amavisd-new at stat.math.ethz.ch > >Hi Gabriel, > >Just to ask the obvious: > > Why is using str() not sufficient for you and instead, > you use 'print.object' {not a good name, BTW, since it looks like a > print() S3 method but isn't one} ? > >The very few cases I found it was insufficient, >certainly dput() was, possibly even using it as >dput(. , control = ....). > >Note that this is a private e-mail only, but feel free to answer >in public (R-devel) if you feel it helps others. > >Regards, >Martin-------------------------------------------------------------------- Gabriel Baud-Bovy tel: (+39) 02 2643 4839 Faculty of Psychology, UHSR University fax: (+39) 02 2643 4892 via Olgettina, 58, 20132 Milan, Italy
Martin Maechler
2005-May-11 09:37 UTC
Fwd: Re: [Rd] Implementation of the names attribute of attribute lists
>>>>> "Gabriel" == Gabriel Baud-Bovy <baud-bovy.gabriel@hsr.it> >>>>> on Tue, 10 May 2005 19:00:53 +0200 writes:Gabriel> Hi Martin, Gabriel> Thanks for your reply. I am responding on r-devel to Gabriel> provide some examples of outputs of the function that Gabriel> I had list in the post-scriptum of my previous Gabriel> email (BTW, did my post went through the list? I Gabriel> subscribed only after mailing it). Gabriel> You wrote: >> Just to ask the obvious: >> >> Why is using str() not sufficient for you and instead, >> you use 'print.object' {not a good name, BTW, since it looks like a >> print() S3 method but isn't one} ? Gabriel> Would printObject or printSEXP a better name? definitely better because not interfering with the S3 pseudo-OO convention... Still not my taste though : every R object is an object (:-) -- and a SEXP internally -- and we don't use 'fooObject' for other function names even though their arguments are R objects.... My taste would rather lead to something like 'displayStructure' (or 'dissectInternal' ;-) or a shorter version of those. >> The very few cases I found it was insufficient, >> certainly dput() was, possibly even using it as >> dput(. , control = ....). Gabriel> As I wrote in my email, I might have reinvented Gabriel> the wheel. I did not know str! (amazingly ... ;-) Gabriel> The output of str and print.object is quite similar Gabriel> for atomic and list objects. I might look at this Gabriel> function to change the argument names of the Gabriel> print.object function. Gabriel> However, the output of str is quite different Gabriel> for language expressions and does not show as well Gabriel> the their list-like strcuture since it respects Gabriel> the superficial C-like syntax of the R language Gabriel> (at the textual level). Ok, thanks for clarifying this aspect, and the difference to both str() and dput() here. <.... much omitted ...> Martin Maechler, ETH Zurich