473,473 Members | 1,874 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

annonymous functions -- how to

Hello:

I would like to define a very large annonymous function, one with
several statements in sequence. I know how to define annonymous
functions, but I don't know how to define a sequence of statements in
their body. Can this be done in Python? If so, how?

Thanks,

Mayer

Jul 19 '05 #1
14 1467
Mayer wrote:
I would like to define a very large annonymous function, one with
several statements in sequence. I know how to define annonymous
functions, but I don't know how to define a sequence of statements in
their body. Can this be done in Python? If so, how?


No, it can't. Why do you prefer your function to be anonymous?

Peter

Jul 19 '05 #2
On Wed, 04 May 2005 23:08:16 +0200, Peter Otten <__*******@web.de> wrote:
Mayer wrote:
I would like to define a very large annonymous function, one with
several statements in sequence. I know how to define annonymous
functions, but I don't know how to define a sequence of statements in
their body. Can this be done in Python? If so, how?


No, it can't. Why do you prefer your function to be anonymous?

Depends on what you mean by "anonymous" ;-)
def foo(): ... print 'statement 1'
... print 'statement 2'
... print 'statement etc'
... foo.__name__ = '' # make really anonymous
fooholder = [foo]
del foo # forget name binding too
dir() ['__builtins__', '__doc__', '__name__', 'fooholder'] fooholder.append(lambda: 'not that anonymous ;-)')
fooholder [<function at 0x02EE8D84>, <function <lambda> at 0x02EE8D14>] [f.__name__ for f in fooholder] ['', '<lambda>'] fooholder[0](), fooholder[1]()

statement 1
statement 2
statement etc
(None, 'not that anonymous ;-)')

Regards,
Bengt Richter
Jul 19 '05 #3
What's wrong with:

def blah():
def _ (a, b, c):
a = a + 2
print "stmt 2"
return a+b/c
return doSomethingWith(_)

It's basically "anonymous", it just uses a name that you don't care
about. AFAIK, it can be immediately clobbered later if need be.
Otherwise, the function shouldn't be anonymous.

Jul 19 '05 #4
Jason Mobarak wrote:
What's wrong with:

def blah():
def _ (a, b, c):
a = a + 2
print "stmt 2"
return a+b/c
return doSomethingWith(_)

It's basically "anonymous", it just uses a name that you don't care
about. AFAIK, it can be immediately clobbered later if need be.
Otherwise, the function shouldn't be anonymous.


Or even better:

def blah():
def doJasonsAlgorithm(a, b, c):
a = a + 2
print "stmt 2"
return a+b/c
return doSomethingWith(doJasonsAlgorithm)

That way you've got reasonably self-documenting code, and don't have to
face an annoyed maintainer saying "what a jerk: he didn't comment this
or even give it a useful name... idiot... grumble grumble."

I doubt there's a valid usecase for a "anonymous" function that has more
than a line or two. Personally, I don't think there's a good usecase
for an anonymous function longer than one line...

-Peter
Jul 19 '05 #5
D H
Peter Hansen wrote:
Jason Mobarak wrote:
What's wrong with:

def blah():
def _ (a, b, c):
a = a + 2
print "stmt 2"
return a+b/c
return doSomethingWith(_)

It's basically "anonymous", it just uses a name that you don't care
about. AFAIK, it can be immediately clobbered later if need be.
Otherwise, the function shouldn't be anonymous.

Or even better:


Python doesn't have anonymous functions.
See http://boo.codehaus.org/Closures
and the closures examples here:
http://svn.boo.codehaus.org/trunk/te...s/integration/
Jul 19 '05 #6
Peter Hansen wrote:
I doubt there's a valid usecase for a "anonymous" function that has more
than a line or two. Personally, I don't think there's a good usecase
for an anonymous function longer than one line...


The case that I keep running into regards event-driven programming. I
need to do a series of operations that are tied together asynchronously
via callback functions, but I still want the actions to read in-order.
With anonymous functions (and I mean the ones that you can use within
expressions, Bengt ;) ), I could write something like the following:

def add_thingy():
with_next_thingy_id(def(thingy_id):
print 'got thingy id:', thingy_id
with_next_doodad_id(def(doodad_id):
pring 'got doodad id:', doodad_id
with_new_thingy_doodad(thingy_id, doodad_id,
def(thingy_doodad):
print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'
)
)
)

In this case, having to name these callback functions is tiring and
awkward, and (IMHO) disrupts the flow of my function:

def add_thingy():
def next_thingy_id_func(thingy_id):
print 'got thingy id:', thingy_id
def next_doodad_id_func(doodad_id):
print 'got doodad id:', doodad_id
def new_thingy_doodad_func(thingy_doodad):
print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'
with_new_thingy_doodad(thingy_id, doodad_id,
new_thingy_doodad_func)
with_next_doodad_id(next_doodad_id_func)
with_next_thingy_id(next_thingy_id_func)

There is no reason why these callbacks would necessarily be one-liners
or ten-liners. I suppose this problem could be solved by defining all
the functions at the top-level (or by using bound methods of an object),
but to me this is harder to maintain and doesn't read as well.

Not life or death, but there's at least one use case that I would at
least consider "valid". Your definition of "valid" may differ, of course. =)

Dave
Jul 19 '05 #7
On Thu, 05 May 2005 07:45:33 -0400, Peter Hansen <pe***@engcorp.com> wrote:
Jason Mobarak wrote:
What's wrong with:

def blah():
def _ (a, b, c):
a = a + 2
print "stmt 2"
return a+b/c
return doSomethingWith(_)

It's basically "anonymous", it just uses a name that you don't care
about. AFAIK, it can be immediately clobbered later if need be.
Otherwise, the function shouldn't be anonymous.


Or even better:

def blah():
def doJasonsAlgorithm(a, b, c):
a = a + 2
print "stmt 2"
return a+b/c
return doSomethingWith(doJasonsAlgorithm)

That way you've got reasonably self-documenting code, and don't have to
face an annoyed maintainer saying "what a jerk: he didn't comment this
or even give it a useful name... idiot... grumble grumble."

I doubt there's a valid usecase for a "anonymous" function that has more
than a line or two. Personally, I don't think there's a good usecase
for an anonymous function longer than one line...

Yes, but only the BDFL can outlaw things on that kind of basis ;-)

My post was just to play with "anonymous" a little, not to motivate
more examples of strange call layering and dynamic execution of defs
that don't change etc. ;-)

BTW, I view a def as a kind of assignment statement with the target restricted
to a local bare name. I.e.,

def foo(): pass # def <restricted assignment target>():pass

So why have this form of assignment? And why restrict it to a bare name, even
if you want to keep the def for mnemonic convention to use as usual?

I.e., why not loosen def to allow e.g.

def MyClass.method(self): pass
or
@staticmethod
def MyClass.square(x): return x*x

or
def fdict['sqr'](x): return x*x

Well, I can see a reason not to do the last that way. It would be much clearer using
an anonymous def, e.g.,

fdict['sqr'] = def(x): return x*x

And then you can say lambda is fine for that, except for the limitation
that the body be just an expression. Then you might ask, why not bend that a little? E.g.,

fdict['sqrt'] = def(x):
if x < 0: raise ValueError, 'x must be non-negative, not %r' %x
return math.sqrt(x)

And then, why not allow an anonymous defs as expressions anywhere expressions can go?
(indentation problems are actually easy to overcome).

Anyway, in general, I'd rather be persuaded than forced ;-)

Regards,
Bengt Richter
Jul 19 '05 #8
Dave Benjamin wrote:
In this case, having to name these callback functions is tiring and
awkward, and (IMHO) disrupts the flow of my function:
so name them all "func" or "next" or something, so you don't have
to think. once the object is bound, the name is irrlevant.
def add_thingy():
def next_thingy_id_func(thingy_id):
print 'got thingy id:', thingy_id
def next_doodad_id_func(doodad_id):
print 'got doodad id:', doodad_id
def new_thingy_doodad_func(thingy_doodad):
print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'
with_new_thingy_doodad(thingy_id, doodad_id,
new_thingy_doodad_func)
with_next_doodad_id(next_doodad_id_func)
with_next_thingy_id(next_thingy_id_func)


there's also:

def add_thingy(self):

yield get_new_thingy_id; thingy_id = self.result

print 'got thingy id:', thingy_id

yield get_new_doodad_id; doodad_id = self.result

print 'got doodad id:', doodad_id

yield get_new_thingy_doodad; thingy_doodad = self.result

print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'

</F>

Jul 19 '05 #9
Fredrik Lundh wrote:

so name them all "func" or "next" or something, so you don't have
to think. once the object is bound, the name is irrlevant.

Or, you could tell him about the reserved word anonymous which can be
used to created unnamed functions of values. A sample definition and
use of the anonymous keyword follows:

def anonymous(text):
return 'modified ' + text

print 'Sample', anonymous('words')

--Scott David Daniels (with his tongue jammed firmly in his cheek)
Sc***********@Acm.Org
Jul 19 '05 #10
Fredrik Lundh wrote:
Dave Benjamin wrote:
In this case, having to name these callback functions is tiring and
awkward, and (IMHO) disrupts the flow of my function:
so name them all "func" or "next" or something, so you don't have
to think. once the object is bound, the name is irrlevant.


Sure, you could do this, but then you'd have multiple functions at
different nesting levels with the same name, which would be confusing.
You could call them "func1", "func2", "func3", and so on, but at this
point it becomes painfully obvious that you really don't care what the
names are; you're only naming them because you have to. As Paul Graham
would say, it's "the human compiler at work".
there's also:

def add_thingy(self):
What object is "self"? Are we defining a method at this point?
yield get_new_thingy_id; thingy_id = self.result


What is "get_new_thingy_id"? A function? To whom are we yielding here?

Dave
Jul 19 '05 #11
Dave Benjamin wrote:
so name them all "func" or "next" or something, so you don't have
to think. once the object is bound, the name is irrlevant.
Sure, you could do this, but then you'd have multiple functions at
different nesting levels with the same name, which would be confusing.


"I don't wanna try that", you mean.

because if you had done so, you would have noticed that "multiple
functions with the same name" doesn't have to be any more confusing
than "multiple print statements" or "multiple if statements" (as long as
you're not using bad names on purpose, of course).
there's also:

def add_thingy(self):


What object is "self"? Are we defining a method at this point?


if you have a problem with methods, you shouldn't use Python.
yield get_new_thingy_id; thingy_id = self.result


What is "get_new_thingy_id"? A function? To whom are we yielding here?


I could have sworn that you mentioned event-driven programming
in your original post. if that's still what you're doing, the answers
are "a token" and "the event source".

</F>

Jul 19 '05 #12
Fredrik Lundh wrote:
Dave Benjamin wrote:
so name them all "func" or "next" or something, so you don't have
to think. once the object is bound, the name is irrlevant.
Sure, you could do this, but then you'd have multiple functions at
different nesting levels with the same name, which would be confusing.


"I don't wanna try that", you mean.


No, I mean, "I have an imagination". But for the sake of argument, here,
I'll try that:

def add_thingy():
def func(thingy_id):
print 'got thingy id:', thingy_id
def funnc(doodad_id):
print 'got doodad id:', doodad_id
def func(thingy_doodad):
print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'
with_new_thingy_doodad(thingy_id, doodad_id, func)
with_next_doodad_id(func)
with_next_thingy_id(func)

This function now has an infinite loop. Can you spot the reason?
because if you had done so, you would have noticed that "multiple
functions with the same name" doesn't have to be any more confusing
than "multiple print statements" or "multiple if statements" (as long as
you're not using bad names on purpose, of course).


I have noticed. It is more confusing. That's the whole point.
there's also:

def add_thingy(self):


What object is "self"? Are we defining a method at this point?


if you have a problem with methods, you shouldn't use Python.


No, I was asking you to clarify, are we rewriting "add_thingy" to be a
method, and if so, what class is it a method of, and what are its
responsibilities? Because it seems like this example now shares data
through an instance, but this data is not required for any other method,
so it will add clutter to the instance namespace. If anything, it seems
that "add_thingy" should be moved into another class at this point, in
which case it follows that every method that needs to do this sort of
asynchronous communication would likewise be moved to a new class. This
is fine, I suppose, but it's a lot more verbose.
yield get_new_thingy_id; thingy_id = self.result


What is "get_new_thingy_id"? A function? To whom are we yielding here?


I could have sworn that you mentioned event-driven programming
in your original post. if that's still what you're doing, the answers
are "a token" and "the event source".


I am just trying to make sense of your example. I am still talking about
event-programming. Here are the events:

1. Program A sends program B a message, saying, "I need a thingy ID".
2. B sends A a message, "Here's a thingy ID: 42".
3. A sends B a message, "I need a doodad ID".
4. B sends A a message, "Here's a doodad ID: 43".
5. A sends B a message, "Make a thingy doodad with IDs 42 and 43".
6. B sends A a message, "Thingy doodad created".
7. A sends B a message, "Now, frooble the thingy doodad".

I don't know what parts of this transcript you would consider "tokens".
And I'm also not sure how generators can provide an alternative solution
to this problem. I am genuinely interested.

Dave
Jul 19 '05 #13
Dave Benjamin wrote:
def add_thingy():
def func(thingy_id):
print 'got thingy id:', thingy_id
def funnc(doodad_id):
print 'got doodad id:', doodad_id
def func(thingy_doodad):
print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'
with_new_thingy_doodad(thingy_id, doodad_id, func)
with_next_doodad_id(func)
with_next_thingy_id(func)

This function now has an infinite loop. Can you spot the reason?


Not offhand, and to be completely honest, the original with the longer
names was equally unreadable. I doubt this is the best way to do
whatever the heck it is that this is supposed to do.

Oh, and while I was typing my eyes fell on "funnc" misspelled above.
Presumably that's your loop...

Spelling "func" as "_" would tend to avoid this as well, unless you have
a keyboard that repeats keys accidentally.

-Peter
Jul 19 '05 #14
Peter Hansen wrote:
Dave Benjamin wrote:
def add_thingy():
def func(thingy_id):
print 'got thingy id:', thingy_id
def funnc(doodad_id):
print 'got doodad id:', doodad_id
def func(thingy_doodad):
print 'thingy doodad created, froobling...'
frooble(thingy_doodad)
print 'froobling complete'
with_new_thingy_doodad(thingy_id, doodad_id, func)
with_next_doodad_id(func)
with_next_thingy_id(func)

This function now has an infinite loop. Can you spot the reason?
Not offhand, and to be completely honest, the original with the longer
names was equally unreadable. I doubt this is the best way to do
whatever the heck it is that this is supposed to do.


I agree. I think both are difficult to read. I find the first version
that I originally posted (using an imaginary anonymous function syntax)
much easier to understand.

I think I've made it pretty clear what this is supposed to do in my
earlier post to Fredrik, delineating each step of the communication
process. If you have a better way to do this, I'd certainly like to see it.
Oh, and while I was typing my eyes fell on "funnc" misspelled above.
Presumably that's your loop...
Yes, precisely. And because of a typo, the wrong callback gets passed,
causing it to use the same callback over and over. With anonymous
functions, there would be nothing to name, and therefore, nothing to
misspell.
Spelling "func" as "_" would tend to avoid this as well, unless you have
a keyboard that repeats keys accidentally.


Hrmmm. Well, it is less to type.

Dave
Jul 19 '05 #15

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

Similar topics

5
by: hokiegal99 | last post by:
A few questions about the following code. How would I "wrap" this in a function, and do I need to? Also, how can I make the code smart enough to realize that when a file has 2 or more bad...
99
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. Perhaps it was buried among too many other less...
1
by: Bob Rock | last post by:
Hello, in the last few days I've made my first few attempts at creating mixed C++ managed-unmanaged assemblies and looking aftwerwards with ILDASM at what is visible in those assemblies from a...
47
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
2
by: Bryan Olson | last post by:
The current Python standard library provides two cryptographic hash functions: MD5 and SHA-1 . The authors of MD5 originally stated: It is conjectured that it is computationally infeasible to...
7
by: Tim ffitch | last post by:
Hi I have created a VB dll file that contains common functions I use across various projects in VB, Access and Excel. Rather than have to code the functions in each I decided to use the dll...
23
by: Timothy Madden | last post by:
Hello all. I program C++ since a lot of time now and I still don't know this simple thing: what's the problem with local functions so they are not part of C++ ? There surely are many people...
3
by: eselk | last post by:
I have a struct defined like this: typedef struct { int file_handle; int x; int y; } BaseFiles; I'd basicly like to "sub-class" this structure so that I can add a
7
by: Immortal Nephi | last post by:
My project grows large when I put too many member functions into one class. The header file and source code file will have approximately 50,000 lines when one class contains thousand member...
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,...
1
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.