R-beta: Re: "as.numeric" `mode' and `cast' should be kept separate.

Bill Venables (wvenable@attunga.stats.adelaide.edu.au)
Wed, 3 Jun 1998 09:36:19 +0930

Date: Wed, 3 Jun 1998 09:36:19 +0930
Message-Id: <9806030006.AA16033@attunga.stats.adelaide.edu.au>
From: Bill Venables <wvenable@attunga.stats.adelaide.edu.au>
To: Ross Ihaka <ihaka@stat.auckland.ac.nz>
Subject: R-beta: Re: "as.numeric" `mode' and `cast' should be kept separate.
In-Reply-To: <199806022209.KAA09607@stat1.stat.auckland.ac.nz>

Ross Ihaka writes:
 > Martin Maechler writes:

 >  > The ``well-known'' (:-) solution is to use
 >  > 
 >  > 	storage.mode(x) <- "numeric"
 >  > 
 >  > instead, which is rather clumy, especially when passing
 >  > arguments to .C(..).  I've seen
 >  > 
 >  > 	As.numeric <- function(x) { storage.mode(x) <- "numeric"; x }

I thought storage.mode<- could only usefully take "double",
"single" or "integer", but I may well be wrong.

 >  > solving the above problem.
 >  > 
 >  > What do you (R-help readers !) think?
 > I like the idea, but maybe not the name so much (too much
 > scope for confusion).  Could I make a plug for something like
 > "mode.numeric" or "as.numeric.mode".
 > A single function of the form
 > 	ensure.mode(x, "double")
 > would be another approach.

As these things rapidly become fixed and permanent idioms it is
probably worthwhile getting it fairly right the first time.

I strongly recommend that the construction

> storage.mode(x) <- "double"

remains an option for compatibility reasons, clumsy or not.  

There are two (admittedly linked) concepts that are usefully kept
fairly separate.  Firstly the S concept of `mode', which is a
mutually exclusive classification of all S objects with classes
labelled "numeric", "list", "function", &c.  

Then there is the concept of `storage mode', which applies only
to atomic objects, and which characterises the way the atoms are
held in central memory and has classes "integer", "double",
"single" and "character" and that may be all.  This is a concept
pretty well only relevant to the interface with user compiled
code,and for C functions it corresponds to the idea of a cast.
If you are going to branch out I would favour using some word
other than `mode' entirely for this concept to avoid some very
common confusions.

I don't say this will appeal to everyone straight away, but I
would even favour using a binary operator syntax for the
assignment function form of the above replacement function, for

"%cast.as%" <- function(x, form) {
	storage.mode(x) <- deparse(substitute(form))

Calls to .C would then take on such a striking form that it would
be immediately noticed if something had been missed:

	result <- .C("some_flashy_C_thing",
		     x = my.x %cast.as% double,
		     i = my.eye %cast.as% integer,
		     oops = forgot.this.one,
		     value = z %cast.as% single)$value

Nothing to do with mode.  If "%cast.as%" is too much typing, well
it's not too difficult to redefine your own shorter version:

"%as%" <- get("%cast.as%")


There is a semi-related but much larger issue that also deserves
to be fully regularised: which classes of functions strip off
attributes and which retain them in the result, and if there is a
conflict, how is it resolved?  (storage.mode<- guarantees
attributes will be retained; as.numeric guarantees they won't.)

In S it seems very illogical to me that if M is a matrix, then
sqrt(M) is a matrix like M in all respects but with square-root
entries but pnorm(M) is a naked vector of probabilities.

This is a very large issue, but one that really does deserve to
be handled in a rigorously consistent and well docuented way.  S
and S-PLUS are a long way from that and getting further all the
time.  Perhaps R can still be nudged back onto a better track.

Bill Venables.
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@stat.math.ethz.ch