Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
1.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.9k
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
400
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.4k
Other Decks in Technology
See All in Technology
エンジニアとPMのドメイン知識の溝をなくす、 AIネイティブな開発プロセス
applism118
2
200
Oracle Cloud Infrastructure:2025年11月度サービス・アップデート
oracle4engineer
PRO
2
170
.NET 10 のパフォーマンス改善
nenonaninu
2
4.9k
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
0
670
Gemini でコードレビュー知見を見える化
zozotech
PRO
1
130
re:Invent 2025 ふりかえり 生成AI版
takaakikakei
1
130
会社紹介資料 / Sansan Company Profile
sansan33
PRO
11
390k
なぜ使われないのか?──定量×定性で見極める本当のボトルネック
kakehashi
PRO
1
1.1k
21st ACRi Webinar - Univ of Tokyo Presentation Slide (Shinya Takamaeda)
nao_sumikawa
0
120
AI時代におけるアジャイル開発について
polyscape_inc
0
120
AIと二人三脚で育てた、個人開発アプリグロース術
zozotech
PRO
0
590
AWS Bedrock AgentCoreで作る 1on1支援AIエージェント 〜Memory × Evaluationsによる実践開発〜
yusukeshimizu
4
290
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
Facilitating Awesome Meetings
lara
57
6.7k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Why Our Code Smells
bkeepers
PRO
340
57k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Git: the NoSQL Database
bkeepers
PRO
432
66k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Thoughts on Productivity
jonyablonski
73
5k
Code Review Best Practice
trishagee
73
19k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
A designer walks into a library…
pauljervisheath
210
24k
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