9 ms·
Ruby-style Blocks in Python
- inklesspen 18y agoNever gonna happen. As GvR said, 'with' already means something completely different. Besides, it's not the Python style to have function calls without the () syntax. I think you could do something interesting with decorators, though.
- russell 18y agoDitto on that. The two uses of with have completely different meanings. The was an interesting discussion of the use of 'there' as a keyword that ferreted out a lot of issues: http://groups.google.com/group/comp.lang.python/browse_thread/thread/b3fdc42e8df48fe6/050c4a9e8e10a7cf#050c4a9e8e10a7cf http://groups.google.com/group/comp.lang.python/browse_threa... Sorry about the url. Tinyurl couldnt digest it. :-) I think 'there' could have good traction, but nobody has made a PEP (see python.org). If a proposal doesnt have a champion, it isn't going anywhere.
- thristian 18y agoI wish that thread had progressed to a more complete conclusion - I've been developing software with Twisted Python recently (a notoriously callback-heavy framework) and that syntax would clean up an awful lot of code in our code-base. In particular, I like that it's not a knee-jerk emulation of a particular syntax-feature of another language, but a general solution that works well for Ruby-style maps, defining property getters and setters, and setting up design-by-contract semantics. I'd happily swap that syntax for some of the other features modern Python has grown, like the "with" statement, or decorators.
- aceofspades19 18y agoI don't understand what the use of anonymous functions besides lambdas would be
- jrockway 18y agoThe use is the same, it's just that the definition can now be more than one line of code. It's pretty arbitrary to say "you can have one-line anonymous functions, but for two lines, the function must have a name". No other language does that, because it makes very little sense. This proposal will make Python behave more like every other programming language that supports anonymous functions.
- aceofspades19 18y agoI just don't understand where you would need an anonymous function with more then one line
- russell 18y agoThe usage case is the same as for a named function of more than one line.
- sah 18y agoYou wouldn't want to have to declare named functions for the bodies of built-in control flow constructs like if/else statements and for loops, right? All of the reasons why also apply to why you might not want to declare named functions in order to pass them to other functions. Read some Ruby code that uses blocks for an example of how passing anonymous functions can become a very clear and natural idiom. In Ruby, you can write your own simple control flow constructs in the form of functions that take a block -- in fact the idiomatic way to iterate through a collection in Ruby is with a function rather than a built-in control flow construct. In languages like Lisp and Smalltalk, where functions can naturally take more than one in-line block, you can write any control flow construct yourself.
- bobbyi 18y agoBut how would this new syntax work when you want to pass two or more anonymous functions to another function? Or when the anonymous function is not the last argument? Having anonymous functions only for the situation where you are passing exactly one of them to another function and it is the last argument is much more arbitrary than the current style of always temporarily binding functions to names.
- lacker 18y agoWhy don't you make a PEP or suggest this to the python mailing list? Might be more effective than blogging for this sort of thing.
- tav 18y ago@lacker I did mail python-dev, but wanted to get general public criticism too...
- relme 18y agoRuby style blocks would have made the with_statement (and a bunch of other stuff) obsolete. In fact most stuff can be implemented from blocks (like decorators and generators) and not the other way around.
- jackdied 18y ago"Ruby does it this way and people like it" isn't an argument that will work. You can accomplish the same things in Python with an extra line of overhead. If you want to get this past python-dev you'll need to explain the benefits, here's a start: 1) Lower cognitive load: Users can understand blocks but the extra naming/reference is one too many things for their brain stack to handle. 2) More descriptive: with blocks the first line says "I'm about to define a function for use with X" instead of the existing way which says "I'm defining a function. Now I'm using that function with X." 3) Show me: take a chunk of an existing project (stdlib is best) and rewrite it with the proposed block syntax. You get to cherry pick the example so if the new version doesn't read much cleaner than the old version maybe the idea isn't so hot. I'm -1 on the idea but if you want to change my mind you have to make an argument that doesn't start with "In Ruby..."
- tav 18y ago@jackdied that's brilliant advice!! thank you -- will bear in mind for the future.
- sah 18y agoA similar feature was already proposed and rejected: http://www.python.org/dev/peps/pep-0340/ http://www.python.org/dev/peps/pep-0340/ Anyway, I'm kind of sad that people seem to want a straight copy of Ruby's blocks. I'd prefer syntax that allowed passing more than one block to a function, like the C-like syntax I proposed here: http://www.hackerdashery.com/2006/10/code-blocks-and-c-like-lambda.html http://www.hackerdashery.com/2006/10/code-blocks-and-c-like-...
- tav 18y ago@sah Nice! Sadly it wouldn't ever fly in the Python context, but I like it nevertheless!
- russell 18y agoActually 340 was withdrawn in favor of the 'with' statement, so blocks haven't been ruled out, as far as I can see. However, it will have to be Pythonic (no braces of block terminators) and well thought out.
- Jebdm 18y agoI was wondering if the one-block limit bothered anyone else. Maybe something like Haskell's where clause: map(foo, pairs) where: pairs = [(0,1), (20, 10), (30, 10)] def foo(pair): a = pair[1] * 2 b = pair[0] * a return (b, a) I'm not terribly familiar with Python's grammar, so it might be difficult to introduce a closing where-clause without ambiguity. In that case, it might be useful to use a do clause as well: do: <statements> where: <statements> Another alternative would be to simply create a real function literal syntax (i.e., lambda that doesn't suck).
- jamongkad 18y agoThe only time I see where Python will adopt a lambda that doesn't suck, is the day when the community itself embraces functional programming. At the rate that is going and from what I've read from the commenters of the article. I don't think that's happening anytime soon.
- tdavis 18y agoIf Python were made to look like Ruby, I'd have to find a new language. I don't want to do that. Luckily, this will never actually happen.
- sah 18y agoObviously no reasonable person wants Python to be identical to Ruby, since those who like Ruby better can go use it. But Python has over its lifetime incorporated new ideas from other languages. Giving substantive reasons why you don't like this particular idea would be a lot more interesting than just registering your distaste for it.
- anamax 18y agoPython's lambdas aren't really functions. They're callable expressions. Once you understand that, a lot of the "issues" go away.
- critic 18y agoI've had a little bit of wine, so you'll have to pardon my honesty: I think Python is a crap language with a great syntax. I'd rather use C++ when performance is very important, or Haskell, when it's not.
- globalrev 18y agoThis has been up so many times. It's not happening, live with it. Python "lambdas" can do most things you need anyway.Normally I don't really find the need for supercomplicated lambdas and you can do if-else in lambda s in Python with the ternary operator, see below: ####### def throwaway_function(emp): if emp.salary > developer.salary: return fireEmployee(emp) else: return extendContract(emp) employees.select(throwaway_function) ###### Python lambda: filter(lambda emp: fireEmployee(emp) if emp.salary > developer.salary else extendContract(emp), employees) Don't know what select does but it sounds like filter. So if that works as intended(is the ruby version both returning value and side-effecting?) or not I'm not sure but you probably could make it.