From Waclaw.Marcin.Kusnierczyk at idi.ntnu.no  Sat Mar  7 10:34:31 2009
From: Waclaw.Marcin.Kusnierczyk at idi.ntnu.no (Wacek Kusnierczyk)
Date: Sat, 07 Mar 2009 10:34:31 +0100
Subject: [Rd] question
In-Reply-To: <62C82B39B8A85E4B95A18F7F7B852F87051705E41B@exvic-mbx03.nexus.csiro.au>
References: <50d1c22d0903050622s2f450835k3edeb8c7f8f4df01@mail.gmail.com>,
	<971536df0903051425h31070a46h76fc666b35fc3d78@mail.gmail.com>
	<62C82B39B8A85E4B95A18F7F7B852F87051705E41B@exvic-mbx03.nexus.csiro.au>
Message-ID: <49B23FA7.9090006@idi.ntnu.no>

Mark.Bravington at csiro.au wrote:
>   
>> The syntax for returning multiple arguments does not strike me as
>> particularly appealing.  would it not possible to allow syntax like:
>>
>>   f= function() { return( rnorm(10), rnorm(20) ) }
>>   (a,d$b) = f()
>>
>>     
>
>
> FWIW, my own solution is to define a "multi-assign operator":
>
> '%<-%' <- function( a, b){
>   # a must be of the form '{thing1;thing2;...}'
>   a <- as.list( substitute( a))[-1]
>   e <- sys.parent()
>   stopifnot( length( b) == length( a))
>   for( i in seq_along( a))
>     eval( call( '<-', a[[ i]], b[[i]]), envir=e)
>   NULL
> }
>   

you might want to have the check less stringent, so that rhs may consist
of more values that the lhs has variables.  or even skip the check and
assign NULL to a[i] for i > length(b).  another idea is to allow %<-% to
be used with just one variable on the lhs.

here's a modified version:

    '%<-%' <- function(a, b){
        a <- as.list( substitute(a))
        if (length(a) > 1)
            a <- a[-1]
        if (length(a) > length(b))
            b <- c(b, rep(list(NULL), length(a) - length(b)))
        e <- sys.parent()
        for( i in seq_along( a))
            eval( call( '<-', a[[ i]], b[[i]]), envir=e)
        NULL }

    {a; b} %<-% 1:2
    # a = 1; b = 2
    a %<-% 3:4
    # a = 3
    {a; b} %<-% 5
    # a = 5; b = NULL


vQ



[Rd] question
Wacek Kusnierczyk