Pure functions no longer work
Here's a small example of how pure functions fail:
In[7]:= fun = MFunction["fun", "@(x)(x*x)"];
In[8]:= fun[3]
During evaluation of In[8]:= MATLink::errx: Previously accessible file "/private/var/folders/31/l_62jfs110lf0dh7k5n_y2th0000gq/T/MATLink191006193822210uhjRgzkOEq/uKtxpwfYskhagiWAUbTICGodXvQBEFnSOVLmJDcljNMeqRZyrH.m" is now inaccessible.
Out[8]= $Failed
The underlying reason seems to be that if a pure function is defined in a script (.m file), then it will only work for as long as the .m file exists on disc. I asked about this here: https://stackoverflow.com/q/58259672/695132
Steps to reproduce this in MATLAB:
- Create a script
foo.mcontainingfun = @(x)(x*x) - Run
foo. This creates the variablefun. - Delete
foo.m - Try running
fun(2).
In recent versions of MATLAB this results in an error:
Previously accessible file "foo.m" is now inaccessible.
In older versions, it worked.
Turning off the JIT using feature('jit', 'off') does not help.
Internally, MFunction uses MEvaluate to create the anonymous function. MEvaluate works by writing the code into an .m file and running that file. There is an undocumented feature where MEvaluate[..., "NoScript"] will avoid doing this.
I do not remember all the reasons why we did this, but here are two:
-
We use the MATLAB Engine API function
engEvalStringto evaluate code. This is buggy and the longer the code, the slower it gets. -
More importantly, we needed to do this in order to be able to retrieve the error information for each evaluation.
If we make MFunction use MEvaluate["...", "NoScript"], then something like this won't report errors anymore (note the missing )):
MFunction["fun", "@(x)(x*x"]
Final note:
It looks like MATLAB have finally updated their engine API. I am not sure when this happened, but I think it is a very recent thing. We should probably use this new C++ API. It may be better, simpler and more flexible than the MEX-based thing we planned for MATLink 2.0.