Skip to content

Commutative dispatching #110

Open
Open

Description

@asmeurer

I want to define multiple dispatching for a function f(x, y) that I know should always be commutative (f(x, y) == f(y, x)). Does multipledispatch support this? Basically, I only want to define f(type_A, type_B) and have it automatically define f(type_B, type_A).

Activity

  1. mrocklin commented on Jun 17, 2020

    @mrocklin
    Owner

    The dumb way to do this is the following:

    @dispatch((A, B), (B, A))
    def f(x, y):
        ...

    There may also be another way to do it (I'm no longer up to date on this library)

  2. asmeurer commented on Jun 17, 2020

    @asmeurer
    CollaboratorAuthor

    Looking at the code, I don't think this is implemented. But I wonder if it can be done simply by subclassing Dispatcher like

    from itertools import permutations
    
    class CommutativeDispatcher(Dispatcher):
        def add(self, signature, func):
            for perm in permutations(signature):
                super().add(perm, func)

    and then also redefine dispatch to use CommutativeDispatcher.

    The dumb way to do this is the following:

    Does that work? I thought tuple meant union. So wouldn't that also define f(A, A) and f(B, B)?

  3. mrocklin commented on Jun 17, 2020

    @mrocklin
    Owner

    Does that work? I thought tuple meant union. So wouldn't that also define f(A, A) and f(B, B)?

    Yes, you're correct. So maybe you want ...

    @dispatch(A, B)
    @dispatch(B, A)
    def f(x, y):
        ...

    As you say, making a wrapper would not be hard.

  4. asmeurer commented on Jun 17, 2020

    @asmeurer
    CollaboratorAuthor

    Yes, that's what I want. Except I don't want to type it twice for each type, because I know that f is always commutative.

    Actually, maybe it will be better make a wrapper at the dispatcher level, rather than Dispatcher.

    (I haven't tested this)

    def commutative_dispatcher(*types):
        def inner(f):
            for perm in permutations(types):
                f = dispatch(*perm)(f)
            return f
        return inner

    (functions that return functions don't compose so easily in Python. I think we need monads or something ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions