[Gambas-user] Wrapping methods which accept optional arguments

Benoît Minisini gambas at ...1...
Thu May 8 17:12:04 CEST 2014


Le 16/04/2014 03:21, Bruno Félix Rezende Ribeiro a écrit :
> Hello Again!
>
> Suppose we are overriding the class 'Array' to add the event 'Update'
> which will be raised after the completion of any method which could
> possibly modify the array structure.  We start by the 'Remove' method
> which has the following signature:
>
>    Public Sub Remove(iIndex As Integer, Optional iLength As Integer)
>
> As our override method is not much more than a wrapper around the
> parent's method, it needs to call 'Super.Remove' method with the same
> arguments it has received in the first place.  Consider our first
> attempt to do just that, which would be:
>
>    Super.Remove(iIndex, iLength)
>
> However, that call won't work as expected because although 'iLength' is
> received as an optional argument, it's invariably passed along to the
> parent's method, be it originally given or not, in which case it would
> default to '0'.
>
> In order to solve that problem we may consider to discriminate
> semantically the optional argument, if that is at all possible.  To
> discover if that is actually the case, we must prove that either one of
> the following properties must hold about the semantics of the method for
> some possible default value of the optional argument:
>
> 1. The method's semantics is defined for the default value of the
>     optional argument, but would be indistinguishable if the optional
>     argument were otherwise omitted.
>
> 2. The method's semantics is undefined for the default value of the
>     optional argument.
>
> It turns out in this particular case the 'Remove' method satisfies both
> properties.   For the first property we can just take 'iLength' as '1',
> since the default behavior (when iLength is omitted) is to remove just
> one element of the array.  Then, our method would look like:
>
>    Public Sub Remove(iIndex As Integer, Optional iLength As Integer = 1)
>
>      Super.Remove(iIndex, iLength)
>      Raise Update()
>
>    End
>
> For the second property we could take 'iLength' as '0' because there is
> no a-priori nor auto-evident distinction between removing zero elements
> of an array and not executing the procedure of removal at all.
> Therefore we can be assured that no one would expect a meaningful
> behavior from a non-meaningful argument and then reserve that for
> internal use, promoting the semantics of the method as
> undefined/unpredictable for that particular optional argument's default
> value.  Our override method would be:
>
>    Public Sub Remove(iIndex As Integer, Optional iLength As Integer = 0)
>
>      If iLength = 0 Then
>        Super.Remove(iIndex)
>      Else
>        Super.Remove(iIndex, iLength)
>      EndIf
>
>      Raise Update()
>
>    End
>
> Notice that this latter method's form could be used to obtain a method
> functionally indistinguishable from the former method's form by just
> replacing the zeros by ones.  Nevertheless, the converse is not true.
>
> Although, we could successfully solve the problem for this particular
> instance of the problem resorting to semantical analysis, it does not
> help much with other methods which have an entire different semantics
> whose analysis must always be done in a case-by-case basis.  Even worse,
> it's possible to prove the following statement:
>
>    There is a primitive method, which accepts optional arguments, that
>    can't be perfectly wrapped by any non-primitive method of the same
>    signature if, and only if, there is a way for primitive methods to
>    unambiguously check whether a particular optional argument was
>    supplied and there is no way of doing so for non-primitive methods.
>
> Where 'primitive method' is defined as a method not written in Gambas
> which is callable from at least one method written in Gambas; and
> 'non-primitive method' is defined as a method written in Gambas.
> Furthermore we admit the premise that it's impossible for a
> non-primitive method to call another method referencing the unchanged
> original argument tuple.
>
> The theorem makes explicit our necessity of providing a way of checking
> unambiguously, in Gambas code, whether any given optional argument were
> actually supplied or, alternatively, preventing primitive methods of
> doing so.  Otherwise, there will be methods for which it is impossible
> to remedy the situation of perfect-wrapping by pure semantic analysis.
>
> Now for a more pragmatic approach, it'd be very useful to document
> the default value of optional arguments as part of the method's
> signature for all primitive and non-primitive methods where it is
> applicable. Those methods can always be perfectly wrapped using the
> first property of the semantical analysis given above.  Moreover there
> is a trivial algorithm to do so, granted we know the default values of
> every optional argument.  That way we eliminate the step of semantical
> analysis even without modification to the interpreter's code.
>
> My questions are: do you see any problem with the reasoning outlined
> above?  Have you ever faced the same problem?  Do you know some
> workaround?  How do you think Gambas may be improved to solve this
> problem?
>
>
> Thank you.
>

Hi,

In revision #6258, I implemented a new special function, IsMissing(), 
that returns if an optional argument is missing.

I didn't tested it with functions taking a variable number of arguments yet.

Enjoy it.

-- 
Benoît Minisini




More information about the User mailing list