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