[cell_array{:}] = foo () syntax and semantics

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[cell_array{:}] = foo () syntax and semantics

John W. Eaton-6
Octave currently does not handle things like

  [cell_array{:}] = foo ()

I've given this some thought in the past, and even started working on
it once, but had to give up when it became fairly complicated and I
ran out of time.  I plan to work on this again soon, but before I
start, I'd like to get some feedback.

For functions that are wrappers around others (like inline or
anonymous function handles) it would be swell if we could write
something as simple as (for example)

  function varargout = foo (varargin)
    [varargout{:}] = svd (varargin{:});
  endfunction

and have it work in all cases:

  foo ([1,2;3,4]);
  sigma = foo ([1,2;3,4]);
  [u, s, v] = foo ([1,2;3,4]);

Can someone tell me whether this will work in Matlab R14?  In R13 it
fails for the nargout == 0 case with an error about the subscript
count of the cell array being zero, and also for the nargout > 0 cases
because varargout is not preallocated automatically based on the value
of nargout, so you have to write the wrapper as

  function varargout = foo (varargin)
    if (nargout == 0)
      svd (varargin{:});
    else
      varargout = cell (nargout, 1);
      [varargout{:}] = svd (varargin{:});
    end

But even this is not quite right as ans (in the nargout == 0 case) is
not propagated to varargout.  So really, you have to write

  function varargout = foo (varargin)
    if (nargout == 0)
      svd (varargin{:});
      varagout = ans;
    else
      varargout = cell (nargout, 1);
      [varargout{:}] = svd (varargin{:});
    end

Hmm.  Although in the svd case, the behavior is identical for the
nargout == 0 and nargout == 1 cases, that may not always be the case.
So we can't write

  function varargout = foo (varargin)
    n = nargout;
    if (nargout == 0)
      n = 1;
    end
    varargout = cell (n, 1);
    [varargout{:}] = svd (varargin{:});

But, *could* we make

  function varargout = foo (varargin)
    [varargout{:}] = svd (varargin{:});
  endfunction

do this automatically?  I think we would only have to do the
following (in addition to making the [x{:}] = foo (...) syntax work to
begin with):

  * Preallocate varargout based on the value of nargout.

  * Allow

      retval = {};
      [retval{:}] = fcn (...);

    to work such that nargout is set to 0 for fcn, but if fcn returns
    any values, retval is reallocated to a one-element cell array to
    hold toe first returned value.

Would these special cases cause trouble anywhere else (i.e., change
the behavior of currently valid code)?

jwe


Reply | Threaded
Open this post in threaded view
|

Re: [cell_array{:}] = foo () syntax and semantics

Keith Goodman
None of the cases work in R14. It chokes on the square brackets and spits out:

??? The left hand side has varargout{:} inside brackets, which
requires that varargout be defined,
so that the number of expected results can be computed.

Changing the function to

function varargout = foo (varargin)
varargout{:} = svd (varargin{:});

gives

>> foo([1,2;3,4])
ans =
    5.4650
    0.3660
>> sigma = foo ([1,2;3,4])
sigma =
    5.4650
    0.3660
>> [u, s, v] = foo ([1,2;3,4])
??? Error using ==> foo
Too many output arguments.

Error in ==> foo at 2
[varargout{:}] = svd (varargin{:});

I'm using

-------------------------------------------------------------------------------------
MATLAB Version 7.0.0.19901 (R14)
MATLAB License Number: XXXXXX
Operating System: Darwin 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug  5
19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC  Power
Macintosh
Java VM Version: Java 1.4.2_05 with "Apple Computer
-------------------------------------------------------------------------------------


On Fri, 17 Sep 2004 09:26:45 -0400, John W. Eaton <[hidden email]> wrote:

> Octave currently does not handle things like
>
>   [cell_array{:}] = foo ()
>
> I've given this some thought in the past, and even started working on
> it once, but had to give up when it became fairly complicated and I
> ran out of time.  I plan to work on this again soon, but before I
> start, I'd like to get some feedback.
>
> For functions that are wrappers around others (like inline or
> anonymous function handles) it would be swell if we could write
> something as simple as (for example)
>
>   function varargout = foo (varargin)
>     [varargout{:}] = svd (varargin{:});
>   endfunction
>
> and have it work in all cases:
>
>   foo ([1,2;3,4]);
>   sigma = foo ([1,2;3,4]);
>   [u, s, v] = foo ([1,2;3,4]);
>
> Can someone tell me whether this will work in Matlab R14?  In R13 it
> fails for the nargout == 0 case with an error about the subscript
> count of the cell array being zero, and also for the nargout > 0 cases
> because varargout is not preallocated automatically based on the value
> of nargout, so you have to write the wrapper as
>
>   function varargout = foo (varargin)
>     if (nargout == 0)
>       svd (varargin{:});
>     else
>       varargout = cell (nargout, 1);
>       [varargout{:}] = svd (varargin{:});
>     end
>
> But even this is not quite right as ans (in the nargout == 0 case) is
> not propagated to varargout.  So really, you have to write
>
>   function varargout = foo (varargin)
>     if (nargout == 0)
>       svd (varargin{:});
>       varagout = ans;
>     else
>       varargout = cell (nargout, 1);
>       [varargout{:}] = svd (varargin{:});
>     end
>
> Hmm.  Although in the svd case, the behavior is identical for the
> nargout == 0 and nargout == 1 cases, that may not always be the case.
> So we can't write
>
>   function varargout = foo (varargin)
>     n = nargout;
>     if (nargout == 0)
>       n = 1;
>     end
>     varargout = cell (n, 1);
>     [varargout{:}] = svd (varargin{:});
>
> But, *could* we make
>
>   function varargout = foo (varargin)
>     [varargout{:}] = svd (varargin{:});
>   endfunction
>
> do this automatically?  I think we would only have to do the
> following (in addition to making the [x{:}] = foo (...) syntax work to
> begin with):
>
>   * Preallocate varargout based on the value of nargout.
>
>   * Allow
>
>       retval = {};
>       [retval{:}] = fcn (...);
>
>     to work such that nargout is set to 0 for fcn, but if fcn returns
>     any values, retval is reallocated to a one-element cell array to
>     hold toe first returned value.
>
> Would these special cases cause trouble anywhere else (i.e., change
> the behavior of currently valid code)?
>
> jwe
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [cell_array{:}] = foo () syntax and semantics

Keith Goodman
Sorry. The last error message in the previous post goes wth the first one:

??? The left hand side has varargout{:} inside brackets, which
requires that varargout be defined,
so that the number of expected results can be computed.

Error in ==> foo at 2
[varargout{:}] = svd (varargin{:});



On Fri, 17 Sep 2004 08:58:17 -0700, Keith Goodman <[hidden email]> wrote:

> None of the cases work in R14. It chokes on the square brackets and spits out:
>
> ??? The left hand side has varargout{:} inside brackets, which
> requires that varargout be defined,
> so that the number of expected results can be computed.
>
> Changing the function to
>
> function varargout = foo (varargin)
> varargout{:} = svd (varargin{:});
>
> gives
>
> >> foo([1,2;3,4])
> ans =
>     5.4650
>     0.3660
> >> sigma = foo ([1,2;3,4])
> sigma =
>     5.4650
>     0.3660
> >> [u, s, v] = foo ([1,2;3,4])
> ??? Error using ==> foo
> Too many output arguments.
>
> Error in ==> foo at 2
> [varargout{:}] = svd (varargin{:});
>
> I'm using
>
> -------------------------------------------------------------------------------------
> MATLAB Version 7.0.0.19901 (R14)
> MATLAB License Number: XXXXXX
> Operating System: Darwin 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug  5
> 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC  Power
> Macintosh
> Java VM Version: Java 1.4.2_05 with "Apple Computer
> -------------------------------------------------------------------------------------
>
>
>
>
> On Fri, 17 Sep 2004 09:26:45 -0400, John W. Eaton <[hidden email]> wrote:
> > Octave currently does not handle things like
> >
> >   [cell_array{:}] = foo ()
> >
> > I've given this some thought in the past, and even started working on
> > it once, but had to give up when it became fairly complicated and I
> > ran out of time.  I plan to work on this again soon, but before I
> > start, I'd like to get some feedback.
> >
> > For functions that are wrappers around others (like inline or
> > anonymous function handles) it would be swell if we could write
> > something as simple as (for example)
> >
> >   function varargout = foo (varargin)
> >     [varargout{:}] = svd (varargin{:});
> >   endfunction
> >
> > and have it work in all cases:
> >
> >   foo ([1,2;3,4]);
> >   sigma = foo ([1,2;3,4]);
> >   [u, s, v] = foo ([1,2;3,4]);
> >
> > Can someone tell me whether this will work in Matlab R14?  In R13 it
> > fails for the nargout == 0 case with an error about the subscript
> > count of the cell array being zero, and also for the nargout > 0 cases
> > because varargout is not preallocated automatically based on the value
> > of nargout, so you have to write the wrapper as
> >
> >   function varargout = foo (varargin)
> >     if (nargout == 0)
> >       svd (varargin{:});
> >     else
> >       varargout = cell (nargout, 1);
> >       [varargout{:}] = svd (varargin{:});
> >     end
> >
> > But even this is not quite right as ans (in the nargout == 0 case) is
> > not propagated to varargout.  So really, you have to write
> >
> >   function varargout = foo (varargin)
> >     if (nargout == 0)
> >       svd (varargin{:});
> >       varagout = ans;
> >     else
> >       varargout = cell (nargout, 1);
> >       [varargout{:}] = svd (varargin{:});
> >     end
> >
> > Hmm.  Although in the svd case, the behavior is identical for the
> > nargout == 0 and nargout == 1 cases, that may not always be the case.
> > So we can't write
> >
> >   function varargout = foo (varargin)
> >     n = nargout;
> >     if (nargout == 0)
> >       n = 1;
> >     end
> >     varargout = cell (n, 1);
> >     [varargout{:}] = svd (varargin{:});
> >
> > But, *could* we make
> >
> >   function varargout = foo (varargin)
> >     [varargout{:}] = svd (varargin{:});
> >   endfunction
> >
> > do this automatically?  I think we would only have to do the
> > following (in addition to making the [x{:}] = foo (...) syntax work to
> > begin with):
> >
> >   * Preallocate varargout based on the value of nargout.
> >
> >   * Allow
> >
> >       retval = {};
> >       [retval{:}] = fcn (...);
> >
> >     to work such that nargout is set to 0 for fcn, but if fcn returns
> >     any values, retval is reallocated to a one-element cell array to
> >     hold toe first returned value.
> >
> > Would these special cases cause trouble anywhere else (i.e., change
> > the behavior of currently valid code)?
> >
> > jwe
> >
> >
>