Four differences between DEF and GOSUB
(Here's hoping [code ] is implemented in the foums...)
1. Functions with only one return value can be used in-place, i.e. anywhere you could normally use a single value.
DEF MyFunc(A,B)
RETURN A+B
END
W=X*MyFunc(Y,Z)
This is the old-fashioned meaning of 'function' in programming terms. See the Instruction List's DEF(3) for more info.
EDIT: This is also what SquareFingers is talking about in the post above.
2. When invoking a function with CALL, the function name can be given as a string variable.
Thus, if you rewrite a normal invocation:
A=MyFunc(X,Y)
...with CALL:
A=CALL("MyFunc",X,Y)
Then, you could replace the function name itself with a string variable,
MyVar$="MyFunc"
A=CALL(MyVar$,X,Y)
This can be used to call different functions (on the same arguments) without long if/elseif structures.
See the Instruction List's entries on CALL for more info.
3. It's easier to pass arguments to functions that are in a separate PRG slot then it is to GOSUB blocks that are in a separate PRG slot.
Among other reasons why you might have your code split into two different PRG slots, there's the idea that one slot could act as a kind of game 'engine' which would provide a suite of functions that the code in the main slot could access. This is hampered by the fact that there is no way to globalize variables across PRGs (no, COMMON doesn't do it).
You can access gosub blocks in a different PRG slot with
GOSUB "n:@MyGosub", where n is a PRG slot 0-3; but if you do this, none of the variables you've got values in from PRG0 can be accessed by the other slot.
The use of functions across PRG slots is more well-supported. If you define the function with COMMON DEF, it can be accessed from any PRG slot, and you can pass arguments to it just like you would any other DEF.
4. This last one isn't an 'advantage' so much as just a difference you should be aware of.
When you run a program, SmileBASIC scans your entire program for DEF blocks and loads them into memory right away. Thus, errors involving your DEF blocks (for example, two functions with identical names, or one with a missing END) show up immediately upon running the program, instead of only when the offending code is reached.
...then again, it might be an advantage after all:
Some speed testing I did earlier suggests (but has not proven) that using functions may actually be faster than navigating around your code with GOSUBs. (I was testing something else at the time so the results aren't clear, but actually it wouldn't be hard to make a test that tests this directly. Maybe I'll try that out tomorrow.)