473,407 Members | 2,306 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

A replacement for lambda

I know, lambda bashing (and defending) in the group is one of the most
popular ways to avoid writing code. However, while staring at some Oz
code, I noticed a feature that would seem to make both groups happy -
if we can figure out how to avoid the ugly syntax.

This proposal does away with the well-known/obscure "lambda"
keyword. It gives those who want a more functional lambda what they
want. It doesn't add any new keywords. It doesn't add any new magic
characters, though it does add meaning to an existing one. That could
be replaced by a new magic token, or adding magic meaning to a
non-magic token. It breaks no old code either way.

I haven't really worked out all the implications; I just wanted to
throw it out and see what everyone else thought about it. As a
result, the code examples tend to be ugly.

As previously hinted, this feature is lifted from Oz.

Currently, class and functions definitions consist of a keyword -
either "class" or "def" - followed by a name, a header, then code. The
code is compiled into an object, and the name is bound to that object.

The proposal is to allow name to be a non-name (or rare name)
token. In this case, the code is compiled and the resulting object is
used as the value of the class/def expression.

My choice for the non-name token is "@". It's already got magic
powers, so we'll give it more rather than introducing another token
with magic powers, as the lesser of two evils.

Rewriting a canonical abuse of lambda in this idiom gives:

myfunc = def @(*args):
return sum(x + 1 for x in args)

In other words, this is identical to:

def myfunc(*args):
return sum(x + 1 for x in args)

We can write the same loop with logging information as:

sum(def @(arg):
print "Bumping", arg
return arg + 1
(x) # '(' at the same indent level as def, to end the definition
for x in stuff)

A more useful example is the ever-popular property creation without
cluttering the class namespace:

class Spam(object):
myprop = property(fget = def @(self):
return self._properties['myprop']
,
fset = def @(self, value):
self._properties['myprop'] = value
,
fdel = def @(self)
del self._properties['myprop']
,
doc = "Just an example")

This looks like the abuse of lambda case, but these aren't
assignments, they're keyword arguments. You could leave off the
keywords, but it's not noticably prettier. fget can be done with a
lambda, but the the others can't.

Giving clases the same functionality seems to be the reasonable thing
to do. It's symmetric. And if anonymous function objects are good,
then anonymous class objects ought to be good as well.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 29 '05 #1
30 2101
Mike Meyer wrote:
My choice for the non-name token is "@". It's already got magic
powers, so we'll give it more rather than introducing another token
with magic powers, as the lesser of two evils.


Doesn't work. The crux of your change isn't introducing a meaning to @
(and honestly, I prefer _), it's that you change the 'define block' from
a compound_stmt (funcdef) (see
www.python.org/doc/current/ref/compound.html) to an expression_stmt
(expresion). This change would allow some really damn weird things, like:

if def _(x,y):
return x**2 - y**2
(5,-5): # ?! How would you immediately call this 'lambda-like'?[1]
print 'true'
else:
print 'false'

[1] -- yes, it's generally stupid to, but I'm just pointing out what has
to be possible.

Additionally, Python's indenting Just Doesn't Work Like That; mandating
an indent "after where the def came on the previous line" (as you do in
your example, I don't know if you intend for it to hold in your actual
syntax) wouldn't parse right -- the tokenizer generates INDENT and
DEDENT tokens for whitespace, as I understand it.

My personal favourite is to replace "lambda" entirely with an
"expression comprehension", using < and > delimeters. It just looks
like our existing list and generator comprehensions, and it doesn't use
'lambda' terminology which will confuse any newcomer to Python that has
experience in Lisp (at least it did me).

g = <x**2 with (x)>
g(1) == 1

Basically, I'd rewrite the Python grammar such that:
lambda_form ::= "<" expression "with" parameter_list ">"

Biggest change is that parameter_list is no longer optional, so
zero-argument expr-comps would be written as <expr with ()>, which makes
a bit more sense than <expr with>.

Since "<" and ">" aren't ambiguous inside the "expression" state, this
shouldn't make the grammar ambiguous. The "with" magic word does
conflict with PEP-343 (semantically, not syntactically), so "for" might
be appropriate if less precise in meaning.
Jul 30 '05 #2
Christopher Subich <sp****************@block.subich.spam.com> writes:
My personal favourite is to replace "lambda" entirely with an
"expression comprehension", using < and > delimeters.


But how does that let you get more than one expression into the
anonymous function?
Jul 30 '05 #3
Christopher Subich wrote:
g = <x**2 with (x)>
g(1) == 1

Basically, I'd rewrite the Python grammar such that:
lambda_form ::= "<" expression "with" parameter_list ">"

Biggest change is that parameter_list is no longer optional, so
zero-argument expr-comps would be written as <expr with ()>, which makes
a bit more sense than <expr with>.

Since "<" and ">" aren't ambiguous inside the "expression" state, this
shouldn't make the grammar ambiguous. The "with" magic word does
conflict with PEP-343 (semantically, not syntactically), so "for" might
be appropriate if less precise in meaning.


What kind of shenanigans must a parser go through to translate:
<x**2 with(x)><<x**3 with(x)>

this is the comparison of two functions, but it looks like a left-
shift on a function until the second with is encountered. Then
you need to backtrack to the shift and convert it to a pair of
less-thans before you can successfully translate it.

--Scott David Daniels
Sc***********@Acm.Org
Jul 30 '05 #4
On 2005-07-30, Scott David Daniels <Sc***********@Acm.Org> wrote:
Christopher Subich wrote:
g = <x**2 with (x)>
g(1) == 1

Basically, I'd rewrite the Python grammar such that:
lambda_form ::= "<" expression "with" parameter_list ">"

Biggest change is that parameter_list is no longer optional, so
zero-argument expr-comps would be written as <expr with ()>, which makes
a bit more sense than <expr with>.

Since "<" and ">" aren't ambiguous inside the "expression" state, this
shouldn't make the grammar ambiguous. The "with" magic word does
conflict with PEP-343 (semantically, not syntactically), so "for" might
be appropriate if less precise in meaning.
What kind of shenanigans must a parser go through to translate:
<x**2 with(x)><<x**3 with(x)>

this is the comparison of two functions, but it looks like a left-
shift on a function until the second with is encountered. Then
you need to backtrack to the shift and convert it to a pair of
less-thans before you can successfully translate it.


I'm just worming my way into learning Lisp, but this seems to be a
perfect example of everything I'm seeing so far. The compiler should
do all sorts of gymnastics and contortions. Make the compiler/interpreter
as complex as possible, to handle any freaky thing a programmer can
invent.

Which does not, in the least, imply that the same attitude should apply toward
python.

I read this thread and my brain hurts. Python code should *never* do this.

Tim Peters (let's all bow down, we're not worthy <g>) might write some code that
I can't quite follow. But at least it's obvious. He doesn't suddenly introduce
an entirely new syntax for the sake of "hey, this would be cool." Or maybe
"It'd be much more simple if we made everyone use more C-like syntax." Or...
wherever you were going with this. This
<x**2 with(x)><<x**3 with(x)> is precisely the kind of code that I got into python to avoid.

I happen to like nice, simple, readable code. Maybe I'm just old and grumpy.
Looking at that line, I get the same "This is just ugly" feel that I get when
I at perl. Some note from other pieces in this thread. Things about $_ or
what-not.
Personally, I can't recall any decent programmer I know who objects to actually
writing out a variable name. In fact, I don't know a single "real" programmer
(this is one who writes programs he intends to look at again in, say, 3 weeks)
who doesn't insist on writing "real" variable names.

(Heh. I'll probably read through some Guido code next week that totally proves
me wrong <g>...such is life).
--Scott David Daniels
Sc***********@Acm.Org

--
Liberty means responsibility. That is why most men dread it.
- George Bernard Shaw

Jul 30 '05 #5
Scott David Daniels <Sc***********@Acm.Org> wrote:

What kind of shenanigans must a parser go through to translate:
<x**2 with(x)><<x**3 with(x)>

this is the comparison of two functions, but it looks like a left-
shift on a function until the second with is encountered. Then
you need to backtrack to the shift and convert it to a pair of
less-thans before you can successfully translate it.


C++ solves this exact problem quite reasonably by having a greedy
tokenizer. Thus, that would always be a left shift operator. To make it
less than and a function, insert a space:
<x**2 with(x)>< <x**3 with(x)>
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Jul 30 '05 #6
James Richards <ro*****@govtabuse.com> writes:
Personally, I can't recall any decent programmer I know who objects
to actually writing out a variable name. In fact, I don't know a
single "real" programmer (this is one who writes programs he intends
to look at again in, say, 3 weeks) who doesn't insist on writing
"real" variable names.


The issue is whether you want to name every intermediate result in
every expression.

sum = a + b + c + d + e

is a lot nicer than

x1 = a + b
x2 = c + d
x3 = x1 + e
sum = x2 + x3

the language has nicely kept all those intermediate results anonymous.

Python has first-class functions, which, like recursion, is a powerful
idea that takes some getting used to. They let you say things like

def derivative(f, t, h=.00001): # evaluate f'(t) numerically
return (f(t+h) - f(t)) / h

dy_dt = derivative(cos, 0.3) # approx. -sin(0.3)

With anonymous functions, you can also say:

dy_dt = derivative(lambda x: sin(x)+cos(x), 0.3) # approx. cos(.3)-sin(.3)

Most Python users have experience with recursion before they start
using Python, so they don't see a need for extra keywords to express
it. Those not used to first-class functions (and maybe some others)
seem to prefer extra baggage. For many of those used to writing in
the above style, though, there's nothing confusing about using a
lambda there instead of spewing extra verbiage to store that
(lambda x: sin(x)+cos(x)) function in a named variable before
passing it to another function.
Jul 30 '05 #7

Tim Roberts schrieb:
Scott David Daniels <Sc***********@Acm.Org> wrote:

What kind of shenanigans must a parser go through to translate:
<x**2 with(x)><<x**3 with(x)>

this is the comparison of two functions, but it looks like a left-
shift on a function until the second with is encountered. Then
you need to backtrack to the shift and convert it to a pair of
less-thans before you can successfully translate it.


C++ solves this exact problem quite reasonably by having a greedy
tokenizer. Thus, that would always be a left shift operator. To make it
less than and a function, insert a space:
<x**2 with(x)>< <x**3 with(x)>
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.


Python does have such a greedy/longest match tokenizer too:
2 .__add__(3) # insert whitespace before dot 5
2.__add__(3) # 2. is a float

-> Exception

Kay

Jul 30 '05 #8
why (x**2 with(x))<(x**3 with(x)) is not taken in consideration?

If 'with' must be there (and substitue 'lambda:') then at least the
syntax is clear.IMO Ruby syntax is also clear.

___________________________________
Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
http://mail.yahoo.it
Jul 30 '05 #9
D H
Mike Meyer wrote:
Rewriting a canonical abuse of lambda in this idiom gives:

myfunc = def @(*args):
return sum(x + 1 for x in args)
Nice proposal. Technically you don't need the @ there, it is
superfluous. But then again so is the colon, so whatever floats your boat.

class Spam(object):
myprop = property(fget = def @(self):
return self._properties['myprop']
,
fset = def @(self, value):
self._properties['myprop'] = value
,
fdel = def @(self)
del self._properties['myprop']
,
doc = "Just an example")


I think the anonymous lambdas need to be outside the parentheses to be
parsable. Maybe like this:

class Spam(object):
myprop = property(fget, fset, fdel, doc="just an example"):
where fget = def (self):
.........
where fset = def (self):
.........
where fdel = def (self):
...........

As you can see, it doesn't save much over the traditional way since you
have to name the "anonymous" lambdas anyway.
Jul 30 '05 #10
D H <no@spam> writes:
where fdel = def (self):
...........
As you can see, it doesn't save much over the traditional way since
you have to name the "anonymous" lambdas anyway.


It saves polluting the surrounding namespace with superfluous variables
that aren't going to be used again.
Jul 30 '05 #11
Christopher Subich <spam.csubich+bl...@block.subich.spam.com> writes:
Basically, I'd rewrite the Python grammar such that:
lambda_form ::= "<" expression "with" parameter_list ">"


I do prefer my parameter list to come before the expression. It would
remain consistant with simple function definitions.

- Cheers, Paddy.

Jul 30 '05 #12
on 30.07.2005 10:20 Paolino said the following:
why (x**2 with(x))<(x**3 with(x)) is not taken in consideration?

If 'with' must be there (and substitue 'lambda:') then at least the
syntax is clear.IMO Ruby syntax is also clear.


I am sorry if this has already been proposed (I am sure it has).

Why not substitue python-lambdas with degenerated generator expressions::

(lambda x: func(x)) == (func(x) for x)

i.e. a one time callable generator expression (missing the `in` part).
The arguments get passed into the generator, I am sure that can be
combined with the PEP about passing args and Exceptions into a generator.

Jul 30 '05 #13
Stefan Rank <st*********@ofai.at> writes:
I am sorry if this has already been proposed (I am sure it has).
Why not substitue python-lambdas with degenerated generator expressions::

(lambda x: func(x)) == (func(x) for x)


I don't think I've seen that one before, and FWIW it's kind of cute.

But what's wrong with leaving lambdas the way they are? Anyone who can
understand generator expressions can understand lambda. I don't see any
point in trying to improve on lambda, without actually fixing its main
problem, which is the inability to create multi-statement closures.
Jul 30 '05 #14
Mike Meyer schrieb:
I know, lambda bashing (and defending) in the group is one of the most
popular ways to avoid writing code. However, while staring at some Oz
code, I noticed a feature that would seem to make both groups happy -
if we can figure out how to avoid the ugly syntax.

This proposal does away with the well-known/obscure "lambda"
keyword. It gives those who want a more functional lambda what they
want. It doesn't add any new keywords. It doesn't add any new magic
characters, though it does add meaning to an existing one. That could
be replaced by a new magic token, or adding magic meaning to a
non-magic token. It breaks no old code either way.


Mike,

in modern functional language design one starts with certain lambda
expressions and add syntax sugar ( operational / statement syntax ) for
constructs based on them. In Python statement- and expression syntax
were introduced seperately. Pythons lambda is simply the symptom of
this separation. Now you suggest ( not the first time on this list or
at python-dev ) to put statements into expressions leading to a strange
syntax and conflicting with Pythons indentation rules.

Another way to deal with the restrictions of lambda is going the other
way round and simply propose expression syntax for conds and
assignments.

Using guards '||' and the keyword 'then' for conditional expressions:

( || x>=0 then f(x) || True then f(-x) )

Or shorter dropping 'then' in the second condition:

( || x>=0 then f(x) || f(-x) )

Both translates to:

if x>=0:
f(x)
else:
f(-x)

Using a reverse arrow for assignments:

x <- y

For loops can be replaced by functional constructs ( use map() or a
list/generator comprehension ).

Finally the lambda keyword can be replaced by expressional syntax e.g.
( EXPR from ARGS ):

Examples:
f = ( || x>=0 then f(x) || True then f(-x) from (x,) )
g = ( || x< 0 then self._a <-x || self._a <- 0 from (x,))

Kay

Jul 30 '05 #15
"Kay Schluehr" <ka**********@gmx.net> writes:
Examples:
f = ( || x>=0 then f(x) || True then f(-x) from (x,) )
g = ( || x< 0 then self._a <-x || self._a <- 0 from (x,))


Is this an actual language? It looks sort of like CSP. Python
with native parallelism, mmmmm.
Jul 30 '05 #16
Paul Rubin wrote:
"Kay Schluehr" <ka**********@gmx.net> writes:
Examples:
f = ( || x>=0 then f(x) || True then f(-x) from (x,) )
g = ( || x< 0 then self._a <-x || self._a <- 0 from (x,))


Is this an actual language? It looks sort of like CSP. Python
with native parallelism, mmmmm.


The syntax was inspired by OCamls pattern matching syntax:

match object with
pattern1 -> result1
| pattern2 -> result2
| pattern3 -> result3
...

But for Python we have to look for an expression not a statement
syntax. In order to prevent ambiguities I used a double bar '||'
instead of a single one.

Kay

Jul 30 '05 #17
Stefan Rank wrote:
on 30.07.2005 10:20 Paolino said the following:
why (x**2 with(x))<(x**3 with(x)) is not taken in consideration?

If 'with' must be there (and substitue 'lambda:') then at least the
syntax is clear.IMO Ruby syntax is also clear.


I am sorry if this has already been proposed (I am sure it has).

Why not substitue python-lambdas with degenerated generator expressions::

(lambda x: func(x)) == (func(x) for x)

i.e. a one time callable generator expression (missing the `in` part).
The arguments get passed into the generator, I am sure that can be
combined with the PEP about passing args and Exceptions into a generator.


It's hard to spot, and it's too different to a genexp to have such a similar
syntax.

Reinhold
Jul 30 '05 #18
I understand that there are a number of people who wish to remove
lambda entirely from the language. Nevertheless, I find it a useful
and powerful tool in actual development.

Any replacement must support the following: *delayed evaluation*.

I need a convenient (def is not always convenient) way of saying,
"don't do this now". That is why I use lambda.

-- Seth Nielson

On 7/30/05, Reinhold Birkenfeld <re************************@wolke7.net> wrote:
Stefan Rank wrote:
on 30.07.2005 10:20 Paolino said the following:
why (x**2 with(x))<(x**3 with(x)) is not taken in consideration?

If 'with' must be there (and substitue 'lambda:') then at least the
syntax is clear.IMO Ruby syntax is also clear.


I am sorry if this has already been proposed (I am sure it has).

Why not substitue python-lambdas with degenerated generator expressions::

(lambda x: func(x)) == (func(x) for x)

i.e. a one time callable generator expression (missing the `in` part).
The arguments get passed into the generator, I am sure that can be
combined with the PEP about passing args and Exceptions into a generator.


It's hard to spot, and it's too different to a genexp to have such a similar
syntax.

Reinhold
--
http://mail.python.org/mailman/listinfo/python-list

Jul 30 '05 #19
Seth Nielson <se****@gmail.com> writes:
Any replacement must support the following: *delayed evaluation*.

I need a convenient (def is not always convenient) way of saying,
"don't do this now". That is why I use lambda.


How's this: f{args} (curly braces instead of parens) is the same as
f(lambda: args).

Examples:

launch_thread{targetfunc(a,b,c)}

b = Button{callback=pressed()} # Button remembers callback()

def ternary(cond, x, y):
if cond(): return x()
else: return y()

sign_of_a = ternary{a < 0, -1, 1}
etc.
Jul 30 '05 #20
On Fri, 29 Jul 2005 18:07:31 -0400, Mike Meyer <mw*@mired.org> wrote:
I know, lambda bashing (and defending) in the group is one of the most
popular ways to avoid writing code. However, while staring at some Oz
code, I noticed a feature that would seem to make both groups happy -
if we can figure out how to avoid the ugly syntax.

This proposal does away with the well-known/obscure "lambda"
keyword. It gives those who want a more functional lambda what they
want. It doesn't add any new keywords. It doesn't add any new magic
characters, though it does add meaning to an existing one. That could
be replaced by a new magic token, or adding magic meaning to a
non-magic token. It breaks no old code either way.

I haven't really worked out all the implications; I just wanted to
throw it out and see what everyone else thought about it. As a
result, the code examples tend to be ugly.

As previously hinted, this feature is lifted from Oz.

Currently, class and functions definitions consist of a keyword -
either "class" or "def" - followed by a name, a header, then code. The
code is compiled into an object, and the name is bound to that object.

The proposal is to allow name to be a non-name (or rare name)
token. In this case, the code is compiled and the resulting object is
used as the value of the class/def expression.

My choice for the non-name token is "@". It's already got magic
powers, so we'll give it more rather than introducing another token
with magic powers, as the lesser of two evils.

Rewriting a canonical abuse of lambda in this idiom gives:

myfunc = def @(*args):
return sum(x + 1 for x in args)
If you remove the '@' -- which is not really needed -- you have exactly my (at least
I think it was mine -- the variation are, in any case ;-) old anonymous def proposal.

So good luck in getting any more favorable attention than I did ;-)
I've also proposed named and anonymous callable local blocks for
the other variations of removing 'def' and/or the binding name from
normal def syntax. E.g.,

def my_func(*args): # normal def
return sum(x + 1 for x in args)

my_func = def(*args): # anonymous def expression
return sum(x + 1 for x in args)

my_local_callable_block(*args): # named local callable block
nargs = len(args) # binds nargs as if this suite were e.g. an "if" suite.
return sum(x + 1 for x in args)

my_local_callable_block = (*args): # local callable block expression
nargs = len(args) # binds nargs as if this suite were e.g. an "if" suite.
return sum(x + 1 for x in args)

The local callable blocks can be made accessible via a dict or list or whatever and called like

lcb_dict[key](args)

to have the bindings occur in the scope of the block definition. This avoids the problem of
the typical case dispatch of function calls via a dict, where the function has its own temporary
local namespace and binding in the calling namespace is kludgey.

In other words, this is identical to:

def myfunc(*args):
return sum(x + 1 for x in args)

We can write the same loop with logging information as:

sum(def @(arg):
print "Bumping", arg
return arg + 1
(x) # '(' at the same indent level as def, to end the definition
for x in stuff)
You are almost quoting me in previous posts (protesting that the indentation "problem" is no big deal ;-)

A more useful example is the ever-popular property creation without
cluttering the class namespace:

class Spam(object):
myprop = property(fget = def @(self):
return self._properties['myprop']
,
fset = def @(self, value):
self._properties['myprop'] = value
,
fdel = def @(self)
del self._properties['myprop']
,
doc = "Just an example")
Again, the '@' is not necessary ;-)
This looks like the abuse of lambda case, but these aren't
assignments, they're keyword arguments. You could leave off the
keywords, but it's not noticably prettier. fget can be done with a
lambda, but the the others can't. Well, they can, but it's not pretty ;-)

Giving clases the same functionality seems to be the reasonable thing
to do. It's symmetric. And if anonymous function objects are good,
then anonymous class objects ought to be good as well.

I agree.

Regards,
Bengt Richter
Jul 30 '05 #21
On Fri, 29 Jul 2005 18:07:31 -0400, Mike Meyer <mw*@mired.org> wrote:
I know, lambda bashing (and defending) in the group is one of the most
popular ways to avoid writing code. However, while staring at some Oz
code, I noticed a feature that would seem to make both groups happy -
if we can figure out how to avoid the ugly syntax.

This proposal does away with the well-known/obscure "lambda"
keyword. It gives those who want a more functional lambda what they
want. It doesn't add any new keywords. It doesn't add any new magic
characters, though it does add meaning to an existing one. That could
be replaced by a new magic token, or adding magic meaning to a
non-magic token. It breaks no old code either way.

I haven't really worked out all the implications; I just wanted to
throw it out and see what everyone else thought about it. As a
result, the code examples tend to be ugly.

As previously hinted, this feature is lifted from Oz.


try

http://groups-beta.google.com/groups...mp.lang.python

for much discussion of this ;-)

Regards,
Bengt Richter
Jul 30 '05 #22
Paul Rubin wrote:
How's this: f{args} (curly braces instead of parens) is the same as
f(lambda: args).

Examples:

launch_thread{targetfunc(a,b,c)}
b = Button{callback=pressed()} # Button remembers callback()
sign_of_a = ternary{a < 0, -1, 1}


I'd consider this an interesting idea if it weren't for the fact that
(at least with the fonts I generally use) I can barely make out the
difference between the {} and the () above.

-Peter
Jul 30 '05 #23
Peter Hansen <pe***@engcorp.com> writes:
sign_of_a = ternary{a < 0, -1, 1}


I'd consider this an interesting idea if it weren't for the fact that
(at least with the fonts I generally use) I can barely make out the
difference between the {} and the () above.


Ok, how about an escaped paren:
sign_of_a = ternary\(a < 0, -1, 1)
Jul 30 '05 #24
On Fri, Jul 29, 2005 at 10:14:12PM -0700, Tim Roberts wrote:
C++ solves this exact problem quite reasonably by having a greedy
tokenizer. Thus, that would always be a left shift operator. To make it
less than and a function, insert a space:
<x**2 with(x)>< <x**3 with(x)>


Incidentally, I read in an article by Bjarne Stroustrup[1] that "C++0x" will parse
vector<vector<double>> v;
just like today's compilers parse
vector<vector<double> > v;

Another of the changes he discusses, letting 'auto i = ...' create i
with the type of the expression '...', will certainly be an improvement.
Even better if the keyword 'auto' could be made optional! (Of course,
this is another break with C, where the declaration
auto i;
makes 'i' an int)

And what's this got to do with Python? I dunno. Sorry.

Jeff
[1] http://www.informit.com/content/imag...inks/rules.pdf

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFC7ABaJd01MZaTXX0RArfAAJ9dpNfnpvVt/iOctmMdwgmpoTQLHgCdFttG
AI5ZtzcaYrntXHy9YRfVqX4=
=td3E
-----END PGP SIGNATURE-----

Jul 30 '05 #25
Paul Rubin wrote:
Christopher Subich <sp****************@block.subich.spam.com> writes:
My personal favourite is to replace "lambda" entirely with an
"expression comprehension", using < and > delimeters.

But how does that let you get more than one expression into the
anonymous function?


It doesn't. Functionally, it's a direct replacement of lambda as-is.
Jul 31 '05 #26
Scott David Daniels wrote:
What kind of shenanigans must a parser go through to translate:
<x**2 with(x)><<x**3 with(x)>

this is the comparison of two functions, but it looks like a left-
shift on a function until the second with is encountered. Then
you need to backtrack to the shift and convert it to a pair of
less-thans before you can successfully translate it.


I hadn't thought of that, but after much diving into the Python grammar,
the grammar would still work with a greedy tokenizer if "<<" (and also
">>", for identical reasons) were replaced in 'shift_expr" with "<" "<"
and ">" ">".

That, of course, introduces some weirdness of '''a = 5 < < 3''' being
valid. I'm not sure whether that is a wart big enough to justify a
special-case rule regarding '>>' and '<<' tokens. We do allow
'def f () :'
as-is, so I'm not sure this is too big of a problem.
Jul 31 '05 #27
Paolino wrote:
why (x**2 with(x))<(x**3 with(x)) is not taken in consideration?
Looks too much like a generator expression for my taste. Also, <expr
...> syntax could be used with 'for' instead of 'with' if PEP343 poses a
problem, whereas (expr for params) is identically a generator expression.
If 'with' must be there (and substitue 'lambda:') then at least the
syntax is clear.IMO Ruby syntax is also clear.


I haven't used Ruby myself, but as I understand it that language allows
for full anonymous blocks. Python probably doesn't want to do that.
Jul 31 '05 #28
Paddy wrote:
Christopher Subich <spam.csubich+bl...@block.subich.spam.com> writes:
Basically, I'd rewrite the Python grammar such that:
lambda_form ::= "<" expression "with" parameter_list ">"

I do prefer my parameter list to come before the expression. It would
remain consistant with simple function definitions.


Stylistic choice; I can appreciate your sentiment, but remember that
this isn't exactly a function definition. It's a form of 'delayed
expression.' Also, <... with ...> is nearly identical (identical if you
replace 'with' with 'for') to existing list and generator
comprehensions, so we'd get to stretch that idiom.
Jul 31 '05 #29
bo**@oz.net (Bengt Richter) writes:
On Fri, 29 Jul 2005 18:07:31 -0400, Mike Meyer <mw*@mired.org> wrote:
I know, lambda bashing (and defending) in the group is one of the most
popular ways to avoid writing code. However, while staring at some Oz
code, I noticed a feature that would seem to make both groups happy -
if we can figure out how to avoid the ugly syntax.

try

http://groups-beta.google.com/groups...mp.lang.python

for much discussion of this ;-)


Well, that pretty much kills that. I knew there had been a lot of
discussion about anonymous functions, anonymous blocks, and of course
various lambda replacements. But I didn't realize almost exactly this
proposal had been discussed before. Shouldn't surprise me, though.

Thanks to everyone who took the time to read and respond.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 31 '05 #30
On Sun, 31 Jul 2005 00:30:36 -0400, Mike Meyer <mw*@mired.org> wrote:
bo**@oz.net (Bengt Richter) writes:
On Fri, 29 Jul 2005 18:07:31 -0400, Mike Meyer <mw*@mired.org> wrote:
I know, lambda bashing (and defending) in the group is one of the most
popular ways to avoid writing code. However, while staring at some Oz
code, I noticed a feature that would seem to make both groups happy -
if we can figure out how to avoid the ugly syntax. try

http://groups-beta.google.com/groups...mp.lang.python

for much discussion of this ;-)


Well, that pretty much kills that. I knew there had been a lot of

Well, why consider it killed? Maybe your weight could tilt the balance ;-)
I still like the anonymous def.
discussion about anonymous functions, anonymous blocks, and of course
various lambda replacements. But I didn't realize almost exactly this
proposal had been discussed before. Shouldn't surprise me, though.

Thanks to everyone who took the time to read and respond.

Sometimes ideas have to sit in the mulch for a while before it's their season to bloom ;-)

Regards,
Bengt Richter
Jul 31 '05 #31

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

53
by: Oliver Fromme | last post by:
Hi, I'm trying to write a Python function that parses an expression and builds a function tree from it (recursively). During parsing, lambda functions for the the terms and sub-expressions...
63
by: Stephen Thorne | last post by:
Hi guys, I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things...
26
by: Steven Bethard | last post by:
I thought it might be useful to put the recent lambda threads into perspective a bit. I was wondering what lambda gets used for in "real" code, so I grepped my Python Lib directory. Here are some...
181
by: Tom Anderson | last post by:
Comrades, During our current discussion of the fate of functional constructs in python, someone brought up Guido's bull on the matter: http://www.artima.com/weblogs/viewpost.jsp?thread=98196 ...
18
by: talin at acm dot org | last post by:
I've been reading about how "lambda" is going away in Python 3000 (or at least, that's the stated intent), and while I agree for the most part with the reasoning, at the same time I'd be sad to see...
4
by: Xah Lee | last post by:
A Lambda Logo Tour (and why LISP languages using λ as logo should not be looked upon kindly) Xah Lee, 2002-02 Dear lispers, The lambda character λ, always struck a awe in me, as with...
23
by: Kaz Kylheku | last post by:
I've been reading the recent cross-posted flamewar, and read Guido's article where he posits that embedding multi-line lambdas in expressions is an unsolvable puzzle. So for the last 15 minutes...
21
by: globalrev | last post by:
i have a rough understanding of lambda but so far only have found use for it once(in tkinter when passing lambda as an argument i could circumvent some tricky stuff). what is the point of the...
1
by: Tim H | last post by:
Compiling with g++ 4: This line: if_then_else_return(_1 == 0, 64, _1) When called with a bignum class as an argument yields: /usr/include/boost/lambda/if.hpp: In member function 'RET...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.