Consider the minimally reproducible example:
f = @(x) x
f(end)
Note, the MATLAB syntax highlighter doesn’t actually highlight end in blue, showing that it is not parsing as a keyword, even though the Stack Overflow syntax highlighting does.
Output:
f =
function_handle with value:
@(x)x
ans =
1
You can even do things like
f = @(x) x
a = f(end + 1)
b = f(end - 100)
c = f(2 + end)
Output:
a =
2
b =
-99
c =
3
Regular Function
If you have a regular function, this doesn’t work
foo(end)
function x = foo(x)
end
Error: <filename> Line: 1 Column: 5
The end operator must be used within an array index expression.
Hypothesis
From this, it appears that end is being coerced into the value 1, similar to how the boolean/logical true gets coerced to 1. My hypothesis is that since the function handle is actually a 1×1 array of function handles, the end keyword is replaced by the last valid index of the array which is 1. Since a function is not stored as an array, it doesn’t work for real functions.
My Bug
I had a particularly nasty bug where I was was trying to index into an array with a similar name as a function handle:
x = 1:5
foo = @(x) x
foos = foo(x) % [1, 2, 3, 4, 5]
out = foos(1) + 2 * sum(foos(2:end-1)) + foo(end)
% Expected: out = 1 + 2 * (2 + 3 + 4) + 5 = 24, Got: out = 1 + 2 * (2 + 3 + 4) + 1 = 20
Obviously, I renamed my variables to make them more distinguishable. Still, this behavior doesn’t seem useful for anything that I can think of. Is this an artifact of result of every object (including a function handle) secretly being an array? If so, is there anything the user do to prevent this or does a fix need to come from MathWorks?
3
There’s no “secretly an array” about it – every value in MATLAB is an array. MATLAB uses the same syntax for array indexing as for function evaluation, hence the ambiguity. The behaviour is documented here: https://uk.mathworks.com/help/matlab/matlab_oop/overload-end.html
Basically, when MATLAB encounters end
inside an indexing expression, it calls the end
method of the thing being indexed to work out the last element in the appropriate dimension. You can implement your own end
method for classes that you write – only useful if you’re writing a class that is a scalar instance with array-type behaviour.
The oddness comes about because “indexing” into a function_handle
actually evaluates the function. However, when interpreting the arguments to that “indexing” expression, the usual rules about evaluating the end
method applies and since function_handle
arrays can only ever be scalar, it always returns the value 1.