From maintainers-request at octave dot org Fri Sep 17 10:59:54 2004 Subject: Re: [cell_array{:}] = foo () syntax and semantics From: Keith Goodman To: "John W. Eaton" Cc: octave maintainers mailing list Date: Fri, 17 Sep 2004 08:58:17 -0700 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 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 > >