what is lambda used for in real code?

S

Steve Holden

Alex said:
Adam DePrince wrote:
[...]
In sort, we must preserve the ability to create an anonymous function
simply because we can do so for every other object type, and functions
are not special enough to permit this special case.

And you'd create an anonymous type how, exactly?
type('',(),{})

<class '__main__.'>

maybe...?
Indeed. And then you'd insert all the methods as lambdas by ....

We both know that the Python language framework has enough introspection
capabilities to do this, but I'm pretty sure you wouldn't try to pretend
that this would represent a realistic programming style. Or am I wrong?

regards
Steve
 
A

Alex Martelli

Steve Holden said:
...
Indeed. And then you'd insert all the methods as lambdas by ....

We both know that the Python language framework has enough introspection
capabilities to do this, but I'm pretty sure you wouldn't try to pretend
that this would represent a realistic programming style. Or am I wrong?

Calling 'type' to make a new type on the fly is occasionally neat -- not
quite as often as (say) using 'lambda', maybe;-). Neither should be a
'programming _style_' as opposed to an occasional convenience -- of the
two, lambda has more sensible use cases, but is also more prone to
overuse in practice. Also, the ability to call 'type' to make a type
adds zero complexity or issues to the language: it's basically zero
cost, just like the ability to call 'int' to make an int, and so on.
This can't be said of lambda, alas: it has a non-zero cost in terms of
(slightly) 'fattening' the language.


Alex
 
J

Jeff Shannon

Steven said:
The only ones that make me a little nervous are examples like:

inspect.py: def formatargspec(args, varargs=None, varkw=None,
...
formatvarargs=lambda name: '*' + name,
formatvarkw=lambda name: '**' + name,
formatvalue=lambda value: '=' + repr(value),

where the lambdas are declaring functions as keyword arguments in a def.

At least in this case, a number of these can be handled with curry /
partial(), I think --

...
formatvarargs = partial(operator.add, '*'),
formatvarkw = partial(operator.add, '**'),
...

The last is a bit more complicated, since it's got an extra (deferred)
function call, so I'm not sure exactly how to deal with that cleanly.

Actually, in this specific case, since these are all creating strings,
it'd be pretty trivial to simply do this manipulation inside of the
function body rather than inside of the arglist:

def formatargspec(..., formatvarargs,
formatkwargs,
formatvalue, ...):
formatvarargs = '*' + formatvarargs
formatvarkw = '**' + formatvarkw
formatvalue = '=' + repr(value)

This has the disadvantage of having names typed multiple times, which
is definitely a minus, but it's arguably a bit more clear to
explicitly manipulate the strings within the function body rather than
burying that manipulation somewhere in the argument list. Personally
I'd call this a wash, though I expect that others will disagree with
me. ;) And whatever the merits of this particular case, similar cases
may not be so easy to avoid in this fashion...

Jeff Shannon
Technician/Programmer
Credit International
 
A

Adam DePrince

Adam said:
Lets not forget the "real reason" for lambda ... the elegance of
orthogonality. Why treat functions differently than any other object?

We can operate on every other class without having to involve the
namespace, why should functions be any different?

Yup. I think in most of the examples that I didn't know how to rewrite,
this was basically the issue. On the other hand, I do think that
lambdas get overused, as indicated by the number of examples I *was*
able to rewrite.[1]

Still, I have to admit that in some cases (especially those involving
reduce), I wish the coder had named the function -- it would have given
me a little bit more documentation as to what the code was trying to do.

This is a long standing philosophical issue that really shouldn't impose
itself on the language. Do you document, and risk that the
documentation doesn't match the code, or do you use the code itself as
documentation.

Leaving, or even expanding upon, anonymous functions permits the
programmer to choose their stance in the above debate; you can still
write

# If I had to give this function a name, it would be ...

before or after the lambda to elect the former option. The removal of
anonymous functions, however, forces the former option. Even if option
latter is misguided, one of the guiding principles of Python is that we
are all consenting adults free to do dumb things.

- Adam

Adam DePrince
 
A

Adam DePrince

Please show me how to create an anonymous type, module, or class,

You can create anonymous instances of classes and types. The actual
type, module or class .. well, that is another special case that isn't
special enough ... but that is somewhat beyond the scope of this
thread. I've seen a number of responses similar to this; I feel that
the lack of anonymous classes, types and modules are flaws with the
language that should be fixed, not used to justify introducing another
flaw.

It is my humble opinion that a good language design is completely
orthogonal. The curse of anonymity in the language can be "cured" at a
management/specification level by requiring the use of the name space.
The alternative, the removal of anonymous functions, adds a "special
case" and dumbs down the language. Personally, I'd like to see Python
evolve in the direction of ML instead of Visual Basic.

There are actually times when I've wanted anonymous classes. Very
often, I've written code that accepts as a parameter, a class. Of
course, the code instantiates this class with the expectation that it
provides a particular interface. And sometimes, it would have been nice
to, in a single invocation of such a function, change a single method of
the class before passing it. In a sense, I've written code for which a
class or type equivalent to a lambda would actually have been really
nice.
especially with an expression. Number, sequences, and dicts have easily
printable values. Functions, like classes and module do not*, so

So do lambdas, classes, types, etc. And I've encountered a good many
lists and dicts that don't qualify as "easily printable." Quite
frankly, it seems a bit capricious to *require* the use of the name
space on the basis of the similarity between the repr of the object and
line noise.

And here is a counter example ... this def fits nicely on one line:

Python 2.4 (#1, Dec 27 2004, 15:19:19)
[GCC 3.4.1] on linux2
definition names act as a standin and as a pointer to the source code that
produced the object. If functions are not special relative to classes and
modules, which is the grouping they belong with, then we should get rid of
lambda ;-)

*Now that memory is 'cheap', someone recently proposed that code objects
(and hence functions) get .source attribute. Maybe, someday...

The .source attribute could be free from a memory consumption
perspective if the source -> byte code conversion is reversible.
Terry J. Reedy
Adam DePrince
 
A

Adam DePrince

Adam DePrince wrote:
[...]
In sort, we must preserve the ability to create an anonymous function
simply because we can do so for every other object type, and functions
are not special enough to permit this special case.
And you'd create an anonymous type how, exactly?

Okay, you got me. Let me rephrase:

.... functions, types, classes and moduless are not special enough ...

I had things like, um, strings, lists, integers, etc in mind.

- adam
regards
Steve
Adam DePrince
 
S

Steven Bethard

I said:
* Functions I don't know how to rewrite
Some functions I looked at, I couldn't figure out a way to rewrite them
without introducing a new name or adding new statements.
[snip]

inspect.py: def formatargspec(args, varargs=None, varkw=None,
...
formatvarargs=lambda name: '*' + name,
formatvarkw=lambda name: '**' + name,
formatvalue=lambda value: '=' + repr(value),
inspect.py: def formatargvalues(args, varargs, varkw, locals,
...
formatvarargs=lambda name: '*' + name,
formatvarkw=lambda name: '**' + name,
formatvalue=lambda value: '=' + repr(value),

Realized today that I do know how to rewrite these without a lambda,
using bound methods:
def formatargspec(args, varargs=None, varkw=None,
...
formatvarargs='*%s'.__mod__,
formatvarkw='**%s'.__mod__,
formatvalue='=%r'.__mod__,
I like this rewrite a lot because you can see that the function is
basically just the given format string. YMMV, of course.

Similarly, if DEF_PARAM, DEF_BOUND and glob are all ints (or supply the
int methods), I can rewrite
symtable.py: self.__params = self.__idents_matching(lambda x:
x & DEF_PARAM)
symtable.py: self.__locals = self.__idents_matching(lambda x:
x & DEF_BOUND)
symtable.py: self.__globals = self.__idents_matching(lambda x:
x & glob)

with the bound methods of the int objects:
self.__params = self.__idents_matching(DEF_PARAM.__rand__)
self.__locals = self.__idents_matching(DEF_BOUND.__rand__)
self.__globals = self.__idents_matching(glob.__rand__)
(Actually, I could probably use __and__ instead of __rand__, but
__rand__ was the most direct translation.)


Ahh, the glory of bound methods... ;)

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,215
Messages
2,571,113
Members
47,710
Latest member
HarleyMoli

Latest Threads

Top