Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?) (http://www.velocityreviews.com/forums/t339901-re-lambda-as-declarative-idiom-was-re-what-is-lambda-used-for-inreal-code.html)

Roman Suzi 01-03-2005 02:59 PM

Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?)
 

Hi all,

BTW, Alex Martelli and me have created a PEP 312 some time ago (when the
debate of inline if was hot).

I wish lambdas will not be deprecated in Python but the key to that is
dropping the keyword (lambda). If anybody could think of a better syntax for
lambdas _with_ arguments, we could develop PEP 312 further.

I DO like the idea of support for universal declaratives in Python. (This way
SQL, Prolog, grammar, DTD, lazy expressions, decision tables (advanced switch
statements) etc things could be added in a Pythonic way.)

We only need brief lambdas and lets (for closures), IMHO.


Sincerely yours, Roman Suzi
--
rnd@onego.ru =\= My AI powered by GNU/Linux RedHat 7.3

Dave Benjamin 01-03-2005 04:16 PM

Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)
 
Roman Suzi wrote:
> I wish lambdas will not be deprecated in Python but the key to that is
> dropping the keyword (lambda). If anybody could think of a better syntax for
> lambdas _with_ arguments, we could develop PEP 312 further.


Well, my vote is still with Ruby-style codeblock syntax, but as a
compromise, what about the following:

fun(a, b): a + b

as a replacement for:

lambda a, b: a + b

Advantages:
- Doesn't use the l-word
- Uses parentheses always
- "fun" is shorter and self-describing
- Makes Python code more "fun" ;)

Disadvantages:
- Requires a new keyword, breaking backward compatibility
(I'm assuming we're still talking about Py3k here)
- (Still) doesn't interface statements with expressions

Dave

Steven Bethard 01-03-2005 06:54 PM

Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)
 
Roman Suzi wrote:
> I wish lambdas will not be deprecated in Python but the key to that is
> dropping the keyword (lambda). If anybody could think of a better syntax for
> lambdas _with_ arguments, we could develop PEP 312 further.


Some suggestions from recent lambda threads (I only considered the ones
that keep lambda as an expression):

***** Args Before Expression *****

Nick Coghlan: def-to syntax [1]
(def (a, b, c) to f(a) + o(b) - o(c))
(def (x) to x * x)
(def () to x)
(def (*a, **k) to x.bar(*a, **k))
((def () to x(*a, **k)) for x, a, k in funcs_and_args_list)

Nick Coghlan: def-arrow syntax [1]
(def (a, b, c) -> f(a) + o(b) - o(c))
(def (x) -> x * x)
(def () -> x)
(def (*a, **k) -> x.bar(*a, **k))
((def () -> x(*a, **k)) for x, a, k in funcs_and_args_list)

Alex Martelli: def-as syntax [2]
(def (a, b, c) as f(a) + o(b) - o(c))
(def (x) as x * x)
(def () as x)
(def (*a, **k) as x.bar(*a, **k))
((def () as x(*a, **k)) for x, a, k in funcs_and_args_list)

Dave Benjamin: fun syntax [7]
(fun(a, b, c): f(a) + o(b) - o(c))
(fun(x): x * x)
(fun(): x)
(fun(*a, **k): x.bar(*a, **k))
((fun(): x(*a, **k)) for x, a, k in funcs_and_args_list)


***** Expression Before Args *****

Robert Brewer: for (no-parens) syntax [3]
(f(a) + o(b) - o(c) for a, b, c)
(x * x for x)
(x for ())
(x.bar(*a, **k) for *a, **k)
((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)

Nick Coghlan: for syntax [6]
(f(a) + o(b) - o(c) for (a, b, c))
(x * x for (x))
(x for ())
(x.bar(*a, **k) for (*a, **k))
((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)

Nick Coghlan: def-from syntax [4]
(def f(a) + o(b) - o(c) from (a, b, c))
(def x * x from (x))
(def x from ())
(def x.bar(*a, **k) from (*a, **k))
((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)

Michael Spencer: from-args syntax [5]
(f(a) + o(b) - o(c) from args(a, b, c))
(x * x from args(x))
(x from args())
(x.bar(*a, **k) from args(*a, **k))
((x(*a, **k) from args()) for x, a, k in funcs_and_args_list)

Michael Spencer: for-args syntax [5]
(f(a) + o(b) - o(c) for args(a, b, c))
(x * x for args(x))
(x for args())
(x.bar(*a, **k) for args(*a, **k))
((x(*a, **k) for args()) for x, a, k in funcs_and_args_list)


So there's a bunch of ideas out there. I don't know if any of them
could be overwhelmingly preferred over lambda.

Personally, I lean slightly towards the def-from syntax because it uses
the 'def' keyword to bring your attention to the fact that a function is
being defined, and it gives the expression precedence over the arglist,
which makes sense to me for an anonymous function, where (IMHO) the
expression is really the most important part of the declaration.

OTOH, I think Michael Spencer's args() function, if implementable, could
have a lot of cool uses, like getting the arguments passed to next
within a generator. (See the thread about that[8].)


Steve

[1]http://mail.python.org/pipermail/python-list/2004-December/256859.html
[2]http://mail.python.org/pipermail/python-list/2004-December/256881.html
[3]http://mail.python.org/pipermail/python-list/2004-December/257023.html
[4]http://boredomandlaziness.skystorm.net/2004/12/anonymous-functions-in-python.html
[5]http://mail.python.org/pipermail/python-list/2004-December/257893.html
[6]http://mail.python.org/pipermail/python-list/2004-December/257977.html
[7]http://mail.python.org/pipermail/python-list/2005-January/258441.html
[8]http://mail.python.org/pipermail/python-list/2005-January/258238.html

Nick Coghlan 01-04-2005 09:31 AM

Deferred expressions (was Re: Lambda as declarative idiom)
 
Steven Bethard wrote:
> Nick Coghlan: def-from syntax [4]
> (def f(a) + o(b) - o(c) from (a, b, c))
> (def x * x from (x))
> (def x from ())
> (def x.bar(*a, **k) from (*a, **k))
> ((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)


After a bit more musing, this is definitely my preferred syntax. I'd call it a
'deferred expression' rather than an anonymous function, though. The name change
may seem minor, but it changes the emphasis of the feature from how it's
implemented to what it is useful for (i.e. deferring evaluation of an expression
until call time).

It's also conducive to a clean no-argument syntax - simply make the 'from' claus
optional when the argument list is empty.

'def' and 'from' are already keywords, so there shouldn't be any compatibility
problems.

Michael Spencer's idea of using 'for' instead of 'from' was quite interesting,
but the use of 'for' without a corresponding 'in' feels a bit misleading :)

Cheers,
Nick.

--
Nick Coghlan | ncoghlan@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net

Bengt Richter 01-04-2005 11:46 AM

Re: Lambda as declarative idiom (was RE: what is lambda used for in real code?)
 
On Mon, 03 Jan 2005 18:54:06 GMT, Steven Bethard <steven.bethard@gmail.com> wrote:

>Roman Suzi wrote:
>> I wish lambdas will not be deprecated in Python but the key to that is
>> dropping the keyword (lambda). If anybody could think of a better syntax for
>> lambdas _with_ arguments, we could develop PEP 312 further.

>
>Some suggestions from recent lambda threads (I only considered the ones
>that keep lambda as an expression):
>

Just for reference, am I correct in assuming these are the equivalent
uses of lambda?:

lambda a, b, c:f(a) + o(b) - o(c)
lambda x: x * x
lambda : x
lambda *a, **k: x.bar(*a, **k)
(lambda : x(*a, **k)) for x, a, k in funcs_and_args_list)

That last seems like it might need the default-arg-value hack: i.e.,
(lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list)


>***** Args Before Expression *****
>
>Nick Coghlan: def-to syntax [1]
>(def (a, b, c) to f(a) + o(b) - o(c))
>(def (x) to x * x)
>(def () to x)
>(def (*a, **k) to x.bar(*a, **k))
>((def () to x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>Nick Coghlan: def-arrow syntax [1]
>(def (a, b, c) -> f(a) + o(b) - o(c))
>(def (x) -> x * x)
>(def () -> x)
>(def (*a, **k) -> x.bar(*a, **k))
>((def () -> x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>Alex Martelli: def-as syntax [2]
>(def (a, b, c) as f(a) + o(b) - o(c))
>(def (x) as x * x)
>(def () as x)
>(def (*a, **k) as x.bar(*a, **k))
>((def () as x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>Dave Benjamin: fun syntax [7]
>(fun(a, b, c): f(a) + o(b) - o(c))
>(fun(x): x * x)
>(fun(): x)
>(fun(*a, **k): x.bar(*a, **k))
>((fun(): x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>
>***** Expression Before Args *****
>
>Robert Brewer: for (no-parens) syntax [3]
>(f(a) + o(b) - o(c) for a, b, c)
>(x * x for x)
>(x for ())
>(x.bar(*a, **k) for *a, **k)
>((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)
>
>Nick Coghlan: for syntax [6]
>(f(a) + o(b) - o(c) for (a, b, c))
>(x * x for (x))
>(x for ())
>(x.bar(*a, **k) for (*a, **k))
>((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)
>
>Nick Coghlan: def-from syntax [4]
>(def f(a) + o(b) - o(c) from (a, b, c))
>(def x * x from (x))
>(def x from ())
>(def x.bar(*a, **k) from (*a, **k))
>((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)
>
>Michael Spencer: from-args syntax [5]
>(f(a) + o(b) - o(c) from args(a, b, c))
>(x * x from args(x))
>(x from args())
>(x.bar(*a, **k) from args(*a, **k))
>((x(*a, **k) from args()) for x, a, k in funcs_and_args_list)
>
>Michael Spencer: for-args syntax [5]
>(f(a) + o(b) - o(c) for args(a, b, c))
>(x * x for args(x))
>(x for args())
>(x.bar(*a, **k) for args(*a, **k))
>((x(*a, **k) for args()) for x, a, k in funcs_and_args_list)
>
>
>So there's a bunch of ideas out there. I don't know if any of them
>could be overwhelmingly preferred over lambda.


Just thought of another, more concise and keywordless, expression-before-args syntax:
(:expression)(formalparams) # equivalent to lambda formalparams:expression

(:f(a) + o(b) - o(c))(a, b, c)
(:x*x)(X)
(:x)()
(:x.bar(*a, **k))(*a, **k)
((:x(*a, **k)() for x, a, k in funcs_and_args_list)
and with args default hack:
((:x(*a, **k)(x=x, a=a, k=k) for x, a, k in funcs_and_args_list)

I would have proposed (expression)(formalparams), but that is already legal ;-)


>
>Personally, I lean slightly towards the def-from syntax because it uses
>the 'def' keyword to bring your attention to the fact that a function is
>being defined, and it gives the expression precedence over the arglist,
>which makes sense to me for an anonymous function, where (IMHO) the
>expression is really the most important part of the declaration.

The syntax above panders to that ;-)

>
>OTOH, I think Michael Spencer's args() function, if implementable, could
>have a lot of cool uses, like getting the arguments passed to next
>within a generator. (See the thread about that[8].)
>

Actually, I would rather have seen the function interface itself used for that, and
not have a scan for yields magically convert the normal function calling interface to
a generator factory interface. But we are past that, unless we invent something new.

E.g. if functions had an f.multicall() factory function that would return a generator
"next" function with the same interface as f but starting code execution at the start
the first time, and after yields on subsequent calls, then we could write

def f(x):
yield x+2
yield x*2
g = f.multicall() # not currently available
[g(n) for n in (2,5)]

and get (untested)
[4, 10]

instead of as now having to write something like

>>> def f(x):

... yield x[0]+2
... yield x[0]*2
...
>>> x = ['ignored']
>>> g = f(x).next
>>> [g() for x[0] in (2,5)]

[4, 10]

or wrapping with something more sugary.

>
>Steve
>
>[1]http://mail.python.org/pipermail/python-list/2004-December/256859.html
>[2]http://mail.python.org/pipermail/python-list/2004-December/256881.html
>[3]http://mail.python.org/pipermail/python-list/2004-December/257023.html
>[4]http://boredomandlaziness.skystorm.net/2004/12/anonymous-functions-in-python.html
>[5]http://mail.python.org/pipermail/python-list/2004-December/257893.html
>[6]http://mail.python.org/pipermail/python-list/2004-December/257977.html
>[7]http://mail.python.org/pipermail/python-list/2005-January/258441.html
>[8]http://mail.python.org/pipermail/python-list/2005-January/258238.html


Regards,
Bengt Richter

Roman Suzi 01-04-2005 12:25 PM

Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?)
 
On Mon, 3 Jan 2005, Steven Bethard wrote:

> Roman Suzi wrote:
> > I wish lambdas will not be deprecated in Python but the key to that is
> > dropping the keyword (lambda). If anybody could think of a better syntax for
> > lambdas _with_ arguments, we could develop PEP 312 further.

>
> Some suggestions from recent lambda threads (I only considered the ones
> that keep lambda as an expression):
>
> ***** Args Before Expression *****
>
> Nick Coghlan: def-to syntax [1]
> (def (a, b, c) to f(a) + o(b) - o(c))
> (def (x) to x * x)


Wow! Is there any wiki-page these could be put on?

By the way, I think to satisfy least-surprise principle, our declarative
idiom must be compatible with type declarations GvR is planning for Python
3.0. This way Python will have ONE style for declarations, be it
type declarations, logical declarations or database-queries, etc.

This means, that there is a need for a LISP's quote, when code is only
written and parsed but may be processed not only by Python interpreter
itself but by any user-made interpreter. For example, type-checker,
cursor.execute, lazy-Python-subinterpreter, DOM-manipulator etc.

I do not know how it could be done syntactically, but it could be done
if thought about long enough.

Lambdas is one of the ways, arguably not the most pleasant one for
a "quote".

Maybe this is too outlandish, but I see lambdas as a "quote" mechanism,
which presents a possibility to postpone (precisely control, delegate)
evaluation. That is, an ovehead for lambda must be much lower but at the
same time visible to the programmer:

d = a + (lambda x, y: x+ y)(3, 4)

if this expression is to be viewed in hypotetical syntax-highlighting
editor, "(lambda x, y: x+ y)" need to be painted with another color
than the rest of the expression, as it represents defining part of the
expression, not the part which is being evaluated right away.

What if we deprecate ` in it's repr() function and reserve it for
inline lambdas (for Python 3.0, of course):

d = a + (` x, y: x+y) (3, 4)

Thus, implicit lambdas will be one more symbol, e.g.

(`: None)

instead of

(: None)

What does Guido think? ;)

Sincerely yours, Roman A.Suzi
--
- Petrozavodsk - Karelia - Russia - mailto:rnd@onego.ru -


Steven Bethard 01-04-2005 02:55 PM

Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)
 
Bengt Richter wrote:
> On Mon, 03 Jan 2005 18:54:06 GMT, Steven Bethard <steven.bethard@gmail.com> wrote:
>
>
>>Roman Suzi wrote:
>>
>>>I wish lambdas will not be deprecated in Python but the key to that is
>>>dropping the keyword (lambda). If anybody could think of a better syntax for
>>>lambdas _with_ arguments, we could develop PEP 312 further.

>>
>>Some suggestions from recent lambda threads (I only considered the ones
>>that keep lambda as an expression):
>>

>
> Just for reference, am I correct in assuming these are the equivalent
> uses of lambda?:
>
> lambda a, b, c:f(a) + o(b) - o(c)
> lambda x: x * x
> lambda : x
> lambda *a, **k: x.bar(*a, **k)
> (lambda : x(*a, **k)) for x, a, k in funcs_and_args_list)


Yeah, I believe that was the intention, though I stole the examples from
[1].

> That last seems like it might need the default-arg-value hack: i.e.,
> (lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list)


Good point.

Steve

Steven Bethard 01-04-2005 03:20 PM

Re: Lambda as declarative idiom (was RE: what is lambda used forin real code?)
 
Roman Suzi wrote:
> On Mon, 3 Jan 2005, Steven Bethard wrote:
>
>
>>Roman Suzi wrote:
>>
>>>I wish lambdas will not be deprecated in Python but the key to that is
>>>dropping the keyword (lambda). If anybody could think of a better syntax for
>>>lambdas _with_ arguments, we could develop PEP 312 further.

>>
>>Some suggestions from recent lambda threads (I only considered the ones
>>that keep lambda as an expression):

>
> Wow! Is there any wiki-page these could be put on?


It's now on:

http://www.python.org/moin/AlternateLambdaSyntax

and I added Bengt Richter's and your recent suggestions.

Steve

Roman Suzi 01-04-2005 05:46 PM

Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?)
 
On Tue, 4 Jan 2005, Steven Bethard wrote:

>Roman Suzi wrote:
>> On Mon, 3 Jan 2005, Steven Bethard wrote:
>>
>>
>>>Roman Suzi wrote:
>>>
>>>>I wish lambdas will not be deprecated in Python but the key to that is
>>>>dropping the keyword (lambda). If anybody could think of a better syntax for
>>>>lambdas _with_ arguments, we could develop PEP 312 further.
>>>
>>>Some suggestions from recent lambda threads (I only considered the ones
>>>that keep lambda as an expression):

>>
>> Wow! Is there any wiki-page these could be put on?

>
>It's now on:
>
>http://www.python.org/moin/AlternateLambdaSyntax
>
>and I added Bengt Richter's and your recent suggestions.


Hmmm... what if we kill two rabbits in one blow: lambda will be even
more implicit, if we just mark parameters by a back-quote while
using PEP 312 convention:

(:f(`a) + o(`b) - o(`c))
(:`x * `x)
(:x)
(:x.bar(*`a, **`k))

Not sure about default args:

((fun(x=x, a=a, k=k): x(*a, **k)) for x, a, k in funcs_and_args_list)

Maybe this needs to be done with closures.
Otherwise I think Python interpreter is quite capable to determine
which parameters the function has... Only their order become a problem.
Probably, ","-s could be used there:

(`a,`b,`c : f(`a) + o(`b) - o(`c))

The whole expressions could be quoted:

`(x, y, z)

meaning a parameter with such structure.



>Steve
>


Sincerely yours, Roman Suzi
--
rnd@onego.ru =\= My AI powered by GNU/Linux RedHat 7.3

Michael Spencer 01-04-2005 10:11 PM

args (was Re: Lambda as declarative idiom (was RE: what is lambdaused for in real code?))
 
Roman Suzi wrote:

> Maybe this is too outlandish, but I see lambdas as a "quote" mechanism,
> which presents a possibility to postpone (precisely control, delegate)
> evaluation. That is, an ovehead for lambda must be much lower but at the
> same time visible to the programmer:
>
> d = a + (lambda x, y: x+ y)(3, 4)

[...]

I believe that this "possibility to postpone" divides into two related but
separate concepts: controlling the moment of evaluation, and assembling the
arguments required at that moment. They are both species of 'eval', but
managing arguments is more specialized, because it includes possibly renaming
parameters, assigning default values, processing positional and keyword
arguments, and, perhaps in the future dealing with argument types.

Meanwhile, GvR wrote (about defining Interfaces in the context of Optional
Static Type Checking)
> Method declarations can be inspected to find out their signature. I propose a
> __signature__ attribute (also for methods defined in classes!) which might be an
> object whose attributes make the signature easily inspectable. This might take
> the form of a list of argument declaration objects giving the name, type and default
> (if any) for each argument, and a separate argument for the return type. For
> signatures that include *args and/or **kwds, the type of the additional arguments
> should also be given (so you can write for example a varargs method whose arguments
> are all strings).


GvR's method.__signature__ object might be related to the args object I proposed
as part of the syntax for anonymous functions without 'lambda'. i.e.,

args(a,*b,**kw) --> an object that specifies but does not evaluate its
parameters until it is supplied to a callable, possibly with calling parameters

This object would contain the default values, and could contain type
annotations, explicit, or inferred, as well as more complex assertions used in
several contexts.

* Current function syntax:
def func(a,*b,**c) : pass

creates func with func.__signature__ = args(a,*b,**c)
and when func is called, the args are evaluated using a mechanism in
args.__call__
so, roughly, eval(func.__signature__) --> func.locals


* Anonymous functions
Syntax alternatives at http://www.python.org/moin/AlternateLambdaSyntax
e.g., (f(a) + o(b) - o(c) for args(a, b, c))

args would evaluated with the calling parameters and made available in the
local scope defined by ()

* A stricter alternative to keyword arguments:
argspec = args(arg1, arg2, arg3)
def func(**argspec): pass

is equivalent to def func(arg1, arg2, arg3): pass


args["arg1"]

(i.e., only args defined in argspec are accepted)

* Useful infrastructure for user-supplied type-based dispatch/lightweight
multimethods:

argspec = args([(a:int, b:int),(a:str,b:str)])

then a framework can provide a custom args.__call__ method that does
conformance-checking, adaptation or whatever




Michael



All times are GMT. The time now is 02:28 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.