docs: def find(dispatcher, args, kwargs):
      """
      Given the arguments contained in `args` and `kwargs`, returns the best match
      from the list of implementations registered on `dispatcher`.
      """
      matches = []
      full_args = args
      full_kwargs = kwargs
      for func, sig in dispatcher.__functions:
          params = sig.parameters
          param_count = len(params)
          # Filter out arguments that will be consumed by catch-all parameters
          # or by keyword-only parameters.
          if sig.has_varargs:
              args = full_args[:param_count]
          else:
              args = full_args
          if sig.has_varkw or sig.has_kwonly:
              kwargs = {kw: full_kwargs[kw] for kw in params if kw in full_kwargs}
          else:
              kwargs = full_kwargs
          kwarg_set = set(kwargs)
          arg_count = len(args) + len(kwargs)
          optional_count = len(sig.defaults)
          required_count = param_count - optional_count
          # Consider candidate functions that satisfy basic conditions:
          # - argument count matches signature
          # - all keyword arguments are recognized.
          if not 0 <= param_count - arg_count <= optional_count:
              continue
          if kwargs and not kwarg_set <= set(params):
              continue
          if kwargs and args and kwarg_set & set(params[:len(args)]):
              raise TypeError("%s() got multiple values for the same parameter"
                              % dispatcher.__name__)
          arg_score = arg_count # >= 0
          type_score = 0
          specificity_score = [None] * dispatcher.__maxlen
          sig_score = required_count
          var_score = -sig.has_varargs
          indexed_kwargs = ((params.index(k), v) for k, v in kwargs.items()) if kwargs else ()
          for param_pos, value in chain(enumerate(args), indexed_kwargs):
              param_name = params[param_pos]
              if value is None and sig.defaults.get(param_name, _empty) is None:
                  expected_type = type(None)
              else:
                  expected_type = sig.types[param_pos]
              specificity = compare(value, expected_type)
              if specificity[0] == -1:
                  break
              specificity_score[param_pos] = specificity
              type_score += 1
          else:
              score = (arg_score, type_score, specificity_score, sig_score, var_score)
              matches.append(Match(score, func, sig))
      if matches:
          if len(matches) > 1:
              matches.sort(key=lambda m: m.score, reverse=True)
              if DEBUG:
                  assert matches[0].score > matches[1].score
          return matches[0].func
      else:
          return None