S programming style & "missing(.)" [was "regarding bugs in barplot" on R-core]

Martin Maechler Martin Maechler <maechler@stat.math.ethz.ch>
Thu, 26 Mar 1998 12:04:30 +0100

	[The part about S (S-plus and R being dialects of S) programming
	 (at the end) makes me cc'ing this to R-devel. MM]

On R-core,
>>>>> "Paul" == Paul Murrell <paul@stat.auckland.ac.nz> writes:

    Paul> hi (i) the problem with the positioning of the legend in your
    Paul> barplot example:

    Paul> barplot(matrix(1:12,ncol=3),bes=T,legend.text=c("ABC","B2","C3","D4"),col=1:4)
    Paul> was actually a bug in legend() (now fixed)

thank you for the fix (I'm probably also among the culprits..).
Since it's mentioned here, following is the patch against 0.61.2:

--- R-0.61.2/src/library/base/R/legend	Wed Nov 12 04:53:32 1997
+++ R-devel/src/library/base/R/legend.R	Thu Mar 26 06:02:23 1998
@@ -60,13 +60,17 @@
 		if(!merge) w <- w + x.intersp * xchar
 	if(merge) w <- w + x.intersp * xchar
 	## (w,h) are now the final box width/height. --> Adjust (x,y) :
-	x <- x - xjust * w
-	y <- y + (1 - yjust) * h
+	left <- x - xjust * w
+	top <- y + (1 - yjust) * h
+	right <- left+w
+	bottom <- top-h
+	if (xlog) { left <- 10^left; right <- 10^right }
+	if (ylog) { top <- 10^top; bottom <- 10^bottom }
 	if (bty != "n")
-		rect(x, y, x+w, y-h, col = bg)
+		rect(left, top, right, bottom, col = bg)
 	## (xt[],yt[]) := 'current' vectors of (x/y) legend text
-	xt <- rep(x, n.leg) + xchar
-	yt <- y - (1:n.leg) * ychar
+	xt <- rep(left, n.leg) + xchar
+	yt <- top - (1:n.leg) * ychar
 	if (!missing(fill)) {	#- draw filled boxes -------------
 		xx <- cbind(xt, xt + xbox)
 		if (xlog) xx <- 10^xx

    Paul> (ii) i am told that the "!missing(col)" condition that meant a
    Paul> legend would not be drawn if col was not specified is a
    Paul> historical "feature" (from when col did not have a default
    Paul> value).  i have removed the condition.

thank you, Paul.

May I add something  much more general here
 	(and also pertinent to barplot(.)):

My point:  || almost never use	missing(arg) ||
	   || rather use	is.null(arg) ||

(I have the impression that this rule is actually even observed by
 increasingly more S "programmers").

This actually goes back to a discussion on S-news of Dec. 20-22, 1994,
 Rick Becker started to give "S Programming Style" hints,
 John Maindonald added to them, giving the is.null(.) hint,
 and Rich Heiberger and me ``concluded'']

Here an excerpt of these December 1994 mailings:
	My conclusion is that an explicit NULL default value is safer than
	a missing default.

MM94> I completely agree ---
MM94> it has the further advantage (hidden in RMH's example)
MM94> that you can explicitly set the parameter to NULL
MM94> which allows for the following  nice code in a calling function :
MM94> 	myfunction <- function(.........) {
MM94>          .....
MM94> 	 mm <- sub.function(x,y,z,u,v,w,  def.par = if(abcdef) pi )
MM94>          .....
MM94> 	}
MM94> The  ``if(CC) A'' as an expression returns NULL if CC evaluates to FALSE
MM94> such that in the example, the  def.par  argument
MM94> is either set to  pi  or NULL.
MM94> WITHIN  sub.function(.),
MM94>   missing(def.par)   evaluates to FALSE in BOTH cases,
MM94> whereas
MM94>   is.null(def.par)
MM94> tells you if the default is taken or not....
MM94> such that when  sub.function(.)  uses  missing(def.par)
MM94> the above code fragment would have to look more ugly, repeating the whole
MM94> argument list of sub.function [think of a LOOOONG list x,y,z,u,v,w,...]
MM94> 	myfunction <- function(.........) {
MM94>          .....
MM94> 	 mm <- if(abcdef) sub.function(x,y,z,u,v,w,  def.par = pi )
MM94>                 else      sub.function(x,y,z,u,v,w)
MM94>          .....
MM94> 	}
r-devel 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-devel-request@stat.math.ethz.ch