I was going over some pages from WikiVS, that I quote from:
because lambdas in Python are restricted to expressions and cannot contain statements
I would like to know what would be a good example (or more) where this restriction would be, preferably compared to the Ruby language.
Thank you for your answers, comments and feedback!
Python support multiple inheritance, while Ruby support single inheritance. Python is mainly used for academic, AI, machine learning, and scientific programming, while Ruby is used for web development and functional programming.
There is a perception that Python is faster than Ruby, and this has often led teams to prefer it over Ruby for web development. The Ruby community is painfully aware of this, and Ruby has gotten way faster over the years. Now, in benchmarks, Ruby performs just about as well as Python, if not better.
While there is potential, Ruby must tweak its machine learning and AI libraries to do as well as Python in this field. Ruby won't replace Python anytime soon. TLDR: Python is a long-standing resource for machine learning programming. Thinking about machine learning in the context of Ruby vs.
A lambda function is a small anonymous function. A lambda function can take any number of arguments, but can only have one expression.
I don't think you're really asking about lambdas, but inline functions.
This is genuinely one of Python's seriously annoying limitations: you can't define a function (a real function, not just an expression) inline; you have to give it a name. This is very frustrating, since every other modern scripting language does this and it's often very painful to have to move functions out-of-line. It's also frustrating because I have a feeling Python bytecode can represent this trivially--it's just the language syntax that can't.
Javascript:
responses = {
"resp1": {
"start": function() { ... },
"stop": function() { ... },
},
"resp2": {
"start": function() { ... },
"stop": function() { ... },
},
...
}
responses["resp1"]["start"]();
Lua:
responses = {
resp1 = {
start = function() ... end;
end = function() ... end;
};
...
}
responses.resp1.start();
Ruby:
responses = {
"resp1" => {
"start" => lambda { },
"stop" => lambda { },
},
}
responses["resp1"]["start"].call
Python:
def resp1_start():
pass
def resp1_stop():
pass
responses = {
"resp1": {
"start": resp1_start,
"stop": resp1_stop,
},
}
responses["resp1"]["start"]()
Note that JavaScript and Lua don't have lambdas: they have no reason to exist, since inline functions cover them in a much more natural and general way.
I'd probably rate this as the single most annoying day-to-day Python limitation.
The most commonly encountered situation regarding statements is probably Python 2.X's print
statement.
For example,
say_hi = lambda name: "Hello " + name
works as expected.
But this will not compile:
say_hi = lambda name: print "Hello " + name
because print
is not a proper function in Python 2.
>>> say_hi = lambda name: "Hello " + name
>>> say_hi("Mark")
'Hello Mark'
>>>
>>> say_hi = lambda name: print "Hello " + name
SyntaxError: invalid syntax
The rest of the statements besides print
can be found in the Python documentation online:
simple_stmt ::= expression_stmt | assert_stmt | assignment_stmt | augmented_assignment_stmt | pass_stmt | del_stmt | print_stmt | return_stmt | yield_stmt | raise_stmt | break_stmt | continue_stmt | import_stmt | global_stmt | exec_stmt
You can try the rest of these out in the REPL if you want to see them fail:
>> assert(True)
>>> assert_lambda = lambda: assert(True)
SyntaxError: invalid syntax
>>> pass
>>> pass_lambda = lambda: pass
SyntaxError: invalid syntax
I'm not sure what parallels there are between Python's lambda
restrictions and Ruby's proc
or lambda
. In Ruby, everything is a message, so you don't have keywords (okay, you do have keywords, but you don't have keywords that appear to be functions like Python's print
). Off the top of my head, there's no easily-mistaken Ruby constructs that will fail in a proc
.
An example that has sometimes come up with me is something like this:
def convert(value):
n = expensive_op(value)
return (n, n + 1)
new_list = map(convert, old_list)
Although it is short and sweet enough, you can't convert it to a lambda without having to run expensive_op()
twice (which, as the name suggests, you don't want to), i.e. you would have to do
new_list = map(lambda v: (expensive_op(v), expensive_op(v) + 1), old_list)
because assignment (n = ...
) is a statement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With