Understanding Overloading Restrictions

Hey everyone,

I’ve been experimenting with some code that involves overloading functions, and I’ve come across an interesting scenario that I’d like to discuss.

Consider the following code snippets:

Working Example:

interface_a := interface:
interface_b := interface:
interface_ab := interface(interface_a, interface_b):

ModuleA := module:
    OverloadedFunction<public>(:interface_a): void = ()
ModuleB := module:
    OverloadedFunction<public>(:interface_b): void = ()
ModuleAB := module:
    OverloadedFunction<public>(:interface_ab): void = ()

TestModule := module:
    using. ModuleA
    using. ModuleB
    using. ModuleAB

    ExampleFunction( InstanceAB: interface_ab ): void =
        OverloadedFunction(interface_a(InstanceAB))  #Finds proper overload "OverloadedFunction(:interface_a)".
        OverloadedFunction(interface_b(InstanceAB))  #Finds proper overload "OverloadedFunction(:interface_b)".
        OverloadedFunction(interface_ab(InstanceAB)) # Error: Finds three possible overloads, so it is ambiguous and shows an error ( which is good ).

Non-Working Example:

interface_a := interface:
interface_b := interface:
interface_ab := interface(interface_a, interface_b):

ModuleSum := module:
    OverloadedFunction(:interface_a): void = ()  # unwarranted Error 
    OverloadedFunction(:interface_b): void = ()  # unwarranted Error 
    OverloadedFunction(:interface_ab): void = () # unwarranted Error 

  <#
  Error Message:
  The function (/localhost/PackageName/ModuleSum:)OverloadedFunction(:interface_a) in package PackageName is ambiguous with these definitions:
      function (/localhost/PackageName/ModuleSum:)OverloadedFunction(:interface_b) in package PackageName
      function (/localhost/PackageName/ModuleSum:)OverloadedFunction(:interface_ab) in package PackageName(3532)
  #>

TestModule := module:
    using. ModuleSum

    ExampleFunction(
        InstanceAB: interface_ab
    ): void =
        OverloadedFunction(interface_a(InstanceAB))  #Finds proper overload "OverloadedFunction(:interface_a)".
        OverloadedFunction(interface_b(InstanceAB))  #Finds proper overload "OverloadedFunction(:interface_b)".
        OverloadedFunction(interface_ab(InstanceAB)) # Error: Finds three possible overloads, so it is ambiguous and shows an error ( which is good ).

In the first example, we have a setup where overloading works as expected. The modules ModuleA, ModuleB, and ModuleAB define overloaded functions for different interfaces, and when called from TestModule, the overloads are resolved correctly.

However, in the second example, when trying to define the overloaded functions directly without using separate modules, we encounter errors indicating ambiguity. I believe that the error encountered is unwarranted. The definitions should be allowed because the problematic calls are already being handled appropriately.

While it might seem intuitive that both scenarios should work similarly, it appears that the direct definition of overloaded functions without modularization leads to ambiguity issues.

Looking forward to your insights!

Best regards,
Daigorō

( @UltimateLambda )

Edt.: This exact same issue doesn’t only apply to interfaces, but also to arrays as example.

@Stevie-Moon Can you forward this too please?

1 Like

@Daigoro Thank you for your feedback. While I cannot guarantee a response, I can confirm that this has been forwarded to the appropriate team.