
On Mon, Oct 25, 2021 at 05:23:38AM +1100, Chris Angelico wrote:
On Mon, Oct 25, 2021 at 4:29 AM Erik Demaine <edemaine@mit.edu> wrote:
On Sun, 24 Oct 2021, Erik Demaine wrote:
I think the semantics are easy to specify: the argument defaults get evaluated for unspecified order, in left to right order as specified in the def. Those may trigger exceptions as usual.
Sorry, that should be:
I think the semantics are easy to specify: the argument defaults get evaluated for unspecified ARGUMENT(s), in left to right order as specified in the def. Those may trigger exceptions as usual.
Ah, but is it ALL argument defaults, or only those that are late-evaluated? Either way, it's going to be inconsistent with itself and harder to explain. That's what led me to change my mind.
The rules for applying parameter defaults are well-defined. I would have to look it up to be sure, but by memory the rules are: 1. apply positional arguments from left to right; - if there are more positional arguments than parameters, raise; 2. apply named keyword arguments to parameters: - if the parameter already has a value, raise; - if the keyword parameter doesn't exist, raise; 3. for any parameter still without a value, fetch its default; - if there is no default, then raise. I would say that it makes most sense to assign early-bound defaults first, then late-bound defaults, specifically so that late-bound defaults can refer to early-bound ones: def func(x=0, @y=x+1) So step 3 above should become: 3. for any parameters still without a value, skip those which are late-bound, and fetch the default of the others; - if there is no default, then raise; 4. for any parameters still without a value, which will all be late-bound, run from left-to-right and evaluate the default. This will be consistent and understandable, and if you get an UnboundLocalError, the cause should be no more confusing than any other UnboundLocalError. Note that step 4 (evaluating the late-bound defaults) can raise *any* exception at all (it's an arbitrary expression, so it can fail in arbitrary ways). I see no good reason for trying to single out UnboundLocalError for extra protection by turning it into a syntax error. -- Steve