Can't extend function type

2005-10-07 Thread Paul Rubin
Oh well.  I had wanted to be able to define two functions f and g, and
have f*g be the composition of f and g.

 func_type = type(lambda: None)
 class composable_function(func_type):
...   def __mult__(f,g):
... def c(*args, **kw):
...   return f(g(*args, **kw))
... return c
...
Traceback (most recent call last):
  File stdin, line 1, in ?
TypeError: Error when calling the metaclass bases
type 'function' is not an acceptable base type


Seems like a wart to me.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can't extend function type

2005-10-07 Thread Diez B. Roggisch
Paul Rubin wrote:
 Oh well.  I had wanted to be able to define two functions f and g, and
 have f*g be the composition of f and g.
 
  func_type = type(lambda: None)
  class composable_function(func_type):
 ...   def __mult__(f,g):
 ... def c(*args, **kw):
 ...   return f(g(*args, **kw))
 ... return c
 ...
 Traceback (most recent call last):
   File stdin, line 1, in ?
 TypeError: Error when calling the metaclass bases
 type 'function' is not an acceptable base type
 
 
 Seems like a wart to me.

Well - function inheritance is not known so far in python - and in no 
other language I know.

How do you expect to create f and g, even if above construct would work? 
Basdically you want __mult__ being part of f or g when python encounters 
  something like this

f * g

But then how did you plan to declare f?

def f(composable_function)(x):
 pass


obviously won't work.

So the only way to achieve this with current semantics is to make f anf 
g objects with a call methods. In that very moment, you're done - as 
extending from object is no problem :)


class ComposeableFunction(object):

 def __call__(self, *args, **kwargs):
return self.second(self.first(*args, **kwargs))

 def __mul__(self, other):
nc = ComposeableFunction()
nc.first = other
nc.second = self
return nc


class f(ComposeableFunction):
 def __call__(self, x):
return x * 2


class g(ComposeableFunction):
 def __call__(self, x):
return x + 2


f = f()
g = g()

print f(4)
print g(4)
print (f*g)(4)


Diez
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can't extend function type

2005-10-07 Thread Christopher Subich
Diez B. Roggisch wrote:
 Paul Rubin wrote:
 
 Oh well.  I had wanted to be able to define two functions f and g, and
 have f*g be the composition of f and g.

  func_type = type(lambda: None)
  class composable_function(func_type):
 ...   def __mult__(f,g):
 ... def c(*args, **kw):
 ...   return f(g(*args, **kw))
 ... return c
 ...
 Traceback (most recent call last):
   File stdin, line 1, in ?
 TypeError: Error when calling the metaclass bases
 type 'function' is not an acceptable base type
 

 Seems like a wart to me.
 
 So the only way to achieve this with current semantics is to make f anf 
 g objects with a call methods. In that very moment, you're done - as 
 extending from object is no problem :)
 
 
 class ComposeableFunction(object):
 
 def __call__(self, *args, **kwargs):
 return self.second(self.first(*args, **kwargs))

Note, with a little bit of massaging, you can turn ComposableFunction 
into a decorator, for more natural function definition:

(Untested, I'm not on a system with Py2.4 at the moment):
class Composable(object):
 def __init__(self,f):
 self.callable = f
 def __call__(self,*args, **kwargs):
 return self.callable(*args, **kwargs)
 def __mul__(self,other):
 return Composable(lambda (*a, **kwa): self.callable(other(*a, 
**kwa)))

Usage:

@Composable
def f(x):
 return x**2

@Composable
def g(x):
 return x+1

# And we shouldn't even need a @Composable on the last in the sequence
def h(x):
 return x/2.0

 f(1)
1
 (f*g)(1)
4
 (f*g*h)(2)
4

This might not combine neatly with methods, however; the bound/unbound 
method magic is still mostly voodoo to me.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can't extend function type

2005-10-07 Thread Paul Rubin
Diez B. Roggisch [EMAIL PROTECTED] writes:
 Well - function inheritance is not known so far in python - and in no
 other language I know.

Yeah, I didn't really expect it to work, but it seems like a logical
consequence of type/class unification.

 Basically you want __mult__ being part of f or g when python
 encounters something like this
 
 f * g
 
 But then how did you plan to declare f?

Come to think of it, that's also a wart.  I'd been thinking of
using a decorator, as Christopher Subich suggested,

@composable
def f(x): ...

but it's not how the decorator could actually work (other than through
gross CPython-specific hacks).

 So the only way to achieve this with current semantics is to make f
 anf g objects with a call methods. In that very moment, you're done -
 as extending from object is no problem :)

Yeah, I thought of that, but felt it wasn't in the proper spirit :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can't extend function type

2005-10-07 Thread Michele Simionato
If you google a bit on the newsgroup, you should find a message
from me asking about the ability to subclass FunctionType, and
a reply from Tim Peters saying that the only reason why this
was not done is lack of developer time and the fact that this was
not considered an important priority.


 Michele Simionato

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can't extend function type

2005-10-07 Thread Paul Rubin
Michele Simionato [EMAIL PROTECTED] writes:
 If you google a bit on the newsgroup, you should find a message
 from me asking about the ability to subclass FunctionType, and
 a reply from Tim Peters saying that the only reason why this
 was not done is lack of developer time and the fact that this was
 not considered an important priority.

Yeah, I just thought of it as a perverse but sort of cute way to
implement composition and similar operations on functions.  It could
be handy though, and simple to implement, if functions supported the
'*' operator for composition.  The example with a callable class is
a possible workaround, but ugly.
-- 
http://mail.python.org/mailman/listinfo/python-list