Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby: A Family History

Ruby: A Family History

Ruby blends some of the best ideas from older programming languages including Smalltalk, Perl, Lisp, and Ada. In this talk, we’ll take a tour of these languages and their influences on Ruby, to better understand Ruby’s core ideas and how we can use it to its full potential.

Geoffrey Litt

December 12, 2017
Tweet

More Decks by Geoffrey Litt

Other Decks in Programming

Transcript

  1. By learning other languages, we can broaden our horizons and

    also more deeply understand Ruby. — matz
  2. Ruby was a Lisp originally, in theory. Let's call it

    MatzLisp from now on. ;-) — Matz
  3. Why we need quote (atom (eq 'foo 'foo)) ;=> t

    (atom '(eq 'foo 'foo)) ;=> ()
  4. 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)) ;...
  5. FORTRAN syntax a = 12.0 b = 15.0 result =

    a + b print *, 'The total is ', result
  6. Functions in Lisp (map (lambda (x) (* x 2)) (1

    2 3)) [1, 2, 3].map( &lambda { |x| x * 2 } )
  7. 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
  8. Functions in Ruby { |x| x * 2 } #

    => SyntaxError def takes_a_block yield 2 end takes_a_block { |x| x * 2 } # => 4
  9. Concise lambdas (map (1 2 3) (lambda (x) (* x

    2))) [1, 2, 3].map { |x| x * 2 }
  10. 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 }
  11. Concise lambdas (describe "my machine" (lambda () ( (it "produces

    widgets" (lambda () ( ;... )))))) describe "my machine" do it "produces widgets" do #... end end
  12. 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 }, )
  13. Macros (defmacro (backwards . body) (cons 'begin (reverse body))) #

    Fake Ruby macro syntax defmacro backwards(code) code.reverse end
  14. Ruby parsing/unparsing code = "2 + 3 * 4" ast

    = Parser::CurrentRuby.parse(code)
  15. 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))), []]
  16. 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)"
  17. I could hardly believe how beautiful and wonderful the idea

    of LISP was...but there were deep flaws in its logical foundations. — Alan Kay
  18. Message passing similarities Integer extend [ doesNotUnderstand: msg [ 'method

    not defined' printNl ] ] class Integer def method_missing(msg) puts 'method not defined' end end
  19. Control flow with message sending Smalltalk: array do: [ :element

    | Transcript show: element ] Ruby: array.each { |element| puts element }
  20. Message passing purity (2 + 2 == 5) ifTrue: [

    Transcript show: 'true'. ] ifFalse: [ Transcript show: 'false'. ].
  21. 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
  22. A brief aside: Other OO languages —Ada: 1977-83 —Eiffel: 1985

    Important features —Multiple inheritance —Generics
  23. "A program is correct if it gets the job done

    before you get fired." -- Larry Wall
  24. Weak typing @cities = qw( Berlin Tokyo London Boston );

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

    # Assign the array to a scalar $cities_count = @cities; # => 4
  26. Perl-inspired oddities END { puts "RB!" } puts "Boston" BEGIN

    { puts "Hello" } # Hello # Boston # RB!