Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?)

Reply
Thread Tools

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

 
 
Roman Suzi
Guest
Posts: n/a
 
      01-04-2005
On Tue, 4 Jan 2005, Michael Spencer wrote:

>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.


Yes. I have the same understanding.

>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.


Very precise!

>Meanwhile, GvR wrote (about defining Interfaces in the context of Optional
>Static Type Checking)


As for GvR's writing, I think he is exploring the ground. What he wrote
is too complex for Python and he guesses it is.

There i another thread in c.l.p where I propose generic programming
approach for Python's "type checking": IMHO, a much simpler and more natural
for Python than programming by contract, just interfaces and such.

And the syntactic way to express concepts is going thru
declarations. That is why lambdas are to be on steroids for this task.

More than that, compile vs. evaluation/parameter dispetching must not muddy
the waters for programmer. It must always be clear (syntactically too)
for him what is going on in the expression at hand. (But I do not know
how this could be elegantly done sytactically)

Is declaration-chewing engine built into Python an overkill?
There are at least 2 specialized ones in it: parser and re.compile +
many for different formats, like xml.dom.


Sincerely yours, Roman Suzi
--
=\= My AI powered by GNU/Linux RedHat 7.3
 
Reply With Quote
 
 
 
 
Bengt Richter
Guest
Posts: n/a
 
      01-05-2005
On Tue, 04 Jan 2005 19:31:37 +1000, Nick Coghlan <> wrote:

>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).

I like the fact that 'def' can serve as a mnemonic for 'defer' or 'deferred'

OTOH, I like concise notation for expressions, and the def and from aren't
really necessary if you can tag the first expression with some syntax marker.
I suggested (: rather than (def since (: is illegal now and won't break anything.

But all this is just a rewrite of lambda params:expr as (def expr from params).
What is the point again? (Not that my rewrite to (:expr)(params) is any more
than a lambda rewrite either). If backticks could be used, `(exprarams)
might be an interesting spelling of lambda params:expr.

I do like being able to leave out the from clause. `(expr) would let you do that too,
just as well as (:expr).
>
>It's also conducive to a clean no-argument syntax - simply make the 'from' claus
>optional when the argument list is empty.

That is an advantage of having it inside the outer parens, which my (:expr)(params)
couldn't benefit from -- unless I just take your format and substitute ':' for
both def and from:

(: f(a) + o(b) - o(c) : (a, b, c))
(: x * x : (x))
(: x) # empty arg list
(: x.bar(*a, **k) : (*a, **k))
((: x(*a, **k) : (x=x, a=a, k=k) for x, a, k in funcs_and_args_list)


>
>'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

What was the point of all this again? Pretending lambda goes away without really killing it?

Regards,
Bengt Richter
 
Reply With Quote
 
 
 
 
Nick Coghlan
Guest
Posts: n/a
 
      01-06-2005
Bengt Richter wrote:
> I like the fact that 'def' can serve as a mnemonic for 'defer' or 'deferred'


Yeah, me too. I didn't actually notice that until after I'd thought of the phrase.

> OTOH, I like concise notation for expressions, and the def and from aren't
> really necessary if you can tag the first expression with some syntax marker.
> I suggested (: rather than (def since (: is illegal now and won't break anything.


True, but I've always liked Python's preference for keywords over punctuation.
And 'def' is only 2 characters longer than ':', too.

> That is an advantage of having it inside the outer parens, which my (:expr)(params)
> couldn't benefit from -- unless I just take your format and substitute ':' for
> both def and from:


But where does that leave "Python is executable pseudocode"?

Compare:
(lambda (a, b, c) : f(a) + o(b) - o(c))
(: f(a) + o(b) - o(c) : (a, b, c))
(def f(a) + o(b) - o(c) from (a, b, c))

Which of the above most clearly expresses "defer a functional expression taking
arguments a, b, and c"?

For comparison, named syntax requires 3 lines, since Guido also wants to remove
suite one-liners in Py3k:

def f1(a, b, c):
return f(a) + o(b) - o(c)
f1

Not so bad for a single deferred expression (particularly a
not-completely-trivial one like this), but fares significantly worse for simple
zero-argument functions, or if you are just setting up a couple of deferred
expressions in a function call. There's no more virtue in completely squandering
vertical screen real estate than there is in being overly conservative with it.

> What was the point of all this again? Pretending lambda goes away without really killing it?


Actually, it was started by the "please don't take our lamdbas!" comments
regarding Python 3k. I suggested that one of the problems with lambda is that it
is an expression but looks like a one-liner statement ("it's ugly as sin" may
have been closer to my actual phrasing), that the syntax would be deservedly
rejected if proposed as a new addition to the language, and a more productive
response might be to consider nicer alternative syntax that Guido would consider
retaining in Python 3k (since it would make sense to try out such a syntax in
the Python 2.x series before committing to it for 3.0).

Of course, after making that suggestion, my brain decided to start working on
its *own* ideas for a more Pythonic syntax (trying to learn from generator
expressions), which seemed to set off a few other people

The name 'deferred expression' is intended to emphasise what I see as the most
appropriate application for anonymous functions - using an entire named function
statement to defer a simple expression is serious overkill. Recognising this use
case was what switched me from "I won't miss lambdas" to "You know, I'd really
regret it if they disappeared completely".

Basically, I think lambda has a PR problem - its usefulness as a way to defer
expression evaluation is obscured by its ugly syntax and its current explanation
as "a neutered form of function definition, but at least you can use it in an
expression".

On backticks, they have a major problem in that many fonts make ` and '
virtually indistinguishable. A secondary problem is that printed text often
renders an opening single quote like a backtick. Guido has already mentioned
this in one of Python Regrets talks (in the context of the backtick repr
syntax). So I don't expect any syntax involving backticks to even be looked at
by the BDFL.

Cheers,
Nick.

--
Nick Coghlan | | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      01-07-2005
On Tue, 04 Jan 2005 14:11:51 -0800, Michael Spencer <> wrote:
[Hm, this didn't go out for some reason. I'll just send it now.]

>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.
>

I imagine that you should be able to identify bytecode substrings in current code
that would have to be part of an implementation of what you are proposing.
But ISTM mabe there's three concepts: 1) defining the formal parameter list,
which is like a template for unpacking and binding an actual arglist produced by
2) the source code for a call of some named function with expression for actual
arguments, and 3) the run time excution of the code compiled from (2).

AFAICS, currently there is no linkage between the called function and the calling code
except that the first thing put on the stack is just the result of an expression that
_should_ put a reference to a compatible callable on the stack. What follows is a sequence
of argument expressions which stack the arg values, and then finally the byte code is executed
to make one of several kinds of specialized function calls to use the stack contents.
At that point the 'callable' could be None, or another function with the wrong signature.

What I see as the deferred-args-evaluation part is the code between pushing the callable
reference and making the specialized call. But that can't be what your args function is,
since UIAM the 'arguments' to that are not run time calling arguments, but a particular
formal parameter signature. That's a guide for unpacking and binding a call's arguments
at an associated function's entry, to create a _part_ of the local bindings, which has
nothing to do with deferring the evaluation of the call args.


>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 is the part I don't understand. To me, that expression doesn't have anything to
do with evaluating parameters, it has to do with unpacking a particular call's parameters
after they have been evaluated. If it could "evaluate ist parameters" it would have
to have code in it to do that, but the code for evaluation of parameters is generated
from the translation of the calling code. And there might be dozens of lines calling
the same function. I.e., args(a,*b,**kw) specifies formal parameter names and structural
information for dealing with callers' post-evaluation actual args.

The only way it could have the ability to control evaluation of args is if it had a reference
to a deferred-arg-eval byte code snippet. IOw, maybe the function should be called argsig instead
of args and args could deal with deferred actual arg evaluation. Then the tuple
argsig(x, y), args(1, 2)
could conceptually be like a bound method for deferred evaluation or args _and_ binding to
names in some namespace like a function's local namespace, but maybe not necessarily. Maybe
it could be applied to other namspaces as well. ... just musing

>
>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.

But it has to be clear that until a particular calling-args list (deferred or not) is
selected by being the "current one" of possibly many, the object doesn't have arg values
to mess with.
>
>* 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

Again, see above for argsig vs argeval. Or what am I missing?
>
>
> * 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
>


BTW, if argseval(arg1, etc) pushes arg1 and etc when "called"
sort of like (*lambda arg,etc:arg,etc) without packing/unpacking
then maybe they could be added, so argseval(a,b)+argseval(c) == argseval(a,b,c).
Don't know what that would be good for. Maybe in currying or such?

Regards,
Bengt Richter
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Type of lambda function returning a lambda function... Haochen Xie C++ 4 03-17-2013 11:23 PM
lambda vs non-lambda proc Steve Dogers Ruby 1 03-30-2009 10:11 PM
Interdependent DropDownLists (with declarative data binding) =?Utf-8?B?VGltbQ==?= ASP .Net 11 06-29-2006 06:49 AM
declarative binding inside a gridview John ASP .Net 0 12-13-2005 06:36 PM
Declarative Security in ASP .net MS Newsgroups ASP .Net 1 10-19-2003 07:21 AM



Advertisments