Verbose and flexible args and kwargs syntax

Eelco hoogendoorn.eelco at gmail.com
Tue Dec 13 07:47:58 EST 2011


On 13 dec, 12:13, Steven D'Aprano <steve
+comp.lang.pyt... at pearwood.info> wrote:
> On Tue, 13 Dec 2011 01:15:46 -0800, Eelco wrote:
> > On Dec 13, 3:43 am, Steven D'Aprano <steve
> > +comp.lang.pyt... at pearwood.info> wrote:
> >> On Mon, 12 Dec 2011 04:21:15 -0800, Eelco wrote:
> >> >> No more, or less, explicit than the difference between "==" and
> >> >> "is".
>
> >> > == may be taken to mean identity comparison; 'equals' can only mean
> >> > one thing.
> [...]
> > We are not talking mathemathics, we are talking programming languages.
>
> What *I* am talking about is your assertion that there is only one
> possible meaning for "equals" in the context of a programing language.
> This is *simply not correct*.
>
> You don't have to believe me, just look at the facts. It's hard to find
> languages that use the word "equals" (or very close to it) rather than
> equals signs, but here are four languages which do:

That python is not the only language to not get this quite as right as
could be is known to me. But within computer science as a discipline,
equality and identity comparisons have a clear enough meaning. 'is'
has a narrower meaning than 'equals'. '==' has no meaning whatsoever
in computer science.

> Again, all this goes to demonstrate that the language designer is free to
> choose any behaviour they like, and give it any name they like.

Certainly you demonstrated as much. Programming languages are created
by people, and they have a tendency to make mistakes, and to have to
compromise (backwards compatibility, and so on). Thats a seperate
matter from 'what ought to be done', when discussing optimal language
design.

> > So 'frequency of use' is no valid interpretation of 'obscurity'? Im not
> > a native speaker, but im pretty sure it is.
>
> No. Things which are obscure are used in language infrequently, because
> if they were common they would not be obscure. But things which are used
> infrequently are not necessarily obscure.
>
> An example in common language: "Napoleon Bonaparte" does not come up in
> conversation very frequently, but he is not an obscure historical figure.
>
> An example from programming: very few people need to use the
> trigonometric functions sin, cos, tan in their code. But they are not
> obscure functions: most people remember them from school. People who have
> forgotten almost everything about mathematics except basic arithmetic
> probably remember sin, cos and tan. But they never use them.

I dont think its terribly interesting to debate whether the term
obscure applies to trigonometric functions or not: the important
matter is that they are where they should be; under math.cos, etc.
They dont have their own special character, and I hope you agree that
is as it should be.

I use trig far more often than modulus, so that argues in favor of
modulus being under math too; infact I used modulus quite recently,
but naturally it was in a piece of code that should be done in C
eventually anyway (evaluating subdivision surfaces)

> Because you asked why Python uses the % operator for remainder.

So you ARE implying python has backwards compatibility with C as a
design goal? Otherwise the given answer to this question is
nonsensical.

>
> [...]
>
> > They are bad ideas because they truely do not lead to the execution of
> > different code, but are merely a reordering, mixing statements in with a
> > function declaration. I am proposing no such thing; again, the type(arg)
> > notation I have dropped, and never was meant to have anything to do with
> > function calling; it is a way of supplying an optional type constraint,
> > so in analogy with function annotations, I changed that to arg::type.
> > Again, this has nothing to do with calling functions on arguments.
>
> You have not thought about this carefully enough. Consider what happens
> when this code gets called:
>
> def f(*args): pass
>
> f(a, b, c)
>
> The Python virtual machine (interpreter, if you prefer) must take three
> arguments a, b, c and create a tuple from them. This must happen at
> runtime, because the value of the objects is not known at compile time.
> So at some point between f(a, b, c) being called and the body of f being
> entered, a tuple must be created, and the values of a, b, c must be
> collated into a single tuple.
>
> Now extend this reasoning to your proposal:
>
> def f(args:FOO): pass
>
> At runtime, the supplied arguments must be collated into a FOO, whatever
> FOO happens to be. Hence, the function that creates FOO objects must be
> called before the body of f can be entered. This doesn't happen for free.
> Whether you do it manually, or have the Python interpreter do it, it
> still needs to be done.

Of course the python interpreted needs to do this; and in case non-
builtin types are allowed, the mechanism is going to be through their
constructor. But thats a detail; the syntax doesnt say: 'please call
this constructor for me', any more than **kwargs says 'please call a
dict constructor for me', even though equivalent operations are
obviously going on under the hood as part of the process. Yes,
whatever type you have needs to be constructed, and its not magically
going to happen, its going to cost CPU cycles. The question is, do you
end up constructing both a tuple and a list, or do you construct the
list directly?


> > First off, type constraints must have some use; all those languages cant
> > be wrong.
>
> But you're not talking about type constraints. You're not instructing the
> function to reject arguments which have the wrong type, you are
> instructing it to collate multiple arguments into a list (instead of a
> tuple like Python currently does). def f(*args) *constructs* a tuple, it
> doesn't perform a type-check.

I am talking about type constraints, but as seems to be the usual
pattern in our miscommunications, you seek to attach a specific far
fetched meaning to it that I never intended. Insofar as I understand
these terms, a type-constraint is part of a declaration; float x; in C-
family languages, args::list in python 4 perhaps. It narrows down the
semantics for further usage of that symbol. A type-check is something
along the lines of type(args)==list, a runtime thing and something
completely different. I havnt mentioned the latter at all, explicitly
or implicitly, as far as im aware.



More information about the Python-list mailing list