R-beta: S Compatibility (again)

Peter Dalgaard BSA p.dalgaard at biostat.ku.dk
Mon Apr 13 12:39:14 CEST 1998

[This is all very interesting and instructive. Thanks for taking the
time, Bill]

Bill Venables <wvenable at attunga.stats.adelaide.edu.au> writes:

>  > > 
>  > >    To be more specific, the R substitute() is much more
>  > >    limited than the S version and coercion to mode "{",
>  > >    "call" or "function" are unavailable, and function
>  > >    objects are not subsetable [and hence not modifiable].
> That still stands, though.

Right. At least when it comes to functions, there seems to be no
workaround (I actually thought there would be. Internally, functions
are just lists, so coercion should be possible. Ross keeps talking
about changing the internals of list structures from the current Lisp
"dotted pair" style to "generic vectors", so it isn't too attractive
to go in and modify things right now. In time, I think we'll get it

As regarding mode "call" and "{", note the following:

> call("{",as.name("x"))

i.e. you *can* create calls from their constituents, and R has "{" as
just another function. For "("-expressions we recently did a change so
that mode() became S-compatible:

> call("(",as.name("x"))
> mode( call("(",as.name("x")))
[1] "("

- whereas we still have
> mode( call("{",as.name("x")))
[1] "call"

which I suppose we should fix too?

[on deriv()]
> have been to allow users to write functions of class
> "differentiable", say, with a "deriv" attribute which would give
> the code fragments necessary for handling the symbolic
> differentiation operation.  

Yes. I rather suspect that this could in fact be implemented fairly
easily using attributes, at least for functions that take a fixed
number of arguments. 

> The main problems are that substitute() is not a general
> substitution tool as it is in S, and while expressions can be
> manipulated, functions it seems cannot.  deriv can build a
> function but you can't.  The following is pretty uncompromising:
> > as.function
> function (x) 
> stop("mode function cannot be assigned")


> What you see here is email transmission damage.  You don't get
> "@" but "\300".

I got something else... Random garbage anyway.

>  > Should get fixed - or R should protest about an invalid
>  > argument.  If for nothing else, then because
>  > 
>  > > substring(n, -2000, nchar(n))
>  > Segmentation fault (core dumped)
> A much more cogent argument. 

Fixed now for both 0.61.3 and 0.62.0-unstable. The C code just
substitutes 1 for values of start < 1.
> However what is the status of "" (nul) as a 'character'?  Is the
> S version itself completely consistent?  What would you expect to
> happen in response to substring("", 1, 0)?  These are not
> rhetorical questions, I just don't know.

I think that bot S and R (now) gives "" as the result of out-of-bounds
indexing. I.e.
substring(ch,i,j) == substring(ch,max(i,1),min(j,length(ch)))
and  i > length(ch) or j < i both gives "" results.

I wouldn't know how S handles an ASCII NUL character in a string,
though. At least, there's no easy way to put one into a string... 

> Here is a cute example of what can be done in S but not in R.
> Make a function for the pdf of an order statistic.
> > pdf.order <- function(n, r, pfun, dfun) {
>   con <- round(exp(lgamma(n + 1) - lgamma(r) - lgamma(n - r + 1)))
>   substitute(
>     function(x) {
>       Fx <- p(x)
>       K*Fx^r1*(1 - Fx)^nr*f(x)
>     }, 
>     list(p = substitute(pfun), f = substitute(dfun), 
>          r1 = r-1, nr = n-r, K = con)
>   )
> }
> > pdf.order(9, 5, pnorm, dnorm)
> function(x)
> {
>         Fx <- pnorm(x)
>         630 * Fx^4 * (1 - Fx)^4 * dnorm(x)
> }
> The substitute()s to get unevaluated arguments do work but the
> one to modify the function definitely does not.  substitute() is
> a very different kind of function in R from what it is in S.

I see the problem. I suspect that there's a workaround, though. Will
look at it. 

> Can I make the plea, though, that when someone does get round to
> looking at it, that the result be fully compatible with S,
> including the representation of non-printable characters in a
> printable (and hence emailable) form?  This should really be a
> fundamental part of the design specification.  Data transfer and
> elementary object transfer between R and S should be a smooth
> operation and data.dump and data.restore are all about efficint,
> portable transfer.

This should certainly be possible for the basic data types, e.g.
numeric vectors, factors, data frames,... Functions could be difficult
for obvious reasons.

>  > Objects(), however, owes some of its differences from S to the
>  > different scoping rules, so I suspect that it can never have
>  > the same semantics.
> You may be right but frankly this surprises me.  Both systems
> have a search path but objects(2) in S has to be written
> objects(pos=2) in R.  I don't think that has much to do with
> scoping.

Mmmno... but in R, you can do objects("package:base"). We could
probably do some  "if (is.numeric..." stuff on the "name" argument to

   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)             FAX: (+45) 35327907

r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch

More information about the R-help mailing list