473,837 Members | 1,763 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How do I dynamically create functions without lambda?

I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)

Jan 27 '06 #1
25 2587
Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)


It doesn't exist, yet. Python 3000 isn't even in planning stages, yet. There are
just some loose ideas floating around about what will (and won't!) be in it.

You can't write Python 3000 compliant code right now because there is nothing to
comply with.

--
Robert Kern
ro*********@gma il.com

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Jan 27 '06 #2
"Russell" <ru************ @hotmail.com> writes:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated.


Nobody knows yet what Python 3000 will change, so relax.
Jan 27 '06 #3

Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)


If you want to code partial application without lambda I recommend
using the code presented in the accepted PEP 309 that will be
implemented in the functional module in Python 2.5.

http://www.python.org/peps/pep-0309.html

Kay

Jan 27 '06 #4
Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)


Is this what you mean?

# making functions partially bound with foo, dynamically

def make_newfunc(fo o):
def _newfunc(x, f=foo):
print x, foo
return _newfunc

foo = 42

newfunc = make_newfunc(fo o)

newfunc()
Jan 27 '06 #5
Kay Schluehr wrote:
Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)

If you want to code partial application without lambda I recommend
using the code presented in the accepted PEP 309 that will be
implemented in the functional module in Python 2.5.

http://www.python.org/peps/pep-0309.html

Kay

For anyone who got my last post: sorry, typos....
def f(foo, x):
print foo, x

def make_newfunc(fo o):
def _newfunc(x, foo=foo):
f(foo, x)
return _newfunc

foo = 42 # or "dynamicall y generated"

newfunc = make_newfunc(fo o)

newfunc(14) # output will be "42 14"

newfunc2 = make_newfunc(69 )

newfunc(21) # output will be "69 21"
If this doesn't fit your needs, then please elucidate.
Jan 27 '06 #6
Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

That's nonsense! A lambda function *IS* a nested function, and has *NO*
extra capabilities over a nested function. If you can do something with
a lambda, you can also do it with a nested function defined at the same
point. However, a nested function *does* give you several extra
capabilities: (1) it has a name rather than being anonymous like the
lambda, and (2) the body can use statements rather just one expression.

So use a nested function. You'll get the same capabilities, plus a
name, plus more expressive power in the body. You won't lose anything.
and your code will survive any eventual removal of the lambda functionality.
Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)


Jan 27 '06 #7
Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.


I don't understand this argument here. The code above is almost exactly
equivalent to:

def newfunc(x):
return f(foo, x)
someobject.newf unc = newfunc

Observe:
class C(object): .... pass
.... someobject = C()
someobject.newf unc = lambda x: f(foo, x)
import dis
dis.dis(someobj ect.newfunc) 1 0 LOAD_GLOBAL 0 (f)
3 LOAD_GLOBAL 1 (foo)
6 LOAD_FAST 0 (x)
9 CALL_FUNCTION 2
12 RETURN_VALUE def newfunc(x): .... return f(foo, x)
.... someobject.newf unc = newfunc
dis.dis(someobj ect.newfunc)

2 0 LOAD_GLOBAL 0 (f)
3 LOAD_GLOBAL 1 (foo)
6 LOAD_FAST 0 (x)
9 CALL_FUNCTION 2
12 RETURN_VALUE

Note that both the lambda and the function have exactly the same
byte-code. The only real difference is that if you use a def-statement
instead of a lambda, your function will get a real name, "newfunc",
instead of <lambda>.

STeVe
Jan 27 '06 #8
On Fri, 27 Jan 2006 11:41:56 -0800, Kay Schluehr wrote:

Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-)


If you want to code partial application without lambda I recommend
using the code presented in the accepted PEP 309 that will be
implemented in the functional module in Python 2.5.

http://www.python.org/peps/pep-0309.html

Fascinating. A couple of thoughts:

- I really wish that people would make up their minds about what currying
is, and how it differs from partials and closures. If the people who
do know can't agree, how do they expect the rest of us to understand?

- What, if anything, is the difference between a closure and an iterator?
Is an iterator just a closure wrapped up with an API?

- The first sample code seems needlessly confusing to me. It gives:

class partial(object) :
def __init__(*args, **kw):
self = args[0]
self.fn, self.args, self.kw = (args[1], args[2:], kw)
def __call__(self, *args, **kw):
if kw and self.kw:
d = self.kw.copy()
d.update(kw)
else:
d = kw or self.kw
return self.fn(*(self. args + args), **d)

It seems to me to needlessly break the convention that the first argument
is self, to no benefit and considerable reduction in clarity. After some
experimentation , I worked out what it was doing, and realised that it
would work just as well but much less obscurely if the __init__ function
was written as:

def __init__(self, fn, *args, **kw):
self.fn, self.args, self.kw = fn, args, kw
- It seems a shame to me that having created a partial _function_ using
that technique, type(partial(.. .)) returns <class partial>. It would be
nicer if the type made it more obvious that the instance was callable.
Something like <callable class partial> perhaps? Is there any way for a
class to customise the type representation?

--
Steven.

Jan 28 '06 #9
Steven D'Aprano wrote:
On Fri, 27 Jan 2006 11:41:56 -0800, Kay Schluehr wrote:
Russell wrote:
I want my code to be Python 3000 compliant, and hear
that lambda is being eliminated. The problem is that I
want to partially bind an existing function with a value
"foo" that isn't known until run-time:

someobject.newf unc = lambda x: f(foo, x)

The reason a nested function doesn't work for this is
that it is, well, dynamic. I don't know how many times
or with what foo's this will be done.

Now, I am sure there are a half-dozen ways to do this.
I just want the one, new and shiny, Pythonic way. ;-) If you want to code partial application without lambda I recommend
using the code presented in the accepted PEP 309 that will be
implemented in the functional module in Python 2.5.

http://www.python.org/peps/pep-0309.html

Fascinating. A couple of thoughts:

- I really wish that people would make up their minds about what currying
is, and how it differs from partials and closures. If the people who
do know can't agree, how do they expect the rest of us to understand?


Me too, but I disagree with the people who won the argument on the name.
Curry derives its name from the mathematician who formulated the
Curry-Howard isomorphism that says a function of multiple arguments
can be expressed as a function taking a single argument which returns a
function which takes a single argument which... takes a single argument
and returns the result of the original multi-argument function. This
isomorphism means that you need only define functions which take single
arguments. In some functional languages, functions are called adjacent
to their arguments, and a function which looks like it takes multiple
arguments is actually taking a single argument of a tuple.

The Curry recipe I put in the Python Cookbook did the analogous thing
for the Python language, since there is no way for a "Curry" argument
to know when to call the underlying function, rather than simply
accumulate arguments.
- What, if anything, is the difference between a closure and an iterator?
Is an iterator just a closure wrapped up with an API?
A closure is a function and the environment it was created in.
So, for example, the result of calling:

def multiplier(n):
def result(m):
return n * m

multiplier(2) returns a closure (the function called result and its
environment where n is set to 2).

An iterator is a different beasty.
- The first sample code seems needlessly confusing to me. It gives:

class partial(object) :
def __init__(*args, **kw):
self = args[0]
self.fn, self.args, self.kw = (args[1], args[2:], kw)
def __call__(self, *args, **kw):
if kw and self.kw:
d = self.kw.copy()
d.update(kw)
else:
d = kw or self.kw
return self.fn(*(self. args + args), **d)

It seems to me to needlessly break the convention that the first argument
is self. Actually, it does, but only because the second doesn't break it as well.
to no benefit and considerable reduction in clarity. After some
experimentation , I worked out what it was doing, and realised that it
would work just as well but much less obscurely if the __init__ function
was written as:

def __init__(self, fn, *args, **kw):
self.fn, self.args, self.kw = fn, args, kw
It would pretty much work like this, _but_ you could not used named args
of self or fn when using one of these things.

A better definition:
class partial(object) :
def __init__(*args, **kw):
self = args[0]
self.fn, self.args, self.kw = (args[1], args[2:], kw)
def __call__(*args, **kw):
self = args[0]
if kw and self.kw:
d = self.kw.copy()
d.update(kw)
else:
d = kw or self.kw
return self.fn(*(self. args + args[1:]), **d)

Now you can, for example:

def function(self, other, fn):
return fn([self, other])

defaults = partial(functio n, self=object(), fn=repr)
print defaults(other= 3), defaults(self=' self', other=3)

The fancy-schmancy stuff is to keep from hiding some names. I suspect
both args and kw have this problem as well. It might have been
reasonable to call them __self, __function, __args, and __kwargs
and do it your way.
- It seems a shame to me that having created a partial _function_ using
that technique, type(partial(.. .)) returns <class partial>. It would be
nicer if the type made it more obvious that the instance was callable. But callable(defaul ts) returns True. You will eventually learn that
partial is callable, just as you know "type"s are callable. Seeing
that it is class partial, you can (if you are nosey), see what the
arguments already provided are (so you could get a nicer print).
For example, adding a method to partial:

def __repr__(self):
return 'partial(%r, *%r, **%r)' % (self.fn, self.args, self.kw)
Something like <callable class partial> perhaps? Is there any way for a
class to customise the type representation?


--
-Scott David Daniels
sc***********@a cm.org
Jan 28 '06 #10

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

Similar topics

99
5946
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 important changes, so in this thread I would like to focus on that issue alone. I have edited the Proposed Syntax example below to take out the changes unecessary to this discussion. I left in the change of "instance variable" syntax (...
53
3716
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 are constructed on the fly. Now my problem is lazy evaluation. Or at least I think it is. :-)
76
3812
by: Nick Coghlan | last post by:
GvR has commented that he want to get rid of the lambda keyword for Python 3.0. Getting rid of lambda seems like a worthy goal, but I'd prefer to see it dropped in favour of a different syntax, rather than completely losing the ability to have anonymous functions. Anyway, I'm looking for feedback on a def-based syntax that came up in a recent c.l.p discussion:...
37
2169
by: Kay Schluehr | last post by:
Since George Sakkis proposed a new way of doing list comprehensions http://groups-beta.google.com/group/comp.lang.python/browse_frm/thread/ac5023ad18b2835f/d3ff1b81fa70c8a7#d3ff1b81fa70c8a7 letting tuples-like objects (x,y,z=0) acting as functions on other tuples I wonder why this would not be a good starting point of rethinking anonymus functions? In Georges proposition the action is
4
2377
by: Max Derkachev | last post by:
Good day to all. Some time ago I'd been playing with a framework which uses dynamic class creation havily. Say, I could do: class A: pass # I method name is dynamic meth_name = 'foo'
8
4836
by: Falc2199 | last post by:
Hi, Does anyone know how to make this work? var sectionId = 5; repeat_section_sectionId(); function repeat_section_5(){ alert("firing"); }
13
4399
by: invincible | last post by:
hi friends , how can I declare / create function during runtime similiar to lambda in lisp. thanks Mohan
11
3932
by: Josiah Manson | last post by:
In the following program I am trying to learn how to use functional programming aspects of python, but the following program will crash, claiming that the recursion depth is too great. I am attempting to make a list of polynomial functions such that poly(3) = 1, poly(3) = 3, poly(3) = 9, etc. Could someone point me in the right direction? Thanks. def make_polys(n): """Make a list of polynomial functions up to order n. """
5
1955
by: Maxim Veksler | last post by:
Hello, I'm new on this list and in python. It seems python has some interesting concept of "ad hoc" function which I'm trying to understand without much success. Take the following code for example: """ .... return lambda x: x + n
0
9691
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10582
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10638
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9418
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7821
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7009
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5859
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4480
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4054
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.