Re: Special keyword argument lambda syntax

2009-03-14 Thread Nick Craig-Wood
Beni Cherniavsky beni.cherniav...@gmail.com wrote:
  This proposal outrageously suggests a special syntax for in-line
  functions passed as keyword arguments::
 
   sorted(range(9), key(n)=n%3)
  [0, 3, 6, 1, 4, 7, 2, 5, 8]
 
  The claim is that such specialization hits a syntax sweet spot, and
  that this use case is frequent enough to contemplate eventually making
  it the only in-line function syntax.

-1 from me.

I think that lambda / inline functions should be discouraged as it
moves python away from, there should be one-- and preferably only one
--obvious way to do it.  IMHO Guido was right in his original impulse
to kill this second class way of making functions...

I would write the above as

def compute_key(n):
Compute the sort key so that x, y and z are true
return n % 3
sorted(range(9), key=compute_key)

Which I think is clearer and more obvious.  It gives you the
opportunity for a docstring also.

Yes it is a bit more typing, but who wants to play code golf all
day?

-- 
Nick Craig-Wood n...@craig-wood.com -- http://www.craig-wood.com/nick
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-14 Thread Beni Cherniavsky
On Mar 14, 5:30 pm, Nick Craig-Wood n...@craig-wood.com wrote:
 BeniCherniavskybeni.cherniav...@gmail.com wrote:
   This proposal outrageously suggests a special syntax for in-line
   functions passed as keyword arguments::

        sorted(range(9), key(n)=n%3)
       [0, 3, 6, 1, 4, 7, 2, 5, 8]

   The claim is that such specialization hits a syntax sweet spot, and
   that this use case is frequent enough to contemplate eventually making
   it the only in-line function syntax.

 -1 from me.

 I think thatlambda/ inline functions should be discouraged as it
 moves python away from, there should be one-- and preferably only one
 --obvious way to do it.  IMHO Guido was right in his original impulse
 to kill this second class way of making functions...

On a second thought, considering the LL(1) problem (which indicates a
real problem for humans parsing it) and the f(x)== confusion, I
agree.

Given that ``lambda`` usage is negligible compared to ``def`` (1.5% in
python3.0 stdlib, ~3% counting most Python files in ubuntu
repository), it should have been killed altogether per YAGNI and the
one way principle.

[Or is it just my if you don't do it my way, don't do it at all
emotion talking?  Don't know.  But I did the statistics only after
formulating the proposal, and I think now that 3% is definitely
YAGNI.]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-14 Thread Rhodri James
On Fri, 13 Mar 2009 16:39:16 -, Scott David Daniels  
scott.dani...@acm.org wrote:



The original proposal was initially appealing to me until I saw this
comment.  That means a relatively invisible typo would turn into good
syntax.  Possibley this is exactly what Rhodri James is talking about,
but just to be explicit, one of these is probably a mistake:
somefun(something, key(x)==5)
somefun(something, key(x)=5)
Right now a syntax error makes you look there, after your extension,
only test cases will show these problems.


Oo, no, I'd missed that!  Good catch.


--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-14 Thread Rhodri James
On Fri, 13 Mar 2009 15:33:26 -, MRAB goo...@mrabarnett.plus.com  
wrote:



Rhodri James wrote:
On Fri, 13 Mar 2009 14:49:17 -, Beni Cherniavsky  
beni.cherniav...@gmail.com wrote:



Specification
=

Allow keyword arguments in function call to take this form:

NAME ( ARGUMENTS ) = EXPRESSION

which is equivallent to the following:

NAME = lambda  ARGUMENTS: EXPRESSION

except that NAME is also assigned as the function's `__name__`.
 My first instinct on seeing the example was that key(n) was a  
function *call*, not a function definition, and to remember the thread  
a month or two ago about assigning to the result of a function call.   
I'm inclined to think this would add confusion rather than remove it.


Guido wants to keep the syntax LL(1), so you're not the only one who has  
a problem with it! :-)


I think that:

def NAME ( ARGUMENTS ): EXPRESSION

is still LL(1).


Yes, but at this point we're arguing about how to spell lambda, and
Python's already got one perfectly good way of spelling it.


--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Special keyword argument lambda syntax

2009-03-13 Thread Beni Cherniavsky
This proposal (a) ignores Guido's clear-cut decision that lambda is
good as it is, (b) is weird in proposing a special-case syntax, (c) is
several Python versions too late for a graceful transition by 3.0.
But I don't won't to just throw the idea away, so I'm posting here.
If there is serious positive feedback proving I'm not crazy, I'll make
a PEP.

Abstract

This proposal outrageously suggests a special syntax for in-line
functions passed as keyword arguments::

 sorted(range(9), key(n)=n%3)
[0, 3, 6, 1, 4, 7, 2, 5, 8]

The claim is that such specialization hits a syntax sweet spot, and
that this use case is frequent enough to contemplate eventually making
it the only in-line function syntax.

Specification
=

Allow keyword arguments in function call to take this form:

NAME ( ARGUMENTS ) = EXPRESSION

which is equivallent to the following:

NAME = lambda  ARGUMENTS: EXPRESSION

except that NAME is also assigned as the function's `__name__`.

Motivation
==

``lambda`` is widely considered arbitrary and ugly, as proven by the
numerous proposals for alternative syntax.  It's also widely
considered good enough, as proven by said proposals being consistently
shot down ;-).

The proposed syntax solves the following drawbacks of lambda:

- It's not obvious from the look of ``lambda n: n % 3`` that it
defines a function.
  ``key(n) = n % 3`` is arguably so clear intuitively, that it won't a
non-familiar
  reader won't have to stop and look it up.  (The ability to look
lambda up is
  cited as one of the main reasons to keep it.)

- A long meaningless (for non-lisp-geeks) keyword in the middle of
code.

- The use of ``:`` to delimit the lambda body is misleading - people
expect
  ``:`` to be followed by a statement, not an expression.

- Lambda functions are anonymous, which makes their origin harder to
  recognize when debugging.  The proposed syntax allows the keyword
  argument to also serve as the function name, giving a (somewhat)
  meaningful name without any naming effort from the user.

However nice this syntax, why should we consider something targeted at
the special case of keyword arguments?

1. It is an important use case.   Consider lambda usage in the 3.0
stdlib:
   * 22 times (ab)used as stand-alone shorthand to ``def``.
   * 18 times passed to `map()` / `filter()` - most are old code
predating list
 comprehensions (given away by ``x=x`` hack predating nested
scopes).
   * 4 times passed to `property()` - now better written as
`...@property`` def.
   * 25 times used as legitimate positional argument (not one of the
above).
   * 31 times used as a keyword argument.
   * 6 times used in other constructs.

   So keyword cover about half of the good uses of lambda, and many
uses
   as positional arguments can be converted to keyword arguments,
sometimes
   improving readability (cf. 3.0's conversion of `key` and `reverse`
arguments
   to keyword-only).

2. We don't have to cover *all* use cases - remember that one can
always fall
   back on ``def`` (which BTW is used ~10250 times in stdlib, making
all uses
   of lambda total 1% of uses of ``def``, making one wonder if we need
in-line
   function syntax at all).

So one can imagine this syntax one day replacing most uses of
``lambda``, at which point ``lambda`` can be killed altogether.

Optional extension
=

Given this syntax for keyword arguments, users might expect it to also
word as a standalone statement:

NAME ( ARGUMENTS ) = EXPRESSION

which is equivallent to the following:

def NAME ( ARGUMENTS):
return EXPRESSION

Should we allow it?  People abuse ``lambda`` in this way already (see
above stdlib statistics), this is just a cleaner version.  But this
syntax has no place for a docstring, so allowing it will encourage
people to write functions without docstings.  Opinions anybody?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-13 Thread Rhodri James
On Fri, 13 Mar 2009 14:49:17 -, Beni Cherniavsky  
beni.cherniav...@gmail.com wrote:



Specification
=

Allow keyword arguments in function call to take this form:

NAME ( ARGUMENTS ) = EXPRESSION

which is equivallent to the following:

NAME = lambda  ARGUMENTS: EXPRESSION

except that NAME is also assigned as the function's `__name__`.


My first instinct on seeing the example was that key(n) was a function  
*call*, not a function definition, and to remember the thread a month or  
two ago about assigning to the result of a function call.  I'm inclined to  
think this would add confusion rather than remove it.


--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-13 Thread MRAB

Rhodri James wrote:
On Fri, 13 Mar 2009 14:49:17 -, Beni Cherniavsky 
beni.cherniav...@gmail.com wrote:



Specification
=

Allow keyword arguments in function call to take this form:

NAME ( ARGUMENTS ) = EXPRESSION

which is equivallent to the following:

NAME = lambda  ARGUMENTS: EXPRESSION

except that NAME is also assigned as the function's `__name__`.


My first instinct on seeing the example was that key(n) was a function 
*call*, not a function definition, and to remember the thread a month or 
two ago about assigning to the result of a function call.  I'm inclined 
to think this would add confusion rather than remove it.


Guido wants to keep the syntax LL(1), so you're not the only one who has 
a problem with it! :-)


I think that:

def NAME ( ARGUMENTS ): EXPRESSION

is still LL(1).

For example:

 sorted(range(9), def key(n): n % 3)
[0, 3, 6, 1, 4, 7, 2, 5, 8]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-13 Thread Scott David Daniels

Rhodri James wrote:
On Fri, 13 Mar 2009 14:49:17 -, Beni Cherniavsky 
beni.cherniav...@gmail.com wrote:

...Allow keyword arguments in function call to take this form:
NAME ( ARGUMENTS ) = EXPRESSION
which is equivallent to the following:
NAME = lambda  ARGUMENTS: EXPRESSION
except that NAME is also assigned as the function's `__name__`.


My first instinct on seeing the example was that key(n) was a function 
*call*, not a function definition, and to remember the thread a month or 
two ago about assigning to the result of a function call.  I'm inclined 
to think this would add confusion rather than remove it.


The original proposal was initially appealing to me until I saw this
comment.  That means a relatively invisible typo would turn into good
syntax.  Possibley this is exactly what Rhodri James is talking about,
but just to be explicit, one of these is probably a mistake:
   somefun(something, key(x)==5)
   somefun(something, key(x)=5)
Right now a syntax error makes you look there, after your extension,
only test cases will show these problems.

--Scott David Daniels
scott.dani...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-13 Thread Hrvoje Niksic
MRAB goo...@mrabarnett.plus.com writes:

 sorted(range(9), def key(n): n % 3)
 [0, 3, 6, 1, 4, 7, 2, 5, 8]

Given the recent pattern of syntactic constructs for expressions using
expr keyword expr (ternary if, listcomps, genexps), and avoiding
the use of colon in expressions, maybe it should be:

sorted(range(9), key=n % 3 def key(n))

this is analogous to

sorted(range(9), foo=n % 3 if bla(n))

It also shares the property that it reuses an existing keyword and
avoids the word lambda, originally (I presume) an homage to Church,
now considered obscure-sounding by many.
--
http://mail.python.org/mailman/listinfo/python-list



Re: Special keyword argument lambda syntax

2009-03-13 Thread MRAB

Hrvoje Niksic wrote:

MRAB goo...@mrabarnett.plus.com writes:


sorted(range(9), def key(n): n % 3)

[0, 3, 6, 1, 4, 7, 2, 5, 8]


Given the recent pattern of syntactic constructs for expressions using
expr keyword expr (ternary if, listcomps, genexps), and avoiding
the use of colon in expressions, maybe it should be:

sorted(range(9), key=n % 3 def key(n))

this is analogous to

sorted(range(9), foo=n % 3 if bla(n))

It also shares the property that it reuses an existing keyword and
avoids the word lambda, originally (I presume) an homage to Church,
now considered obscure-sounding by many.


If you want to avoid the colon then:

 sorted(range(9), def key(n)=n % 3)
[0, 3, 6, 1, 4, 7, 2, 5, 8]

which would be syntactic sugar for:

 sorted(range(9), key=lambda n: n % 3)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Special keyword argument lambda syntax

2009-03-13 Thread bearophileHUGS
MRAB:
   sorted(range(9), def key(n): n % 3)

I am fine with the current lambda syntax, but another possibility:
sorted(range(9), n = n % 3)

Bye,
bearophile
--
http://mail.python.org/mailman/listinfo/python-list