Announcement

Collapse
No announcement yet.

Optional params?

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

  • 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/

    Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
    http://zijlema.basicguru.eu
    *** Opinions expressed here are not necessarily untrue ***

  • #2
    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]

    Comment


    • #3
      Correct - even PB/DOS supports optional parameters.


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

      Comment


      • #4
        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/

        Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
        http://zijlema.basicguru.eu
        *** Opinions expressed here are not necessarily untrue ***

        Comment


        • #5
          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>
          Lance
          mailto:[email protected]

          Comment


          • #6
            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]

            Comment


            • #7
              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)

              Comment


              • #8
                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).]
                "Not my circus, not my monkeys."

                Comment


                • #9
                  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).]
                  [email protected]
                  www.dreammodel.dk

                  Comment


                  • #10
                    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).]

                    Comment


                    • #11
                      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).]
                      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                      Comment


                      • #12
                        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
                        Daniel Corbier
                        uCalc Fast Math Parser
                        uCalc Language Builder
                        sigpic

                        Comment

                        Working...
                        X