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
5.7k
7
Share
Writing your own Programming Language to understand Ruby better
@GoGaRuCo 2011
Plataformatec
March 02, 2012
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
250
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
330
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
320
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
PHP と TypeScript の型システム比較:AI 時代の「型」は誰のためにあるのか? #frontend_phpcon_do / frontend_phpcon_do_2026
shogogg
1
220
Dynamic Workersについて
yusukebe
2
550
サプライチェーンセキュリティの空白地帯 - 信頼できる”依存性”の未来を考える
rung
PRO
2
590
インフラが苦手でも大丈夫! 紙芝居 Kubernetes -WWGT 10周年編-
aoi1
1
320
『家族アルバム みてね』における インシデント対応との向き合い方 / Approach incident response in Family Album
kohbis
2
280
もりもり新機能を一挙紹介! AgentCoreに入門して、AWS上にAIエージェントを構築しよう
minorun365
PRO
6
540
Terraformモジュールは、なぜ「魔境」化するのか
hayama17
1
130
AIプラットフォームを運用し続けるための可観測性
tanimuyk
4
880
AI フレンドリーなエラー監視を TypeScript で実現する
shinyaigeek
2
200
Oracle AI Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
4
2.8k
AI時代の私の技術インプットとアウトプット術
tonkotsuboy_com
15
8.1k
Gradle×GitHub_ActionsでCI時間を約50%短縮 ジョブ分割の設計と落とし穴 / Cutting CI Time by ~50% with Gradle and GitHub Actions: Job-Splitting Design and Pitfalls
takatty
0
560
Featured
See All Featured
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
150
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
190
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
340
Crafting Experiences
bethany
1
160
Code Reviewing Like a Champion
maltzj
528
40k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
230
First, design no harm
axbom
PRO
2
1.2k
The Cult of Friendly URLs
andyhume
79
6.9k
Color Theory Basics | Prateek | Gurzu
gurzu
0
320
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
380
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