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

Ruby: A Family History (no notes)

Ruby: A Family History (no notes)

A talk I gave at Railsconf 2018.

Rails is made possible by Ruby’s unique combination of deep dynamism and pragmatic elegance. In turn, Ruby inherited many of its core ideas from older languages including Lisp, Smalltalk, and Perl.

In this talk, we’ll take a tour of these languages and their myriad influences on Ruby, to better understand the foundations of our tools, improve our ability to use them to their full potential, and imagine how they might be further improved.

Geoffrey Litt

April 18, 2018
Tweet

More Decks by Geoffrey Litt

Other Decks in Technology

Transcript

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

    also more deeply understand Ruby. — matz
  2. !

  3. Ruby was a Lisp originally, in theory. Let's call it

    MatzLisp from now on. ;-) — matz
  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. Functions (map (lambda (x) (* x 2)) (1 2 3))

    [1, 2, 3].map( &lambda { |x| x * 2 } )
  6. Functions { |x| x * 2 } # => SyntaxError

    def takes_a_block yield 2 end takes_a_block { |x| x * 2 } # => 4
  7. Functions (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 }
  8. Functions (describe "my machine" (lambda () ( (it "produces widgets"

    (lambda () ( ;... )))))) describe "my machine" do it "produces widgets" do #... end end
  9. Ruby parsing/unparsing code = "2 + 3 * 4" ast

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

    of LISP was...but there were deep flaws in its logical foundations. — Alan Kay
  13. Control flow with message sending Smalltalk: array do: [ :element

    | Transcript show: element ] Ruby: array.each { |element| puts element }
  14. Metaprogramming Integer extend [ doesNotUnderstand: msg [ 'method not defined'

    printNl ] ] class Integer def method_missing(msg) puts 'method not defined' end end
  15. Message passing purity (2 + 2 == 5) ifTrue: [

    Transcript show: 'true'. ] ifFalse: [ Transcript show: 'false'. ].
  16. Weak typing @cities = qw( Berlin Tokyo London Boston );

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

    # Assign the array to a scalar $cities_count = @cities; # => 4