[Gambas-user] Wrapping methods which accept optional arguments

Bruno Félix Rezende Ribeiro oitofelix at ...181...
Wed Apr 16 03:21:37 CEST 2014


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.


-- 
 ,= ,-_-. =.  Bruno Félix Rezende Ribeiro (oitofelix) [0x28D618AF]
((_/)o o(\_)) There is no system but GNU;
 `-'(. .)`-'  GNU Linux-Libre is one of its official kernels;
     \_/      All software must be free as in freedom;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://lists.gambas-basic.org/pipermail/user/attachments/20140415/8534b3a1/attachment.sig>


More information about the User mailing list