Announcement

Collapse
No announcement yet.

Optional params?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Daniel Corbier
    replied
    Lance, I see what you mean. But here's a different approach that
    would be a lot easier. Rather than have the compiler count the
    number of arguments that were passed, the function definition
    would include default values for parameters that were meant to
    be optional. For instance:

    Code:
    Function MyRoutine(a, b=20, c=30)
       MyRoutine = a+b+c
    End Function
    Then these calls would be acceptable:
    Code:
    i = MyRoutine(1)
    i = MyRoutine(1, 2)
    i = MyRoutine(1, 2, 3)
    At compile-time, when a function call has missing parameters,
    the compiler would simply substitute in the default values from
    the function definition, as thought that's what was in the source
    code. As far as the actual compiled code is concerned, it would
    be as though you had actually typed in:
    Code:
    i = MyRoutine(1, 20, 30)
    i = MyRoutine(1, 2, 30)
    i = MyRoutine(1, 2, 3)
    This would work without breaking any existing code.
    It is for the convenience of the PB programmer. It is not
    necessary to do anything special to make these functions
    exportable. If exported, the calling code would be required to
    pass all the parameters. The other code would be responsible
    for wrapping the function call in a function of its own with
    optional parameters. So there would be no conflict.

    This next option would be icing on the cake, but it would be
    nice as well. You can have a hidden 1-byte argument that has
    1 bit set on or off for each argument, to determine whether or
    not it was passed. So for instance:
    Code:
    Function MyRoutine(a, b=0, c=0, [OptionalArg])
       If Bit(OptionalArg, 2) = 0 _
          Then MyRoutine = 12345 _
          Else MyRoutine = a+b/c
    End Function
    
    i = MyRoutine(5)
    This would be for internal use in PB. If it must be exported,
    the last parameter would be required by the caller (which can
    wrap it in another function). Lance, do you see now how this
    can be easily done (conceptually at least) without sacrificing
    the present way of handling functions. I haven't thought about
    this for a while, but it's important in the context of my product.
    Although it was written in PB, my component is much easier to
    implement with other compilers than with PB, with their support
    for optional parameters and/or function overloading.

    Function overloading is a little different, but it's useful as
    well. You'd be able to accomplish something similar to optional
    arguments (although it would require more code to do it). But in
    addition, it would come in handy where arguments are of a
    different type. Again, it would not be necessary for PB to worry
    about how to export such functions. You'd simply alias the
    overloaded functions with different export names, and handle
    the function overloading in the include file for the host compiler
    (not at the point of the function call to the DLL).

    BTW, InStr-type functions represent a more complicated type of
    problem, so I can understand if it's not implemented in PB. But
    for any one who's interested, for my own math parser, I am going
    through, and adding functions like InStr, with leading AND
    trailing optional arguments (VB supports a useful "compare"
    trailing argument for several string functions such as InStr).
    The present version of UCalc Fast Math Parser already includes
    an example which shows how to define InStr (with just the
    leading optional parameter) for the parser.


    ------------------
    Daniel Corbier
    UCalc Fast Math Parser
    http://www.ucalc.com

    Leave a comment:


  • Kev Peel
    replied
    Guys,

    I'm all for the optional parameter idea, so add my vote Lance!.

    Code:
    Function MyFunction (ByVal Optional sStr1 As String, ByVal Optional sStr2 As String, ByVal Optional sStr3 As String) As String
    
    s = MyFunction("1",,"2")
    ...and maybe add a new keyword, such as IsVarPassed(MyVar) ?

    Regards,


    ------------------
    Kev G Peel
    KGP Software, Bridgwater, UK.
    http://www.kgpsoftware.com

    [This message has been edited by Kev Peel (edited February 16, 2001).]

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Hey guys,


    This would be a good place for function overloading.

    Code:
    function AddRecord(Record as CRecord) as long
    end function
    
    function AddRecord(byval Row as long,Record as CRecord) as long
    end function
    
    function AddRecord(byval Row as long,Record as COtherRecord) as long
    end function
    
    function AddRecord(Record1 as CRecord,Record2 as CRecord) as long
    end function

    I think the only drawback to this would be slightly larger executables because of all the semi-duplicate functions.


    OOPS! There could be problems with other compilers calling PB functions then. If PB were to impliment function overloading then each function would have to have a unique internal name.

    Code:
    [email protected](CRecord)
    [email protected](Long):byref(CRecord)
    [email protected](Long):byref(COtherRecord)
    [email protected](CRecord):byref(CRecord)
    These internal function names would have to be used by other compilers in the same way PB uses the ALIAS key word when declaring functions inside a DLL.

    ------------------
    Cheers

    [This message has been edited by mark smit (edited February 16, 2001).]

    Leave a comment:


  • Peter P Stephensen
    replied
    Maybe the solution could be to allow the user to make his
    own decorations:
    Code:
    declare function TestFunc_1 alias "TestFunc" (long) as long
    declare function TestFunc_2 alias "TestFunc" (long, string) as long
     
    function TestFunc_1(x as long) as long
        function = x
    end function
     
    function TestFunc_2(x as long, s as string) as long
        s = format$(x)
        function = x
    end function
     
    function pbmain
     
        local x as long
        local s as string
          
        x = TestFunc(4)
        x = TestFunc(x, s)    
         
        msgbox s
         
    end function
    Regards
    Peter

    ------------------


    [This message has been edited by Peter P Stephensen (edited February 16, 2001).]

    Leave a comment:


  • Eric Pearson
    replied
    Paul --

    > It seems odd to announce that a method is
    > not good practice yet use it yourselves.

    IMO you're comparing apples and oranges. EXE and DLL files must contain functions that conform to specific rules, or the operating system won't be able to deal with them. Windows EXE and DLL files simply do not make provisions for functions that work like INSTR([x], y, z). You can do things like MyFunc(x, y, [z]), with optional trailing parameters, but the first syntax, which is traditional to BASIC, is not supported by the operating system. (Take a look at the WIN32API.INC file, which lists hundreds of Windows functions. None of them use optional first parameters.)

    On the other hand, the PowerBASIC compilers take a disk file -- essentially a "soft" data source that can be formatted many different ways -- and turn it into a binary file (EXE or DLL) that is formatted in a very specific way. Internally, I suspect there are actually two functions, like INSTRA and INSTRB or something like that, and when the parser sees INSTR in your code it chooses the correct internal function, based on the number of parameters you type. Or maybe the parser auto-inserts a "1" for the first parameter, if you don't specify [x]. But either way, it does end up hard-coded, or Windows would not be able to deal with it at runtime.

    The optional first parameter of INSTR (and other functions) is strictly a convenience for the programmer, so we don't have to type INSTRA and INSTRB when we want to use the INSTR function in different ways, or always type "1" as the first parameter.

    If BASIC was being created today, I doubt that "optional first parameters" would be part of the syntax. But it is part of the "legacy" syntax, and personally I'm glad. {G}

    > the original question still stands, if we wnat the
    > functionality to create a function like INSTR like
    > PB's how do we do it?

    The same way PowerBASIC does it. {G} You accept a string of characters and decide what needs to be done. You take an input string, and choose between hard-coded alternatives. In other words, unless you want to write a parser/compiler, you would have to write an interpreter. The operating system does not support any other technique.

    -- Eric


    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>



    [This message has been edited by Eric Pearson (edited February 16, 2001).]

    Leave a comment:


  • Paul Dwyer
    replied
    Hang on,

    Lance, doesn't it seem a little 'odd' (to avoid using the word 'hypocritical') to supply built in functions that can't actually be done with PB!!! It's like saying, "We like selling PB but we don't use it ourselves because it lacks the functionality we need" It seems odd to announce that a method is not good practice yet use it yourselves.

    Either way the original question still stands, if we wnat the functionality to create a function like INSTR like PB's how do we do it? notice it's the first parameter that is optional too



    ------------------

    Paul Dwyer
    Network Engineer
    Aussie in Tokyo
    (Paul282 at VB-World)

    Leave a comment:


  • Semen Matusovski
    replied
    Egbert --

    PB compiler is able to understand nomber of parameters, because it processes a text.
    In run-time such way is impossible.

    As I remember my work with IBM/370 (it was many years ago), last parameter was marked by &H80 in highest byte of last parameter.
    It was possible, because OS actually used 24-bit addresses.
    Under Win32 are used all 32 bits and there is no place for bit-flag and is impossible to avoid additional parameter (counter or another signal).

    BTW, counter could be only first parameter:
    push is right to left, but pop is left to right.
    Code:
       #Compile Exe
       #Dim All
       #Register None
       
       Function aSum Cdecl(ByVal n As Long [, ByVal p1 As Long, ByVal p2 As Long, _
          ByVal p3 As Long, ByVal p4 As Long, ByVal p5 As Long]) As Long
          Dim Sum As Long
          If n >= 1 Then Sum = p1
          If n >= 2 Then Sum = Sum + p2
          If n >= 3 Then Sum = Sum + p3
          If n >= 4 Then Sum = Sum + p4
          If n >= 5 Then Sum = Sum + p5
          Function = Sum
       End Function
       
       Function PbMain
         ' MsgBox Str$(aSum (2, 5, 7))
         Dim Answer As Long
         ! PUSH 7
         ! PUSH 5
         ! PUSH 2
         ! Call aSum
         ! MOV Answer, EAX
         MsgBox Format$(Answer)
         
         MsgBox Str$(aSum (5, 10, 20, 30, 40, 50))
         
       End Function
    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Lance Edmonds
    replied
    This request has been raised a few times before.

    To automate this for you, the compiler would have to pass a value to the sub/function to indicate the parameter count. This would likely cause two effects:

    1. The count parameter would need to be passed on the stack, and therefore it would perform identically to adding your own parameter anyway.

    2. Because the stack would have an additional (yet effectively hidden) parameter, it would break any code that needed to call the sub/function. This would be especially harmful if the code was called from an external (non-PowerBASIC) module unless such code passed the extra parameter as well.

    Therefore, this appoach would actually compilicate the issue, rather than simplify.




    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Egbert Zijlema
    replied
    Semen,

    Thanks. But - and this is my reply to Lance as well - it is not what I mean.
    As said: the way PBasic itself accepts conditional params, so without a counter param in advance (or at the end, as you wish, because CDECL reads from right to left).
    In terms of writing efficient code, it is not very profitable to need ONE extra param (counter) in order to tell a function or procedure that there may be ONE extra param.
    A function (or sub) should at least have 2 optional params to be efficient. Unfort. this is not often the case in my programming practice.


    ------------------
    mailto:[email protected][email protected]</A>
    www.basicguru.com/zijlema/

    Leave a comment:


  • Lance Edmonds
    replied
    Correct - even PB/DOS supports optional parameters.


    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Semen Matusovski
    replied
    Egbert --
    look DECLARE statement in help file. CDECL.
    A sample
    Code:
       #Compile Exe
       #Dim All
       #Register None
       
       Function aSum Cdecl(n As Long [, p1 As Long, p2 As Long, p3 As Long, p4 As Long, p5 As Long]) As Long
          Dim Sum As Long
          If n >= 1 Then Sum = p1
          If n >= 2 Then Sum = Sum + p2
          If n >= 3 Then Sum = Sum + p3
          If n >= 4 Then Sum = Sum + p4
          If n >= 5 Then Sum = Sum + p5
          Function = Sum
       End Function
       
       Function PbMain
         MsgBox Str$(aSum (2, 5, 7))
         MsgBox Str$(aSum (5, 10, 20, 30, 40, 50))
       End Function
    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Egbert Zijlema
    started a topic Optional params?

    Optional params?

    Lance/Tom,

    Is it possible - or will it be in future releases - to create PBDLL60 functions with optional parameters? In the same way PBDLL60 itself does, for instance:
    Code:
    result& = INSTR([startpos,] mainstring, matchstring)
    In this example passing a starting position for the character search throughout mainstring is not required. If you omit it, search will start with the first character.


    ------------------
    mailto:[email protected][email protected]</A>
    www.basicguru.com/zijlema/
Working...
X