what is the differents

Blitz3D Forums/Blitz3D Beginners Area/what is the differents

malicnite(Posted 2005) [#1]
what is the differents between functions and subs.


Sledge(Posted 2005) [#2]
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


Bot Builder(Posted 2005) [#3]
Subs - No return value
Functions - Has a return value

Sledge - having a different name is rather redundant so I doubt bmax will have them.


Sir Gak(Posted 2005) [#4]
Functions take a slight performance hit, I understand, over subroutines.


DH(Posted 2005) [#5]
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.


Rob Farley(Posted 2005) [#6]
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 function
Of 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 Function
This 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



DH(Posted 2005) [#7]
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.


Stevie G(Posted 2005) [#8]
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


Sledge(Posted 2005) [#9]

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


VP(Posted 2005) [#10]
Last time I used gosub was on my C64. Made a breakout clone in basic using standard character graphics.

It sucked.


Chevron(Posted 2005) [#11]
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.


octothorpe(Posted 2005) [#12]
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.


jfk EO-11110(Posted 2005) [#13]
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.


Sledge(Posted 2005) [#14]

This is simply a semantic argument



We're having a discussion about language - semantics matter a great deal.