[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