[Python-Dev] Re: "groupby" iterator
Robert Brewer
fumanchu at amor.org
Tue Dec 2 15:06:03 EST 2003
After:
> > > I agree with Thomas - rather than adding yet more specialised
> > > functions, it would seem more sensible to optimize lambda
> - probably
> > > via special cases like this.
> >
> > One question that remains is: do a handful of these specialized
> > functions make it possible to replace the remaining uses lambda
> > completely?
> >
> > Looking at parts of my codebase nearly all uses of lambda are
> > 'lambda self: self.someattr'.
>
Guido van Rossum wrote:
> Aha. Very interesting ideas both!
>
> So again, here we have a mechanism that's rather generic (lambda)
> which is frequently used in a few stylized patterns (to extract an
> attribute or field). So Raymond's new functions attrgetter and
> itemgetter (whose names I cannot seem to remember :-) take care of
> these.
>
> But, at least for attrgetter, I am slightly unhappy with the outcome,
> because the attribute name is now expressed as a string literal rather
> than using attribute notation. This makes it harder to write
> automated tools that check or optimize code. (For itemgetter it
> doesn't really matter, since the index is a literal either way.)
>
> So, while I'm not particularly keen on lambda, I'm not that keen on
> attrgetter either. But what could be better? All I can think of are
> slightly shorter but even more crippled forms of lambda; for example,
> we could invent a new keyword XXX so that the expression (XXX.foo) is
> equivalent to (lambda self: self.foo). This isn't very attractive.
> Maybe the idea of recognizing some special forms of lambda and
> implementing them more efficiently indeed makes more sense!
I swore I wouldn't post here without lurking for a couple months, but I
can't help myself.
I mentioned on c.l.p. that extract() looked like a classic case for
currying to me, using getattr() and currying the attribute name. So that
instead of (lambda self: self.foo), you'd end up with
(rightcurry(getattr, 'foo')), which might give some of the speed
increase desired. If one could assure that each object in an iteration
had that 'foo' attribute at the same mem location (for example,
instances of a class with a common function def), you could optimize
further.
> Now the question remains, would it be better to hide this and simply
> use it under the hood as an alternative way of generating code for
> lambda, or should it be some sort of standard library module, to be
> invoked explicitly? In favor of the latter pleads that this would
> solve the semantic differences with lambda when free variables are
> involved: obviously X+q would evaluate q only once, while
> (lamda X: X+q) evaluates q on each invocation. Remember that for
> generator expressions we've made the decision that
> (X+q for X in seq)
> should evaluate q only once.
Which currying would do, no? Instead of (lambda X: X+q) you get
(rightcurry(operator.add, q)).
The reason I bring it up is because I see curry applying in many more
and more powerful situations than just extract(). Kill 16 birds with one
stone. Obviously, there's been some work on curry already in PEP 309,
which included the community response of "Lambda is good enough."
Perhaps it's not in this case.
Criticism welcomed, constructive or destructive. :)
Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org
More information about the Python-Dev
mailing list