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
Scheme Interpreter in Ruby
Search
HORINOUCHI Masato
January 26, 2016
Programming
0
70
Scheme Interpreter in Ruby
社内LT大会 0x64物語 #04 Compiler / Interpreter 資料
HORINOUCHI Masato
January 26, 2016
Tweet
Share
More Decks by HORINOUCHI Masato
See All by HORINOUCHI Masato
balenaCloud
thermes
0
74
Church Numerals
thermes
0
47
CPS & CTO
thermes
0
250
FM synthesis
thermes
0
36
A440
thermes
0
61
Inside mml2wav.rb
thermes
0
86
Clock / Timer
thermes
0
160
Hash Tree
thermes
0
75
POSIX Threads
thermes
0
56
Other Decks in Programming
See All in Programming
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
700
dchart: charts from deck markup
ajstarks
3
990
AIで開発はどれくらい加速したのか?AIエージェントによるコード生成を、現場の評価と研究開発の評価の両面からdeep diveしてみる
daisuketakeda
1
970
CSC307 Lecture 06
javiergs
PRO
0
680
CSC307 Lecture 01
javiergs
PRO
0
690
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
550
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
610
プロダクトオーナーから見たSOC2 _SOC2ゆるミートアップ#2
kekekenta
0
200
Implementation Patterns
denyspoltorak
0
280
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
170
Rust 製のコードエディタ “Zed” を使ってみた
nearme_tech
PRO
0
150
コントリビューターによるDenoのすゝめ / Deno Recommendations by a Contributor
petamoriken
0
200
Featured
See All Featured
Leo the Paperboy
mayatellez
4
1.4k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.4k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
250
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Code Reviewing Like a Champion
maltzj
527
40k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
91
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
61
52k
Deep Space Network (abreviated)
tonyrice
0
47
Writing Fast Ruby
sferik
630
62k
Accessibility Awareness
sabderemane
0
49
From π to Pie charts
rasagy
0
120
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Transcript
Scheme Interpreter in Ruby 2016/01/26 0x64 Tales #04 Compiler /
Interpreter Livesense Inc. HORINOUCHI Masato
ϋοΧʔʹͳΖ͏ LISP ɺͦΕΛϞϊʹͨ͠ͱ͖ͷ͢Β͍͠ޛΓମݧͷͨΊʹษ ڧ͠·͠ΐ͏ɻ͜ͷମݧɺͦͷޙͷਓੜͰΑΓΑ͍ϓϩάϥϚ ʔͱͳΔखॿ͚ͱͳΔͣͰ͢ɻͨͱ͑ɺ࣮ࡍʹ LISP ͦͷͷ Λ͋·ΓΘͳͯ͘ɻ — Eric
S. Raymond ϋοΧʔʹͳΖ͏ (How To Become A Hacker) ͔ΒҾ༻
ී௨ͷͭΒͷ্Λߦ͚ ൴͕Lispʹ͍ͭͯݴ͍ͬͯΔ͜ͱΑ͋͘Δҙݟͩɻͭ·ΓɺLisp ΛֶΑ͍ϓϩάϥϚʔʹͳΕΔɺͰͦΕΛ࣮ࡍʹ͏͜ͱ ͳ͍ɺͱɻ Կނ͍ͩ? ϓϩάϥϛϯάݴޠͳΜͯͨͩͷಓ۩͡Όͳ͍͔ɻLisp Ͱྑ͍ϓϩάϥϜ͕ ॻ͚ΔͳΒɺ͏͖ͳΜͩɻ — Paul
Graham ී௨ͷͭΒͷ্Λߦ͚ Bea%ng the Averages ͔ΒҾ༻
Let's Talk Lisp Πϕϯτͷೋ࣍ձͰʮ࣮RubyͬͯʰMatzLispʱͱ͍͏Lispͷ ํݴͩͬͨΜͩΑʂʯͱޠΒΕͨΑ͏Ͱ͢ɻԿͱܼ࡞ͳωλͰ ͕͢ɺLispͷڧ͞Λ௧ײͨ͠Θ͕ͨ͠ʮ͕ࣗຬ͢ΔͨΊʹʯ ࡞Γग़ͨ͠Rubyɺจ๏ͦ͜ҧ͏ͷͷɺͦͷຊ࣭ͱͯ͠Lispจ ԽΛܧঝ͍ͯ͠Δͷ͔͠Ε·ͤΜɻ — ·ͭͱΏ͖ͻΖ
Let's Talk Lisp ͔ΒҾ༻
ࢀߟਤॻ ֶͭͬͯ͘Ϳϓϩάϥϛϯάݴޠ Rubyʹ ΑΔSchemeॲཧܥͷ࣮ 1 ϓϩάϥϛϯάΛΑΓਂ͘ཧղ͢ΔͨΊ ͷۙಓɺϓϩάϥϛϯάݴޠΛ࣮͠ ͯΈΔ͜ͱɻSchemeͷαϒηοτΛRuby Ͱ࣮͍ͯ͘͜͠ͱͰɺϓϩάϥϜͲ ͏࣮ߦ͞ΕΔͷ͔ɺͦͷجຊ͕͖ͬΓ
͔Γ·͢ɻ 1 CC BY ͳͷͰແঈͩΑɻ༗ঈ൛͋ΔͷͰྑ͔ͬͨΒങͬͯͶɻ
σϞ
Fibonacci number (Scheme) (define (fib n) (cond ((= n 0)
0) ((= n 1) 1) (else (+ (fib (- n 2)) (fib (- n 1))))))
Fibonacci number (Ruby) def fib(n) case n when 0 0
when 1 1 else fib(n-2) + fib(n-1) end end
What is Environments.
͠ಈతείʔϓͩͱͨ͠Β… ((lambda (x) ((lambda (fun) ((lambda (x) (fun)) 1)) (lambda
() x))) 2) # => 1 ↑ಈతείʔϓͷ Emacs Lisp Ͱ্هͷίʔυͰ 1 ͕ฦΓ·͢ɻ
͠(ུ) (Ruby൛) (lambda { |x| (lambda { |fun| (lambda {
|x| fun.call }).call(1) }).call(lambda { x }) }).call(2) ͪͳΈʹ Ruby ੩తείʔϓͳͷͰɺ͋͘·ͰίʔυͷΘ͔Γ ͢͞ͷɻ Scheme ͱ͋·ΓมΘΒͳ͍ͷώϛπ…ɻ
͠(ུ) (y ʹมߋ) ((lambda (x) ((lambda (fun) ((lambda (y) (fun))
1)) (lambda () x))) 2) # => 2 ↑ଆͷ (x) Λ (y) ʹม໊มߋ͚ͨͩ͠Ͱ 2 ʹͳΔɻ
͠੩తείʔϓͩͱͨ͠Β… ((lambda (x) ((lambda (fun) ((lambda (x) (fun)) 1)) (lambda
() x))) 2) # => 2 ↑ y ʹมߋͱಉ༷ 2 ʹͳΔɻ
ڥϞσϧ • ֎ଆͷ lambda x ͱଆͷ lambda x Λ۠ผ͢Δඞཁ͕͋Δɻ •
֎ଆͷ lambda ΛධՁ͍ͯ͠Δͱ͖ {x: 2} ͱ͢Δɻ • ଆͷ lambda ΛධՁ͍ͯ͠Δͱ͖ {x: 1} ͱ͢Δɻ • ਅΜதͷ lambda fun ΛධՁͨ͠ࡍʹɺλࣜͱධՁ࣌ͷڥΛϖ Ξͱͯ͠ΫϩʔδϟʔΛฦ͢ɻ
closure • ΫϩʔδϟʔλࣜͱڥͷϖΞɻ • λࣜΛධՁ͢ΔͱΫϩʔδϟʔ͕ධՁͱͳΔɻ • ΫϩδϟʔΛؔద༻͢Δͱ͖ɺΫϩʔδϟʔதͷڥΛ༻ ͍ͯධՁ͢Δɻ => ڥ(੩తείʔϓ)͕ͳ͍ͱ
closure ࡞Εͳ͍ɻ
ධՁͱؔద༻ • ؔͱҾͷ෦ʹ͚ɺͦΕͧΕΛධՁ͢Δɻ • ҾΛͦͷؔʹద༻͢Δɻ • ؔͷԾҾʹ࣮ҾΛଋറ͠ɺؔͷϘσΟΛධՁ͢Δɻ => ධՁ(eval)ͱؔద༻(apply)Λ࠶ؼతʹ܁Γฦ͢ɻ
࣮ • Ruby ͷ _eval ؔͱ apply ؔΛ࣮ߦ͍ͯ͘͠ • Scheme
ͷϦετ Ruby ͷ Array • Scheme ͷڥ Ruby ͷ Hash ͷ Array • Scheme Lisp-1 ͳͷͰɺHash ͷ Array 1͚ͭͩͰ okܥɻ
_eval def _eval(exp, env) if not list?(exp) if immediate_val?(exp) exp
else lookup_var(exp, env) end else if special_form?(exp) eval_special_form(exp, env) else fun = _eval(car(exp), env) args = eval_list(cdr(exp), env) apply(fun, args) end end end
apply def apply(fun, args) if primitive_fun?(fun) apply_primitive_fun(fun, args) else lambda_apply(fun,
args) end end
lookup_var ͱ extend_env def lookup_var(var, env) alist = env.find {
|alist| alist.key?(var) } if alist == nil raise "couldn't find value to variables: '#{var}'" end alist[var] end def extend_env(parameters, args, env) alist = parameters.zip(args) h = Hash.new alist.each { |k, v| h[k] = v } [h] + env # ↑ ্هͰ env.find ͯ͠ΔͷͰ Array ͷઌ಄ʹՃ͢Δͷ͕ॏཁɻ end
parse def parse(exp) program = exp.strip(). gsub(/[a-zA-Z\+\-\*><=][0-9a-zA-Z\+\-=!*]*/, ':\\0'). gsub(/\s+/, ',
'). gsub(/\(/, '['). gsub(/\)/, ']') eval(program) end ↑࠷ޙʹ Ruby ͷ eval ͯ͠Δɻ
Next Step ܭࢉػϓϩάϥϜͷߏͱղऍ (௨শ SICP) MITͷೖίʔεͰ͏ܭࢉػՊֶͷ༏ ΕͨڭՊॻ ϋϧɾΤΠϒϧιϯ, δΣϦ ʔɾαεϚϯ,
δϡϦʔɾαεϚϯڞஶ( ాӳҰ༁)ʮܭࢉػϓϩάϥϜͷߏͱղ ऍ ୈೋ൛ʯ(ϐΞιϯɾΤσϡέʔγϣϯ 2000). දࢴͷຐज़ࢣΏ͑ʹͦ͏͍ΘΕ Δ. LISP/Schemeੈքͷయͷͻͱͭ. ← ਤʹ "Eval / Apply" ͷଠۃਤ (Tao) ͕ඳ ͔Ε͍ͯΔͷʹ͝ɻ
·ͱΊ • LISP ߏจղੳ͕ඞཁͳ͍͔Βॲཧܥ࡞Γ͍͢ɻ • ڥϞσϧʹΑͬͯ੩తείʔϓΛ࣮ݱ͍ͯ͠Δɻ • Scheme શͳ੩తείʔϓͷΫϩʔδϟΛ࣋ͭ࠷ॳͷݴޠ ͱͯ͠ొͨ͠ɻ
• Scheme Ғେɻ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠