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
32
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
Zendeskのチケットを Amazon Bedrockで 解析した
ryokosuge
3
300
250830 IaCの選定~AWS SAMのLambdaをECSに乗り換えたときの備忘録~
east_takumi
0
390
GitHubとGitLabとAWS CodePipelineでCI/CDを組み比べてみた
satoshi256kbyte
4
220
時間軸から考えるTerraformを使う理由と留意点
fufuhu
15
4.7k
モバイルアプリからWebへの横展開を加速した話_Claude_Code_実践術.pdf
kazuyasakamoto
0
320
「待たせ上手」なスケルトンスクリーン、 そのUXの裏側
teamlab
PRO
0
500
「手軽で便利」に潜む罠。 Popover API を WCAG 2.2の視点で安全に使うには
taitotnk
0
850
2025 年のコーディングエージェントの現在地とエンジニアの仕事の変化について
azukiazusa1
24
12k
さようなら Date。 ようこそTemporal! 3年間先行利用して得られた知見の共有
8beeeaaat
3
1.4k
MCPとデザインシステムに立脚したデザインと実装の融合
yukukotani
4
1.4k
CJK and Unicode From a PHP Committer
youkidearitai
PRO
0
110
MCPで実現するAIエージェント駆動のNext.jsアプリデバッグ手法
nyatinte
7
1.1k
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Building an army of robots
kneath
306
46k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.1k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Thoughts on Productivity
jonyablonski
70
4.8k
Faster Mobile Websites
deanohume
309
31k
Docker and Python
trallard
45
3.6k
It's Worth the Effort
3n
187
28k
Speed Design
sergeychernyshev
32
1.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 Ғେɻ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠