Argument validation
I often see the need of argument validation for which the arguments depend on each other.
function result = myFcn(points, attributes, queryIdx)
% INPUT
% points: [Nx3]
% attributes: [Nx1]
% queryIdx: [Mx1]
%
% OUTPUT
% result: [Mx1]
end
points and attributes depend in size, queryIdx and result as well. The current arguments/end block does not allow to formulate such constraints. The best you can do currently is
function result = myFcn(points, attributes, queryIdx)
arguments(Input)
points (:,3)
attributes (:,1)
queryIdx (:,1)
end
arguments(Output)
result (:,1)
end
assert(height(points) == height(attributes), "Argument validation failed")
...
assert(height(queryIdx) == height(result), "Argument validation failed")
end
Reading just the header without additional comments is unclear for a developer and prone to misunderstanding.
What do you think of the following language extension proposal?
function result = myFcn(points, attributes, queryIdx)
arguments(Input)
points (N,3)
attributes (N,1)
queryIdx (M,1)
end
arguments(Output)
result (M,1)
end
end
The intention is clear for the reader at first sight and gives you guarantees about input/output parameters (in contrast to simple comments). Validating the parameter "points" sets the (temporary) variable N, which can be reused in further argument validations. To be discussed if N and M are valid just within the arguments block or also in the whole function.
What is your opinion on such a language improvement?
11 Comments
Time DescendingYou cannot do this with just size validation. But using validation functions you can enforce conditions that relate to multiple input arguments. A validation function can include as input arguments the argument being validated, literals, or previous defined positional input arguments. In the example in that section of the linked documentation page, the local function mustBeEqualSize enforces that the input argument v that it's being used to validate is the same size as the previously defined input argument x.
To me, seeing a validation function named mustBeEqualSize(v, x) in the arguments block is a pretty clear statement of the constraint on the sizes of those two input arguments, so long as the author isn't trying to be misleading (having mustBeEqualSize enforcing that the input arguments are the same data type, for example, which ought to be flagged as "Change the name of your validation function to reflect what it's actually doing" in a code review.)
And if mustBeEqualSize were a validation that you wanted to do in multiple functions that you're writing, there's nothing preventing you from adding it to your own personal collection of functions. It doesn't have to be a local function.
This approach is more flexible than your proposal (for example, it can enforce that two inputs are compatibly sized not just equally sized), albeit also being more verbose.
If were to do some such, this example should also have some syntax to ensure M<=N
My only concern would be one of how much more runtime overhead is introduced continuing to extend to more and more testing in the runtime code instead of verification in ensuring inputs meet the contract.
I would like to see improvements along these lines.
Also, this post is related:
Sign in to participate
