Ideas for Python 3

David MacQuigg dmq at gain.com
Fri May 7 20:09:08 EDT 2004


On Wed, 05 May 2004 23:23:52 -0700, Josiah Carlson <jcarlson at uci.edu>
wrote:

>
>>>>L = [:x:x**2, :x:x+4, :x:x/5, :x:2-x, :x:x*7 ]
>>>
>>>Ick.
>> 
>> Could you be more specific? :>)
>
>Sure, the general format of your anonymous function syntax given above 
>does not offer anything that a new user can search for.

This is a good point, and one I hadn't thought of.  The counter is
that function definition syntax is so basic and so prevalent that any
user of Python will already know it.  Lambdas are seldom used, but by
making their syntax almost identical to normal functions, we can make
them self-explanatory.  I would add one very short paragraph at the
end of an introduction to functions.
"""
Nameless Functions
------------------
There is a short form of a function definition, which is sometimes
used in lists or other places where space is tight.  If you can write
your function as a single expression, you can use the short form by
just leaving off the function's name and the return keyword.
... example above showing long form and short form.
"""
[snip further discussion on searchability]

>> You seem to be suggesting that the current syntax is preferable.  Is
>> this really what you would prefer:
>> 
>> L = [(lambda x:x**2), (lambda x:x+4), (lambda x:x/5),
>>   (lambda x:2-x), (lambda x:x*7)]
>
>You fail to notice that:
>     L = [:x:x**2, :x:x+4, :x:x/5, :x:2-x, :x:x*7]
>needs to be:
>     L = [(:x:x**2), (:x:x+4), (:x:x/5), (:x:2-x), (:x:x*7)]
>...unless of course you want to remove the ability for anonymous 
>functions/lambdas to return tuples.

I'm not seeing the need for parentheses in the above example.  The
commas clearly show this is a five-item list.

I think the parentheses should be optional, to be used in cases where
there is ambiguity, like the one you have identified below.

>The only difference between the syntax you offer is the replacement of 
>'lambda ' with ':', which I don't believe is an advancement in the language.

The important difference is that it makes the short form (lambda)
almost identical to the normal form.  This makes it self-explanatory,
and avoids five pages in an introductory text.

>> The barrier *should* be low, but it isn't.  In Learning Python, 2nd
>> ed., there is a 5-page section under "Advanced Topics" devoted to
>> lambdas.  Some experts like the association with lambda calculus, even
>> though that doesn't help beginners.  In fact, it only serves to make
>> lambdas seem even more mysterious.  The benefit of lambdas *could* be
>> provided in a simple, self-explanatory syntax that requires zero pages
>> in a textbook and has none of the mystique that turns off beginners.
>
>How about this for a manual page for lambda...
>
>In other languages, Python's lambda would be considered an 'anonymous 
>function', that is, a function that does not require a name.:
>
>     >>> (lambda arg: arg*arg)(9)
>     81
>
>Certainly you can give lambdas names with standard assignments.:
>
>     >>> square = lambda arg: arg*arg
>     >>> square(9)
>     81
>
>The equivalent function definition is below.:
>
>     >>> def square(arg):
>     ...     return arg*arg
>     ...
>     >>> square(9)
>     81
>
>Generally, lambdas are functions with a single expression in its body 
>whose value is returned.  Just like normal function definitions, lambdas 
>can take multiple arguments, contain keyword arguments, return any 
>Python type, etc., as long as the function body is a single expression, 
>and whose parameters match standard function definition syntax, the 
>lambda is valid. (leave annotation and/or link to what an expression is)
>
>An ugly example of this is as follows.:
>
>     >>> f = lambda a, b=1, *args, **kwargs: (a, b, args, kwargs)
>     >>> f(1,2,3,c=4)
>     (1, 2, (3,), {'c': 4})
>
>Which is equivalent to:
>
>     >>> def f(a, b=1, *args, **kwargs):
>     ...     return (a, b, args, kwargs)
>     ...
>     >>> f(1,2,3,c=4)
>     (1, 2, (3,), {'c': 4})
>

I would like to eliminate this explanation entirely, and just include
a simple paragraph at the end of the introduction to functions.

>> Lamdas add an unnecessary keyword and unnecessary burdens to the
>> syntax of the language.  The benefit is very small -- being able to
>> cram a function definition in a tight space.  Due to the mystique of
>> lambdas, it took me a while to realize that was their only benefit.
>
>And removing the keyword would remove their 'mystique'?  

Can you imagine some mathematician trying to foist "lambda calculus"
on us, when everyone can clearly see a nameless function is nothing
but a function without a name?  Maybe you haven't seen some of the
discussions of lambda calculus.

>No, all it 
>would do is remove a keyword from Python.

Which, in itself is a good thing.

>  If we used your alternative 
>syntaxes, the 'mystique' would still exist and be unsearchable. 
>Removing the functionality entirely would result in no longer seeing the 
>below (which you use as an example):
>
>     L = [(lambda...),
>          (lambda...),
>          ...]
>
>But it being replaced with:
>
>     def fun1(arg): return ...
>     def fun2(arg): return ...
>     ...
>     L = [fun1, fun2,...]
>
>Neither of which are terribly attractive, but I prefer the lambda version.

And I prefer the second form.  It's a little more space, but much more
clarity.  Space is rarely a worry for me.

>>>>f :(x): return x**2  # a simple function
>>>>:x:x**2              # equivalent lambda expression
>>>>
>>>>-- or --
>>>>
>>>>f = def(x): return x**2
>>>>def x:x**2
>>>
>>>Ick on the four options just given.
>> 
>> The parentheses are optional when we have colons around the arguments.
>> Leaving them out is my preference, but I would be just as happy with
>> 
>> L = [:(x):x**2, :(x):x+4, :(x):x/5, :(x):2-x, :(x):x*7 ]
>
>I'm not icking on the parenthesis, I'm icking on the general syntax. 
>While Python 3 is supposed to be a mythical creature that fixes all of 
>the problems with previous versions, I don't believe that the syntax 
>options you provide are a fix.  In fact, what about the following...
>
>     L[:x:x**.5]
>
>Using current python syntax, that is a slice into a sequence.  With your 
>syntax, that is an anonymous function that takes an argument and returns 
>its square root, that is used as an index into some mappable type.  Are 
>you also talking about changing slice syntax?

Nice work!!

No, I would say this is a rare case where we need to add the optional
parentheses if we really want a function not a slice.  The slice
syntax is more important, and should have priority.

>As for
>     a. f :(x): return x**2
>     b. f = def(x): return x**2
>     c. def x:x**2
>
>a. Also looks like a bad slice to me.
I now think that f(x): would be the best option.  A normal function
definition always starts at the beginning of a line, so this won't get
confused with a dictionary key or list index.

>b. What was wrong with:
>     def f(x): return x**2
See pros and cons on this issue at
http://ece.arizona.edu/~edatools/Python/PrototypeSyntax.htm
Pro1:  See all the variables at a glance in one column.
Pro2:  Emphasize the similarity between data and functions as
       attributes of an object.
Pro3:  Eliminates the need for special syntax in lambda functions.

>c. Now you're just replacing the lambda keyword with the def keyword.
Which users already understand.  Also two letters shorter, since the
sole purpose of lambdas is to save space.

>> This would more strongly highlight the argument x, and still have a
>> form that parallels the standard function definition.
>> 
>> How about this:
>> 
>> f(x): return x**2
>> (x):x**2
> >
> > Neat and clean, but I don't know if there would be parser problems
>
>First looks like magic.
>Second looks like a slice.
>Neither are neat and clean.

I think we should leave these matters of personal preference and style
to GvR, and focus here on finding hidden problems, like -- This syntax
won't work because ..."

>> with the short form.  Unlike the long form, which can only occur at
>> the beginning of a line, the short form might occur in a dictionary
>> item, where the colon could lead to ambiguity.  Maybe we could say
>> lambdas in dictionaries must be enclosed in parentheses, or maybe just
>> not allow them at all where they might cause ambiguity.
>
>With the 'lambda' (or other equivalent) keyword, there does not exist 
>ambiguity.  Your removal of the keyword seems to not add any 
>understandability to the syntax (or the one-line-function 'problem'), 
>but adds ambiguity to the meaning of an equivalent anonymous function. 
>I thought Python was about removing ambiguity, not encouraging it.

The ambiguity you have discovered ( and I appreciate these discoveries
) is still an edge case, best resolved by putting the burden of adding
parentheses on the least used syntax ( these nameless functions ).

>>>>I am especially interested in feedback from users who have recently
>>>>learned Python.  I suspect that many experienced users will have long
>>>>forgotten any difficulties they had while learning.
>
>>>Learning lambda expressions are trivial when you have experience with 
>>>derivatives of LISP.  While I generally don't like to point users off to 
>>>go RTFM, in this case, 5 minutes of manual reading (without LISP 
>>>experience) will go a long way toward understanding lambda expressions.
>
>> My users ( EE students and professional design engineers ) have no
>> experience with LISP.  I agree, 5 minutes should be enough to explain
>> lambdas properly, but unfortunately, they are not explained properly
>> in the texts I have seen.
>
>So why are you explaining lambdas to them?  If they are having 
>difficulty understanding them, then don't teach it.  Since you are also 
>advocating the removal of the lambda functionality entirely, I see no 
>reason to show them something that they are going to struggle with 
>understanding.

The reason we need to include lambdas is because they are now a part
of the Python culture, and users will be seeing them, encountering
long discussions about "lambda calculus" and other useless
obfuscations.  I will give a short explanation, and advice to avoid
them.  Students should also be aware of the discussion on pages
219-224 of Learning Python, in case they need to decipher a really
nasty lambda.

>If you are still going to teach them lambdas, then do it by example. 
>Give a simple function definition, translate it into a lambda, then have 
>them do it.  I find that learn-by-example works pretty well, at least 
>for simple algorithms like definition-to-lambda.  If your students can't 
>translate a few simple function definitions to lambdas, then Iyou should 
>ask yourself if they deserve to get degrees in their field.

Bad attitude.  They have plenty of opportunites for mental
masturbation in their own field of study, and lots of pressure to do
something more useful with their time. :>)

>> In my humble opinion, GvR should have ignored the experts who told him
>> lambdas were great, and just applied some simple common sense to find
>> a better solution.
>
>I don't believe that lambdas were a solution to a problem.  I believe 
>the /desire/ was to have a way of defining simple functions in a general 
>fashion.  They do just that, allow simple functions to be defined in a 
>general fashion, albeit using a slightly altered function syntax.  Their 
>ability to be placed in lists, gain names, etc., was a side-effect of 
>them being Python objects.

Are we talking about the same thing?  The *sole purpose* of lambdas is
to squeeze a function into a tight space.  There is no other advantage
over a simple, normal, general-purpose, function definition.

-- Dave




More information about the Python-list mailing list