Unregister a function

Issue #3 new
Laurent Gautier
created an issue

It is currently only possible to "register" a function, without the possibility to can cancel that registration.

It appears possible to add that behavior (http://stackoverflow.com/questions/25951651/unregister-for-singledispatch), but this could be part of the base API.

Comments (3)

  1. Łukasz Langa repo owner

    I wonder what your use case is.

    I originally left unregister() out because: 1. it wasn't there in simplegeneric() 2. can lead to surprising behaviour of the library exposing generic functions. What I mean by that is that your library provides some default implementations of the generic function for some types that your users can extend. By removing a registered implementation, the user might break a contract that your library expects. 3. you can always .register() an alternative implementation for an existing type, for instance:

    @func.register(dict)
    def _(arg):
      return func.dispatch(object)(arg)
    

    Summing up, in principle I'm not saying "NO". I just need to think about actual use cases that "unregister()" will help solving.

  2. Laurent Gautier reporter

    Still here. Sorry for the lag.

    The original need from having unregister came from porting the conversion system in rpy2 to use singledispatch. The conversion system allows the activation/deactivation of conversions, and the latter was initially thought to require an unregister function.

    I have managed to make an implementation without unregister by making a copy of a generic and adding the "activated" conversions to it, saving the original generic for the "deactivation", but I still think that both the absence of unregister and something like nextmethod is limiting for interactive use (e.g. ipython / ipython notebook).

    Whether the use case is indeed frequent might an other matter though.

    # assume a generic "teleport"
    
    class Foo(object):
        pass
    
    # use beam_up() to teleport Foo
    teleport.register(Foo, beam_up)
    
    # so far so good
    # now comes a child class
    class Bar(Foo):
        pass
    
    # the user is finding that beam_up does not handle too well
    # instances of class Bar, so an new function is quickly put together
    # (remember, this is interactive)
    def bamf(obj):
        pass
    
    teleport.register(Bar, bamf)
    
    # however, after few attempts it seems that the original beam_up() is still better than that new bamf().
    # The interactive user still wants to go with that session but just discard that handling.
    
    teleport.unregister(Bar) 
    # or
    teleport.register(Bar, lambda x: callnext(x))
    
    # would answer that need.
    
  3. Log in to comment