what is the differents
Blitz3D Forums/Blitz3D Beginners Area/what is the differents
| ||
what is the differents between functions and subs. |
| ||
A subroutine, as the name suggests, allows you to parcel away bits of code that might otherwise clutter up your source... handy for your main loop where reading through a list of thoughtfully named subroutines (rather than the raw code they contain, all in a big heap) can help keep things clear. Or for instances where you might want to reuse code without repeating it inline. Functions can take values, manipulate them and return a value - so you can apply the same process to any variables/objects you please (within the bounds of what makes syntactic sense) whereas a subroutine can only affect the variables/objects that it is hard-coded to alter. Each has their place, I think - does Max have subs yet? ;D |
| ||
Subs - No return value Functions - Has a return value Sledge - having a different name is rather redundant so I doubt bmax will have them. |
| ||
Functions take a slight performance hit, I understand, over subroutines. |
| ||
Or for instances where you might want to reuse code without repeating it inline. More important than keeping things clear in my eyes ;-) Functions take a slight performance hit, I understand, over subroutines. True to a certain extent. Technically-yes, noticably-no. When you make a function call with arguments, your merely pushing registers on to a stack, in CPU time, thats not much time at all... When a function is ran, it pops the registers to use the data, then at the end, pushes the return. Subs dont take values, or return values, therefore they are technically faster than functions. However the performance hit from a function should only be considered if your doing 100's of thousands of function hits (from the same function) per scan. If so, then take out the function (include the code into the caller), unless of course the function is for general use (modular) at which point keeping the function is probably best suited. Just my opinion. |
| ||
Something that needs to be mentioned is that a function basically creates a command and uses LOCAL variables So you could have a function called Add for example. So you could say a = add(5,10) print a waitkey function add(val1,val2) return val1 + val2 end functionOf course this is a very simple example but you get the idea. A slightly more complex example would be something like Function Interpolate#(a#, b#, x#) Return a*(1-x) + b*x End FunctionThis will take 2 values a and b and return the inbetween value at point x (0-1) So a#=Interpolate (1,2,.5) would return 1.5 for example (the halfway point between 1 and 2). Other functions you might create would be versions of existing commands, for example I have an oText command that I use a lot, works in exactly the same way as the text command but draws an outlined bit of text. Function oText(x,y,T$,centre_x = False,centre_y = False) Color 0,0,0 Text x-1,y-1,t$,centre_x,centre_y Text x+1,y-1,t$,centre_x,centre_y Text x-1,y+1,t$,centre_x,centre_y Text x+1,y+1,t$,centre_x,centre_y Color 255,255,255 Text x,y,t$,centre_x,centre_y End Function |
| ||
Good point Rob. When you call a sub or a function, the program merely diverts its run to another portion of a stack (think of goto where the program flow merely goes to that label). Functions will push off arguments, Go to the portion of hte program stack that has the function register calls, create a local variable stack, pop back the arguments, do its thing, then push off the return (if no return is expressed, it pushes off a 0). Then return to where it was in the program stack. Subs merely take program flow and go to the portion of the program stack and continue running. |
| ||
Using Functions is a far more elegant way of running bits of code which are reused in your program ( not withstanding being able to return a value ). AKAIK gosub etc... shouldn't be allowable as it's bad practice. I guess that's a matter of opinion but just my 10p worth. Stevie |
| ||
shouldn't be allowable as it's bad practice Yawn... somebody always pipes up with that one. They're conceptually different things - it's perfectly fine, desirable even, for a BASIC variant to distinguish between them. Just because C loves the compiler more than the user it doesn't mean every language has to. A void, argument-less function is an oxymoron. :D |
| ||
Last time I used gosub was on my C64. Made a breakout clone in basic using standard character graphics. It sucked. |
| ||
Personally I think gosub and goto are perfectly good commands. IMO The main reason they are deemed bad practice is because they are so often misused by the begineer and when used incorrectley can make the code very hard to debug/understand. |
| ||
I agree for Goto: there are a few situations where the no-goto equivilent of a function ends up with needlessly disgusting nested If blocks and/or repeated code. I disagree for Gosub: although I'm intimately familiar with Gosubbing (BASIC was my first language) I have yet to find a situation where it yields even arguably cleaner code than regular functions and calls. It's my belief that Gosub has been deprecated long ago and it's only available in Blitz Basic to complete support for the original BASIC command set. It may be useful as a learning tool; however, I would wean my students off of it as soon as I introduced functions. A void, argument-less function is an oxymoron. :D This is simply a semantic argument - the term "function" may be technically incorrect from the perspective of mathematics, but it's been adopted long ago by computer science to include subroutines. |
| ||
Sometimes when you convert a basic program to blitz that contains Gosub, it's the quick and easy way not to touch it, so you don't have to worry about globals and locals. In fact, sometimes the reason why a program doesn't work is when you forget to declare something to be global. The "strict" option in bmax is a solution that was missing in Blitz3D. However. what's the diffrence between Gosub and Function? Most important: Variables that are used inside of a function are locals, unless they are defined as globals outside the function. example: for i=0 to 10 job() print a next waitkey() function job() a=a+1 end function You see, although we call the function "job()" that will inclement a, it always remains the same. The reason is, threre are two A's, one in the main program (outside any function) and one in the function "job()". The a inside the function is local, this means the functoin cannot remember it's value. It is recreated whenever the function is called. Now this is totally diffrent when you add the line "Global a" to he top of the example: global a for i=0 to 10 job() print a next waitkey() function job() a=a+1 end function the function "job()" will now recognize that there is a global variable A and access it, instead of creating its own local variable. In case you don't want the function "job()" to use the global a, but a local version, then you may define a as a local inside the function: global a for i=0 to 10 job() print a next waitkey() function job() local a a=a+1 end function This last way is useful when you want to use a local variable (that is no longer used when the function is finished, but want to make sure not to disturb any other variable with the same name) Basicly good programming style is to use as few as possible global variables in a program, Functions that are not using global variables are perfectly modular, this means, you can copy/paste one function to an other program without to worry about identic variable names. Furthermore Functions take and return values. It was described earlier in this thread. You don't have to use the Return Command in a function, if you omit it, the function will be finised at the "end function" command. There may be multiple Return commands in your function, eg: print "the max of 3 and 4 is " + max#(3,4) function max#(a#,b#) if a>b then return a else return b end function One important bit is also this: depending on the return value you want to receive from a function (int, float or string) you need to call the function, eg: a$=my_edited_string$("hello") a#=my_ed_float#(3.12345) a=my_int_or_something(358132134) to make sure the function will be able to return the value. BTW if you want the function to return multiple values, you may use globals or a bank. |
| ||
This is simply a semantic argument We're having a discussion about language - semantics matter a great deal. |