Scripts contain as many or as few functions as you want, and the same is true for function files.
There are only a small number of circumstances under which you must put code into separate files:
- class definitions must be in separate files
- packages must be defined in separate directories
- if you want to be able to call a function from outside the file that defines the function, then either the function must be the first function in its .m file or else you need to arrange for the caller to have a handle to the function (function handle)
The main difference between scripts and functions is that scripts have access to the workspace of the function that invoked them (possibly through a chain of scripts). This has the consequence that variables defined within a script do not disappear at the end of the script, because the variables are not in the script's workspace but rather in the workspace of the caller.
Because scripts have access to the workspace of the caller, MATLAB has a much more difficult time optimizing the execution of the calling routine and of the script itself, because any given variable reference might be to a variable that is used at another level.
For example, you might have code
i = 1;
while i <= 5
i = i + 1;
How many times will my_script be called? The answer cannot be determined without knowing the content of my_script, since my_script might change the variable i.
So how does a routine that is calling a script ensure that its control variables are not accidentally changed in the script?
MyPrivateControlVariableJW581 = 1;
while MyPrivateControlVariableJW581 <= 5
MyPrivateControlVariableJW581 = MyPrivateControlVariableJW581 + 1;
No, this is not enough, because my_script might happen to use MyPrivateControlVariableJW581 . Or my_script might happen to have
Therefore in order for a routine and a script to avoid conflicting with each other accidentally, there has to be an "interface contract", such as an agreement that the script will use a particular prefix for its local private variables and that the calling routines must avoid that particular prefix for their local private variables.
Now, using interface conventions like this do not improve the speed of MATLAB, because MATLAB does not know the interface convention -- it cannot know that my_script_local_variable_JW581 has been carefully avoided as a possible name in the callers and so has to check every variable.
If you are going to the trouble of constructing an interface contract like that to avoid accidental conflict between caller and script... then why not just formalize the interface with a function() header, after which there is no problem because any variable not assigned to by the function call cannot have its value changed (unless the called routine cheats and calls assignin() or evalin() that contains an assignment.)
So using scripts makes robust programming more difficult and less efficient.
As for generating code from a script: remember that if the script does something like
for i = 1 : 5
then to properly generate code for that that is fully equivalent to calling the script, then the generated code would need to have logic that looked back through the workspace of the caller of the code in order to determine whether the caller happened to have a variable named i, in which case the generated code would have to overwrite that variable, in order to have the same effect that calling the script would have.
Why would you want to do any of this??