Your example:
compare_key = {
# Same target(s).
ast.Assign: lambda node: ' '.join(dump(t) for t in node.targets),
# Same target and same operator.
ast.AugAssign: lambda node: dump(node.target) + dump(node.op) + "=",
# A return statement is always compatible with another.
ast.Return: lambda node: "(easy)",
# Calling these never compatible is wrong. Calling them
# always compatible will give lots of false positives.
ast.Expr: lambda node: "(maybe)",
# These ones are never compatible, so return some
# object that's never equal to anything.
ast.Import: lambda node: float("nan"),
ast.ImportFrom: lambda node: float("nan"),
ast.Pass: lambda node: float("nan"),
ast.Raise: lambda node: float("nan"),
ast.If: lambda node: float("nan"),
}
vs (my proposal):
with key from ast:
if Assign:
return ' '.join(dump(t) for t in node.targets)
elif AugAssign:
# Same target and same operator.
return dump(node.target) + dump(node.op) + "="
elif Return:
# A return statement is always compatible with another.
return "(easy)"
elif Expr:
# Calling these never compatible is wrong. Calling them
# always compatible will give lots of false positives.
return "(maybe)"
else:
# These ones are never compatible, so return some
# object that's never equal to anything.
return float("nan")
Which do *you* find more readable?
Your proposal requires that I wrap the whole thing up in a function,
or else pass the lookup key to my function every time and switch on
it, instead of getting back a single function once. So you haven't
truly matched the functionality, which means it's hard to compare
readability - I'd have to also look at how readable the call site is,
and that's definitely going to be penalized. Remember, I pointed out
that the function gets called more than once - once on the special
case and then once in a loop.
Plus, how do you implement mutability? The else clause needs to do a
one-off print to stderr, so either the dispatch table needs to be
changed, or the else clause needs some other system of keeping track
of its previously-seen list. Additionally, I have another script that
actually monkey-patches the Expr case out, simply by changing the
dict. It works just fine, because, again, the dict is mutable. To do
that with a switch statement, I'd need to put an explicit 'if' into
there. Show me that version and let's see how readable it is.
There may be a case (pun intended) for adding a switch block to
Python, but this isn't a strong supporting instance.
ChrisA