[Tutor] default argument frustration
Karl Pflästerer
sigurd at 12move.de
Fri Feb 11 22:44:30 CET 2005
On 11 Feb 2005, alan.gauld at freenet.co.uk wrote:
>> FOR THE LOVE OF MIKE can someone tell me even one reason why this
>> isn't a misfeature?!?!
> Its the only sane way to implement default arguments. The whole
> point of function definitions is that they provide a single concise
> interface. The function should return the same result each time
> you call it with the same input. The only way to achieve that
> is to have the default calculated once.
IBTD.
With full lexical scope you only need to calculate the default argument
in the lexical scope it was defined in. Look at a languale like Common
Lisp.
Here is first an example in Python:
.>>> def mutate_list (L=list()):
.... L.append(1)
.... return L
....
.>>> mutate_list()
.[1]
.>>> mutate_list()
.[1, 1]
.>>
Now the same in Common Lisp:
[17]> (defun dont-mutate (&optional (L (list)))
(push 1 L))
DONT-MUTATE
[18]> (dont-mutate)
(1)
[19]> (dont-mutate)
(1)
As you can see here I defined an optional argument L and as default
value a list (the same as in Python). But the difference is: each call
of that function evaluates the default argument in the lexical
environment it was defined in (`push' is a destructive function). To
make that clearer here is a second version where I shadow the definition
of `list' (with labels I can shadow the lexical function binding of a
symbol (here the symbol `list')). After the labels form is closed the
old binding of `list' is restored.
[20]>
(labels ((list (&optional &rest args) (apply 'list 'shadow args)))
(defun dont-mutate-with-shadowed-list (&optional (L (list)))
(push 1 L)))
DONT-MUTATE-WITH-SHADOWED-LIST
[21]> (dont-mutate-with-shadowed-list)
(1 SHADOW)
[22]> (dont-mutate-with-shadowed-list)
(1 SHADOW)
[23]> (list 1 2)
(1 2)
So these functions return the same result each time you call them with
the same arguments (even with mutable default arguments).
[...]
> But I agree that it can be confusing when the default is mutable
> but since the only reasonable option would have been to restrict
> default values to immutable types I think I prefer the confusion...
You see it can be done different (I'm not sure which version is better;
both will have their advantages).
Karl
--
Please do *not* send copies of replies to me.
I read the list
More information about the Tutor
mailing list