Skip to content

Instantly share code, notes, and snippets.

@adeak
Last active August 6, 2020 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adeak/bd20bad4fa517bcfe75063ce5fe7e7cb to your computer and use it in GitHub Desktop.
Save adeak/bd20bad4fa517bcfe75063ce5fe7e7cb to your computer and use it in GitHub Desktop.
deleted undocumentedmatlab post
A small unfamiliar coding pattern by Dave Foti in Loren’s latest blog post (https://blogs.mathworks.com/loren/2020/07/31/the-value-of-value-semantics) caught the eye of astute reader Brad Stiritz (who’s been a keen follower of this blog for years). This was probably an unintentional outing by MathWorks of a very important (and so-far undocumented) new Matlab feature, that enables named input arguments. The relevant code snippet in Dave’s code was this:
...
function t = MultTest(params)
arguments
params.?MultTest
end
... %code of this function/method
end
...
What seems at first glance to be a typo in line #4, is actually valid new Matlab syntax since R2019b, which enables users to specify named parameter-value pairs of values, in addition to the traditional (so-called “positional”) function input arguments.
### The documented mechanism
The documented mechanism (https://www.mathworks.com/help/matlab/matlab_prog/function-argument-validation-1.html) enables setting the dimensional size, data type, validation functions and default value of positional function arguments using an arguments block, similarly to class property declarations in a properties block. For example:
function result = myFunction(x, v, method)
arguments
x (1,:) {mustBeNumeric,mustBeReal}
v (1,:) {mustBeNumeric,mustBeReal,mustBeEqualSize(v,x)}
method (1,:) char {mustBeMember(method,{'linear','cubic','spline'})} = 'linear'
end
... %code of this function/method
end
Using this mechanism, all the input arguments are positional, meaning that their values are set depending on the position of the data in the function-call invocation. For example, if I call myFunction(123,456,'cubic'), then within the myFunction code, input argument x will be assigned the 1st positional value (123), input arg v will be assigned the 2nd (456), and method will be assigned the 3rd (‘cubic’). No surprise so far.
### Named class property values
Other programming languages (Python for example) enable specifying function input args in a non-positional manner, using the input arg’s name. When using the input argument name, users can specify the args in any order, and the code becomes much more readable and maintainable. Matlab’s attempt to mimic this feature, which has been requested for a long time, is at least partially answered by the undocumented feature unveiled here:
If we declare an argument using argName.?className, then the Matlab engine will interpret this to mean “any combination of public properties in the specified className“.
For example, if I have a class called MyClass that has properties prop1-prop3, then I could set these properties directly, in any order:
function result = myFunction(data)
arguments
data.?MyClass
end
... %code of this function/method
data % display the input data
end
In this specific case, since we display the input data in our function code, we’d see the following:
>> result = myFunction('prop3',-2, 'prop2','Yair'); %no value specified for prop1
data =
struct with fields:
prop2: 'Yair'
prop3: -2
Note that the input args are converted into a struct (NOT a class object), which only contains the specified fields (and not all of the class properties). In this case, for example, prop1 was not specified in the function all, so it does not appear in the data struct.
We can think of it this way: any input arguments to the function, which match any of the specified class’s properties, will be included as separate fields in the declared input struct.
If multiple values are specified, the last value overrides:
>> result = myFunction('prop3',-2, 'prop2','Yair', 'prop3',15); %prop3 set to -2, then to 15
data =
struct with fields:
prop2: 'Yair'
prop3: 15
Note that for some reason, this mechanism does not allow specifying a default value.
### Named struct field values
In addition to allowing named inputs based on class properties, we can also specify custom argument names, such as ‘field1’-‘field3’ below:
function result = myFunction(data)
arguments
data.field1 char = 'Yair' % default value = 'Yair'
data.field2 = -pi % default value = -pi
data.field3 % no default value
end
... %code of this function/method
data % display the input data
end
>> result = myFunction('field2',17); %no value specified for field1, field3
data =
struct with fields:
field1: 'Yair'
field2: 17
Note that field1 has a default value so it is included in the data struct despite not being specified in the function call. In contrast, field3 that was also not specified, has no default value and so is not included in the data struct.
### Combining mechanisms
We can combine positional and named function arguments, as long as we specify all the positional arguments before the named ones, in both the arguments block declaration and the function call. For example:
function result = myFunction(x, v, method, extraProps1, extraProps2)
arguments
% regular positional arguments
x (1,:) {mustBeNumeric,mustBeReal}
v (1,:) {mustBeNumeric,mustBeReal,mustBeEqualSize(v,x)}
method (1,:) char {mustBeMember(method,{'linear','cubic','spline'})} = 'linear'
% Named arguments
extraProps1.?MyClass
extraProps2.field1 char = 'Yair' % default value = 'Yair'
extraProps2.field2 = -pi % default value = -pi
extraProps2.field3 % no default value
end
... %code of this function/method
end
### Analysis
The issue of named parameter-value pairs (so called “P-V pairs” in Matlab) has been a hot topic of debate for decades, with quite a few approaches, best-practices and design-patterns proposed over the years. The new mechanism seems to be an attempt to extend/generalize the entrenched Matlab P-V mechanism to all functions, and along the way reduce Matlab code dependency on positional args. Both of these are to be applauded.
The implementation seems to me to be easier to use (by the function developer) than the varargin mechanism (which continues to work side-by-side, for backward compatibility). Time will tell whether developers will indeed be tempted to switch from using varargin.
The specific implementation may seem a bit clunky (and perhaps that’s the reason that it’s still undocumented. Users should beware that this mechanism, although being apparently stable for at least a year (since R2019b), might well change in the future. A similar thing happened with class properties, where the data-type declaration mechanism has been around for many years (https://undocumentedmatlab.com/articles/setting-class-property-types) before it was eventually modified in R2016a (https://undocumentedmatlab.com/articles/setting-class-property-types-2) and became documented.
p.s. – Readers who are interested to see the parsing of property declarations, can check the code of %matlabroot%/toolbox/matlab/codetools/@mtree/private/tt2ss.m, around lines 670-700 (depending on your specific release). There are very few usage examples of this mechanism in the shipping Matlab code. Aside from the code of tt2ss, check the top of the source code of the built-in meshc function (%matlabroot%/toolbox/matlab/specgraph/meshc.m) in the latest Matlab release. Perhaps the new mechanism is not widely known even inside MathWorks; if so, then maybe things will change a bit with this post…
The post Named function input arguments (http://undocumentedmatlab.com/articles/named-function-input-arguments) appeared first on Undocumented Matlab.
### Related posts:
1. ishghandle's undocumented input parameter (http://undocumentedmatlab.com/articles/ishghandle-undocumented-input-parameter) The built-in function ishghandle accepts a second input argument with the expected handle type....
2. Function call timeline profiling (http://undocumentedmatlab.com/articles/function-call-timeline-profiling) A new utility enables to interactively explore Matlab function call timeline profiling. ...
3. IP address input control (http://undocumentedmatlab.com/articles/ip-address-input-control) A built-in JIDE control can be used in Matlab GUI for IP-address entry/display. ...
4. Editbox data input validation (http://undocumentedmatlab.com/articles/editbox-data-input-validation) Undocumented features of Matlab editbox uicontrols enable immediate user-input data validation...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment