Reputation: 5977
I'd like to write kind of CPS code higher functions. They should take a function code, encapsulate it in the object and add means for combining this objects.
Something like this:
myFunction=MyFunction(
a = b+c
print(c)
return a)
But there is only one pythonic expression for anonymous functions - lambda statement. It suits not too well.
Python is a powerful language, it has different expressions: decorators, eval, etc... Is there a good way to write anonymous functions like in the mentioned example?
Other way is to extend lambda expressions with special functions like monadic bind and return, and other higher-order functions for writing complex expressions single-lined.
The main purpose is to create custom throw control expressions.
class TimeoutExpression:
def __init__(self,name,function,timeout):
...
def eval(self):
""" eval functions, print result and error message
if functions failed to calculate in time """
...
def andThen(self,otherExpression):
""" create complex sequential expression"
...
def __call__(self):
...
And it is used in the follow way:
TimeoutExpression( time consuming calculation ).andThen(
file object access).andThen(
other timer consuming calcualtion )
What is the best python idiomatic way for creating custom control flow constructions?
I've read the discussion: How to make an anonymous function in Python without Christening it? There were mentioned several decisions with same approach: generating function from triple quoted strings. It is seemed quite cumbersome while absolutely correctly behave. Is it the best approach engineered for now?
Update:
I was told there is no problem, python allows you use def in any context. I've assumed that my python experience tricks me and tried to use def in any scope as suggested. I've got an error. How exactly should I place def in any context?
def compose(f):
return lambda k: lambda x: f(k(x))
test = compose( def sqr(x) :
print ("sqr "+str(x))
return x*x
return sqr) ( def x2(x):
print("x2 "+str(x))
return x*2
return x2 )
The error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "anonFunction.py", line 4
test = compose( def sqr(x) :
^
SyntaxError: invalid syntax
Upvotes: 1
Views: 519
Reputation: 31
I have a hack -- and that's truly the only proper term for it -- using nested functions that gives the sort of functionality that a multi-line lambda might give. You can check out my GitHub repository here.
Basically it allows you to do things like:
fibonacci = f('result = t(a-1)+t(a-2) if a>2 else 1; return result')
fibonacci(6) #Output: 8
Or more to the point of anonymous functions:
cube = f('result = a**3; return result')(4)
print(cube) #Output: 64
There are obviously limitations with this hack; for example, I still have not figured out a way to implement more complicated indented constructs like if
or while
, but again, this is a really cheap hack.
Upvotes: 1
Reputation: 63737
There is no advantage in using lambda's w.r.t Python. Lambda's and Anonymous functions are generally used for simple functions, and if you need a more complex multi-line functions, its more readable to write a named function.
As Functions are first class objects, you can simply define it, assign it to a variable and use it and pass it around. Unless otherwise you need a throwaway simple function for which you may opt for lambda's, named function is favorable. Also nevertheless using lambda in never quite Pythonic.
Coming back to your example,
myFunction=MyFunction(
a = b+c
print(c)
return a)
In Python, writing it similarly as
def MyFunction:
a =b + c
print c
return a
and then passing it around your code as MyFunction
is quite Pythonic. I have seen codes in Javascripts where Callbacks are written as anonymous. But each languages have them own philosophy and Python's philosophy is readability.
---Readability counts.
Upvotes: 3
Reputation: 76715
In Python, using the lambda
keyword, you can only make a function object that evaluates a single expression and returns the result. To make a function using statements or with multiple lines, you must use the def
keyword, which requires a name.
The reasons for the restrictions on lambda
are mostly based on the fact that Python treats end-of-line as a significant thing:
No Multiline Lambda in Python: Why not?
However, the name is not important. You can make a convention that every one of your "anonymous" functions will all be defined with the name anon
or something. If you really care, you can erase all trace of the name:
y = 5
def anon(x):
return x + y # note "closure" over the current value of y
myFunction = anon
# if you really care, you can erase all evidence of name "anon"
anon.__name__ = '' # wipe the record of original name "anon"
del(anon) # unbind the name "anon"
So, for functional programming, Python can create first-class function objects, pass them around, etc. The one thing Python cannot do is create a complex function object that never has a name, but there is really no reason why that should matter.
Upvotes: 1