Transcript
Page 1: What can Ruby learn from Python (and vice versa)?

What Ruby can learn from Python

(and vice versa)Reuven M. Lerner, PhD • [email protected]

Rails Israel 2014 November 4th, 2014

Page 2: What can Ruby learn from Python (and vice versa)?

Who am I?• Programmer, consultant, developer, trainer

• Long-time Ruby, Python user

• Linux Journal columnist

• Author, Practice Makes Python!

• PhD in Learning Sciences from Northwestern

• Read (lots) more at http://lerner.co.il/

2

Page 3: What can Ruby learn from Python (and vice versa)?

Python, Ruby, and me

Page 4: What can Ruby learn from Python (and vice versa)?

Sapir-Whorf Hypothesis

"Cognitive processes, such as thought and experience, may be influenced by the categories and patterns of the language a person speaks." — Wikipedia

4

Page 5: What can Ruby learn from Python (and vice versa)?

Or: You are what you speak!

5

Page 6: What can Ruby learn from Python (and vice versa)?

Learning a language helps you not only communicate,

but also to think in new ways

6

Page 7: What can Ruby learn from Python (and vice versa)?

7

Page 8: What can Ruby learn from Python (and vice versa)?

你有叉⼦子吗?

Nǐ yǒu chāzi ma? Do you have a fork?

8

Page 9: What can Ruby learn from Python (and vice versa)?

Possible answers

• "Yes"

• "No"

• "What's a fork?"

• "Your accent is so bad, I have no idea what you're saying"

9

Page 10: What can Ruby learn from Python (and vice versa)?

The actual answer?

• None of the above!

• Chinese doesn't have words for "yes" and "no."

10

Page 11: What can Ruby learn from Python (and vice versa)?

你有叉⼦子吗? Nǐ yǒu chāzi ma?

Do you have a fork?

11

Answer: 有 (yǒu) "Have"

Page 12: What can Ruby learn from Python (and vice versa)?

Can you think of another language that

works this way?

12

Page 13: What can Ruby learn from Python (and vice versa)?

בראשית כ״ט, ו׳

ויאמר, ״השלום לו?״ ויאמרו ״שלום.״

13

Genesis 29:6

And he said, "Is he well?" And they said, "Well!" (i.e., "Yes!")

Page 14: What can Ruby learn from Python (and vice versa)?

And also…

CREATE TABLE Foo (id SERIAL, stuff TEXT);

CREATE TABLE

INSERT INTO Foo (stuff) VALUES ('abc');

INSERT 0 1

14

Page 15: What can Ruby learn from Python (and vice versa)?

Comparing languages

• Appreciate each one more

• Reflect on the relative trade-offs

15

Page 16: What can Ruby learn from Python (and vice versa)?

Ruby and Python both…• … dynamically and strongly typed

• … are JIT byte-compiled

• … are cross-platform

• … are widely used for a variety of tasks

• … popular among Web developers

• … have multiple implementations

• … have an object system based (in part) on Smalltalk

16

Page 17: What can Ruby learn from Python (and vice versa)?

And yet

• Python and Ruby feel very different

• What can we learn from these differences?

• What can we learn from the Python world? (And what can they learn from us?)

17

Page 18: What can Ruby learn from Python (and vice versa)?

General attitude• Ruby wants to give you freedom, to allow you to be

creative and flexible, as in a natural language

• TMTOWTDI, POLS

• Python wants to restrict you, for your own good

• "There should be one — and preferably only one — obvious way to do it."

18

Page 19: What can Ruby learn from Python (and vice versa)?

The result?• Python is

• easier to learn

• easier to debug and maintain

• Ruby

• offers you richer options

• greater expressiveness

19

Page 20: What can Ruby learn from Python (and vice versa)?

Development process

• Python Enhancement Proposals (PEPs)

• Ruby could use such a system

• Heck, Rails could use such a system

20

Page 21: What can Ruby learn from Python (and vice versa)?

Backward compatibility• Historically, Python upgrades were conservative

• But not 2.x -> 3.x

• Ruby was less conservative, breaking things (especially going from 1.8 to 1.9/2.0)

• Maybe Python emphasis on compatibility and inclusiveness hurt the 3.x upgrade

21

Page 22: What can Ruby learn from Python (and vice versa)?

What is truth?

• Ruby: Everything is true, except for false and nil

• Python: Everything is true, except for None, False, 0, and empty data (e.g., '' or [])

• So: 0 is false in Python, but true in Ruby!

• But we all like #blank? and #present? in Rails…

22

Page 23: What can Ruby learn from Python (and vice versa)?

Everything is an object…

• In both Ruby and Python, everything is an object!

• But in Python, some objects are more equal than others…

• So you can't do this in Python:

5.times { puts "Hello" }

23

Page 24: What can Ruby learn from Python (and vice versa)?

Blocks

• Ruby people love blocks!

• Python doesn't have them.

• They create functions, and pass those

• Or they use lambdas (or not)

24

Page 25: What can Ruby learn from Python (and vice versa)?

Namespaces• Python has a single namespace for functions and

variables. So x can be an int, a str, or a function

• Ruby has two separate namespaces — one for methods, and one for data

• Ruby's approach can lead to surprises!

x = 10 # set a local variable

self.x = 10 # invoke an attr_ method

25

Page 26: What can Ruby learn from Python (and vice versa)?

Reserved words

• Python barely has any:

True, False = False, True

• Ruby lets us open built-in classes, but not this!

26

Page 27: What can Ruby learn from Python (and vice versa)?

Modern Python

• Fine, modern Python outlaws this. But it allows:

>>> str = [1,2,3]

>>> type(str)

<class 'list'>

27

Page 28: What can Ruby learn from Python (and vice versa)?

Scoping

• Python has clear rules for scoping: LEGB (local, enclosing function, global builtin)

• Ruby's scoping rules feel natural, but the rules aren't easy to learn or remember.

28

Page 29: What can Ruby learn from Python (and vice versa)?

Indentation• Newcomers to Python hate the indentation rules

• But I actually like them!

• Easy to read

• No annoying "end - end - end - end" all over

• Easy to see where code begins and ends

• That said, Ruby's syntax would never work with Python's indentation rules

29

Page 30: What can Ruby learn from Python (and vice versa)?

Parentheses• Needed in Python to invoke methods and create classes

• Makes it easier to pass functions as parameters

• Not needed in Ruby to invoke methods

• Makes DSLs cleaner, easier to write and read

• You cannot pass a method just by name; use method(:foo)

• DSLs in non-Ruby languages look far uglier, and look like the original language, not a new one

30

Page 31: What can Ruby learn from Python (and vice versa)?

Explicit return

• In Ruby, the value of the final line evaluated is the value of the method. We often don't say "return"

• In Python, if you don't say "return", then your method returns None

• I don't see an advantage to Python's behavior

31

Page 32: What can Ruby learn from Python (and vice versa)?

Attributes vs. methods• In Ruby, object state is private, and access is all done

through methods.

• Want to access data? Write a getter or setter

• Or use attr_*, and Ruby will write them for you

• In Python, object state is public

• Getters and setters are discouraged

• Want the logic of a getter or setter? Use a "property," which invokes a method when you access an attribute

32

Page 33: What can Ruby learn from Python (and vice versa)?

In other words• Ruby tries to make data look like methods

• Method calls are the fundamental form of inter-object communication

• Python tries to make methods look like data

• Attributes are open, and thus there is less need for methods to access data

• Besides, attributes exist in a single namespace

33

Page 34: What can Ruby learn from Python (and vice versa)?

Object model• In Ruby, the object model emphasizes methods

and inheritance of those methods

• What are your methods, and what are your superclass's methods?

• In Python, the object model emphasizes attributes and "inheritance" of those attributes

• What attributes are defined on an object, and what are define on its class?

34

Page 35: What can Ruby learn from Python (and vice versa)?

What is hard to learn?

• Each object model leads to something that is hard for people to understand

• In Ruby, you have to understand singleton classes (aka eigenclasses)

• In Python, you have to understand how attributes work, including attribute scoping rules

35

Page 36: What can Ruby learn from Python (and vice versa)?

Multiple inheritance vs. include/extend

• Python: Multiple inheritance is OK, if you do it right

• Ruby: You won't get it right. Use modules!.

• The inheritance tree is very easy to figure out

• Modules allow for mixins, the only good reason for multiple inheritance

36

Page 37: What can Ruby learn from Python (and vice versa)?

for loops vs. Enumerable

• In Ruby, we want to iterate over everything

• Implement #each in your class

• include Enumerable

• Now you get map, select, and many other methods

37

Page 38: What can Ruby learn from Python (and vice versa)?

for loops vs. Enumerable

• In Python, we also want to iterate over everything

• We do that with "for" loops and other global constructs (e.g., comprehensions)

• Our object plug into these constructs by implementing the iteration protocol

38

Page 39: What can Ruby learn from Python (and vice versa)?

list.sort's return type

• Python's, list.sort returns None, not the list

• In Ruby, we almost always return an object from a method, so that we can chain the method calls.

39

Page 40: What can Ruby learn from Python (and vice versa)?

Comprehensions• Python has comprehensions:

[str(x) for x in range(5)]

[x*x for x in range(5)]

[line.split(":")[0]

for line in open('/etc/passwd')]

40

Page 41: What can Ruby learn from Python (and vice versa)?

Sets and dicts• Set comprehensions

{word.strip()

for word in open('/usr/share/dict/words')}

• Dictionary comprehensions

{line.split(":")[0] : line.split(":")[2]

for line in open('/etc/passwd')

if line.startswith("#")}

41

Page 42: What can Ruby learn from Python (and vice versa)?

Comprehensible?

42

No.

Page 43: What can Ruby learn from Python (and vice versa)?

Ruby is more consistent• In Ruby, we use the block syntax everywhere

(0..4).map {|n| n.to_s}

(0..4).map {|n| n * n}

File.open('/etc/passwd').readlines.

map {|line| line.split(":")[0]}

43

Page 44: What can Ruby learn from Python (and vice versa)?

The Ruby versionHash[File.open('/etc/passwd').

readlines.

select {|line| line[0] != '#'}.

map {|line| line.split(":")}.

map {|row| [row[0], row[2]]} ]

• Longer, but more consistent

44

Page 45: What can Ruby learn from Python (and vice versa)?

Easy metaprogramming

• Metaprogramming is fun and easy in Ruby

• Python permits it, but discourages such things

• Most of the time, use decorators

45

Page 46: What can Ruby learn from Python (and vice versa)?

46

Oscar

Felix(Python)

(Ruby)

Page 47: What can Ruby learn from Python (and vice versa)?

你们有问题吗? יש לכם שאלות?

(Do you have any questions?)

[email protected] @reuvenmlerner http://lerner.co.il/

47


Top Related