Wish Optional arguments in Function or Sub

Laurent95

Active Member
Licensed User
Longtime User
Hi,

One thing that is really interesting in Visual Basic under Windows, the optional argument in a Function or a Sub.

Many cumbersome functions can be used but not always with all arguments i.e. for charts with Google.
I think this improvement don't need many test inside the function or sub for test if the argument is empty or null. And it allow the program to use shared modules with functions who have optional argument possibility.

Regards.
 

Troberg

Well-Known Member
Licensed User
Longtime User
I agree, optional arguments, or even better, the generic case of overloading, is very nice.

Consider these subs in my settings framework:

B4X:
SettingStr(Key as string, Value as string, Write as bool) as string
SettingInt(Key as string, Value as int, Write as bool) as int
SettingLong(Key as string, Value as long, Write as bool) as long
SettingBool(Key as string, Value as bool, Write as bool) as bool
SettingFloat(Key as string, Value as float, Write as bool) as float
SettingDouble(Key as string, Value as double, Write as bool) as double
SettingList(Key as string, Value as list, MaxItems as int, Write as bool) as list 'list of strings is assumed, MaxItems=0 for no limit

Wouldn't it be neater to just have this, and let the compiler figure out which to call, based on the arguments:

B4X:
Setting(Key as string, Value as string, Write as bool) as string
Setting(Key as string, Value as int, Write as bool) as int
Setting(Key as string, Value as long, Write as bool) as long
Setting(Key as string, Value as bool, Write as bool) as bool
Setting(Key as string, Value as float, Write as bool) as float
Setting(Key as string, Value as double, Write as bool) as double
Setting(Key as string, Value as list, MaxItems as int, Write as bool) as list 'list of strings is assumed, MaxItems=0 for no limit

Some argues that it means a lot of duplication of code, but, in my experience, you usually just write the most generic case (in this example, the string version), and then the others becomes trivial stubs that just do some minor stuff and call the most generic one.

Sidenote: I like to make my settings framwork symmetrical, so write and read is the same call, differentiated with an argument. It saves a lot of:

B4X:
Sub ReadSettings()
  ThisSetting=ReadSetting(ThisSetting,ThisDefault)
  ThatSetting=ReadSetting(ThatSetting,ThatDefault)
End Sub
 
Sub WriteSettings()
  WriteSetting(ThisSetting,ThisValue)
  WriteSetting(ThatSetting,ThatValue)
End Sub

Instead, I just do:

B4X:
Sub Settings(Write as bool)
   ThisSetting=Setting(ThisSetting,ThisSetting,Write)
   ThatSetting=Setting(ThatSetting,ThatSetting,Write)
End Sub

This handles both cases, and if reading, if the value does not exist, the previous value of the setting (which is hopefully initialized to a senible value) is returned as default.
 

Laurent95

Active Member
Licensed User
Longtime User
B4X compiler converts automatically between strings and number types. So you don't really need to create all these subs. Create a single one and expect Object or String and it will just work.

Hi Erel,

Thank you for take the time to read and respond to our wishes.
I know well that to do an hotline that's not really easy, so often the users don't give enough explanation about their request.

Can you explain your reply a bit more, If it's ok for all case or only for the settings ?
I don't really see how i can apply it in the case i talk before, i explain what i mean.
In the case i give for shows a Google chart in a webview :
Many chart have interesting optional argument in the "options" of the chart.
And also Google assemble several type of chart in the corechart constructor.
Then, in this case, we need to test each argument if it's possible to apply or not, and if it's ok or not for the value.
It's why i give this example, in this case if the argument is optional the compiler don't return an error even if the argument is not set.
That can allow us to don't write, in many case, more than one conditional code, depends the type of chart of the corechart is used.
That's only an example that i work around on for now, but i remember that i have had the same remark in many case before.

Thank you by advance for give more explanation about it.

Regards.
 

Laurent95

Active Member
Licensed User
Longtime User
ah ok, thank you for this precision, i understand better.
Then, the wish is always in actuality :)

Good day to you Erel, Laurent.
 

Troberg

Well-Known Member
Licensed User
Longtime User
B4X compiler converts automatically between strings and number types. So you don't really need to create all these subs. Create a single one and expect Object or String and it will just work.

True, but not always. Sometimes, for example, I might want to add a specific formating, for example, I might want to save bools as "yes/no" and dates in "yyyy-mm-dd hh:mm:ss" format, for human readability (and editability).

Another example where I've previously used overloading is for status display, where I had (and this is from memory, so there might be some errors):

B4X:
SetStatus() 'Clears status
SetStatus(Text as string) 'Sets status text
SetStatus(Percent as int) 'Sets status bar
SetStatus(CurrentValue as int, MaxValue as int) 'Sets status bar
SetStatus(CurrentChunk as int, MaxChunks as int, CurrentValue as int, MaxValue as int) 'Sets status bar, used when several long database operations are run in series, where each operation becomes one "chunk"
SetStatus(EstimatedTime as long) 'Starts an automatic status bar increasing asymptotically towards 100% on a timer, with 50% at half the estimated time. Used to fake a bar when you don't know how far along an operation is.
SetStatus(Text as string, Percent as int) 'Sets text and status bar
SetStatus(Text as string, CurrentValue as int, MaxValue as int) 'Sets text and status bar
SetStatus(Text as string, CurrentChunk as int, MaxChunks as int, CurrentValue as int, MaxValue as int) 'Sets text and status bar, used when several long database operations are run in series, where each operation becomes one "chunk"
SetStatus(Text as string, EstimatedTime as long) 'Sets the text and starts an automatic status bar increasing asymptotically towards 100% on a timer, with 50% at half the estimated time. Used to fake a bar when you don't know how far along an operation is.

These were used a several very database heavy projects, where big, slow calculations were common, and I needed to make it dead simple to display status, otherwise the other developers would not use it, and the application would often seem unresponsive to the user. This way, no matter what situation they are in, some variant would fit the need.

Of course, behind the scenes, all of these just do some minor calculation and calls SetStatus(Text as string) and/or SetStatus(Percent as int).

I also did some minor neatifications for the other developers, such as, even if it was operation 1 of 1000000, it would still show 1%, and even if it was operation 999999 of 1000000, it would still show 99%. Not mathematically correct, but makes more sense to the user.
 

Troberg

Well-Known Member
Licensed User
Longtime User
That's a reason as good as any, and I understand that it might be a problem.

Just take note that it's a much wished for feature, and maybe slowly nudge the code base in a direction where it some time might be possible. :)
 
Top