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.

7a6310a990212e2b392d95a67855afc2?s=128

Geoffrey Litt

April 18, 2018
Tweet

Transcript

  1. Ruby: A Family History Geoffrey Litt @geoffreylitt Panorama Education

  2. Why do I Ruby?

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

    also more deeply understand Ruby. — matz
  4. !

  5. None
  6. LISP

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

    MatzLisp from now on. ;-) — matz
  8. None
  9. 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)) ;...
  10. None
  11. None
  12. None
  13. Functions (lambda (x) (* x 2))

  14. Functions (map (lambda (x) (* x 2)) (1 2 3))

  15. Functions (map (lambda (x) (* x 2)) (1 2 3))

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

  17. Functions { |x| x * 2 } # => SyntaxError

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

    (lambda () ( ;... )))))) describe "my machine" do it "produces widgets" do #... end end
  20. Thoughtful inconsistency

  21. Syntax ( (let a 1) (let b 2) (+ a

    b))
  22. The project...was neither finalized nor explicitly abandoned. It just receded

    into the indefinite future... — John McCarthy
  23. LISP Syntax ( (let a 1) (let b 2) (+

    a b))
  24. FORTRAN Syntax a = 1 b = 2 result =

    a + b
  25. Pick your battles.

  26. Ruby parsing/unparsing code = "2 + 3 * 4" ast

    = Parser::CurrentRuby.parse(code)
  27. 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))), []]
  28. 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)"
  29. Smalltalk

  30. None
  31. None
  32. None
  33. What is "object-oriented programming"?

  34. What is "object-oriented programming"? What was the original intention of

    object- oriented programming?
  35. I could hardly believe how beautiful and wonderful the idea

    of LISP was...but there were deep flaws in its logical foundations. — Alan Kay
  36. None
  37. None
  38. None
  39. In computer terms, Smalltalk is a recursion on the notion

    of computer itself. — Alan Kay
  40. Message passing 3 + 4 "=> 7

  41. None
  42. None
  43. None
  44. Message passing similarities Smalltalk: 3 perform: '+' asSymbol with: 4

    Ruby: 3.send(:+, 4)
  45. Message passing similarities Smalltalk: 3 isKindOf: Integer Ruby: 3.is_a? Integer

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

  47. Control flow with message sending Smalltalk: array do: [ :element

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

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

    Transcript show: 'true'. ] ifFalse: [ Transcript show: 'false'. ].
  50. Thoughtful inconsistency

  51. None
  52. None
  53. Pick your battles.

  54. Perl

  55. None
  56. "A program is correct if it gets the job done

    before you get fired."
  57. "There's more than one way to do it"

  58. "Easy things should be easy and hard things should be

    possible"
  59. None
  60. Effortless string interpolation $x = 5; $msg = "The value

    is $x now.";
  61. More little details —native regex syntax —%w array syntax —heredocs

    —1_000_000 number syntax
  62. Globals $global_variable = 1

  63. Globals $$

  64. Globals $$ # => 19936 Process ID!

  65. Weak typing print "8" + "1";

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

  67. Weak typing @cities = qw( Berlin Tokyo London Boston );

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

    # Assign the array to a scalar $cities_count = @cities; # => 4
  69. Why do I Ruby?

  70. None
  71. Thanks! Twitter: @geoffreylitt