Slide 1

Slide 1 text

Ruby: A Family History

Slide 2

Slide 2 text

Why learn many programming languages?

Slide 3

Slide 3 text

By learning other languages, we can broaden our horizons and also more deeply understand Ruby. — matz

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

LISP

Slide 6

Slide 6 text

Ruby was a Lisp originally, in theory. Let's call it MatzLisp from now on. ;-) — Matz

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Expressions () (foo bar) (1 (2 3) (4 5))

Slide 9

Slide 9 text

7 primitive operators —quote —atom —eq —car —cdr —cons —cond

Slide 10

Slide 10 text

quote (quote foo) ;=> foo 'foo ;=> foo

Slide 11

Slide 11 text

Lisp primitives: atom (atom 'foo) ;=> t (atom '(a b c)) ;=> ()

Slide 12

Slide 12 text

Lisp primitives: eq (eq 'foo 'foo) ;=> t (eq 'foo 'bar) ;=> ()

Slide 13

Slide 13 text

Why we need quote (atom (eq 'foo 'foo)) ;=> t (atom '(eq 'foo 'foo)) ;=> ()

Slide 14

Slide 14 text

Lisp primitives: car (car '(foo bar baz)) ;=> foo

Slide 15

Slide 15 text

Lisp primitives: cdr (cdr '(foo bar baz)) ;=> (bar baz)

Slide 16

Slide 16 text

Lisp primitives: cons (cons 'foo '(bar baz)) ;=> (foo bar baz)

Slide 17

Slide 17 text

Lisp primitives: cond (cond ((eq 'foo 'bar) 'first ((eq 'foo 'foo) 'second)) ;=> second

Slide 18

Slide 18 text

Defining functions (lambda (arg1) (eq arg1 'foo))

Slide 19

Slide 19 text

7 primitive operators + function definition —quote —atom —eq —car —cdr —cons —cond —lambda

Slide 20

Slide 20 text

An interpreter (defun eval (e a) (cond ((atom e) (assoc. e a)) ((atom (car e)) (cond ((eq (car e) 'quote) (cadr e)) ((eq (car e) 'atom) (atom (eval (cadr e) a))) ((eq (car e) 'eq) (eq (eval (cadr e) a) (eval (caddr e) a))) ((eq (car e) 'car) (car (eval (cadr e) a))) ((eq (car e) 'cdr) (cdr (eval (cadr e) a))) ((eq (car e) 'cons) (cons (eval (cadr e) a) (eval (caddr e) a))) ((eq (car e) 'cond) (evcon. (cdr e) a)) ;...

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

FORTRAN syntax a = 12.0 b = 15.0 result = a + b print *, 'The total is ', result

Slide 25

Slide 25 text

The project...was neither finalized nor explicitly abandoned. It just receded into the indefinite future... — John McCarthy

Slide 26

Slide 26 text

Lisp firsts —conditionals —dynamic typing —garbage collection —symbol types

Slide 27

Slide 27 text

Functions in Lisp (lambda (x) (* x 2))

Slide 28

Slide 28 text

Functions in Lisp (map (lambda (x) (* x 2)) (1 2 3))

Slide 29

Slide 29 text

Functions in Lisp (map (lambda (x) (* x 2)) (1 2 3)) [1, 2, 3].map( &lambda { |x| x * 2 } )

Slide 30

Slide 30 text

Functions in Ruby my_fun = lambda { |x| x * 2 } # => Proc def takes_a_lambda(fun) fun.call(2) end takes_a_lambda(my_fun) # => 4

Slide 31

Slide 31 text

Functions in Ruby { |x| x * 2 } # => SyntaxError def takes_a_block yield 2 end takes_a_block { |x| x * 2 } # => 4

Slide 32

Slide 32 text

Concise lambdas (map (1 2 3) (lambda (x) (* x 2))) [1, 2, 3].map { |x| x * 2 }

Slide 33

Slide 33 text

Concise lambdas (remove-if (lambda (n) (< n 4)) (map (lambda (x) (* x 2)) (1 2 3))) [1, 2, 3]. map { |x| x * 2 }. reject{ |n| n < 4 }

Slide 34

Slide 34 text

Concise lambdas (describe "my machine" (lambda () ( (it "produces widgets" (lambda () ( ;... )))))) describe "my machine" do it "produces widgets" do #... end end

Slide 35

Slide 35 text

Multiple function arguments (even-odd-map (lambda (x) (* x 2)) (lambda (x) (* x 3)) (1 2 3 4)) [1, 2, 3, 4].even_odd_map( lambda { |x| x * 2 }, lambda { |x| x * 3 }, )

Slide 36

Slide 36 text

Lisp is consistent Ruby is pragmatic

Slide 37

Slide 37 text

Concise lambdas catching on Ruby 1.9+: lambda { |x| x * 2 } ->(x) { x * 2 }

Slide 38

Slide 38 text

Concise lambdas catching on Javascipt ES6: array.map(function(x) { x * 2 }) array.map(x => x * 2)

Slide 39

Slide 39 text

Concise lambdas catching on Scala: array.map(_ * 2) array.map(2*)

Slide 40

Slide 40 text

Metaprogramming

Slide 41

Slide 41 text

Macros #define square(x) x*x

Slide 42

Slide 42 text

Macros #define square(x) x*x 2/square(10) 2/10*10

Slide 43

Slide 43 text

Macros #define square(x) ( (x) * (x) )

Slide 44

Slide 44 text

Macros (+ 1 2)

Slide 45

Slide 45 text

Macros (defmacro (backwards . body) (cons 'begin (reverse body)))

Slide 46

Slide 46 text

Macros (defmacro (backwards . body) (cons 'begin (reverse body))) # Fake Ruby macro syntax defmacro backwards(code) code.reverse end

Slide 47

Slide 47 text

Ruby parsing/unparsing code = "2 + 3 * 4" ast = Parser::CurrentRuby.parse(code)

Slide 48

Slide 48 text

Ruby parsing/unparsing code = "2 + 3 * 4" ast = Parser::CurrentRuby.parse(code) # => [s(:send, # s(:int, 2), :+, # s(:send, # s(:int, 3), :*, # s(:int, 4))), []]

Slide 49

Slide 49 text

Ruby parsing/unparsing code = "2 + 3 * 4" ast = Parser::CurrentRuby.parse(code) # => [s(:send, # s(:int, 2), :+, # s(:send, # s(:int, 3), :*, # s(:int, 4))), []] 2.1.5 :005 > Unparser.unparse(ast) # => "2 + (3 * 4)"

Slide 50

Slide 50 text

Ruby metaprogramming define_method instance_eval class_eval method_missing

Slide 51

Slide 51 text

Smalltalk

Slide 52

Slide 52 text

What is "object-oriented programming"? inheritance polymorphism UML diagrams class hierarchies factories

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

I could hardly believe how beautiful and wonderful the idea of LISP was...but there were deep flaws in its logical foundations. — Alan Kay

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

In computer terms, Smalltalk is a recursion on the notion of computer itself. — Alan Kay

Slide 59

Slide 59 text

Message passing 3 + 4 "=> 7

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Message passing similarities Smalltalk: 3 perform: '+' asSymbol with: 4 Ruby: 3.send(:+, 4)

Slide 64

Slide 64 text

Message passing similarities Smalltalk: 3 isKindOf: Integer Ruby: 3.is_a? Integer

Slide 65

Slide 65 text

Message passing similarities Smalltalk: Integer isKindOf: Class Ruby: Integer.is_a? Class

Slide 66

Slide 66 text

Message passing similarities Integer extend [ doesNotUnderstand: msg [ 'method not defined' printNl ] ] class Integer def method_missing(msg) puts 'method not defined' end end

Slide 67

Slide 67 text

Control flow with message sending Smalltalk: array do: [ :element | Transcript show: element ] Ruby: array.each { |element| puts element }

Slide 68

Slide 68 text

Message passing purity (2 + 2 == 5) ifTrue: [ Transcript show: 'true'. ] ifFalse: [ Transcript show: 'false'. ].

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

A brief aside: Other OO languages Not many people know this, but before I created Ruby, as a student I was an advocate for statically typed OO langauges. — Matz

Slide 73

Slide 73 text

A brief aside: Other OO languages —Ada: 1977-83 —Eiffel: 1985 Important features —Multiple inheritance —Generics

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

"A program is correct if it gets the job done before you get fired." -- Larry Wall

Slide 76

Slide 76 text

Variable sigils $scalar @array %hash &subroutine *typeglob

Slide 77

Slide 77 text

The easiest string interpolation $x = 5; $msg = "The value is $x now.";

Slide 78

Slide 78 text

Weak typing print "8" + "1";

Slide 79

Slide 79 text

Weak typing print "8" + "1"; # => 9

Slide 80

Slide 80 text

Weak typing @cities = qw( Berlin Tokyo London Boston ); # Assign the array to a scalar $cities_count = @cities;

Slide 81

Slide 81 text

Weak typing @cities = qw( Berlin Tokyo London Boston ); # Assign the array to a scalar $cities_count = @cities; # => 4

Slide 82

Slide 82 text

Little Perl niceties —native regex syntax —%w array syntax —heredocs —1_000_000 number syntax

Slide 83

Slide 83 text

Perl-inspired oddities $global_variable = 1

Slide 84

Slide 84 text

Perl-inspired oddities $$

Slide 85

Slide 85 text

Perl-inspired oddities $$ # => 19936 Process ID!

Slide 86

Slide 86 text

Perl-inspired oddities $/

Slide 87

Slide 87 text

Perl-inspired oddities $/ # => "\n" Input record separator, obviously

Slide 88

Slide 88 text

Perl-inspired oddities /([a-zA-Z]*)/ =~ string match_contents = $1

Slide 89

Slide 89 text

Perl-inspired oddities END { puts "RB!" } puts "Boston" BEGIN { puts "Hello" }

Slide 90

Slide 90 text

Perl-inspired oddities END { puts "RB!" } puts "Boston" BEGIN { puts "Hello" } # Hello # Boston # RB!

Slide 91

Slide 91 text

Perl mantras "There's more than one way to do it"

Slide 92

Slide 92 text

Perl mantras "Easy things should be easy and hard things should be possible"

Slide 93

Slide 93 text

What is Ruby? Two elegant theoretical foundations + a big dose of practicality

Slide 94

Slide 94 text

Thanks! @geoffreylitt