Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Writing your own Programming Language to unders...
Search
Plataformatec
March 02, 2012
Technology
7
5.7k
Writing your own Programming Language to understand Ruby better
@GoGaRuCo 2011
Plataformatec
March 02, 2012
Tweet
Share
More Decks by Plataformatec
See All by Plataformatec
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ Elixir Brasil 2019
plataformatec
5
1k
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ QCon SP 2018
plataformatec
1
230
Elixir @ iMasters Intercon 2016
plataformatec
1
260
GenStage and Flow by @josevalim at ElixirConf
plataformatec
17
2.8k
Elixir: Programação Funcional e Pragmática @ 2º Tech Day Curitiba
plataformatec
2
310
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
300
What's ahead for Elixir: v1.2 and GenRouter
plataformatec
15
2.1k
Arquiteturas Comuns de Apps Rails @ RubyConf BR 2015
plataformatec
6
390
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.4k
Other Decks in Technology
See All in Technology
今日からあなたもGeminiを好きになる
subaruhello
1
520
An introduction to Claude Code SDK
choplin
3
3.2k
室長の逆襲 :データ活用の陣地を増やすためのヒント
masatoshi0205
0
180
AI時代にも変わらぬ価値を発揮したい: インフラ・クラウドを切り口にユーザー価値と非機能要件に向き合ってエンジニアとしての地力を培う
netmarkjp
0
210
ObsidianをLLM時代のナレッジベースに! クリッピング→Markdown→CLI連携の実践
srvhat09
7
8.6k
Bill One 開発エンジニア 紹介資料
sansan33
PRO
4
13k
ML Pipelineの開発と運用を OpenTelemetryで繋ぐ @ OpenTelemetry Meetup 2025-07
getty708
0
170
大規模組織にAIエージェントを迅速に導入するためのセキュリティの勘所 / AI agents for large-scale organizations
i35_267
5
190
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.2k
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
5
39k
分散トレーシングによる コネクティッドカーのデータ処理見える化の試み
thatsdone
0
140
[SRE NEXT 2025] すみずみまで暖かく照らすあなたの太陽でありたい
carnappopper
2
860
Featured
See All Featured
Done Done
chrislema
184
16k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
GitHub's CSS Performance
jonrohan
1031
460k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
21
1.3k
4 Signs Your Business is Dying
shpigford
184
22k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
How STYLIGHT went responsive
nonsquared
100
5.6k
Transcript
José Valim @josevalim blog.plataformatec.com Writing your own Programming Language to
Understand Ruby sexta-feira, 2 de março de 12
blog twitter ID José Valim @josevalim blog.plataformatec.com Writing your own
Programming Language to Understand Ruby sexta-feira, 2 de março de 12
Elixir Simple Object Orientation and charming syntax on top of
Erlang sexta-feira, 2 de março de 12
Erlang VM + Concurrent Processes + Message Based + Hot
Code Swapping + Runs with low memory sexta-feira, 2 de março de 12
Erlang Language + Small and quick to learn + Functional
programming - Syntax gets too much in your way - No object orientation sexta-feira, 2 de março de 12
Elixir Simple Object Orientation and charming syntax on top of
Erlang sexta-feira, 2 de março de 12
<3 Ruby <3 sexta-feira, 2 de março de 12
sexta-feira, 2 de março de 12
@tenderl—ve sexta-feira, 2 de março de 12
* Things I learned about Ruby sexta-feira, 2 de março
de 12
Things I learned about sexta-feira, 2 de março de 12
The Syntax sexta-feira, 2 de março de 12
puts sexta-feira, 2 de março de 12
puts Lexe sexta-feira, 2 de março de 12
puts Lexe [:identifier, “puts”], sexta-feira, 2 de março de 12
puts Lexe [:identifier, “puts”], Parse sexta-feira, 2 de março de
12
puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse sexta-feira, 2
de março de 12
puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c
sexta-feira, 2 de março de 12
puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c
[:call, “puts”,[ [:string, sexta-feira, 2 de março de 12
puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c
[:call, “puts”,[ [:string, Native / Bytecod sexta-feira, 2 de março de 12
puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c
[:call, “puts”,[ [:string, Native / Bytecod sexta-feira, 2 de março de 12
Flexible Grammar sexta-feira, 2 de março de 12
def foo 1 end foo #=> 1 self.foo #=> 1
sexta-feira, 2 de março de 12
def foo 1 end foo #=> 1 self.foo #=> 1
foo = 2 foo #=> 2 self.foo #=> 1 sexta-feira, 2 de março de 12
foo sexta-feira, 2 de março de 12
foo Lexe sexta-feira, 2 de março de 12
foo Lexe [:identifier, “foo”] sexta-feira, 2 de março de 12
foo Lexe [:identifier, “foo”] Parse sexta-feira, 2 de março de
12
foo Lexe [:identifier, “foo”] [:identifier, Parse sexta-feira, 2 de março
de 12
foo Lexe [:identifier, “foo”] [:identifier, Parse Semanti c sexta-feira, 2
de março de 12
foo Lexe [:identifier, “foo”] [:identifier, Parse Semanti c ? sexta-feira,
2 de março de 12
foo Lexe [:identifier, “foo”] [:identifier, Parse Semanti c Native /
Bytecod ? sexta-feira, 2 de março de 12
def bar foo = 1 foo end sexta-feira, 2 de
março de 12
def bar foo = 1 foo end [:method,:bar,[ [:assign, "foo",
[:integer,1]], [:identifier,"foo"] ]] lexer + parser sexta-feira, 2 de março de 12
def bar foo = 1 foo end [:method,:bar,[ [:assign, "foo",
[:integer,1]], [:identifier,"foo"] ]] lexer + parser [:method,:bar,[ [:assign, "foo", [:integer,1]], [:var,"foo"] ]] semantic analysis sexta-feira, 2 de março de 12
sexta-feira, 2 de março de 12
def bar(arg) arg.class end bar /foo/m sexta-feira, 2 de março
de 12
def bar(arg) arg.class end bar /foo/m bar, foo, m =
0, 1, 2 bar /foo/m sexta-feira, 2 de março de 12
sexta-feira, 2 de março de 12
sexta-feira, 2 de março de 12
def show @user = User.find(self.params[:id]) if @user.name =~ %r/^Ph\.D/i self.render
:action => "show" else self.flash[:notice] = "Ph.D required" self.redirect_to "/" end end sexta-feira, 2 de março de 12
def show @user = User.find(params[:id]) if @user.name =~ /^Ph\.D/i render
:action => "show" else flash[:notice] = "Ph.D required" redirect_to "/" end end sexta-feira, 2 de março de 12
Trivia sexta-feira, 2 de março de 12
Trivia array = [1,2,3] sexta-feira, 2 de março de 12
Trivia array = [1,2,3] array.length+1 sexta-feira, 2 de março de
12
Trivia array = [1,2,3] array.length+1 #=> 4 sexta-feira, 2 de
março de 12
Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 sexta-feira,
2 de março de 12
Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 #=>
ArgumentError sexta-feira, 2 de março de 12
Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 #=>
ArgumentError array.length + 1 sexta-feira, 2 de março de 12
Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 #=>
ArgumentError array.length + 1 #=> 4 sexta-feira, 2 de março de 12
Trivia p { } p { a: 1 } Is
it a block or a sexta-feira, 2 de março de 12
The Object sexta-feira, 2 de março de 12
object = Object.new def object.greet(name) puts "Hello #{name}" end object.greet("Matz")
sexta-feira, 2 de março de 12
Ruby methods are stored in modules sexta-feira, 2 de março
de 12
module Greeter def greet(name) "Hello #{name}" end end class Person
include Greeter end Person.new.greet "Matz" sexta-feira, 2 de março de 12
class Person def greet(name) "Hello #{name}" end end Person.new.greet "Matz"
sexta-feira, 2 de março de 12
Person.is_a?(Module) #=> true Class.superclass #=> Module sexta-feira, 2 de março
de 12
object = Object.new def object.greet(name) puts "Hello #{name}" end object.greet("Matz")
sexta-feira, 2 de março de 12
object.class.ancestors #=> [Object, Kernel, BasicObject] sexta-feira, 2 de março de
12
object.class.ancestors #=> [Object, Kernel, BasicObject] object.class.ancestors.any? do |r| r.method_defined?(:greet) end
#=> false sexta-feira, 2 de março de 12
object.class.ancestors #=> [Object, Kernel, BasicObject] object.class.ancestors.any? do |r| r.method_defined?(:greet) end
#=> false object.singleton_class. method_defined?(:greet) #=> true sexta-feira, 2 de março de 12
object.class.ancestors #=> [Object, Kernel, BasicObject] object.class.ancestors.any? do |r| r.method_defined?(:greet) end
#=> false object.singleton_class. method_defined?(:greet) #=> true object.singleton_class.is_a?(Module) #=> true sexta-feira, 2 de março de 12
_why once said: Creating your own programming language is fun
if you can keep it Trivia sexta-feira, 2 de março de 12
Ruby’s parse.y is more than 10k LOC Trivia sexta-feira, 2
de março de 12
What if? sexta-feira, 2 de março de 12
... we did not have blocks? sexta-feira, 2 de março
de 12
<3 Blocks sexta-feira, 2 de março de 12
File.open "gogaruco.txt" do |f| f.write "doing it live" end sexta-feira,
2 de março de 12
File.open "gogaruco.txt", do |f| f.write "doing it live" end sexta-feira,
2 de março de 12
File.open "gogaruco.txt", do |f| f.write "doing it live" end sexta-feira,
2 de março de 12
File.open("gogaruco.txt", do |f| f.write "doing it live" end) sexta-feira, 2
de março de 12
do_it = do |f| f.write "doing it live" end File.open
"gogaruco.txt", do_it sexta-feira, 2 de março de 12
No blocks + No need for yield, &block + Passing
more than one block around is more natural sexta-feira, 2 de março de 12
... we had Array and Hash comprehensions sexta-feira, 2 de
março de 12
n = [1,2,3,4] [x * 2 for x in n]
# => [2,4,6,8] sexta-feira, 2 de março de 12
n = [1,2,3] [x * 2 for x in n,
x.odd?] # => [2,6] sexta-feira, 2 de março de 12
n = [1,2,3,4] [[x,y] for x in n, y in
n, x * x == y] # => [[1,1],[2,4]] sexta-feira, 2 de março de 12
n = [1,2,3,4] {x => y for x in n,
y in n, x * x == y} # => { 1 => 1, 2 => 4 } sexta-feira, 2 de março de 12
... our hashes were more like sexta-feira, 2 de março
de 12
{ a: 1 } sexta-feira, 2 de março de 12
{ "a": 1 } sexta-feira, 2 de março de 12
Trivia { "a-b": 1 } == { :"a-b" => 1
} sexta-feira, 2 de março de 12
... we had (better)pattern sexta-feira, 2 de março de 12
x, y, *z = [1,2,3,4,5] x #=> 1 y #=>
2 z #=> [3,4,5] sexta-feira, 2 de março de 12
x, [y1,*y2], *z = [1,[2,3,4],5] x #=> 1 y1 #=>
2 y2 #=> [3,4] z #=> [5] sexta-feira, 2 de março de 12
x, x, *z = [1,2,3,4,5] #=> Raises an error sexta-feira,
2 de março de 12
x, x, *z = [1,1,3,4,5] #=> Works! sexta-feira, 2 de
março de 12
x = 1 ^x, *y = [3, 2, 1] #=>
Raises an error! ^x, *y = [1, 2, 3] # => Works! sexta-feira, 2 de março de 12
def form_for(object) case object when Hash # ... when Array
# ... else # ... end end sexta-feira, 2 de março de 12
def form_for(record : Hash) # ... end def form_for(record :
Array) # ... end def form_for(record) # ... end sexta-feira, 2 de março de 12
+ Better to maintain + Better to document - No
duck typing Method pattern matching sexta-feira, 2 de março de 12
Haskell / Go interfaces interface ActiveModel::Compliance def :to_key def :persisted?
end def form_for(object : ActiveModel::Compliance) # ... end sexta-feira, 2 de março de 12
... we had partial application? sexta-feira, 2 de março de
12
_ has special semantics in many functional sexta-feira, 2 de
março de 12
_ = 1 _ # => nil sexta-feira, 2 de
março de 12
x, [y1,*_], *z = [1,[2,3,4],5] sexta-feira, 2 de março de
12
Instead of: names.each { |x| puts(x) } sexta-feira, 2 de
março de 12
Instead of: names.each { |x| puts(x) } Do: names.each &puts(_)
sexta-feira, 2 de março de 12
puts(_) #=> lambda { |x| puts(x) } respond_to?(_, _) #=>
lambda { |x,y| respond_to?(x,y) } sexta-feira, 2 de março de 12
... we defined a syntax tree? sexta-feira, 2 de março
de 12
[:method,:bar,[ [:assign, "foo", [:integer,1]], [:var,"foo"] ]] sexta-feira, 2 de março
de 12
class Foo memoize def bar # Something end end sexta-feira,
2 de março de 12
class Foo memoize(def bar # Something end) end sexta-feira, 2
de março de 12
def memoize(method) tree = method.tree # Do something method.redefine! new_tree
end sexta-feira, 2 de março de 12
Wrapping up sexta-feira, 2 de março de 12
<3 Elixir <3 github.com/josevalim/ sexta-feira, 2 de março de 12
createyourproglang.com sexta-feira, 2 de março de 12
José Valim @josevalim blog.plataformatec.com Questions? sexta-feira, 2 de março de
12
blog twitter ID José Valim @josevalim blog.plataformatec.com Questions? sexta-feira, 2
de março de 12