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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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.2k
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ QCon SP 2018
plataformatec
1
240
Elixir @ iMasters Intercon 2016
plataformatec
1
280
GenStage and Flow by @josevalim at ElixirConf
plataformatec
17
2.9k
Elixir: Programação Funcional e Pragmática @ 2º Tech Day Curitiba
plataformatec
2
320
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
310
What's ahead for Elixir: v1.2 and GenRouter
plataformatec
15
2.2k
Arquiteturas Comuns de Apps Rails @ RubyConf BR 2015
plataformatec
6
410
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.5k
Other Decks in Technology
See All in Technology
The_Evolution_of_Bits_AI_SRE.pdf
nulabinc
PRO
0
230
会社紹介資料 / Sansan Company Profile
sansan33
PRO
16
410k
TypeScript 7.0の現在地と備え方
uhyo
7
1.7k
コンテキスト・ハーネスエンジニアリングの現在
hirosatogamo
PRO
3
400
A Casual Introduction to RISC-V
omasanori
0
160
OpenClaw を Amazon Lightsail で動かす理由
uechishingo
0
160
情シスのための生成AI実践ガイド2026 / Generative AI Practical Guide for Business Technology 2026
glidenote
0
270
Go標準パッケージのI/O処理をながめる
matumoto
0
220
決済サービスを支えるElastic Cloud - Elastic Cloudの導入と推進、決済サービスのObservability
suzukij
2
650
わたしがセキュアにAWSを使えるわけないじゃん、ムリムリ!(※ムリじゃなかった!?)
cmusudakeisuke
1
780
進化するBits AI SREと私と組織
nulabinc
PRO
1
240
Kubernetesにおける推論基盤
ry
1
410
Featured
See All Featured
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
150
The Pragmatic Product Professional
lauravandoore
37
7.2k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
990
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
440
Build your cross-platform service in a week with App Engine
jlugia
234
18k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
270
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
64
53k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
85
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
320
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
How Software Deployment tools have changed in the past 20 years
geshan
0
33k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
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