Calculations in procedure declarations

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Calculations in procedure declarations

Post 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?
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Calculations in procedure declarations

Post 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 ;-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Calculations in procedure declarations

Post 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
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Calculations in procedure declarations

Post 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)

User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Calculations in procedure declarations

Post by Kaeru Gaman »

xactly.
oh... and have a nice day.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Calculations in procedure declarations

Post 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.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: Calculations in procedure declarations

Post by eesau »

Code: Select all

Procedure ReplaceImageColor(imgnum,oldcolor,newcolor=ReplaceImageColor(imgnum,oldcolor))
  ...
EndProcedure
This would be interesting...
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Calculations in procedure declarations

Post 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).

:?:
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Calculations in procedure declarations

Post by freak »

Technically the applying of the default parameter happens _outside_ the procedure.

The compiler turns this:

Code: Select all

ReplaceImageColor(0, 0)
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.
quidquid Latine dictum sit altum videtur
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Calculations in procedure declarations

Post 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? :shock:
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Calculations in procedure declarations

Post 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. :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Calculations in procedure declarations

Post 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.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Calculations in procedure declarations

Post 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.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Calculations in procedure declarations

Post 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)
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Calculations in procedure declarations

Post 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)
Post Reply