functions vs. script

48 views (last 30 days)
carmen
carmen on 12 Mar 2012
Commented: Jan on 29 May 2017
Hello, my question is, what advantages do i have from using functions instead of scripts?
I am writing code with matlab for about one year now, my greatest project was about 1200 lines. I am fine with structuring my code with scripts & subscripts but lately i get in touch with the matlab GUI where i have to face functions. they appear to me as horribly inconvenient relatively to scrips. Can you give my reasons why i should ever use functions instead of scripts?
the pro arguments I have collected so far:
1) the private/public variables aspet. In fact I dont see where the difference is between a variabele that cannot be changed by other scripts/ functions and a variable that is not changed by other scripts by design (although it could if i wanted it to.) So this is no advantage for me.
Con arguments:
1)communication between functions is labourus since i have to set the public property multiple times(!) per variable or use handles etc which i recognize as inconvenient but still best option.
2) VERY IMPORTANT: when the program aborts with an error, the workspace of a fuction is lost and i cant use it for debugging. i have to use breakpoints and wait (considerable time... data processing takes time sometimes) until the program gets to the same point again. this is actually what i spend most time on when developing.
so for me its 2:0 for using scripts. any ideas why i should use functions or where they are more practical than scripts?
thank you :)
[edid: sorry, the answeres semm not to show up chronologically, so maybe some comments by me wont fit into the thread at their current position anymore]

Accepted Answer

Walter Roberson
Walter Roberson on 12 Mar 2012
While you are doing development, instead of using breakpoints (or as well as using breakpoints), consider using
dbstop if error
dbstop if warning
Then if you get an unexpected crash, you will have access to the context no matter where it is.
  2 Comments
carmen
carmen on 13 Mar 2012
A most valuable answer, thanks! that makes it soo much easier for me.
Jan
Jan on 13 Mar 2012
"dbstop if all error" allows the debugging even when the error appears inside a TRY-CATCH block.

Sign in to comment.

More Answers (6)

Daniel Shub
Daniel Shub on 12 Mar 2012
While I wouldn't term it private/public, the unique workspaces that you hint at in pro 1 is the real selling point to me. With a 1200 line project you might be able to keep the entire scope in your head, but as your programs grow, it will become very difficult to remember all your variable names and make sure you do not change something accidentally. The ability of scripts to freely interact with other scripts makes debugging a nightmare.
As for your cons. Once you get the hang of it, communication between functions is not that hard. Many functions only have a few inputs, other taken parameter value pairs, making it pretty painless. The ability to independently test a function makes debugging so much easier.
  5 Comments
Daniel Shub
Daniel Shub on 12 Mar 2012
The issue is with your con arguments. As I said, you get used to the communication issue. The encapsulation provided by functions makes debugging much easier. You do not have to rerun all your code to debug, rather you give the function a set of known inputs and check the outputs. It becomes a one step process and you don't have to worry about interactions.
carmen
carmen on 12 Mar 2012
thats correct, but does this hold for GUIs?
I got to this topic when i was annoyed about being forced to use functions for a GUI. when it crashes, i cant tell what the input arguments for the last function looked like since its gone. I need to re-run everything from the last state that i saved to harddisk (or from dummydata etc...) in order to debug the function. And i dont know how run the GUI from the middle of the code, so i start it all over again

Sign in to comment.


G A
G A on 12 Mar 2012
  4 Comments
G A
G A on 12 Mar 2012
"Every time a script is used in MATLAB, it is loaded into memory and evaluated one line at a time. Functions, on the other hand, are compiled into pseudo-code and loaded into memory once. Therefore, additional calls to the function are faster."
http://www.caspur.it/risorse/softappl/doc/matlab_help/techdoc/matlab_prog/ch8_pr18.html#44320
carmen
carmen on 12 Mar 2012
perfect answers for the "what" question, thank you a lot.

Sign in to comment.


Jan
Jan on 12 Mar 2012
Using TRY-CATCH with a meaningful error handling is more useful than running all code in a global context by using scripts. Imagine your code crashs and you want to find the line, which is responsible for the current value of "i". In a bunch of scripts, this can be very hard. If the code is divided into small functions, it is very clear where the definition of a variable must be searched.
Another important aspect is the code-reusability. If you have programmed and tested a function, you can re-use it in another context also. For a script the interaction with the context can lead to inconsistencies, such that a well tested code can fail to work. A typical example is the redefinition of max as a variable:
max(1:10);
max = rand(1, 10);
max(1:10);
Inside a bunch of scripts, such problems are harder to identify.
Nevertheless, with using enough evalin and assignin calls, you can destroy the stability advantage of the function approach effectively. These commands allow to get the drawbacks of scripts and of functions at the same time.
  3 Comments
sciscitari
sciscitari on 29 May 2017
Dear Jan, I did not understand what's the difference between scripts and function in your example about "max" function/variable. Is the following? If I have functions A, B and script A2, B2 (equal to A,B but scripts) and I call first A and then B, B will see max as the Matlab function. If I call instead the scripts, first A2 and then B2, B2 will see max as the redifined variable. Is this the difference you wanted to highlight? Thank you!
function A ()
max = rand(1, 10);
max(1:10)
end
function B()
max(1:10)
end
% script A2
max = rand(1, 10);
max(1:10)
% script B2
max(1:10)
Jan
Jan on 29 May 2017
@sciscitari: My code example concerns the difference between functions and variables. It should demonstrate, that using scripts is dangerous, because you might create a variable in it, which equals the name of a function, which is used in the caller. Then finding the cause of the problem is very hard:
% script: myDangerousScript.m
max = rand(1, 10);
% function file: mySafeFunction.m
function max = mySafeFunction
max = rand(1, 10);
end
% function file: mainFunc.m
function myFunc
max(1:10)
myDangerousScript;
max(1:10) % Unexpected and hard to debug
clear('max');
max(1:10)
data = mySafeFunction();
max(1:10) % Exactly what you expect when reading the code
end
Of course shadowing the built-in function max() is a bad idea. But if you use functions, this mistake does not propagate to the caller and thus you have a chance to find the source of problems during debugging.
Imagine you call a script, which calls a script, which calls a script - preferrably written by another person and tested with a different Matlab version with other toolboxes. Then it is extremely hard to find a shadowed built-in function, or an overwritten variable used in the main function.
It is not possible to check the correct working of a script by running an exhaustive unit-test, because you cannot check the inputs and outputs reliably. The created variables can have unpredictable side-effects in the caller.
Therefore I do not use scripts ever under no circumstances in no way not at all never ever. Even not for tiny hacks: If a hack is bad, I delete it, if it is good, it will grow, be enhanced and included in a greater code.

Sign in to comment.


Joao Henriques
Joao Henriques on 12 Mar 2012
As you've seen, it's very tempting to use functions as if they were scripts. Many people just use "global" to share variables between functions, and this is as messy as using scripts, so there's no advantage. To get all the advantages of functions, forget "global":
function f(param1, param2)
global a b c
...
And do this:
function [a, b, c] = f(param1, param2, a, b, c)
...
You may think this is slow when a/b/c are large, but it's not. Matlab won't do unnecessary copies of variables unless you modify them, so don't be afraid to pass large matrices around.
Some functions will have lots of parameters but when calling them I just copy&paste the definition. It's clear what data each function modifies, and you can redirect input/output at any time. This makes debug much easier.
You can also store parameters in a struct to pass them around. You can extract the variables to make them local (as I'm showing here) or modify the struct directly. Again, don't worry because matlab is smart when it comes to copying memory.
function s = f(param1, param2, s)
a = s.a;
...
s.a = a;
About the debugging, Walter Roberson is right. With "dbstop if error" active, it automatically creates a breakpoint when there's an error, so you can see what's happening and debug. I recommend you put them in your "startup.m" file so they run automatically when you start matlab.
  2 Comments
carmen
carmen on 13 Mar 2012
now, technically, whats the difference in your first two examples of code? both times you have variables that are "globally" available for modification (lets not think about nested functions)
in fact its not at all fancy what you write, but well worth being mentioned. also the startup.m is something i could really use but did not know.
Thank you for a nice answer.
Stephen23
Stephen23 on 1 Mar 2015
Edited: Stephen23 on 1 Mar 2015
"now, technically, whats the difference in your first two examples of code?"
Traceability is the difference. With globals you lose control over knowing when and under what circumstances those variables can change. It makes debugging a complete nightmare. With simple inputs and outputs it is possible to trace much more easily when variables have particular values, and under what circumstances. This has been explained many times:
To quote from the first link, Doug Hull: "I have never seen MATLAB code where globals were the right thing to do". And Matt Fig: "Those beginners (at my work) who use these constructs end up calling me to come fix their mess a few months down the road". And Jan Simon: "these commands cause more problems than they solve". This is an example of how globals make bad code:

Sign in to comment.


Stephen
Stephen on 12 Mar 2012
I find it easier to write separate functions and then just call them as needed with some big script or function instead of copy and pasting lines of code and having to check that the variable names agree. each little function is like a black box that can be inspected on its own that way.
  1 Comment
carmen
carmen on 12 Mar 2012
I use my scripts in the exact same way.
" having to check that the variable names agree" is a good point.
Thanks

Sign in to comment.


carmen
carmen on 13 Mar 2012
Thank you everybody for a set of very good answers, i think you helped me out to a great extend and made me do a big step forward in my matlab skills.
  2 Comments
carmen
carmen on 13 Mar 2012
.... i should be allowrd to accept more than only one answer, it would make sense here.
Jan
Jan on 13 Mar 2012
You can vote answers also.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!