I was going though C# course and found "Default Parameter Value"
B4X:
static void MyMethod(string country = "Norway")
{
Console.WriteLine(country);
}
static void Main(string[] args)
{
MyMethod("Sweden");
MyMethod("India");
MyMethod();
MyMethod("USA");
}
// Sweden
// India
// Norway
// USA
I know we have made wishes from very early version of B4A (year 2016 maybe), but again I see the benefit of it, when we have big project.
We already have GetDefault() method for class, so maybe we can have the reverse "default parameter value" in the Sub.
One-time-only Sub for shared use by Subs that have parameter defaults:
'returns array of defaults-filled-in parameters that is at least as long as the array of default values
Sub FillInDefaultParameters(ParGot() As Object, ParDefault() As Object) As Object()
Dim NumGot As Int = ParGot.Length
Dim NumDefault As Int = ParDefault.Length
If NumGot > NumDefault Then
Dim NumComplete As Int = NumGot
Else
Dim NumComplete As Int = NumDefault
End If
Dim ParComplete(NumComplete) As Object
For I = 0 To NumComplete - 1
Dim TempPar As Object = Null
If I < NumGot Then
TempPar = ParGot(I)
End If
If TempPar = Null Then
If I < NumDefault Then
TempPar = ParDefault(I)
End If
End If
ParComplete(I) = TempPar
Next
Return ParComplete
End Sub
Example Sub with def... uh, what it says:
Sub ExampleSubWithDefaultParameters(Par() As Object) As String
Dim RealPar() As Object = FillInDefaultParameters(Par, Array As Object( _
"25th", _
"December", _
2022, _
"The Best Christmas Ever!" _
))
Return RealPar(0) & " of " & RealPar(1) & " " & RealPar(2) & " = " & RealPar(3)
End Sub
Example calls:
'defaults are: "25th" "December" 2022 "The Best Christmas Ever!"
' ====== ========== ==== ================================
Log(ExampleSubWithDefaultParameters(Array As Object(Null , Null , Null , Null )))
Log(ExampleSubWithDefaultParameters(Array As Object(Null , Null , 2023 , Null )))
Log(ExampleSubWithDefaultParameters(Array As Object(Null , Null , 2020 , "the worst xmas I've ever seen?" )))
Log(ExampleSubWithDefaultParameters(Array As Object("31st" , Null , Null , "the last day of this year." )))
Log(ExampleSubWithDefaultParameters(Array As Object("1st" , "January" , 2023 , "the first day of next year." )))
Log(ExampleSubWithDefaultParameters(Array As Object("1st" , "August" , Null , "Swiss National Day this year." )))
Log output:
Waiting for debugger to connect...
Program started.
25th of December 2022 = The Best Christmas Ever!
25th of December 2023 = The Best Christmas Ever!
25th of December 2020 = the worst xmas I've ever seen?
31st of December 2022 = the last day of this year.
1st of January 2023 = the first day of next year.
1st of August 2022 = Swiss National Day this year.
Bonus dynamic default parameters (although tbh I've never used them) (yet ? ) :
B4X:
Sub ExampleSubWithDefaultParameters(Par() As Object) As String
Dim RealPar() As Object = FillInDefaultParameters(Par, Array As Object( _
"25th", _
"December", _
DateTime.GetYear(DateTime.Now), _
"The Best Christmas Ever!" _
))
Return RealPar(0) & " of " & RealPar(1) & " " & RealPar(2) & " = " & RealPar(3)
End Sub
Just realised you can use it to "specify" the Sub's functionality according to the number and/or type of parameters... there's a word for that, but I can't think what it is.
Anyway eg:
B4X:
Sub MonthToMonthNumber(Month As Object) As Int
Dim AllMonths() As String = Array As String( _
"january", "february", "march", _
"april", "may", "june", _
"july", "august", "september", _
"october", "november", "december" _
)
Dim MonthNumber As Int = 0 'pessimists of the world, unite!
If Month Is Int Then 'if parameter is a number then...
If Month >= 1 And Month <= 12 Then
MonthNumber = Month
End If
else if Month Is String Then 'if parameter is a string then...
Dim TempMonth As String = Month
TempMonth = TempMonth.Trim.ToLowercase 'clean up to match AllMonths()
If TempMonth.Length <> 0 Then
Dim NumMatches As Int = 0
For I = 0 To AllMonths.Length - 1
If AllMonths(I).StartsWith(TempMonth) Then
NumMatches = NumMatches + 1
MonthNumber = I + 1 'reset to 0 if not exactly one match
End If
Next
If NumMatches <> 1 Then
MonthNumber = 0
End If
End If
End If
Return MonthNumber '0 = month not 100% certain (or could return Null to flag same)
End Sub
B4X:
Dim TestMonths() As Object = Array As Object( _
5, 11, 15, 21, _
4.9, 5.0, 5.1, 5.2, _
"J", "Ja", "Jan", "Janu", _
"Ju", "Jun", "Jul", _
"O", "OC", "OCT", "OCTO", "OCTOP", "OCTOPUSSY", _
"M", "Mo", "Mon", "S", "Sa", "Sat", "Wed" _
)
For Each O As Object In TestMonths
Log( _
(O Is Int) & TAB & _
(o Is String) & TAB & _
(O Is Float Or O Is Double) & TAB & _
O & TAB & _
MonthToMonthNumber(O) _
)
Next
Log output:
Waiting for debugger to connect...
Program started.
true false false 5 5
true false false 11 11
true false false 15 0
true false false 21 0
false false true 4.9 0
false false true 5.0 0
false false true 5.1 0
false false true 5.2 0
false true false J 0
false true false Ja 1
false true false Jan 1
false true false Janu 1
false true false Ju 0
false true false Jun 6
false true false Jul 7
false true false O 10
false true false OC 10
false true false OCT 10
false true false OCTO 10
false true false OCTOP 0
false true false OCTOPUSSY 0
false true false M 0
false true false Mo 0
false true false Mon 0
false true false S 9
false true false Sa 0
false true false Sat 0
false true false Wed 0
Example:
First I made SUB PopUp(nWidth, nHeight) which show at center of screen and used it every projects, big or small.
Next I needed to show it at bottom right, so PopUp(nWidth, nHeight, nLeft, nRight), but all the uses code of the PopUp() in all projects, gives error in IDE.
Making every SUB as PopUp(cObject) or PopUp(Array) is not the same. We can not see the parameter requirement here from the syntax of PopUp.
Please note B4X has 3 CallSubDelay for new parameters, and never use Object or Array as parameters for all future versions.
The default value of a SUB does not come when we first make a new SUB. It is done on the project requirement. Later when a different project requires extra parameter for same SUB, we need to the default value, so that all old codes do not generate error.
I have been using this feature in all programming languages I use. It will only benefit the developer if B4X has this feature too.
I am not a full-time developer, but I can appreciate wanting to extend existing functionality of subroutines.
When I have been in situations as described in #7 (and that seems to happen daily), I need to make a sub with a different name.
Like many functions in B4X (Substring, CallSubDelayed, Initialize, etc.) I add a suffix with the number of parameters expected.
This prevents an error in existing code, and makes it clear what the intention is for the new sub which will be used in future code.
I do believe that this design choice for B4X is intentional, and not an omission.
I also have coded in other computer languages with the feature in #1, but thinking back about it, I didn't use it much (or ever).
I am not sure why not, but maybe it has to do with the fact that defaults can cause hard-to-find bugs.
There are no errors, but the program doesn't work the way you expect.
In any case this topic deserves further discussion. I thank @AnandGupta for bringing it up.
I am not sure why not, but maybe it has to do with the fact that defaults can cause hard-to-find bugs.
There are no errors, but the program doesn't work the way you expect.
As a senior developer I am responsible for 15 developers under me. I develop all black boxes for them to use in many different projects as required by our company. If any black box need a new parameter, the default, saves those juniors to use their old projects as it is with the new class, when I release it.
Hope one remembers why B4X created GetDefault() method ?
When a creator of a class added new property in new version and the user uses it in old project where the property was not there, it gave error.
The GetDefault() stops the error.
It might also be good to point out it isn't some weird and obscure feature being requested. This is a standard feature in many languages, for instance python and php. (Python also uses named parameters, which this thread and wish doesn't cover.)
It's also an awesome way to not have to use the pattern of MyFunction, MyFunction2 and MyFunction3. That has always felt a bit like a clutch to me.
Still not the same as adding 'help text' makes IDE not to throw the error.
We still have to make changes in all codes manually.
Default parameter stops the IDE from throwing error.
Hey I'm just doing this for fun, and I agree that there are syntactic niceties that would make B4X nicer to use. ??
Doing roll-your-own variable parameters etc is a bit verbose, I grant you, but like all Subs it's write-once, use-many.
Plus you can do precisely what you need done, unconstrained by the language designer's field of view (although presumably you'd still be able to do this anyway, ie adding polymorphism etc to B4X is unlikely to rule out still using these Array As Object techniques when they are useful).
Sub with variable number of parameters plus parameter defaults plus parameter type checking:
'Parameters are: Array As Object(
' nWidth As Int (default = 100)
' nHeight As Int (default = 50)
' nLeft As Int (default = 325)
' nRight As Int (default = 475)
' Title As String (default = "B4X FTW!")
')
Sub AnandVarPar(Par() As Object) As String
If Par.Length < 2 Then "".SubString(1)
If Par.Length > 5 Then "".SubString(1)
Dim UsePar() As Object = Array As Object(100, 50, 325, 475, "B4X FTW!")
For I = 0 To Par.Length - 1
If Par(I) <> Null Then
UsePar(I) = Par(I)
End If
Next
If Not(UsePar(0) Is Int) Then "".SubString(1)
If Not(UsePar(1) Is Int) Then "".SubString(1)
If Not(UsePar(2) Is Int) Then "".SubString(1)
If Not(UsePar(3) Is Int) Then "".SubString(1)
If Not(UsePar(4) Is String) Then "".SubString(1)
Dim nWidth As Int = UsePar(0)
Dim nHeight As Int = UsePar(1)
Dim nLeft As Int = UsePar(2)
Dim nRight As Int = UsePar(3)
Dim Title As String = UsePar(4)
Log("Parameters are " & nWidth & ", " & nHeight & ", " & nLeft & ", " & nRight & ", """ & Title & """")
End Sub
Test of above:
Sub TrySubTipsInHere
AnandVarPar(Array As Object(123, 456))
AnandVarPar(Array As Object(123, 456, 78))
AnandVarPar(Array As Object(123, 456, 78, 90))
AnandVarPar(Array As Object(123, 456, 78, 90, "Anand Was Here"))
AnandVarPar(Array As Object(Null, Null, 12, 34, Null))
'and for one show only...
AnandVarPar(Array As Object(123, 456, "78", "90"))
End Sub
Log output:
Waiting for debugger to connect...
Program started.
Parameters are 123, 456, 325, 475, "B4X FTW!"
Parameters are 123, 456, 78, 475, "B4X FTW!"
Parameters are 123, 456, 78, 90, "B4X FTW!"
Parameters are 123, 456, 78, 90, "Anand Was Here"
Parameters are 100, 50, 12, 34, "B4X FTW!"
Error occurred on line: 40 (B4XMainPage)
That's not a bad a pretty good idea. If not for the first implementation, at least for the subsequent changes.
As I understand it, the first implementation might look like:
B4X:
Sub PopUp(nWidth As Int, nHeight As Width)
'do stuff
End Sub
and then the new improved implementation like:
B4X:
Sub PopUp4(nWidth As Int, nHeight As Width, nLeft As Int, nRight As Int)
'do stuff
End Sub
'support code that uses previous version
Sub PopUp(nWidth As Int, nHeight As Width)
PopUp4(nWidth, nHeight, DefaultnLeft, DefaultnRight)
End Sub
Lol that just gave me flashbacks to replacing Microsoft ISAM with Btrieve, and writing a whole lot of ISAM-lookalike functions that called their Btrieve equivalents, so that the rest of the program mostly compiled and ran just like it used to.
The 2 in Substring2, CallSubDelayed2, Initialize2 refers to the version#. But for Substring that coincides with the # of parameters.
In CallSubDelayed2, the number of parameters is 3. In Initialize2 the # of parameters could be anything.
For me it is just a mnemonic device for new versions of Subs. I am not suggesting it would work for others.
@emexes I too have bad memories of wrapping the new with the old, or old with the new, or laborious global search and replace.
@AnandGupta as soon as one works with a group of people, a whole other set of considerations come into play, I get that.
Your wish come true would be very useful.
Considering the talent Erel has demonstrated by creating B4X I cannot for the life of me think that this would pose a large challenge for him.
Instead I think it will mostly come down to whether it fits his vision for B4X, and as far as I am able to reverse engineer his vision based on previous discussions, the answer will be no. It adds something extra that can be complicated to understand, and that doesn't fit his vision to make the language as accessible and low-barrier as possible for newcomers. (Granted, that's my interpretation of his vision, which might be severly faulty and overly simple. I'm not aware of him actually describing it somewhere. Apologies all around if I'm way off base.)
I wrote in C# for years and in that time successive version grew things like this that in my opinion contribute nothing and obfuscate understanding. Having worked with Erel from the early days I'm pretty sure Sandman is correct and Erel would see it as an unnecessary complication to what is intended to be a straightforward language.