developing a language
DESCRIPTION
Evan Phoenix's LARubyConf 2010 keynote talk.TRANSCRIPT
Developinga
Language
Evan Phoenix Feb 5th, 2011
★ @evanphx github.com/evanphx
Tuesday, February 8, 2011
#11Tuesday, February 8, 2011
LA.RBLos Angeles Ruby Brigade
Tuesday Night. Every Week.http://rb.la
Tuesday, February 8, 2011
DINNER
Tuesday, February 8, 2011
DINNER
Tuesday, February 8, 2011
DINNER
Tuesday, February 8, 2011
DINNERTuesday, February 8, 2011
Which came first?
Tuesday, February 8, 2011
Language > Idea
Tuesday, February 8, 2011
Language < Idea
Tuesday, February 8, 2011
Language = Idea
Tuesday, February 8, 2011
The programmer, like the poet,
works only slightly removed
from pure thought-stuff.
- Fred Brooks
Tuesday, February 8, 2011
If ideas are a manifestation of
language
Tuesday, February 8, 2011
Can better language lead to
better ideas?
Tuesday, February 8, 2011
better!=
newer
Tuesday, February 8, 2011
���������
Tuesday, February 8, 2011
To craft a language from
scratch is to take 95% from the
past and call it groundbreaking.
- Evan Phoenix
Tuesday, February 8, 2011
Peek back
Tuesday, February 8, 2011
Tuesday, February 8, 2011
RLK
Tuesday, February 8, 2011
Implement with ease
RLK
Tuesday, February 8, 2011
KPeg
RLK
Tuesday, February 8, 2011
KPeg
A new parsing library
RLK
Tuesday, February 8, 2011
Prattle < RLK
Tuesday, February 8, 2011
github.com/evanphx/prattle.git
github.com/evanphx/kpeg.git
URLs
git://192.168.2.88/prattle
In the Building
In the Cloud
Tuesday, February 8, 2011
Tuesday, February 8, 2011
Dude. Really?
Tuesday, February 8, 2011
Prattle
Tuesday, February 8, 2011
selftruefalsenil
Tuesday, February 8, 2011
+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+end
Tuesday, February 8, 2011
+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+end
Tuesday, February 8, 2011
def self.grammar(g) g.self = g.str("self") { Self.new }end
047b522
Self
Tuesday, February 8, 2011
def self.grammar(g) g.true = g.str("true") { True.new }end
04ad51b
True
Tuesday, February 8, 2011
def self.grammar(g) g.false = g.str("false") { False.new }end
04ad51b
False
Tuesday, February 8, 2011
def self.grammar(g) g.nil = g.str("nil") { Nil.new }end
7609e64
Nil
Tuesday, February 8, 2011
01042
10323
Number
Tuesday, February 8, 2011
def self.grammar(g) g.number = g.reg(/0|([1-9][0-9]*)/) { |i| Number.new(i.to_i) }end
a06d98c
Number
Tuesday, February 8, 2011
def self.grammar(g) g.root = g.any(:true, :false, :self, :nil, :number) end
dfd78cb
Root
Tuesday, February 8, 2011
root = self | true | false | nil | number
Tuesday, February 8, 2011
REPL
Tuesday, February 8, 2011
Instant Gratification
REPL
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 42#<Prattle::AST::Number:0x9c @value=42>> true#<Prattle::AST::True:0x9d>
Tuesday, February 8, 2011
def bytecode(g) g.push :selfend
4e4c1c9
Self
Tuesday, February 8, 2011
def bytecode(g) g.push :trueend
4e4c1c9
True
Tuesday, February 8, 2011
def bytecode(g) g.push :falseend
4e4c1c9
False
Tuesday, February 8, 2011
def bytecode(g) g.push :nilend
4e4c1c9
Nil
Tuesday, February 8, 2011
def bytecode(g) g.push @valueend
4e4c1c9
Number
Tuesday, February 8, 2011
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) }end
String
Tuesday, February 8, 2011
char = escapes | [^’]not_quote = char* string = “‘“ not_quote “‘“
String
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 42=> 42> true=> 42> ‘hello’=> “hello”
Tuesday, February 8, 2011
BORING
Tuesday, February 8, 2011
Unary Send
3 class
Tuesday, February 8, 2011
Unary Send
3.classRuby
Tuesday, February 8, 2011
Unary Send
3 class
Tuesday, February 8, 2011
Unary Send
3 class
Tuesday, February 8, 2011
g.seq(:number, “ “, :method_name) { |v,_,n| UnarySend.new(v,n) }
Unary Send
Tuesday, February 8, 2011
us = number “ “ method_name
Unary Send
Tuesday, February 8, 2011
Unary Send
true class
Tuesday, February 8, 2011
g.seq(:atom, “ “, :method_name) { |v,_,n| UnarySend.new(v,n) }
Unary Send
Tuesday, February 8, 2011
atom = true | false | self | nil | number | string
Tuesday, February 8, 2011
us = atom “ “ method_name
Unary Send
Tuesday, February 8, 2011
Unary Send
3 class class
Tuesday, February 8, 2011
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) })
Unary Send
Tuesday, February 8, 2011
us = us “ “ method_name | atom “ “ method_name
Unary Send
Tuesday, February 8, 2011
def bytecode(g) @receiver.bytecode(g) g.send @method_name.to_sym, 0end
Unary Send
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 3 class=> Fixnum> 3 class class=> Class> ‘hello’ class=> String
Tuesday, February 8, 2011
‘hello’ index: ‘o’
Keyword Send
Tuesday, February 8, 2011
“hello”.index(“o”)
Keyword Send
Ruby
Tuesday, February 8, 2011
g.keyword_send = g.seq(:atom, ‘ ‘, :method_name, “:”, “ “, :atom)
Keyword Send
Tuesday, February 8, 2011
ks = atom “ “ method_name “: ” :atom
Keyword Send
Tuesday, February 8, 2011
‘hello’ at: 0 put: ‘j’
Keyword Send
Tuesday, February 8, 2011
“hello”[0] = “j”
Keyword Send
Ruby
Tuesday, February 8, 2011
g.pairs = g.seq(:method_name, “:”, “ “, :atom)
Keyword Send
Tuesday, February 8, 2011
g.keyword_send = g.seq( :atom, ‘ ‘, g.many([:pair, ‘ ‘]), :pair )
Keyword Send
Tuesday, February 8, 2011
ks = atom (pair ‘ ‘)+ pair
Keyword Send
Tuesday, February 8, 2011
def bytecode(g) @receiver.bytecode(g) @arguments.each do |a| a.bytecode(a) end g.send @method_name.to_sym, @arguments.sizeend
Keyword Send
Tuesday, February 8, 2011
def bytecode(g) @receiver.bytecode(g) @arguments.each do |a| a.bytecode(a) end g.send @method_name.to_sym, @arguments.sizeend
Keyword Send
Tuesday, February 8, 2011
$ rbx bin/repl.rb> ‘hello’ index: ‘o’
NoMethodError: Unknown method ‘index:’
Tuesday, February 8, 2011
$ rbx bin/repl.rb> ‘hello’ index: ‘o’
NoMethodError: Unknown method ‘index:’
Tuesday, February 8, 2011
‘hello’ index: ‘o’
Keyword Send
Tuesday, February 8, 2011
“hello”.send( “index:”, “o” )
Keyword Send
Ruby
Tuesday, February 8, 2011
‘hello’ ~index: ‘o’
Keyword Send
Tuesday, February 8, 2011
def bytecode(g) if @method_name[0] == ?~ ruby_style else smalltalk_style endend
Keyword Send
Tuesday, February 8, 2011
“hello”.send( “index”, “o” )
Keyword Send
Ruby
Tuesday, February 8, 2011
$ rbx bin/repl.rb> ‘hello’ ~index: ‘o’=> 4NoMethodError: Unknown method ‘index:’
Tuesday, February 8, 2011
obj string at: 0 put: ‘j’
Keyword Send
Tuesday, February 8, 2011
obj string at: 0 put: ‘j’
Keyword Send
Tuesday, February 8, 2011
obj string at: 0 put: ‘j’
Keyword Send
Tuesday, February 8, 2011
g.keyword_send = g.seq( :atom, ‘ ‘, g.many([:pair, ‘ ‘]), :pair )
Keyword Send
Tuesday, February 8, 2011
g.keyword_send = g.seq( :atom, ‘ ‘, g.many([:pair, ‘ ‘]), :pair )
Keyword Send
Tuesday, February 8, 2011
ks = atom (pair ‘ ‘)+ pair
Keyword Send
Tuesday, February 8, 2011
g.any(:atom, :unary_send)
Keyword Send
Tuesday, February 8, 2011
recv = us | atom ks = recv (pair ‘ ‘)+ pair
Keyword Send
Tuesday, February 8, 2011
[ 1 ]Block
Tuesday, February 8, 2011
g.block = g.seq(‘[‘, :expr, ‘]’)
Keyword Send
Tuesday, February 8, 2011
expr = ks | us | atom
Keyword Send
Tuesday, February 8, 2011
block = “[“ expr “]
Keyword Send
Tuesday, February 8, 2011
[ 1. 2 ]Block
Tuesday, February 8, 2011
g.exprs = g.seq(:expr, g.kleene(‘.’, :expr))
Keyword Send
Tuesday, February 8, 2011
exprs = (‘.’ expr)*
Keyword Send
Tuesday, February 8, 2011
block = “[“ exprs “]
Keyword Send
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 10 ~times: [ Kernel ~puts: ‘hello’ ]
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 10 ~times: [ Kernel ~puts: ‘rb.la’ ]“rb.la”“rb.la”“rb.la”...=> 10
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 10 ~times: [ :x | Kernel ~p: x ]
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 10 ~times: [ :x | Kernel ~p: x ]012...=> 10
Tuesday, February 8, 2011
ary concat: a; concat: b; concat: c
Cascade Send
Tuesday, February 8, 2011
3 + 4 * 5
Operators
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 3 + 4 * 5
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 3 + 4 * 5=> 35
Tuesday, February 8, 2011
parens = “(“ expr “)
Parens
Tuesday, February 8, 2011
$ rbx bin/repl.rb> 3 + (4 * 5)=> 23
Tuesday, February 8, 2011
zero to usable
Tuesday, February 8, 2011
BIG IDEA
Tuesday, February 8, 2011
little idea
Tuesday, February 8, 2011
ComplexLanguage
Tuesday, February 8, 2011
simple language
Tuesday, February 8, 2011
See ya out there.
Thanks!
Tuesday, February 8, 2011
MIA: Return
Tuesday, February 8, 2011
MIA: =
Tuesday, February 8, 2011