MATLAB: Anonymous functions behavior is weird

anonymous functionsfunctionsMATLABoopsubsref

I encountered a weird behavior with anonymous functions
take a look at this class:
classdef object1 < handle
properties
x;
end
methods
function this = foo(this, x)
this.x = x;
this.print();
end
function this = foo1(this, x)
this.x = x;
end
function this = foo2(this, x, y)
if x > y
this.x = x;
else
this.x = y;
end
end
function this = print(this)
disp(['printing ' num2str(this.x)]);
end
end
end
Now because all the functions return this, I can use it to chain commands:
object1().foo(10).foo1(20).foo2(10, 20).foo(1:10)
printing 10
printing 1 2 3 4 5 6 7 8 9 10
ans =
object1 with properties:
x: [1 2 3 4 5 6 7 8 9 10]
Ok, this is nice, now I want to send this little functionality as a callback function to some operation
so let's throw this in an anonymous function:
@() object1().foo(10).foo1(20).foo2(10, 20).foo(1:10)
ans =
function_handle with value:
@()%T0.1%1%.foo(10).foo1(20).foo2(10,20).foo(1:10)


So far, so good…
now when I try to pu it in a variable it getss weird:
func = @() object1().foo(10).foo1(20).foo2(10, 20).foo(1:10)
Error: This statement is incomplete.
and weird gets even weirder:
@() object1().foo(10).foo1(20).foo2(10, 20).foo(1:10);
func = ans
func =
function_handle with value:
@()%T0.1%1%.foo(10).foo1(20).foo2(10,20).foo(1:10)
func();
printing 10
printing 1 2 3 4 5 6 7 8 9 10
Expected one output from a curly brace or dot indexing expression, but there were 0 results.
Error in @()%T0.1%1%.foo(10).foo1(20).foo2(10,20).foo(1:10)
This is strange as I saw already that this line of code returns a value
This behavior persists if i send it as an argument to a function instead of saving in a varialbe
that much at least is expected…
I know I can work around that by using function notation instead of dot indexing
but I like to avoid the pyramid of doom when I can, as this code is by far less readable:
func = @() foo(foo2(foo1(foo(object1(), 10), 20), 10, 20), 1:10)
func =
function_handle with value:
@()foo(foo2(foo1(foo(object1(),10),20),10,20),1:10)
>> func()
printing 10
printing 1 2 3 4 5 6 7 8 9 10
ans =
object1 with properties:
x: [1 2 3 4 5 6 7 8 9 10]
Sugestions?

Best Answer

I don't think the problem stems from anonymous function per se. I believe that the root of what you're seeing is that the chaining you're using in
object1().foo(10).foo1(20).foo2(10, 20).foo(1:10)
is not really allowed in matlab. You're indexing (dot is an indexing operation) the return value of a function which is illegal.
I know that mathworks have put in place some machinery to support some common use cases of dot indexing with functions, but clearly when you combine that with anonymous function (which also have some special machinery since they are closures) it breaks down.
See Philip's answer to a related question where he states that you shouldn't use chaining and also this answer to another question. Philip, if he's still around, would probably be the best person to explain the nitty gritty of why it brearks down with anonymous functions, but the bottom line is that you shouldn't be using function chaining even if it works in some cases. There's no guarantee it'll keep on working in future versions of matlab.