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
150
Hash Tree
thermes
0
73
POSIX Threads
thermes
0
53
Other Decks in Programming
See All in Programming
Honoアップデート 2025年夏
yusukebe
1
920
Zendeskのチケットを Amazon Bedrockで 解析した
ryokosuge
3
280
Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行うためのSekibanの試行錯誤 / Sekiban: Exploring Efficient Development and Deployment with Microsoft Orleans and Dapr Actor Models
tomohisa
0
240
はじめてのMaterial3 Expressive
ym223
2
130
AIを活用し、今後に備えるための技術知識 / Basic Knowledge to Utilize AI
kishida
20
5.1k
為你自己學 Python - 冷知識篇
eddie
1
340
デザイナーが Androidエンジニアに 挑戦してみた
874wokiite
0
190
Tool Catalog Agent for Bedrock AgentCore Gateway
licux
6
2k
もうちょっといいRubyプロファイラを作りたい (2025)
osyoyu
0
340
Protocol Buffersの型を超えて拡張性を得る / Beyond Protocol Buffers Types Achieving Extensibility
linyows
0
110
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
430
Ruby×iOSアプリ開発 ~共に歩んだエコシステムの物語~
temoki
0
270
Featured
See All Featured
Optimizing for Happiness
mojombo
379
70k
Designing for Performance
lara
610
69k
Faster Mobile Websites
deanohume
309
31k
Documentation Writing (for coders)
carmenintech
74
5k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Being A Developer After 40
akosma
90
590k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
YesSQL, Process and Tooling at Scale
rocio
173
14k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Into the Great Unknown - MozCon
thekraken
40
2k
Designing Experiences People Love
moore
142
24k
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 Ғେɻ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠