MATLAB R2009b was recently released. My favorite new language feature is the introduction of the ~ notation to denote missing inputs in function declarations, and missing outputs in calls to functions. Let me show you how this works.
I have occasionally found that I would like the indices from sorting a vector, but I don't need the sorted values. In the past, I wrote one of these code variants :
[dummy, ind] = sort(X) [ind, ind] = sort(X)
In the first case, I end up with a variable dummy in my workspace that I don't need. If my data to sort, X, has a large number of elements, I will have an unneeded large array hanging around afterwards. In the second case, I am banking on MATLAB assigning outputs in order, left to right, and I create somewhat less legible code, but I don't have an extra array hanging around afterwards.
Now you can write this instead:
[~, ind] = sort(X)
and I hope you find your code readable, with the clear intention to not use the first output variable.
You can similarly designate unused inputs with ~ in function declarations. Here's how you'd define the interface where the second input is ignored.
function out = mySpecialFunction(X,~,dim)
You might ask why that is useful. If I don't use the second input, why put it in at all? The answer is that your function might be called by some other function that expects to send three inputs. This happens for many GUI callbacks, and particularly those you generate using guide. So your function needs to take three inputs. But if it is never going to use the second input, you can denote the second one with ~.
Yes! Consider this function mySpecialFunction shown here.
function ind = mySpecialFunction(X,second,dim) % mySpecialFunction Function to illustrate ~ for inputs and outputs. [dummy,ind] = sort(X,dim);
Running mlint on this code produces two messages.
msgs = mlint('mySpecialFunction'); disp(msgs(1).message(1:50)) disp(msgs(1).message(51:end)) disp(' ') disp(msgs(2).message(1:49)) disp(msgs(2).message(50:end))
Input argument 'second' might be unused, although a later one is used. Consider replacing it by ~. The value assigned here to 'dummy' appears to be unused. Consider replacing it by ~.
Since M-Lint is running continuously in the editor, you would see these messages as you edit the file. Here's a cleaned up version of the file.
function ind = mySpecialFunction1(X,~,dim) % mySpecialFunction Function to illustrate ~ for inputs and outputs. [~,ind] = sort(X,dim);
And let's see what M-Lint finds.
It finds nothing at all.
Get the MATLAB code
Published with MATLAB® 7.9
Comments are closed.
53 CommentsOldest to Newest
function [c,ce] = nonLinearCon(~) % ... endunless tilde cannot be used to ignore the first input argument---I suppose there shouldn't be such a limitation. Nice addition. Thanks Loren for bringing this to our attention. -Omid
[~, that]=~MyFunction();still errors with the same message. The ~ operator applies to a single array but there are multiple outputs from the function. It's an interesting idea to extend ~ in the way you mention. --Loren
[~, that]=~MyFunction();or more often maybe something like:
[~, that]=-2*MyFunction(); or [~, that]=sort(MyFunction());or even something where i do something to one output and something different to another. Sometimes i also wish that i could do like this:
number10=sort(x)(10); or perhaps like this to be more explicit: number10=(sort(x))(10);
[x x] = fun;(such as in the reply to Jason's question on the newsgroup) although I must admit I've never been comfortable with the idea. Are there differences in stability/efficiency etc between this and the new syntax? For unused inputs, if it's true that only pointers are passed until the variable is actually used, does the new syntax make much difference in the efficiency of function calls? Lastly, are there any plans for future versions to allow direct referencing of function outputs? Something like
(A^2)(1,1)(since the documentation for subsref advises us not to use it!) thanks, Ben
[x x] = fun;relies on MATLAB always assigning left to right. It does that currently, but seems like a slightly precarious assumption to rely on. Hence I prefer the new syntax which is guaranteed to do what you want. So I guess that makes it more stable in your terms perhaps. Efficiency is the same as the function being called still sees nargout=2 and creates both outputs. The first output just gets dumped on completion.
[~ x] = fun;I've mentioned in other posts that the direct referencing of function outputs is on our future wishlist. I don't have a date for its appearance. --Loren
~does indeed seem nifty and I'm quite sure I'll make use of the feature in some of my experimental code. On the other hand I will echo Mr. DErrico's concern from the 12th of September. Maintaining backwards compatibility does rule out employing such features, at least in the near future. For instance, one of the larger packages I'm currently working on will currently run "out of the box" only in releases >= R2007a due to frequent use of BSXFUN. It's a conscientious choice that I stand by because BSXFUN is such a wonderful tool, but it is nevertheless a concern when distributing the code to other users. To finish on a more `upbeat' note I'll just say that, for me personally, the thread support for BSXFUN and SORT rates higher than
~. It just seems more immediately useful and doesn't preclude backwards compatibility. Best regards, Bård Skaflestad SINTEF ICT, Applied Mathematics
[x,y]=funky(a,b) if (~isargpresent(a)) fprintf ('Hey, you didn''t pass me anything for a!') end if (~isargpresent(x)) fprintf ('Whatsa matter?! How come you don''t want x?') ; end
y = plus(x, ~);What would you expect MATLAB to do in this case? You gave the PLUS function two inputs, as it expected, but you somehow expect it to ignore the second one? You can use ~ in the _output_ argument list when you call the function (if you don't care what value the function assigned to that output when you called it) and/or you can use it in the input argument list when you _define_ the function (if you're going to ignore whatever the caller passed into the function.) In a MEX-file, you can't use ~ in the declaration, but you don't need to. You can simply not reference that element of the array containing the right-hand sides, prhs. In MATLAB, doing that would earn you a warning from M-Lint:
function y = myfun(x, t) % t is not used y = x.^2;but M-Lint, as the name implies, doesn't apply to MEX-file source code. Using ~ in the output argument list of a call to a function works the same way regardless of how the function is implemented -- MEX, M-file, or built-in. Hoi, If we'd chosen to create a new keyword for this, it would have the potential to break older code that used the keyword as a variable or function name, as attempting to create a variable whose name is a keyword is an error:
for = 4;and you can't call a function whose name is a keyword -- the keyword will take precedence.
myfunc(argOne, argTwo, argThree)and it's called like this:
myfunc('arg', ~, 'arg')Is nargin 2, or 3? Is argTwo undefined or empty or something else? Thanks
function myfunc(arg1, ~, arg3) narginand nargin returns 3. You can't, in the function body, refer to the second input. It's there because some other use requires the second input, which this function will totally ignore. The other use of ~ is to ignore defined outputs. See the example in the post or in the documentation. --Loren