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
68
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
67
Church Numerals
thermes
0
40
CPS & CTO
thermes
0
240
FM synthesis
thermes
0
33
A440
thermes
0
58
Inside mml2wav.rb
thermes
0
83
Clock / Timer
thermes
0
150
Hash Tree
thermes
0
73
POSIX Threads
thermes
0
53
Other Decks in Programming
See All in Programming
ポスターセッション: 「まっすぐ行って、右!」って言ってラズパイカーを動かしたい 〜生成AI × Raspberry Pi Pico × Gradioの試作メモ〜
komofr
0
1.3k
2分台で1500examples完走!爆速CIを支える環境構築術 - Kaigi on Rails 2025
falcon8823
3
3.6k
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
190
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
980
Devoxx BE - Local Development in the AI Era
kdubois
0
130
『毎日の移動』を支えるGoバックエンド内製開発
yutautsugi
2
240
CI_CD「健康診断」のススメ。現場でのボトルネック特定から、健康診断を通じた組織的な改善手法
teamlab
PRO
0
210
大規模アプリのDIフレームワーク刷新戦略 ~過去最大規模の並行開発を止めずにアプリ全体に導入するまで~
mot_techtalk
1
430
CSC509 Lecture 04
javiergs
PRO
0
300
Swift Concurrency - 状態監視の罠
objectiveaudio
2
510
オープンソースソフトウェアへの解像度🔬
utam0k
13
2.6k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
310
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
The Straight Up "How To Draw Better" Workshop
denniskardys
238
140k
Git: the NoSQL Database
bkeepers
PRO
431
66k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
860
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
61k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
RailsConf 2023
tenderlove
30
1.2k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Docker and Python
trallard
46
3.6k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Into the Great Unknown - MozCon
thekraken
40
2.1k
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 Ғେɻ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠