Path: csiph.com!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Marko Rauhamaa Newsgroups: comp.lang.python Subject: Re: What is a function parameter =[] for? Date: Fri, 20 Nov 2015 14:28:17 +0200 Organization: A noiseless patient Spider Lines: 71 Message-ID: <877flcrh26.fsf@elektro.pacujo.net> References: <564dbe6b$0$1610$c3e8da3$5496439d@news.astraweb.com> <564df258$0$1604$c3e8da3$5496439d@news.astraweb.com> <564e71f6$0$1619$c3e8da3$5496439d@news.astraweb.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="b7cb1518d23ec19d482dcc9c31d30fdd"; logging-data="28638"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6nh/BuU6WI82ssz/vQoXV" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:1qketZq4ENT34i8QBdppXBF1SPU= sha1:ansYC5YVIwS5PUnRR8Gk5GA50kI= Xref: csiph.com comp.lang.python:99140 BartC : > On 20/11/2015 01:05, Steven D'Aprano wrote: >> On Fri, 20 Nov 2015 04:30 am, BartC wrote: >>> The whole concept of 'mutable' default is alien to me. A default is just >>> a convenient device to avoid having to write: >>> >>> fn(0) or fn("") or fn([]) >> >> Says who? > > People who want to avoid having to write: > > fn(0) or fn("") or fn([]) Undoubtedly a mutable default value can lead to accidents. However, I already showed C++ default values can also be mutable and lead to analogous problems, so the question is not related to Python alone. If there is a risk of a default [] or {} ending up in the wrong hands, you can always write your function with a sentinel: omitted = object() def f(collection=omitted): if collection is omitted: collection = [] ... > We're arguing at cross-purposes then since you are obviously > interested in these esoteric aspects, The Ackermann function really is an esoteric example, but the other example that has been discussed here can make practical use of the default-value semantics: [ lambda x: i * x for i in range(4) ] which is salvaged with a default value: [ lambda x, i=i: i * x for i in range(4) ] or, more hygienically: [ (lambda i=i: lambda x: i * x)() for i in range(4) ] Even more appropriately, you may expressly want a mutable, singleton object to be the default: def initiate_query(query, database=global_database): > but all I want to do is avoid remembering a long list of defaults. > Here's an example from another language, a function I'm working on at > the minute: > > function asklist(caption,&data,n=1, rows=10, width=50, flags="", > buttons=(), tablist=(), heading="")= One could argue that you should always use a sentinel object for default values. That also allows you to distinguish between omitted values and default values: def asklist(caption, data, n=omitted, rows=omitted, width=omitted, flags=omitted, buttons=omitted, tablist=omitted, heading=omitted): but that would be rather pedantic in most circumstances. Marko