From Waclaw.Marcin.Kusnierczyk at idi.ntnu.no  Sat Mar  7 17:35:48 2009
From: Waclaw.Marcin.Kusnierczyk at idi.ntnu.no (Wacek Kusnierczyk)
Date: Sat, 07 Mar 2009 17:35:48 +0100
Subject: [Rd] question
In-Reply-To: <971536df0903070645x6f93663y9969f1d2df875d29@mail.gmail.com>
References: <49B23FA7.9090006@idi.ntnu.no>	
	<000325575fc2f3201e046488263f@google.com>	
	<971536df0903070628x46a4951dt9d14da97ea720dd0@mail.gmail.com>	
	<50d1c22d0903070638g2a2f65dexefc45b69d4118dfe@mail.gmail.com>
	<971536df0903070645x6f93663y9969f1d2df875d29@mail.gmail.com>
Message-ID: <49B2A264.6030409@idi.ntnu.no>

Gabor Grothendieck wrote:
> On Sat, Mar 7, 2009 at 9:38 AM, ivo welch <ivowel at gmail.com> wrote:
>   
>> hi gabor:  this would be difficult to do.  I don't think you want to
>> read my programs.  it would give you an appreciation of what ugly
>> horror programs end users can write in the beautiful R language  ;-).
>>
>> clearly, one can work around the lack of such a feature.
>> multiple-return values are syntax sugar.  but maybe it helps to
>> explain how I got to my own view.  I had to send an R program to
>> someone who had never used it before.  without knowing R, he could
>> literally read the entire program.  the only thing that stumped him
>> was the multiple return values.  In my program, he saw
>>
>>  f= function() { return(list(a=myvector1, b=myvector2)) }
>>
>>  result=f()
>>  a= result$a
>>  b= result$a
>>  rm(result)
>>
>> I had picked this method up over the years reading r-help.  of course,
>> I had 10 return values, not two, each return value with its own long
>> name.  I think it would have been a whole lot nicer if I could have
>> written FOR HIM simply
>>
>>  f= function() { return(myvector1,myvector2); }
>>  (a,b)= f()
>>     
>
> The function would be better written
>
> f <- function() list(a = myvector1, b = myvector2)
>
> and then called:
>
> L <- f()
>   

that's exactly what ivo shows above, with an explanation of why he finds
it inconvenient. 

one point that could be made in favour of multiple return values is that
when you return a list, you a) have a nuissance object, some of whose
components may not be of interest at all, and b) elongate the value
lookup path (list$variable vs. variable), both of which add performance
penalty -- which is surely negligible in many cases.

you can  of course use with, as here:

    with(f(),
       <do something with a and b>)

which rather remotely resembles call-with-values in scheme or receive in
guile, but this adds a penalty again (with constructs a new local
environment) and makes the code less readable.  it also suffers from the
same problem as accessing the variables explicitly from the returned
list (as l$a, for example), namely, that the variable names are as given
by the author rather than the user of the function.

i have had occasions where it would be convenient to be able to do
something like

    c(first, last) = f(...)[1, 4]

or
   
    c(left, right) = f(...)[c('u.glyNAME', 'uninformative.name')]

as to the usefulness of capturing multiple return values each in a
variable on its own, it's really at the heart of perl, where you can
capture the return either into an array variable or into a collection of
scalar (and array) variables:

    @values = &function(...)
    ($first, $second, @rest) = function(...)

but of course, r is not perl and vice versa, so this is a red herring
argument.


vQ



[Rd] question
Wacek Kusnierczyk