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 understand Ruby better
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
770
O case da Plataformatec com o Elixir - Como uma empresa brasileira criou uma linguagem que é usada no mundo inteiro @ QCon SP 2018
plataformatec
1
210
Elixir @ iMasters Intercon 2016
plataformatec
1
240
GenStage and Flow by @josevalim at ElixirConf
plataformatec
17
2.6k
Elixir: Programação Funcional e Pragmática @ 2º Tech Day Curitiba
plataformatec
2
200
Elixir: Programação Funcional e Pragmática @ Encontro Locaweb 2016
plataformatec
4
220
What's ahead for Elixir: v1.2 and GenRouter
plataformatec
15
1.8k
Arquiteturas Comuns de Apps Rails @ RubyConf BR 2015
plataformatec
6
360
Pirâmide de testes, escrevendo testes com qualidade @ RubyConf 2015
plataformatec
10
2.1k
Other Decks in Technology
See All in Technology
BDD(Cucumber)コミュニティが無料提供しているコンテンツの紹介と現在起きている危機
nihonbuson
4
750
あらゆる商品を扱う商品データベースを再設計した話 / product db re-architecture
rince
8
3.8k
20240321_生成AI時代のDevOps
kzkmaeda
2
610
ハイパフォーマンスな組織をつくるための開発生産性の考え方 / developer-productivity-high-performer-link-and-motivation
lmi
3
270
GraphQLに入門してみた
chiroruxx
2
130
LLMプロダクト事業の立ち上げにおける挑戦
layerx
PRO
7
1.5k
マイクロサービス環境におけるDB戦略 in DMMプラットフォーム
pospome
11
3k
プッシュ型子育てサービスを、先行プロジェクト実施自治体において開始します
govtechtokyo
0
290
Azureコストは水道代/The_47th_Tokyo_Jazug
aeonpeople
3
380
戦略的DDDを実践するための跳躍力 / OOC 2024
pictiny
6
4.2k
Why do you get AWS certificates
hirosys
0
120
TypeScript Quiz (Encraft #12 Frontend Quiz Night)
uhyo
6
720
Featured
See All Featured
Bash Introduction
62gerente
604
210k
Practical Orchestrator
shlominoach
180
9.7k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
111
35k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
657
120k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
67
38k
Intergalactic Javascript Robots from Outer Space
tanoku
266
26k
Building Adaptive Systems
keathley
29
1.8k
Atom: Resistance is Futile
akmur
258
25k
YesSQL, Process and Tooling at Scale
rocio
160
13k
Code Review Best Practice
trishagee
54
15k
The Language of Interfaces
destraynor
150
23k
Learning to Love Humans: Emotional Interface Design
aarron
266
39k
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