Page 1 of 2
Calculations in procedure declarations
Posted: Thu Sep 17, 2009 11:22 am
by PB
I tried something like this today and was surprised to get a syntax error:
Code: Select all
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=GetSysColor_(#COLOR_BTNFACE))
...
EndProcedure
Even this gives a syntax error:
Code: Select all
Global syscol=GetSysColor_(#COLOR_BTNFACE)
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=syscol)
...
EndProcedure
Would it be possible to have procedure parameters calculated in future, or this this technically impossible?
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 11:34 am
by blueznl
You're specifying a default parameter, for those situations where no parameter is specified in the function call. What you're requesting that if there is no parameter that parameter is going to be replaced with the specified function call. I'm not so sure that would lead to predictable results

I thought the idea of a default value was a default value, and you're want the default value no longer to be a default value

Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 12:43 pm
by PB
> What you're requesting that if there is no parameter that parameter is going to be replaced with the specified function call
No, it means if I call the procedure without specifying a newcolor, then it takes the value of #COLOR_BTNFACE instead, no matter what that value is set to in Windows by the user's color scheme. Surely you agree that's not an unreasonable thing to want? Otherwise, I'd have to code it something like this (where passing -1 means use the default system color, and any other value means use that value):
Code: Select all
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor)
If newcolor=-1 : newcolor=GetSysColor_(#COLOR_BTNFACE) : EndIf
...
EndProcedure
Which is why the concept of having default parameters came about in the first place, to avoid doing code like this.
Here's another example. Say you have an email app that lets the user specify a custom port to send through (default is 25) and the value of the custom port is held in a variable called myport, but you also want the user to be able to switch ports on the fly. You get a syntax error with this:
Code: Select all
Global myport=136
Procedure SendMailViaCustomPort(mailto$,mailfrom$,port=myport)
...
EndProcedure
So you have to code it something like this (where -1 means use the custom port, and any other value means use that value):
Code: Select all
Global myport=136
Procedure SendMailViaCustomPort(mailto$,mailfrom$,port)
If port=-1 : port=myport : EndIf
...
EndProcedure
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 12:54 pm
by Trond
PB wrote:Otherwise, I'd have to code it something like this (
where passing -1 means use the default system color, and any other value means use that value):
Code: Select all
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor)
No absolutely not! This is why default parameters were introduced: so you DON'T have to pass -1!
See:
Code: Select all
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=-1)
If newcolor = -1
newcolor=GetSysColor_(#COLOR_BTNFACE)
EndIf
EndProcedure
ReplaceImageColor(0, 0)
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:06 pm
by Kaeru Gaman
xactly.
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:41 pm
by PB
> This is why default parameters were introduced: so you DON'T have to pass -1!
I agree! You're preaching to the choir. I just want to know why we can't use GetSysColor_(#COLOR_BTNFACE) as a default parameter then, like in my first post. Surely the compiler can say: "Oh, PB wants the default system color here because he called it with
ReplaceImageColor(imgnum,oldcolor) only, leaving
out the
newcolor param, so let me fetch it for him... done!".
And then later if I want to use red to replace the old color, I can just call it like this:
ReplaceImageColor(imgnum,oldcolor,#Red).
See what I mean? The idea is to
avoid doing an If/Then inside the procedure, as Trond demonstrated above.
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:46 pm
by eesau
Code: Select all
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=ReplaceImageColor(imgnum,oldcolor))
...
EndProcedure
This would be interesting...
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:50 pm
by Trond
I just want to know why we can't use GetSysColor_(#COLOR_BTNFACE) as a default parameter then, like in my first post.
So what kind of answer do you want?
Answer 1: Fred didn't bother to implement this because he thought it was really a waste of time, since you can simply do what I did.
Answer 2: It's ugly.
Answer 3: One of the parameters can take a default value. A function call is not a value. Yes, it returns a value, but it isn't one. So that's why you can't use a function call there.
Answer 4: For the same reason you can't do #DefaultColor = GetSysColor_(#COLOR_BTNFACE).

Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:51 pm
by freak
Technically the applying of the default parameter happens _outside_ the procedure.
The compiler turns this:
Into this:
Code: Select all
ReplaceImageColor(0, 0, <default value>)
If the default value could contain variables, procedure calls, etc then this would lead to complications because we are actually inside the scope of the caller, not the scope of the procedure. This is why only literal values are allowed which can be placed everywhere without side effects.
Just use Tronds way. I don't see a problem with it.
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:52 pm
by PB
I just wanna get this off my chest.
This (which fails):
Code: Select all
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=GetSysColor_(#COLOR_BTNFACE))
is surely technically no different to this (which works):
Code: Select all
Debug GetSysColor_(#COLOR_BTNFACE) ; Returns 14933984.
Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=14933984)
EndProcedure
So why a syntax error? Just because the calculation is done in the procedure declaration?

Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:53 pm
by PB
I see both Trond and Freak replied while I typed my last post. Points taken. I just thought it was technically possible to do it and maybe it hadn't been considered. No worries, then, if that's not the case.

Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 1:58 pm
by Trond
I must point out that the two codes you posted as equivalent, actually aren't. Because in one case, the default value is a function call, in the other case it's a constant value, which was the result of the function call at a given time. The function call in the second code is really irrellevant to the workings of the code.
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 2:02 pm
by PB
> was the result of the function call at a given time
I know that, I thought perhaps at the given time the procedure would just fetch the value, that's all. It didn't seem to me to be such an issue, but obviously it is or it would've been done. No worries then. My pre-processor will save the day instead.
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 2:04 pm
by Trond
Actually, it seems like Freak is slightly inaccurate. The evaluation of the default parameter happens at the procedure declaration, not at the call. However, to enable this, run-time features (like variables and function calls) cannot be used, else this would not be possible.
A macro code demonstrates that "ReplaceImageColor(0, 0)" is actually NOT literally turned into "ReplaceImageColor(0, 0, <default value>)":
Code: Select all
#Const = 123
Procedure OptoParam(Required, Optional = #Const)
Debug Optional
EndProcedure
Macro A(Const)
OptoParam(1)
OptoParam(1, #Const)
EndMacro
A(MAXLONG)
Re: Calculations in procedure declarations
Posted: Thu Sep 17, 2009 2:06 pm
by Trond
This has to be a bug?
Code: Select all
Declare OptoParam(Required, Optional = 789)
OptoParam(0)
#Const = 123
Procedure OptoParam(Required, Optional = #Const)
Debug Optional
EndProcedure
OptoParam(0)