Script vs Function with no input/output

Sometimes I have to write a function ad-hoc for a script purpose. Usually I was simply creating a new .m file containing the function.
In order to increase the robustness of my code and avoid a crowd of small .m files roaming around i'm starting considering to exploit the ability of function files to include sub-functions directly in their inside. To exploit this ability however I have to declare the whole script as a function with no input and no output.
Therefore, instead of having:
  • Script.m
a=1;
b=2;
c=fun(a,b);
  • fun.m
function c=fun(a,b)
c=a+b;
I create a single file
  • Script.m
function script()
a=1;
b=2;
c=fun(a,b);
function c=fun(a,b)
c=a+b;
Of course in this case it seems useless. But sometimes this allows to have only one file instead of 5, 10 or maybe even more that can be shared more easily and are more "compact". (Indeed this kind of behavior can be done natively in other languages such as Python)
Now my question is: except for the "usual" care that have to be put in place when debugging a function and not a script due to the different workspace the variable resides into; is there any drawback you can spot?
Thank you for your opinion. Regards, Luca

 Accepted Answer

functions are usually better than scripts.
Depending on the exact MATLAB release and the complexity of the code and what the code does, there have been some cases where a script could be marginally faster than a function. Single-command scripts can potentially be faster than functions due to function-call overhead. For anything longer, functions are almost always faster.
There have also been some cases, historically, where there have been subtle errors in code interpretation due to the Just In Time optimizer being applied to functions but not to scripts. It happens. It is not at all common.
You do have to watch out for calls such as ode45 where Way Back (like MATLAB 5 and earlier) the way to pass the names of routines to call was as strings, whereas everything newer using function handles is preferred. If you do have something coded using a string as a routine name, and you move the function that is designated to become a function in the same file, then the routine that is doing the calling will not be able to find the function. When functions to call are named by strings, then the function has to have its own .m function file (because the expression that is executed to find the function from the string is executed in the base workspace). The real fix is to convert the call to @ syntax, as that syntax is fine with looking in the same file.

5 Comments

Ok. So as soon as I use a recent (actually the last) release there's actually no draw-back in that method. Did I understand correctly?
About your answer, I just did not understand what you mean by "using a string as a routine name". Is this some sort of old and now deprecated alternative to the @ notation? Sorry, but I never heard of it (I started using MATLAB around 2010. I was 11 y.o. when MATLAB 6 came out ;) )
Stephen23
Stephen23 on 4 Nov 2015
Edited: Stephen23 on 4 Nov 2015
Yes, just ignore older users referring to "inline functions", or calling functions via strings. The function handle @ has replaced all of these uses, and is more robust and better suited to the task... because it was designed exactly for the task of being a handle to a function :)
My basic rule of thumb:
  • Use scripts for short term work: trying things out, testing how a function can be used, doing a quick calculation.
  • If the functionality will be used the next day, then it should be in a function: its own workspace, no variable name clashes, abstraction of functionality... there are many advantages to functions.
Ok. After few days of testing this "new" method I found a drawback that I leave here for future readers.
I have a .mat file containing a variable "beta"
The script
load file.mat
alpha=beta+2;
works finely. However if you convert it to
function script()
load file.mat
alpha=beta+2
it returns an error saying that beta has not enough input.
I figured out that this was due to the Just In time optimizer that doesn't see any declaration for beta and therefore "thinks" beta to be the built-in "beta" function.
To workaround this I found two possible solutions:
  1. Don't use variables name equal to function ones. This should already be deprecated, but sometimes can happens. In this case moreover I could not change the name, so I went for solution number 2
  2. Declare a dummy variable with that name at the beginning of the funtion. Changing the function to
function script()
beta=[];
load file.mat
alpha=beta+2
makes the JIT interpreter to understand that beta from thereafter is indeed a variable and correctly interprets the script.
I would have become mad if it wasn't for your warning regarding the care that have to be put in place when switching from script to function. Thank you very much for it.
Bye
The better approach is to never "poof" variables into existence. Use the function form of load()
function script()
fd = load('file.mat');
alpha = fd.beta;
Also note that if you use the newer style of function in which you have an "end" matching the "function" line, then attempting to poof variables into existence will create an error about attempting to add variables to a static workspace. MATLAB can optimize notably better when it knows that variables cannot suddenly appear or suddenly be changed by functions.
Another (simpler I think) fix is to specify the name of the variable to be loaded in the load call, then the JIT knows it will exist.
function script()
load file.mat beta
alpha=beta+2
This works without error.

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!