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
66
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
140
Hash Tree
thermes
0
72
POSIX Threads
thermes
0
53
Other Decks in Programming
See All in Programming
既存デザインを変更せずにタップ領域を広げる方法
tahia910
1
240
ReadMoreTextView
fornewid
1
480
プロダクト志向ってなんなんだろうね
righttouch
PRO
0
160
VS Code Update for GitHub Copilot
74th
1
340
Code as Context 〜 1にコードで 2にリンタ 34がなくて 5にルール? 〜
yodakeisuke
0
100
Create a website using Spatial Web
akkeylab
0
300
「ElixirでIoT!!」のこれまでとこれから
takasehideki
0
370
A2A プロトコルを試してみる
azukiazusa1
2
1.1k
Team operations that are not burdened by SRE
kazatohiei
1
200
DroidKnights 2025 - 다양한 스크롤 뷰에서의 영상 재생
gaeun5744
3
320
つよそうにふるまい、つよい成果を出すのなら、つよいのかもしれない
irof
1
300
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
300
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
92
6.1k
RailsConf 2023
tenderlove
30
1.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.4k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
4 Signs Your Business is Dying
shpigford
184
22k
Build The Right Thing And Hit Your Dates
maggiecrowley
36
2.8k
Done Done
chrislema
184
16k
The World Runs on Bad Software
bkeepers
PRO
69
11k
It's Worth the Effort
3n
185
28k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.3k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
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 Ғେɻ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠