Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Securing a future for anonymous functions in Python

Reply
Thread Tools

Securing a future for anonymous functions in Python

 
 
John Roth
Guest
Posts: n/a
 
      12-30-2004

"Ian Bicking" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> John Roth wrote:
>> The syntax I prefer (and I don't know if it's actually been
>> suggested before) is to use braces, that is { and }.
>>
>> In other words, an anonymous function looks like:
>> {p1, p2, p3 |
>> stmt1
>> stmt2
>> }

>
> What's the advantage of something like that over the non-anonymous
> equivalent:
>
> def some_func(p1, p2, p3):
> stmt1
> stmt2
>
> I appreciate some of the motivation, but merely avoiding giving something
> a name doesn't seem like a laudible goal.


Actually, it is a laudable goal. It's always easier to understand
something when it's right in front of your face than if it's
off somewhere else.

This, of course, trades off with two other forces: avoiding
repetition and making the whole thing small enough to
understand.

So the niche is small, single use functions. The problem
with lambdas is that they're restricted to one expression,
which is too small.

Languages that are designed with anonymous functions
in mind use them very heavily. Smalltalk is the standard
example, and it's also one of the major (possibly the
only) attraction Ruby has over Python.

Python isn't designed that way, which restricts their
utility to a much smaller niche than otherwise.

> The one motivation I can see for function expressions is callback-oriented
> programming ...


Well, that's true, but that's a very global statement:
when you pass a function into another routine, it's
essentially a callback.

....

> Function expressions could get really out of hand, IMHO, and could easily
> lead to twenty-line "expressions". That's aesthetically incompatible with
> Python source, IMHO.


Anything can get out of hand; there's no way of legislating
good style without restricting the language so much that it
becomes unusable for anything really interesting. Even then
it doesn't work: see COBOL as a really good example of
good intentions gone seriously wrong.

Have you ever programmed in a language that does use
anonymous functions extensively like Smalltalk?

John Roth
>
> --
> Ian Bicking / http://www.velocityreviews.com/forums/(E-Mail Removed) / http://blog.ianbicking.org


 
Reply With Quote
 
 
 
 
Jeff Shannon
Guest
Posts: n/a
 
      12-30-2004
David Bolen wrote:

>>I think this specific use case -- defining callbacks -- should be
>>addressed, rather than proposing a solution to something that isn't
>>necessary. (...)
>>
>>

>
>I'd be interested in this approach too, especially if it made it simpler
>to handle simple manipulation of callback arguments (e.g., since I often
>ignore a successful prior result in a callback in order to just move on
>to the next function in sequence).
>
>


It seems to me that what most people *actually* want, when asking for
lambdas, is a quicker and more convenient way to get closures. (At
least, that's what the vast majority of examples of lambda use seem to
be for.) Perhaps one could get a bit more traction by looking for
improved closure syntax instead of focusing on the anonymous function
aspect.

All of the suggestions for anonymous multiline functions (with embedded
indentation) seem to me to miss what seems to me to be the only
significant benefit of lambda -- its ability to be used in-line without
creating a huge ugly tangle. (I'd argue that lambdas create a *small*
ugly tangle, but apparently that's just me. ) Lambdas do have some
value in defining callbacks, but that value derives almost exclusively
from the fact that they are in-line (rather than a few lines above).
Mimicking function-def indentation inside of another function's arglist
strikes me as an abomination just waiting to happen; in comparison, the
need to type a name twice seems trivial.

As a result, it seems to me that, rather than generalize lambdas into
"full" anonymous functions (with most of the negatives and few of the
positives of lambda), it would be much better to specialize them further
into inline-closure-creators, where they can serve a valuable purpose
without quite as much risk of code pollution.

Jeff Shannon
Technician/Programmer
Credit International

 
Reply With Quote
 
 
 
 
Bengt Richter
Guest
Posts: n/a
 
      12-31-2004
On Thu, 30 Dec 2004 15:15:51 -0800, Jeff Shannon <(E-Mail Removed)> wrote:

>David Bolen wrote:
>
>>>I think this specific use case -- defining callbacks -- should be
>>>addressed, rather than proposing a solution to something that isn't
>>>necessary. (...)
>>>
>>>

>>
>>I'd be interested in this approach too, especially if it made it simpler
>>to handle simple manipulation of callback arguments (e.g., since I often
>>ignore a successful prior result in a callback in order to just move on
>>to the next function in sequence).
>>
>>

>
>It seems to me that what most people *actually* want, when asking for
>lambdas, is a quicker and more convenient way to get closures. (At
>least, that's what the vast majority of examples of lambda use seem to
>be for.) Perhaps one could get a bit more traction by looking for
>improved closure syntax instead of focusing on the anonymous function
>aspect.

Not sure what you mean by closure here. To me it means the necessary
external environment needed to be captured for use by a function definition
getting exported from its definition environment. I.e., it is something
a function uses, and part of the function definition, but it isn't the
function itself. I would compare a closure more to a callable class instance's
self attributes, except that the latter are more flexible.

In fact, for a callback, a constructor call creating a suitable
callable class instance could sometimes work well as a substitute
for a lambda expression, ISTM. (I.e., when it is not important to
show the code in line, and the differences are in initialization parameters
rather than code).

>
>All of the suggestions for anonymous multiline functions (with embedded
>indentation) seem to me to miss what seems to me to be the only
>significant benefit of lambda -- its ability to be used in-line without
>creating a huge ugly tangle. (I'd argue that lambdas create a *small*
>ugly tangle, but apparently that's just me. ) Lambdas do have some
>value in defining callbacks, but that value derives almost exclusively
>from the fact that they are in-line (rather than a few lines above).

They do let you define _code_ inline, which a constructor call doesn't do
(unless you pass a string to compile etc -- not cool).

>Mimicking function-def indentation inside of another function's arglist
>strikes me as an abomination just waiting to happen; in comparison, the
>need to type a name twice seems trivial.

Self-restraint can avoid abominations

>
>As a result, it seems to me that, rather than generalize lambdas into
>"full" anonymous functions (with most of the negatives and few of the
>positives of lambda), it would be much better to specialize them further
>into inline-closure-creators, where they can serve a valuable purpose
>without quite as much risk of code pollution.


There's always the temptation to be enforcer when being persuader
is not the easiest

(BTW, again, by closure, do you really mean deferred-action-thingie?)

Regards,
Bengt Richter
 
Reply With Quote
 
Jeff Shannon
Guest
Posts: n/a
 
      12-31-2004
Bengt Richter wrote:

> On Thu, 30 Dec 2004 15:15:51 -0800, Jeff Shannon <(E-Mail Removed)> wrote:
>
>>Mimicking function-def indentation inside of another function's arglist
>>strikes me as an abomination just waiting to happen; in comparison, the
>>need to type a name twice seems trivial.

>
> Self-restraint can avoid abominations


It can, but given the prevalence of lambda abominations (such as the
many that the Martellibot described among Cookbook submissions), is
there any reason to believe that there would be *more* restraint in
using a less-constrained feature??

>>As a result, it seems to me that, rather than generalize lambdas into
>>"full" anonymous functions (with most of the negatives and few of the
>>positives of lambda), it would be much better to specialize them further
>>into inline-closure-creators, where they can serve a valuable purpose
>>without quite as much risk of code pollution.

>
> (BTW, again, by closure, do you really mean deferred-action-thingie?)


My understanding of "closure" (which may well be wrong, as I've
inferred it entirely from past discussions on this newsgroup) is that
it's a callable with some or all of its parameters already set; e.g.,

def one_and(foo):
def closure(arg):
return foo(1, arg)
return closure

incr = one_and(operator.add)

The function one_and() returns a closure, here bound to incr. It is
essentially a (partially) deferred action thingy, if you want to use
technical terms. I suppose that one could look at it as the
environment in which to call a given function, exported for later use...

My thesis here is that one of the most common (legitimate) uses of
lambda is as an adapter, to create an intermediary that allows a
callable with a given signature to be used in places where a different
signature is expected -- that is, altering the number or order of
arguments passed to a given callable (and possibly also capturing the
current value of some other variable in the process). I feel that
it's more fruitful to focus on this "adapter" quality rather than
focusing on the "anonymous function" quality.

Jeff Shannon
Technician/Programmer
Credit International

 
Reply With Quote
 
Nick Coghlan
Guest
Posts: n/a
 
      12-31-2004
Bengt Richter wrote:
> This is an easy trap to fall into, so if the new lambda-substitute could
> provide a prettier current-closure-variable-value capture than passing a dummy default
> value or nesting another def and passing the value in, to provide a private closure for each,
> that might be something to think about.


I forgot about that little trap. . .

Cheers,
Nick.

--
Nick Coghlan | (E-Mail Removed) | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
 
Reply With Quote
 
Nick Coghlan
Guest
Posts: n/a
 
      12-31-2004
Carl Banks wrote:
> Nick Coghlan wrote:
> In much the same way that programmers often spend a lot of time
> optimizing parts of their program that will yield very minor dividends,
> while they could have spent that time working on other things that will
> pay off a lot, many of the wannabe language designers here are spending
> a lot of time on aspects of the language for which any improvement
> would only pay small dividends.


Whereas I see it as wannabe language designers only being able to tinker at the
edges of Python, because GvR already got the bulk of the language right.
Anonymous functions are the major core construct that doesn't 'fit right', so a
disproportionate amount of time is spent playing with ideas about them.

Cheers,
Nick.

--
Nick Coghlan | (E-Mail Removed) | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      12-31-2004
On Thu, 30 Dec 2004 17:39:06 -0800, Jeff Shannon <(E-Mail Removed)> wrote:

>Bengt Richter wrote:
>
>> On Thu, 30 Dec 2004 15:15:51 -0800, Jeff Shannon <(E-Mail Removed)> wrote:
>>
>>>Mimicking function-def indentation inside of another function's arglist
>>>strikes me as an abomination just waiting to happen; in comparison, the
>>>need to type a name twice seems trivial.

>>
>> Self-restraint can avoid abominations

>
>It can, but given the prevalence of lambda abominations (such as the
>many that the Martellibot described among Cookbook submissions), is
>there any reason to believe that there would be *more* restraint in
>using a less-constrained feature??

Maybe. If people are determined to overcome limitations that needn't exist,
they are likely to invent horrible hacks

>
>>>As a result, it seems to me that, rather than generalize lambdas into
>>>"full" anonymous functions (with most of the negatives and few of the
>>>positives of lambda), it would be much better to specialize them further
>>>into inline-closure-creators, where they can serve a valuable purpose
>>>without quite as much risk of code pollution.

>>
>> (BTW, again, by closure, do you really mean deferred-action-thingie?)

>
>My understanding of "closure" (which may well be wrong, as I've
>inferred it entirely from past discussions on this newsgroup) is that
>it's a callable with some or all of its parameters already set; e.g.,
>
> def one_and(foo):
> def closure(arg):
> return foo(1, arg)
> return closure
>
> incr = one_and(operator.add)
>
>The function one_and() returns a closure, here bound to incr. It is
>essentially a (partially) deferred action thingy, if you want to use
>technical terms. I suppose that one could look at it as the
>environment in which to call a given function, exported for later use...


Quoting from "Essentials of Programming Languages" (Friedman, Wand, Haynes):
(using *xxx yyy etc* for italics)
"""
In order for a procedure to retain the bindings that its free variables had
at the time it was created, it must be a *closed* package, independent of
the environment in which it is used. Such a package is called a closure.
In order to be self-contained, a closure must contain the procedure body,
the list of formal parameters, and the bindings of its free variables.
It is convenient to store the entire creation environment, rather than
just the bindings of the free variables. We sometimes say the procedure
*is closed over* or *closed in* its creation environment. We represent
closures as records.
"""

So it looks like you infer better than I remember, and attachment to
faulty memory has led me to resist better inferences ;-/

Closure is the name for the whole thing, apparently, not just the environment
the procedure body needs, which was the aspect that I (mis)attached the name to.

(Representing closures as records doesn't really belong in that paragraph IMO,
since it is not really part of the definition there, just a choice in that stage
of exposition in the book, using scheme-oriented examples. But I quoted verbatim.).

On the subject CLtL finally (after some stuff beyond my current caffeine level) says,
"""
The distinction between closures and other kinds of functions is somewhat pointless,
actually, since Common Lisp defines no particular representation for closures and
no way to distinguish between closures and non-closure functions. All that matters
is that the rules of lexical scoping be obeyed.
"""
I guess that clinches it

Might be a good python glossary wiki entry.

>
>My thesis here is that one of the most common (legitimate) uses of
>lambda is as an adapter, to create an intermediary that allows a
>callable with a given signature to be used in places where a different
>signature is expected -- that is, altering the number or order of
>arguments passed to a given callable (and possibly also capturing the
>current value of some other variable in the process). I feel that
>it's more fruitful to focus on this "adapter" quality rather than
>focusing on the "anonymous function" quality.
>

I see what you are saying (I think), but I think I'd still like a full
anonymous def, whatever adapter you come up with. And I prefer to be persuaded

Regards,
Bengt Richter
 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      12-31-2004
Jeff Shannon wrote:
> My thesis here is that one of the most common (legitimate) uses of
> lambda is as an adapter, to create an intermediary that allows a
> callable with a given signature to be used in places where a different
> signature is expected -- that is, altering the number or order of
> arguments passed to a given callable (and possibly also capturing the
> current value of some other variable in the process). I feel that it's
> more fruitful to focus on this "adapter" quality rather than focusing on
> the "anonymous function" quality.


Maybe the 'functional' module proposed in PEP 309[1] could provide such
functions?

py> def ignoreargs(func, nargs, *kwd_names):
.... def _(*args, **kwds):
.... args = args[nargs:]
.... kwds = dict((k, kwds[k])
.... for k in kwds if k not in kwd_names)
.... return func(*args, **kwds)
.... return _
....
py> def f(x, y):
.... print x, y
....
py> ignoreargs(f, 2)(1, 2, 3, 4)
3 4
py> ignoreargs(f, 2, 'a', 'b')(1, 2, 3, 4, a=35, b=64)
3 4

Steve

[1] http://python.fyxm.net/peps/pep-0309.html
 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      12-31-2004
(E-Mail Removed) (Bengt Richter) writes:
> print either(A == B, (def "A equals B"), (def "A does not equal B"))
> either(thefile, (def thefile.close()), (def 0))


I'd really rather have some reasonable macro facility, than to resort
to using anonymous functions and deferred evaluation for common things
like that.

 
Reply With Quote
 
Ian Bicking
Guest
Posts: n/a
 
      12-31-2004
John Roth wrote:
>> I appreciate some of the motivation, but merely avoiding giving
>> something a name doesn't seem like a laudible goal.

>
> Actually, it is a laudable goal. It's always easier to understand
> something when it's right in front of your face than if it's
> off somewhere else.


Naming the function doesn't move it far away. It changes the order (you
have to define it before you use it), and it introduces a name.

>> The one motivation I can see for function expressions is
>> callback-oriented programming ...

>
> Well, that's true, but that's a very global statement:
> when you pass a function into another routine, it's
> essentially a callback.


Sure, technically. But I'm thinking of real use cases. One I'm
familiar with is things like map and filter. These are generally better
handled with list expressions (and MUCH more readable as such, IMHO).
Another is control structures, ala Ruby or Smalltalk. IMHO, we have all
the control structures we need -- while, for, if. Most "novel" control
structures in Ruby or Smalltalk are just another take on iterators. The
exception being callbacks, and perhaps some other lazy evaluation
situations (though outside of what I think of as "callbacks", I can't
think of any lazy evaluation situations off the top of my head).

So that's why I think callbacks are important; callbacks in the style of
Twisted Deferred, GUI events, etc.

>> Function expressions could get really out of hand, IMHO, and could
>> easily lead to twenty-line "expressions". That's aesthetically
>> incompatible with Python source, IMHO.

>
> Anything can get out of hand; there's no way of legislating
> good style without restricting the language so much that it
> becomes unusable for anything really interesting. Even then
> it doesn't work: see COBOL as a really good example of
> good intentions gone seriously wrong.


OK, I should go further -- even a two-line expression (i.e., an
expression that contains meaningful vertical whitespace) is
aesthetically incompatible with Python source. Which covers any
anonymous function that is more powerful than lambda. I'm not arguing
that it can be abused, but more that it isn't any good even when it's
not being abused.

> Have you ever programmed in a language that does use
> anonymous functions extensively like Smalltalk?


Yep, I've done a fair amount of Smalltalk and Scheme programming. I
don't expect Python to act like them. I appreciate the motivation, but
I don't think their solution is the right one for Python.

--
Ian Bicking / (E-Mail Removed) / http://blog.ianbicking.org
 
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
Would Anonymous Functions Help in Learning Programming/Python? Cristian Python 66 09-24-2007 03:26 PM
Is this a local anonymous class or a member anonymous class Reporter Java 3 05-12-2007 05:23 AM
help with an anonymous array of anonymous hashes noeldamonmiller@gmail.com Perl Misc 1 02-10-2005 01:08 AM
Re: Securing a future for anonymous functions in Python Jp Calderone Python 8 01-01-2005 12:00 AM
please help me in distinguish redefining functions, overloading functions and overriding functions. Xiangliang Meng C++ 1 06-21-2004 03:11 AM



Advertisments