Call by Reference - Optional Paramters

BlitzMax Forums/BlitzMax Programming/Call by Reference - Optional Paramters

N3m(Posted 2005) [#1]
If i have a function with a parameter wich uses the call by reference mechanism, like this one:

Function MyFunction ( a:String, b:String Var )
...
End Function


is there a way to make this parameter b optional?


klepto2(Posted 2005) [#2]
I don't know if there is a better way, but I would do it that way:


Function MyFunction (a:String, b:String = Null)
If b <> Null then 
 .. code for both strings
else
 .. code only for a
endif

End Function




N(Posted 2005) [#3]
Nope, I've tried passing Null to'em and such, but it doesn't work. Just gotta work it out with temporary variables.


Dreamora(Posted 2005) [#4]
With var there is no use in making it optional.
VAR is for returning value not for entering nothing ... as a return needs to have an existing object reference, you need to pass an object.
If you have the case where you would need to pass nothing in, you have some quite bad design flaws in your OO system. (ie functionality should NEVER return values and change something in one step)


For regular cases without var: = "const of the needed type" (number for numeric, "" or null for string and null for real objects)


Chris C(Posted 2005) [#5]
I could do it if I could figure out how many items are in and array, this is as close as I can get off the top of my head
test(["a"],1)

test(["a","b","c"],3)

test(["hello","there"],2)


Function test(s:String[],n:Int)
	Print

	For x=0 To n-1
		Print (x+1)+" "+s[x]
	Next
	
EndFunction



N(Posted 2005) [#6]
Chris:

Function test( s:String[] )
	For Local x:Int = 0 To s.Length-1
		Print ( x + 1 ) + " " + s[x]
	Next
End Function



Koriolis(Posted 2005) [#7]
With var there is no use in making it optional.
Not quite true. It would make sense with global variables as default values. Just like in C++ by example:
int a = 7;
int b = 123;

void myFunc(int & bla = a) {
	cout << bla << endl;
	++bla;
}

int main(int argc, char* argv[])
{
	int c = 5;

	myFunc(); // same as myFunc(a)
	myFunc(b);
	myFunc(c);

	return 0;
}
Sure you'll find a lot less legitimate uses for it, but it does make sense.


Dreamora(Posted 2005) [#8]
Ok this might make some sense ...
At least on C++ level of OO ...

But for globals there is no need to pass them in so on the other side there isn't much real sense as well ... you could check if there was an input if not take global for example


Koriolis(Posted 2005) [#9]
But for globals there is no need to pass them in so on the other side there isn't much real sense as well
Uh?!? If I have N globals that I want to apply a function on, you're suggesting duplicating the function N times, one for each global variable?


N(Posted 2005) [#10]
Koriolis is right in that case.


Dreamora(Posted 2005) [#11]
No, but if you have 100 globals you can't have 100 "default values" so we are at the point where you don't need one.

So far the only examples I've seen on usages of it are cases that work without a default var value without problems.


Koriolis(Posted 2005) [#12]
No, but if you have 100 globals you can't have 100 "default values" so we are at the point where you don't need one
But by the same reasonin I could say that standard default parameter values are of no use because I can have only one default parameter. Which doesn't quite makes sense don't you think.
Just an example:
Global MyInt1%
Global MyInt2%
...
Global MyInt100%

' I make the default value be MyInt7, because I really really like that variable and I will use very often
Function MySuperDuperFunction(bla:Int Var = MyInt7)
   bla = bla + 1
End Function
I have 100 variables, and I do have a default parameter value for my function. No problem. I can do MySuperDuperFunction(), but I can still do MySuperDuperFunction(MyInt1) ..MySuperDuperFunction(MyInt100). Still no problem.


Dreamora(Posted 2005) [#13]
But you miss the main problem:

On VAR you need an existing type instance and this is can only be said at compilertime using consts ...

With unintialized stuff the app would just crash.

So for VAR there would be the need of an existance check and the bold 24pt note in the docs that null and unexisting type instances are not allowed and even then most would not read it and spam the board with errors that do not exist ...


Koriolis(Posted 2005) [#14]
Geez, what the heck are you saying? OK, better give up, good night.


Dreamora(Posted 2005) [#15]
VAR access the memory of the variable, not the value. So the memory musst exist. Problem is that globals can or can not be initialized when the function is called and in the case that they are not, your program would just crash as it tries to access something that does not exist.

For that reason, only constant values are allowed as default values, as their state can be guaranteed at compile time.


Koriolis(Posted 2005) [#16]
Ahem, the memory of globals will *always* exist at the time the function is called. And the adress of the global will also *always* be known (or else I couldn't even pass explicitely the global as in MySuperDuperFunction(MyInt7).
All the compiler has to do is to pass at the call site the adress of the global variable that was specified as the default value. Bbecause this is internally what is passed, the address. How do you figure C++ is doing it?
Heck, it's so simple that it could even be done by a preprocessor: just replace every occurence of MySuperDuperFunction() by MySuperDuperFunction(MyInt7). You do agree that such a replacement would be doable, don't you? So now the compiler encounters "MySuperDuperFunction(MyInt7)", where's the problem in compiling that?

Oh, also you seemed to want to talk about object parameters (when my example was about simple integers, but whatever). While the object itself can indeed not be allocated yet, that is no problem because what is passed by var is a *reference* and it *has* to be allocated at the time the function is called, just like integers. Wether it's Null or already points to an object is another story.


N3m(Posted 2005) [#17]

With var there is no use in making it optional.
VAR is for returning value not for entering nothing ... as a return needs to have an existing object reference, you need to pass an object.
If you have the case where you would need to pass nothing in, you have some quite bad design flaws in your OO system. (ie functionality should NEVER return values and change something in one step)


I am using var for returning but not every body needs the returned value. It is for a regular expressions matching method:

Local matches:String []
if MyRegularExpression.Match ( "match the regex against this string", matches ) 
 For Local match:String = eachin matches
  print match
 Next
else 
 Print "No Match"
endif


I would like to make the matches parameter optional, because it is not needed in every application.


Koriolis(Posted 2005) [#18]
Well actually in this specific case it indeed doesn't make much sense to have a default parameter. How would you use it exactly, without passing the string array reference?


Rambo_Bill(Posted 2005) [#19]
I'd think you would put an if statement in front of the function call if there is no reason to use it, instead of calling the function without passing it anything. It's kind of like giving the ReadLine function an empty array instead of a tStream object and expecting it to do something.