Developing                                 a                             Language                            @evanphx     ...
#11Tuesday, February 8, 2011
LA.RB                               Los Angeles Ruby Brigade                            Tuesday Night. Every Week.        ...
DINNERTuesday, February 8, 2011
DINNERTuesday, February 8, 2011
DINNERTuesday, February 8, 2011
DINNERTuesday, February 8, 2011
Which came first?Tuesday, February 8, 2011
Language > IdeaTuesday, February 8, 2011
Language < IdeaTuesday, February 8, 2011
Language = IdeaTuesday, February 8, 2011
The programmer, like the poet,                            works only slightly removed                            from pure...
If ideas are a                       manifestation of                           languageTuesday, February 8, 2011
Can better                  language lead to                    better ideas?Tuesday, February 8, 2011
better                              !=                            newerTuesday, February 8, 2011
Tuesday, February 8, 2011
To craft a language from                            scratch is to take 95% from the                            past and ca...
Peek backTuesday, February 8, 2011
Tuesday, February 8, 2011
RLKTuesday, February 8, 2011
RLK                            Implement with easeTuesday, February 8, 2011
RLK                            KPegTuesday, February 8, 2011
RLK                                  KPeg                            A new parsing libraryTuesday, February 8, 2011
Prattle < RLKTuesday, February 8, 2011
URLs             In the Building                      git://192.168.2.88/prattle             In the Cloud            githu...
Tuesday, February 8, 2011
Dude.                            Really?Tuesday, February 8, 2011
PrattleTuesday, February 8, 2011
self                            true                            false                             nilTuesday, February 8, ...
+module Prattle                            + module AST                            +    class Self < AST::Node            ...
+module Prattle                            + module AST                            +    class Self < AST::Node            ...
Self                    def self.grammar(g)                      g.self = g.str("self") {                                 ...
True                    def self.grammar(g)                      g.true = g.str("true") {                                 ...
False                    def self.grammar(g)                      g.false = g.str("false") {                              ...
Nil                    def self.grammar(g)                      g.nil = g.str("nil") {                                Nil....
Number                              0                             10                             42                       ...
Number              def self.grammar(g)               g.number =                  g.reg(/0|([1-9][0-9]*)/) {              ...
Root                    def self.grammar(g)                     g.root = g.any(:true, :false,                             ...
root =   self                                 |   true                                 |   false                          ...
REPLTuesday, February 8, 2011
REPL                            Instant GratificationTuesday, February 8, 2011
$ rbx bin/repl.rb                   > 42                   #<Prattle::AST::Number:0x9c                     @value=42>     ...
Self                            def bytecode(g)                              g.push :self                            end  ...
True                            def bytecode(g)                              g.push :true                            end  ...
False                            def bytecode(g)                              g.push :false                            end...
Nil                            def bytecode(g)                              g.push :nil                            end    ...
Number                            def bytecode(g)                              g.push @value                            en...
String             def self.grammar(g)               not_quote = g.many(                 g.any(escapes, /[^]/)) {         ...
String                  char =    escapes                       |    [^’]             not_quote =    char*                ...
$ rbx bin/repl.rb                   > 42                   => 42                   > true                   => 42         ...
BORINGTuesday, February 8, 2011
Unary Send                            3 classTuesday, February 8, 2011
Unary Send                            3.class                                      RubyTuesday, February 8, 2011
Unary Send                            3 classTuesday, February 8, 2011
Unary Send                            3 classTuesday, February 8, 2011
Unary Send            g.seq(:number, “ “,                   :method_name) { |v,_,n|                      UnarySend.new(v,n...
Unary Send                  us = number “ “ method_nameTuesday, February 8, 2011
Unary Send            true classTuesday, February 8, 2011
Unary Send            g.seq(:atom, “ “,                   :method_name) { |v,_,n|                      UnarySend.new(v,n) ...
atom =   true                                 |   false                                 |   self                          ...
Unary Send                  us = atom “ “ method_nameTuesday, February 8, 2011
Unary Send                      3 class classTuesday, February 8, 2011
Unary Send            g.any(              g.seq(:unary_send, “ “,                     :method_name) { |v,_,n|             ...
Unary Send                  us =   us “ “ method_name                     | atom “ “ method_nameTuesday, February 8, 2011
Unary Send        def bytecode(g)          @receiver.bytecode(g)          g.send @method_name.to_sym, 0        endTuesday,...
$ rbx bin/repl.rb                   > 3 class                   => Fixnum                   > 3 class class               ...
Keyword Send‘hello’ index: ‘o’Tuesday, February 8, 2011
Keyword Send“hello”.index(“o”)                            RubyTuesday, February 8, 2011
Keyword Sendg.keyword_send =  g.seq(:atom, ‘ ‘,        :method_name, “:”,        “ “, :atom)Tuesday, February 8, 2011
Keyword Send   ks = atom “ “ method_name          “: ” :atomTuesday, February 8, 2011
Keyword Send‘hello’ at: 0        put: ‘j’Tuesday, February 8, 2011
Keyword Send“hello”[0] = “j”                            RubyTuesday, February 8, 2011
Keyword Sendg.pairs =  g.seq(:method_name, “:”,        “ “, :atom)Tuesday, February 8, 2011
Keyword Sendg.keyword_send =  g.seq(    :atom, ‘ ‘,    g.many([:pair, ‘ ‘]),    :pair  )Tuesday, February 8, 2011
Keyword Send                ks = atom (pair ‘ ‘)+                     pairTuesday, February 8, 2011
Keyword Send           def bytecode(g)             @receiver.bytecode(g)             @arguments.each do |a|               ...
Keyword Send           def bytecode(g)             @receiver.bytecode(g)             @arguments.each do |a|               ...
$ rbx bin/repl.rb                   > ‘hello’ index: ‘o’                   NoMethodError:                     Unknown meth...
$ rbx bin/repl.rb                   > ‘hello’ index: ‘o’                   NoMethodError:                     Unknown meth...
Keyword Send‘hello’ index: ‘o’Tuesday, February 8, 2011
Keyword Send     “hello”.send(         “index:”, “o”       )                            RubyTuesday, February 8, 2011
Keyword Send‘hello’ ~index: ‘o’Tuesday, February 8, 2011
Keyword Send           def bytecode(g)             if @method_name[0] == ?~               ruby_style             else     ...
Keyword Send     “hello”.send(         “index”, “o”       )                            RubyTuesday, February 8, 2011
$ rbx bin/repl.rb                   > ‘hello’ ~index: ‘o’                   => 4                   NoMethodError:         ...
Keyword Send          obj string                  at: 0                 put: ‘j’Tuesday, February 8, 2011
Keyword Send          obj string                  at: 0                 put: ‘j’Tuesday, February 8, 2011
Keyword Send          obj string                  at: 0                 put: ‘j’Tuesday, February 8, 2011
Keyword Sendg.keyword_send =  g.seq(    :atom, ‘ ‘,    g.many([:pair, ‘ ‘]),    :pair  )Tuesday, February 8, 2011
Keyword Sendg.keyword_send =  g.seq(    :atom, ‘ ‘,    g.many([:pair, ‘ ‘]),    :pair  )Tuesday, February 8, 2011
Keyword Send                ks = atom (pair ‘ ‘)+                     pairTuesday, February 8, 2011
Keyword Send                            g.any(:atom,                                  :unary_send)Tuesday, February 8, 2011
Keyword Send         recv = us | atom           ks = recv (pair ‘ ‘)+                pairTuesday, February 8, 2011
Block                            [ 1 ]Tuesday, February 8, 2011
Keyword Send       g.block =         g.seq(‘[‘, :expr, ‘]’)Tuesday, February 8, 2011
Keyword Send               expr = ks | us | atomTuesday, February 8, 2011
Keyword Send                       block = “[“ expr “]Tuesday, February 8, 2011
Block                            [ 1. 2 ]Tuesday, February 8, 2011
Keyword Send       g.exprs =         g.seq(:expr,           g.kleene(‘.’,                    :expr))Tuesday, February 8, 2...
Keyword Send                      exprs = (‘.’ expr)*Tuesday, February 8, 2011
Keyword Send                       block = “[“ exprs “]Tuesday, February 8, 2011
$ rbx bin/repl.rb                   > 10 ~times: [                       Kernel ~puts: ‘hello’                     ]Tuesda...
$ rbx bin/repl.rb                   > 10 ~times: [                       Kernel ~puts: ‘rb.la’                     ]      ...
$ rbx bin/repl.rb                   > 10 ~times: [ :x |                       Kernel ~p: x                     ]Tuesday, F...
$ rbx bin/repl.rb                   > 10 ~times: [ :x |                       Kernel ~p: x                     ]          ...
Cascade Send          ary concat: a;              concat: b;              concat: cTuesday, February 8, 2011
Operators                            3 + 4 * 5Tuesday, February 8, 2011
$ rbx bin/repl.rb                   > 3 + 4 * 5Tuesday, February 8, 2011
$ rbx bin/repl.rb                   > 3 + 4 * 5                   => 35Tuesday, February 8, 2011
Parens                   parens = “(“ expr “)Tuesday, February 8, 2011
$ rbx bin/repl.rb                   > 3 + (4 * 5)                   => 23Tuesday, February 8, 2011
zero to usableTuesday, February 8, 2011
BIG IDEATuesday, February 8, 2011
little ideaTuesday, February 8, 2011
Complex                 LanguageTuesday, February 8, 2011
simple languageTuesday, February 8, 2011
Thanks!                            See ya out there.Tuesday, February 8, 2011
MIA: ReturnTuesday, February 8, 2011
MIA: =Tuesday, February 8, 2011
Upcoming SlideShare
Loading in...5
×

Developing a Language

473

Published on

Evan Phoenix's LARubyConf 2010 keynote talk.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
473
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Developing a Language

  1. 1. Developing a Language @evanphx github.com/evanphx Evan Phoenix Feb 5th, 2011Tuesday, February 8, 2011
  2. 2. #11Tuesday, February 8, 2011
  3. 3. LA.RB Los Angeles Ruby Brigade Tuesday Night. Every Week. http://rb.laTuesday, February 8, 2011
  4. 4. DINNERTuesday, February 8, 2011
  5. 5. DINNERTuesday, February 8, 2011
  6. 6. DINNERTuesday, February 8, 2011
  7. 7. DINNERTuesday, February 8, 2011
  8. 8. Which came first?Tuesday, February 8, 2011
  9. 9. Language > IdeaTuesday, February 8, 2011
  10. 10. Language < IdeaTuesday, February 8, 2011
  11. 11. Language = IdeaTuesday, February 8, 2011
  12. 12. The programmer, like the poet, works only slightly removed from pure thought-stuff. - Fred BrooksTuesday, February 8, 2011
  13. 13. If ideas are a manifestation of languageTuesday, February 8, 2011
  14. 14. Can better language lead to better ideas?Tuesday, February 8, 2011
  15. 15. better != newerTuesday, February 8, 2011
  16. 16. Tuesday, February 8, 2011
  17. 17. To craft a language from scratch is to take 95% from the past and call it groundbreaking. - Evan PhoenixTuesday, February 8, 2011
  18. 18. Peek backTuesday, February 8, 2011
  19. 19. Tuesday, February 8, 2011
  20. 20. RLKTuesday, February 8, 2011
  21. 21. RLK Implement with easeTuesday, February 8, 2011
  22. 22. RLK KPegTuesday, February 8, 2011
  23. 23. RLK KPeg A new parsing libraryTuesday, February 8, 2011
  24. 24. Prattle < RLKTuesday, February 8, 2011
  25. 25. URLs In the Building git://192.168.2.88/prattle In the Cloud github.com/evanphx/prattle.git github.com/evanphx/kpeg.gitTuesday, February 8, 2011
  26. 26. Tuesday, February 8, 2011
  27. 27. Dude. Really?Tuesday, February 8, 2011
  28. 28. PrattleTuesday, February 8, 2011
  29. 29. self true false nilTuesday, February 8, 2011
  30. 30. +module Prattle + module AST + class Self < AST::Node + Prattle::Parser.register self + + def self.rule_name + "self" + end + + def initialize + # Nothing. + end + + def self.grammar(g) + g.self = g.str("self") { Self.new } + end + end + end +endTuesday, February 8, 2011
  31. 31. +module Prattle + module AST + class Self < AST::Node + Prattle::Parser.register self + + def self.rule_name + "self" + end + + def initialize + # Nothing. + end + + def self.grammar(g) + g.self = g.str("self") { Self.new } + end + end + end +endTuesday, February 8, 2011
  32. 32. Self def self.grammar(g) g.self = g.str("self") { Self.new } end 047b522Tuesday, February 8, 2011
  33. 33. True def self.grammar(g) g.true = g.str("true") { True.new } end 04ad51bTuesday, February 8, 2011
  34. 34. False def self.grammar(g) g.false = g.str("false") { False.new } end 04ad51bTuesday, February 8, 2011
  35. 35. Nil def self.grammar(g) g.nil = g.str("nil") { Nil.new } end 7609e64Tuesday, February 8, 2011
  36. 36. Number 0 10 42 10323Tuesday, February 8, 2011
  37. 37. Number def self.grammar(g) g.number = g.reg(/0|([1-9][0-9]*)/) { |i| Number.new(i.to_i) } end a06d98cTuesday, February 8, 2011
  38. 38. Root def self.grammar(g) g.root = g.any(:true, :false, :self, :nil, :number) end dfd78cbTuesday, February 8, 2011
  39. 39. root = self | true | false | nil | numberTuesday, February 8, 2011
  40. 40. REPLTuesday, February 8, 2011
  41. 41. REPL Instant GratificationTuesday, February 8, 2011
  42. 42. $ rbx bin/repl.rb > 42 #<Prattle::AST::Number:0x9c @value=42> > true #<Prattle::AST::True:0x9d>Tuesday, February 8, 2011
  43. 43. Self def bytecode(g) g.push :self end 4e4c1c9Tuesday, February 8, 2011
  44. 44. True def bytecode(g) g.push :true end 4e4c1c9Tuesday, February 8, 2011
  45. 45. False def bytecode(g) g.push :false end 4e4c1c9Tuesday, February 8, 2011
  46. 46. Nil def bytecode(g) g.push :nil end 4e4c1c9Tuesday, February 8, 2011
  47. 47. Number def bytecode(g) g.push @value end 4e4c1c9Tuesday, February 8, 2011
  48. 48. String def self.grammar(g) not_quote = g.many( g.any(escapes, /[^]/)) { |*a| a.join } g.string = g.seq("", g.t(not_quote), "") { |str| String.new(str) } endTuesday, February 8, 2011
  49. 49. String char = escapes | [^’] not_quote = char* string = “‘“ not_quote “‘“Tuesday, February 8, 2011
  50. 50. $ rbx bin/repl.rb > 42 => 42 > true => 42 > ‘hello’ => “hello”Tuesday, February 8, 2011
  51. 51. BORINGTuesday, February 8, 2011
  52. 52. Unary Send 3 classTuesday, February 8, 2011
  53. 53. Unary Send 3.class RubyTuesday, February 8, 2011
  54. 54. Unary Send 3 classTuesday, February 8, 2011
  55. 55. Unary Send 3 classTuesday, February 8, 2011
  56. 56. Unary Send g.seq(:number, “ “, :method_name) { |v,_,n| UnarySend.new(v,n) }Tuesday, February 8, 2011
  57. 57. Unary Send us = number “ “ method_nameTuesday, February 8, 2011
  58. 58. Unary Send true classTuesday, February 8, 2011
  59. 59. Unary Send g.seq(:atom, “ “, :method_name) { |v,_,n| UnarySend.new(v,n) }Tuesday, February 8, 2011
  60. 60. atom = true | false | self | nil | number | stringTuesday, February 8, 2011
  61. 61. Unary Send us = atom “ “ method_nameTuesday, February 8, 2011
  62. 62. Unary Send 3 class classTuesday, February 8, 2011
  63. 63. Unary Send g.any( g.seq(:unary_send, “ “, :method_name) { |v,_,n| UnarySend.new(v,n) }, g.seq(:atom, “ “, :method_name) { |v,_,n| UnarySend.new(v,n) } )Tuesday, February 8, 2011
  64. 64. Unary Send us = us “ “ method_name | atom “ “ method_nameTuesday, February 8, 2011
  65. 65. Unary Send def bytecode(g) @receiver.bytecode(g) g.send @method_name.to_sym, 0 endTuesday, February 8, 2011
  66. 66. $ rbx bin/repl.rb > 3 class => Fixnum > 3 class class => Class > ‘hello’ class => StringTuesday, February 8, 2011
  67. 67. Keyword Send‘hello’ index: ‘o’Tuesday, February 8, 2011
  68. 68. Keyword Send“hello”.index(“o”) RubyTuesday, February 8, 2011
  69. 69. Keyword Sendg.keyword_send = g.seq(:atom, ‘ ‘, :method_name, “:”, “ “, :atom)Tuesday, February 8, 2011
  70. 70. Keyword Send ks = atom “ “ method_name “: ” :atomTuesday, February 8, 2011
  71. 71. Keyword Send‘hello’ at: 0 put: ‘j’Tuesday, February 8, 2011
  72. 72. Keyword Send“hello”[0] = “j” RubyTuesday, February 8, 2011
  73. 73. Keyword Sendg.pairs = g.seq(:method_name, “:”, “ “, :atom)Tuesday, February 8, 2011
  74. 74. Keyword Sendg.keyword_send = g.seq( :atom, ‘ ‘, g.many([:pair, ‘ ‘]), :pair )Tuesday, February 8, 2011
  75. 75. Keyword Send ks = atom (pair ‘ ‘)+ pairTuesday, February 8, 2011
  76. 76. Keyword Send def bytecode(g) @receiver.bytecode(g) @arguments.each do |a| a.bytecode(a) end g.send @method_name.to_sym, @arguments.size endTuesday, February 8, 2011
  77. 77. Keyword Send def bytecode(g) @receiver.bytecode(g) @arguments.each do |a| a.bytecode(a) end g.send @method_name.to_sym, @arguments.size endTuesday, February 8, 2011
  78. 78. $ rbx bin/repl.rb > ‘hello’ index: ‘o’ NoMethodError: Unknown method ‘index:’Tuesday, February 8, 2011
  79. 79. $ rbx bin/repl.rb > ‘hello’ index: ‘o’ NoMethodError: Unknown method ‘index:’Tuesday, February 8, 2011
  80. 80. Keyword Send‘hello’ index: ‘o’Tuesday, February 8, 2011
  81. 81. Keyword Send “hello”.send( “index:”, “o” ) RubyTuesday, February 8, 2011
  82. 82. Keyword Send‘hello’ ~index: ‘o’Tuesday, February 8, 2011
  83. 83. Keyword Send def bytecode(g) if @method_name[0] == ?~ ruby_style else smalltalk_style end endTuesday, February 8, 2011
  84. 84. Keyword Send “hello”.send( “index”, “o” ) RubyTuesday, February 8, 2011
  85. 85. $ rbx bin/repl.rb > ‘hello’ ~index: ‘o’ => 4 NoMethodError: Unknown method ‘index:’Tuesday, February 8, 2011
  86. 86. Keyword Send obj string at: 0 put: ‘j’Tuesday, February 8, 2011
  87. 87. Keyword Send obj string at: 0 put: ‘j’Tuesday, February 8, 2011
  88. 88. Keyword Send obj string at: 0 put: ‘j’Tuesday, February 8, 2011
  89. 89. Keyword Sendg.keyword_send = g.seq( :atom, ‘ ‘, g.many([:pair, ‘ ‘]), :pair )Tuesday, February 8, 2011
  90. 90. Keyword Sendg.keyword_send = g.seq( :atom, ‘ ‘, g.many([:pair, ‘ ‘]), :pair )Tuesday, February 8, 2011
  91. 91. Keyword Send ks = atom (pair ‘ ‘)+ pairTuesday, February 8, 2011
  92. 92. Keyword Send g.any(:atom, :unary_send)Tuesday, February 8, 2011
  93. 93. Keyword Send recv = us | atom ks = recv (pair ‘ ‘)+ pairTuesday, February 8, 2011
  94. 94. Block [ 1 ]Tuesday, February 8, 2011
  95. 95. Keyword Send g.block = g.seq(‘[‘, :expr, ‘]’)Tuesday, February 8, 2011
  96. 96. Keyword Send expr = ks | us | atomTuesday, February 8, 2011
  97. 97. Keyword Send block = “[“ expr “]Tuesday, February 8, 2011
  98. 98. Block [ 1. 2 ]Tuesday, February 8, 2011
  99. 99. Keyword Send g.exprs = g.seq(:expr, g.kleene(‘.’, :expr))Tuesday, February 8, 2011
  100. 100. Keyword Send exprs = (‘.’ expr)*Tuesday, February 8, 2011
  101. 101. Keyword Send block = “[“ exprs “]Tuesday, February 8, 2011
  102. 102. $ rbx bin/repl.rb > 10 ~times: [ Kernel ~puts: ‘hello’ ]Tuesday, February 8, 2011
  103. 103. $ rbx bin/repl.rb > 10 ~times: [ Kernel ~puts: ‘rb.la’ ] “rb.la” “rb.la” “rb.la” ... => 10Tuesday, February 8, 2011
  104. 104. $ rbx bin/repl.rb > 10 ~times: [ :x | Kernel ~p: x ]Tuesday, February 8, 2011
  105. 105. $ rbx bin/repl.rb > 10 ~times: [ :x | Kernel ~p: x ] 0 1 2 ... => 10Tuesday, February 8, 2011
  106. 106. Cascade Send ary concat: a; concat: b; concat: cTuesday, February 8, 2011
  107. 107. Operators 3 + 4 * 5Tuesday, February 8, 2011
  108. 108. $ rbx bin/repl.rb > 3 + 4 * 5Tuesday, February 8, 2011
  109. 109. $ rbx bin/repl.rb > 3 + 4 * 5 => 35Tuesday, February 8, 2011
  110. 110. Parens parens = “(“ expr “)Tuesday, February 8, 2011
  111. 111. $ rbx bin/repl.rb > 3 + (4 * 5) => 23Tuesday, February 8, 2011
  112. 112. zero to usableTuesday, February 8, 2011
  113. 113. BIG IDEATuesday, February 8, 2011
  114. 114. little ideaTuesday, February 8, 2011
  115. 115. Complex LanguageTuesday, February 8, 2011
  116. 116. simple languageTuesday, February 8, 2011
  117. 117. Thanks! See ya out there.Tuesday, February 8, 2011
  118. 118. MIA: ReturnTuesday, February 8, 2011
  119. 119. MIA: =Tuesday, February 8, 2011
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×