Greg McIntyre wrote: > Thanks to all of you who answered and cleared up some of my perceptions > about Python. As a result I've put together some slides introducing Ruby > to Python programmers (hopefully without any misinformation!). > > This is a 30 minute lecture on Ruby, aimed at 3rd year university > students who have just learnt Python. Feedback welcome. > > http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ On Philosophy: ============== Is this really how a Ruby programmer would characterize POLS? To be honest, the way you state it, I wouldn't be interested in _either_ Python or Ruby. A language that tries to cater to everyone's tastes is doomed to failure. Sounds like the popular image of Ada! http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img4.html I would say POLS is: "Ruby attempts to conform to programmer's intuitions." But then any decent language, operating system or user interface strives for POLS. I admit that some fail badly. ;) As far as "Only One Way To Do It." I'm sure that the way you describe Python is not how a Python programmer would! ;) Let me try: "Only one way to do it." "Also known in computer science literature as "orthogonality", Python attempts to reduce to a minimum the variant ways of "spelling" a common construct. This improves the regularity of code, reduces the size of the Python language and makes reading other people's code easier." But I don't expect you to put in such a Python-positive spin! If Python is "rigid" what does that say about Java, COBOL, Pascal, C and other similar languages that are much more strict than Python? Re: type and class. Consistency of method use is _unrelated_ to the issue of type and class. It has always been the case that Python types could have methods. The array type has always had methods. If you want to knock Python for being inconsistent about functions versus methods it would be more straightforward just to do so. ==== On Private Variables http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img6.html First, I don't think your Python code will behave as you say it does. It won't throw an exception (though there are ways to code the class that would make it do so). Second, add a second underscore and see what happens. Third, Python doesn't the title is misleading. OOM is something that happens completely separate from coding in a particular programming language. It's widely understood to be UML-style stuff. Really you're talking about _enforced encapsulation_ (as opposed to voluntary encapsulation). Fourth, I think that in both Python and Ruby there are hacks that will allow you to get at "private" variables. In Ruby, it is instance_eval, right? ==== On Syntax http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img7.html Ruby also has more ways of spelling things, e.g. if statements that follow their tests and magical Perl $_-style variables. http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img8.html ==== On Blocks You say that Python has generators which are equivalent to Ruby's blocks. I think that blocks and generators are mostly unrelated. IMO, blocks are just unnamed closures with a nice syntax. I can't think of any situation where you can accomplish something with blocks that you can't with closures. (although block syntax is arguably simpler) But generators do allow you to do something that is very difficult without them. Consider this code: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66316 What makes this interesting is that the generator "g" is an object that can be passed around from place to place through your program. A function that takes a closure/block doesn't have that ability. There is probably a way to accomplish this in Ruby (doesn't Ruby have full continuations?) but I would say that's a separate feature than just blocks/closure/functions. The nice thing about blocks (compared to straightforward higher order functions) is that they have a nice syntax. But I think that they are more limited in that you can pass many higher order functions to a procedure but you can only pass one block (unless you wrap it in a function!). I think. e.g. def upload(handle_data_func, output_func, print_error_func, block_limit) for blocknum in 0, block_limit try: block = read_block_from_network() output_func("block received " + blocknum) handle_data_func(block) except: print_error_func("something screwed up") upload(handle_data_func = lambda data: blocks.append(data), output_func = lambda data: logger.write_msg(data), print_error_func = lambda: logger.write_err(data), block_limit = 5) Paul Prescod