つくって学ぶプログラミング言語 RubyによるScheme処理系の実装

Similar documents
(CC Attribution) Lisp 2.1 (Gauche )

r3.dvi

r3.dvi

1. A0 A B A0 A : A1,...,A5 B : B1,...,B

¥×¥í¥°¥é¥ß¥ó¥°±é½¬I Exercise on Programming I [1zh] ` `%%%`#`&12_`__~~~ alse


Parametric Polymorphism

parser.y 3. node.rb 4. CD-ROM

Jacques Garrigue


1. A0 A B A0 A : A1,...,A5 B : B1,...,B

haskell.gby

Microsoft PowerPoint - IntroAlgDs-06-8.ppt

Ruby Ruby ruby Ruby G: Ruby>ruby Ks sample1.rb G: Ruby> irb (interactive Ruby) G: Ruby>irb -Ks irb(main):001:0> print( ) 44=>

SCM (v0201) ( ) SCM 2 SCM 3 SCM SCM 2.1 SCM SCM SCM (1) MS-DOS (2) Microsoft(R) Windows 95 (C)Copyright Microsoft Corp

51 Lego MindStorms Lisp XS Lego MindStorms 8 CPU RCX RCX Lisp XS XS RCX PC Scheme Lego MindStorms is a robot development kit which makes it possible t

6-1

r1.dvi

BASIC / / BA- SIC Web 1/10 1/10 / / JavaScript

listings-ext

¥×¥í¥°¥é¥ß¥ó¥°±é½¬I Exercise on Programming I [1zh] ` `%%%`#`&12_`__~~~ alse

VDM-SL VDM VDM-SL Toolbox VDM++ Toolbox 1 VDM-SL VDM++ Web bool

( ) ( ) lex LL(1) LL(1)

r2.dvi

# let rec sigma (f, n) = # if n = 0 then 0 else f n + sigma (f, n-1);; val sigma : (int -> int) * int -> int = <fun> sigma f n ( : * -> * ) sqsum cbsu

org/ghc/ Windows Linux RPM 3.2 GHCi GHC gcc javac ghc GHCi(ghci) GHCi Prelude> GHCi :load file :l file :also file :a file :reload :r :type expr :t exp

untitled

Microsoft PowerPoint - IntroAlgDs-05-7.ppt

Microsoft PowerPoint - IntroAlgDs-05-2.ppt

provider_020524_2.PDF

4 (induction) (mathematical induction) P P(0) P(x) P(x+1) n P(n) 4.1 (inductive definition) A A (basis ) ( ) A (induction step ) A A (closure ) A clos

Microsoft PowerPoint Lisp.ppt [互換モード]

: gettoken(1) module P = Printf exception End_of_system (* *) let _ISTREAM = ref stdin let ch = ref ( ) let read () = (let c =!ch in ch := inp

109 i Lisp KVM Java VM Lisp Java Lisp JAKLD KVM Lisp JAKLD Java Lisp KVM API We present a Lisp system that can be downloaded to and used on mobile pho


ld-2.dvi

jssst-ocaml.mgp

生活設計レジメ

44 4 I (1) ( ) (10 15 ) ( 17 ) ( 3 1 ) (2)

I II III 28 29


「プログラミング言語」 SICP 第4章 ~超言語的抽象~ その6

r9.dvi

Emacs ML let start ::= exp (1) exp ::= (2) fn id exp (3) ::= (4) (5) ::= id (6) const (7) (exp) (8) let val id = exp in


Microsoft PowerPoint - 13Kadai.pptx

ML Edinburgh LCF ML Curry-Howard ML ( ) ( ) ( ) ( ) 1

ohp1.dvi

2 Mar Java (2) Java 3 Java (1) Java 19),20) Scheme Java car public static void Lcar(BCI bci) { Object x = bci.vs[bci.vsbase + 1]; if (!(x instan

AccessflÌfl—−ÇŠš1

lifedesign_contest_No3

連立1次方程式Ax=bの解法:公式にしたがって解くのは,計算量大

¥×¥í¥°¥é¥ß¥ó¥°±é½¬I Exercise on Programming I [1zh] ` `%%%`#`&12_`__~~~ alse

ex01.dvi


Ruby 50 Ruby UTF print, \n [Ruby-1] print("hello, Ruby.\n") [Ruby-2] Hello, Ruby. [Ruby-3] print("hello, \"Ruby\".\n") 2 [Ruby-4] seisuu = 10 pr

2

jakld-lecture13.pptx

test.gby

ohp07.dvi

syspro-0405.ppt

untitled

C言語によるアルゴリズムとデータ構造

=

Emacs Ruby..

6 (1) app.html.eex 28 lib/nano_planner_web/templates/layout/app.html.eex 27 <footer> Oiax Inc <%= this_year() %> Oiax Inc. 29 </footer>

( ) ( ) ( ) 2

comp -MYPEDIA Programing- Ruby 1 attr_accessor :< 1>, :< 2> class Car def = carname end attr_accessor :name end car = Car.ne

Microsoft PowerPoint - 11RubyIntro-No02.ppt [互換モード]

() / (front end) (back end) (phase) (pass) 1 2

JavaScript 1.! DOM Ajax Shelley Powers,, JavaScript David Flanagan, JavaScript 2

10 (1) s 10.2 rails c Rails 7 > item = PlanItem.new => #<PlanItem id nil, name nil,...> > item.name = "" => "" > item.valid? => true valid? true false

# let st1 = {name = "Taro Yamada"; id = };; val st1 : student = {name="taro Yamada"; id=123456} { 1 = 1 ;...; n = n } # let string_of_student {n

2

exec.dvi

ML λ λ 1 λ 1.1 λ λ λ e (λ ) ::= x ( ) λx.e (λ ) e 1 e 2 ( ) ML λx.e Objective Caml fun x -> e x e let 1

i


Wide Scanner TWAIN Source ユーザーズガイド

bdd.gby

Microsoft PowerPoint - 2-LispProgramming-full

untitled

「計算と論理」 Software Foundations その4

プログラミングD - Java

所報

¥¤¥ó¥¿¡¼¥Í¥Ã¥È·×¬¤È¥Ç¡¼¥¿²òÀÏ Âè2²ó

fp.gby

soto44_kosei_03.pdf


aichi_1_24_b

javascript key

第1部 一般的コメント

( ) [2] H 4 4! H 4 4! (5 4 3 )= = Fortran C 0 #include <stdio.h> 1 #include

3 Powered by mod_perl, Apache & MySQL use Item; my $item = Item->new( id => 1, name => ' ', price => 1200,

untitled

表1票4.qx4

福祉行財政と福祉計画[第3版]

第1章 国民年金における無年金

shift/reset [13] 2 shift / reset shift reset k call/cc reset shift k shift (...) k 1 + shift(fun k -> 2 * (k 3)) k 2 * (1 + 3) 8 reset shift reset (..

Transcription:

Ruby Scheme 2013-04-16

( )! SICP *1 ;-) SchemeR SICP MIT * 1 Structure and Interpretaion of Computer Programs 2nd ed.: 2 i

SchemeR Ruby Ruby Ruby Ruby & 3.0 Ruby ii

https://github.com/ichusrlocalbin/scheme_in_ruby 3.0 (http://creativecommons.org/ licenses/by/3.0/deed.ja) iii

i 1 1 1.1.................................. 1 1.2............................... 1 1.3........................................... 5 2 7 2.1............................................. 7 2.2 let............................................ 10 2.3......................................... 10 2.4 (eval) (apply)............................... 13 2.5.................................. 13 2.6........................................... 14 3 15 3.1........................................... 15 3.2............................................. 17 3.3?............................. 19 3.4 for?........................... 20 3.5........................................... 20 4 21 4.1........................................... 21 4.2............................................. 22 4.3 cond........................................... 24 4.4.......................................... 24 4.5 quote............................................ 25 4.6 REPL............................................ 26 4.7........................................... 28 4.8........................................... 28 iv

5 29 5.1 Scheme in SchemeR.......................... 29 5.2 SICP.................................... 30 5.3.................................... 31 32 v

1 1.1 *1 Ruby 1.2 [:+, 1, 2] SchemeR( ) * 1 (operetional semantics) 1

1 1.2 1 2 1 2 :+ 2 [:+, [:+, 1, 2], 3] [:+, 1, 2] 3 2 :+ (evaluation) :+ 2 : SchemeR SchemeR [:+, 1, 2] x + y * z (x + y) * z x + (y * z) if [:if, :true, 1, 0] [ :if if (true) then 1 else 2; x = y + 1; ( / ) ( ), [ ] Ruby + x if : :+ :x :if Ruby Ruby _eval *2 exp * 2 eval _eval Ruby eval Ruby module _eval eval 4 parse eval Kernel::eval 2

1 1.2 (apply) _eval *3 2 2 (Ruby ) def _eval(exp) if not list?(exp) if immediate_val?(exp) exp else lookup_primitive_fun(exp) else fun = _eval(car(exp)) args = eval_list(cdr(exp)) apply(fun, args) 2 2? 2 ( SchemeR) 2 (Ruby ) 2 1.1 Ruby def list?(exp) exp.is_a?(array) Ruby def lookup_primitive_fun(exp) $primitive_fun_env[exp] $primitive_fun_env = { :+ => [:prim, lambda{ x, y x + y}], * 3 Ruby return < > 3

1 1.2 } :- => [:prim, lambda{ x, y x - y}], :* => [:prim, lambda{ x, y x * y}], car cdr *4 Scheme def car(list) list[0] def cdr(list) list[1..-1] eval_list def eval_list(exp) exp.map{ e _eval(e)} def immediate_val?(exp) num?(exp) def num?(exp) exp.is_a?(numeric) (Ruby ) (Ruby ) fun_val.call(*args) fun_val Ruby args * args [1, 2] fun_val.call(1, 2) args [1, 2, 3] fun_val.call(1, 2, 3) def apply(fun, args) apply_primitive_fun(fun, args) def apply_primitive_fun(fun, args) fun_val = fun[1] fun_val.call(*args) [:+, 1, 2] 1.1 :+ lambda{ x, y x + y} * 4 car Contents of the Address part of Register cdr Contents of the Decrement part of Register cons CONStruct Lisp IBM 4

1 1.3 (Ruby ) 1, 2 (Ruby )1, 2 (Ruby ) 3 puts Ruby *5 1.1 SchemeR Ruby puts _eval([:+, 1, 2]) 3 [:+, [:+, 1, 2], 3] _eval 1.3 ( ) ( Ruby ) * 5 SchemeR 5

1 1.3 x = y; 6

2 :+ 2 [[:lambda, [:x, :y], [:+, :x, :y]], 3, 2] Ruby def add(x, y) x + y add(3, 2) 3 2 [:lambda, parameters, body ] parameters body :+ 3, 2 x, y 2.1 [[:lambda, [:x], [:+, [[:lambda, [:x], :x], 2], :x]], 1] 7

2 2.1 :lambda :x 1 :+ :+ 3 :lambda :x 2 2 4 :x :x 1 :x 2 2+2 4 ( 2.1) 2.1 x : :x 1 :x 1 ( ) (bind variable to value) Ruby h = {x:1} 1 x 1 x h[:x] SchemeR :x 1 :x :y [[:lambda, [:x], [:+, [[:lambda, [:y], :y], 2], :x]], 1] 3 8

2 2.1 :x 1 4 :lambda :x :lambda :x :lambda :x 2 :x 1 :lambda :x 1 :lambda :x 2 :x 1 ( 2.2 *1 ) 2.2 {x:1, y:2} x 1 y 2 [{x:1, y:2}, {x:3}] :lambda [{x:1}] :lambda [{x:2}, {x:1}] :lambda [{x:1}] Ruby lookup_var def lookup_var(var, env) alist = env.find{ alist alist.key?(var)} if alist == nil raise "couldn't find value to variables:'#{var}'" alist[var] * 1 {x:1} 9

2 2.2 let def ext_env(parameters, args, env) alist = parameters.zip(args) h = Hash.new alist.each { k, v h[k] = v } [h] + env 2.2 let let [:let, [[:x, 3], [:y, 2]], [:+, :x, :y]] :x 3 :y 2 [:+, :x, :y] let let [[:lambda, [:x, :y], [:+, :x, :y]], 3, 2] let def eval_let(exp, env) parameters, args, body = let_to_parameters_args_body(exp) new_exp = [[:lambda, parameters, body]] + args _eval(new_exp, env) let def let_to_parameters_args_body(exp) [exp[1].map{ e e[0]}, exp[1].map{ e e[1]}, exp[2]] let def let?(exp) exp[0] == :let 2.3 let 10

2 2.3 [:let, [[:x, 2]], [:let, [[:fun, [:lambda, [], :x]]], [:let, [[:x, 1]], [:fun]]]] let :x 2 :fun :x :x 1 :fun :x :fun ( :x 1 ) ( :x 2 ) (!) 2 *2 2 ([lambda() x, [{x:2}]]) :fun :x 1 [{x:1}, {x:2}] :fun [{x:2}] x 2 ( ) Ruby def eval_lambda(exp, env) make_closure(exp, env) def make_closure(exp, env) parameters, body = exp[1], exp[2] [:closure, parameters, body, env] def lambda_apply(closure, args) parameters, body, env = closure_to_parameters_body_env(closure) new_env = ext_env(parameters, args, env) _eval(body, new_env) * 2 1 11

2 2.3 def closure_to_parameters_body_env(closure) [closure[1], closure[2], closure[3]] _eval let apply def _eval(exp, env) if not list?(exp) if immediate_val?(exp) exp else lookup_var(exp, env) 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) def special_form?(exp) lambda?(exp) or let?(exp) def lambda?(exp) exp[0] == :lambda def eval_special_form(exp, env) if lambda?(exp) eval_lambda(exp, env) elsif let?(exp) eval_let(exp, env) def eval_list(exp, env) exp.map{ e _eval(e, env)} def apply(fun, args) if primitive_fun?(fun) apply_primitive_fun(fun, args) else lambda_apply(fun, args) 12

2 2.4 (eval) (apply) def primitive_fun?(exp) exp[0] == :prim lookup_var $global_env = [$primitive_fun_env] exp = [[:lambda, [:x, :y], [:+, :x, :y]], 3, 2] puts _eval(exp, $global_env) [:let, [[:x, 3]], [:let, [[:fun, [:lambda, [:y], [:+, :x, :y]]]], [:+, [:fun, 1], [:fun, 2]]]] :fun :x *3 2.4 (eval) (apply) (eval) (apply) 2.5 ( ) FORTRAN * 3 5 13

2 2.6 *4 2.6 * 4 14

3 [:letrec, [[:fact, [:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]]], [:fact, 3]] SchemeR 3.1 if [:if, [:>, 3, 2], 1, 0] if if : if? if special form x 1 set! ( 5 ) x 4 [:if, :false, [:set!, :x, [:+, :x, 1], [:set!, :x, [:+, :x, 2]] if ( letrec ) 15

3 3.1 def special_form?(exp) lambda?(exp) or let?(exp) or letrec?(exp) or if?(exp) def eval_special_form(exp, env) if lambda?(exp) eval_lambda(exp, env) elsif let?(exp) eval_let(exp, env) elsif letrec?(exp) eval_letrec(exp, env) elsif if?(exp) eval_if(exp, env) def eval_if(exp, env) cond, true_clause, false_clause = if_to_cond_true_false(exp) if _eval(cond, env) _eval(true_clause, env) else _eval(false_clause, env) def if_to_cond_true_false(exp) [exp[1], exp[2], exp[3]] def if?(exp) exp[0] == :if if :true, :false (Ruby )true, false $boolean_env = {:true => true, :false => false} $global_env = [$primitive_fun_env, $boolean_env] $primitive_fun_env = { :+ => [:prim, lambda{ x, y x + y}], :- => [:prim, lambda{ x, y x - y}], :* => [:prim, lambda{ x, y x * y}], :> => [:prim, lambda{ x, y x > y}], :>= => [:prim, lambda{ x, y x >= y}], :< => [:prim, lambda{ x, y x < y}], 16

3 3.2 :<= => [:prim, lambda{ x, y x <= y}], :== => [:prim, lambda{ x, y x == y}], } $global_env = [$primitive_fun_env, $boolean_env] 3.2 [:let, [[:fact, [:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]]], [:fact, 0]] 1 [:let, [[:fact, [:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]]], [:fact, 1]] :let :fact :fact [:fact 1] if :fact :fact ( 3.1) let 3.1 [:fact 1] fact fact [:fact 1] fact :lambda :fact :fact :fact ( :fact) ( 3.2(a)) 17

3 3.2 ( 3.2(b)) letrec [:fact, 1] ( 3.2(c)) :fact 3.2 (a) fact dummy (b) fact (c)[:fact 1] fact letrec def eval_letrec(exp, env) parameters, args, body = letrec_to_parameters_args_body(exp) tmp_env = Hash.new parameters.each do parameter tmp_env[parameter] = :dummy ext_env = ext_env(tmp_env.keys(), tmp_env.values(), env) args_val = eval_list(args, ext_env) set_ext_env!(parameters, args_val, ext_env) new_exp = [[:lambda, parameters, body]] + args _eval(new_exp, ext_env) def set_ext_env!(parameters, args_val, ext_env) parameters.zip(args_val).each do parameter, arg_val ext_env[0][parameter] = arg_val 18

3 3.3? def letrec_to_parameters_args_body(exp) let_to_parameters_args_body(exp) def letrec?(exp) exp[0] == :letrec exp = [:letrec, [[:fact, [:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]]], [:fact, 3]] puts _eval(exp, $global_env) 6 3.3? (pure functional language) Ruby set_ext_env! *1 let (Ruby let ) * 1! quote Scheme! 19

3 3.4 for? 3.4 for? for eval_let eval fact 0 +1 0 4.1 ( length ) 3.5 SchemeR 20

4 4.1 *1 Scheme Ruby null? :nil def null?(list) list == [] $list_env = { :nil => [], :null? => [:prim, lambda{ list null?(list)}], :cons => [:prim, lambda{ a, b cons(a, b)}], :car => [:prim, lambda{ list car(list)}], :cdr => [:prim, lambda{ list cdr(list)}], :list => [:prim, lambda{ *list list(*list)}], } $global_env = [$list_env, $primitive_fun_env, $boolean_env] cons def cons(a, b) if not list?(b) * 1 Scheme Lisp List Processing 21

4 4.2 raise "sorry, we haven't implemented yet..." else [a] + b ( )car cdr def car(list) list[0] def cdr(list) list[1..-1] list Ruby def list(*list) list 4.2 [:define, :id, [:lambda, [:x], :x]] :id [:id, 3] 3 [:define, [:id, :x], :x] (! ) 22

4 4.2 def eval_define(exp, env) if define_with_parameter?(exp) var, val = define_with_parameter_var_val(exp) else var, val = define_var_val(exp) var_ref = lookup_var_ref(var, env) if var_ref!= nil var_ref[var] = _eval(val, env) else ext_env!([var], [_eval(val, env)], env) nil def ext_env!(parameters, args, env) alist = parameters.zip(args) h = Hash.new alist.each { k, v h[k] = v } env.unshift(h) def define_with_parameter?(exp) list?(exp[1]) def define_with_parameter_var_val(exp) var = car(exp[1]) parameters, body = cdr(exp[1]), exp[2] val = [:lambda, parameters, body] [var, val] def define_var_val(exp) [exp[1], exp[2]] def lookup_var_ref(var, env) env.find{ alist alist.key?(var)} def define?(exp) exp[0] == :define *2 [:define, [:length, :list], [:if, [:null?, :list], 0, [:+, [:length, [:cdr, :list]], 1]]] * 2 4.5 special_form? eval_special_form 23

4 4.3 cond [:length, [:list, 1, 2]] 4.3 cond if if cond [:cond, [[:>, 1, 1], 1], [[:>, 2, 1], 2], [[:>, 3, 1], 3], [:else, -1]] cond :else 2 if def eval_cond(exp, env) if_exp = cond_to_if(cdr(exp)) eval_if(if_exp, env) def cond_to_if(cond_exp) if cond_exp == [] '' else e = car(cond_exp) p, c = e[0], e[1] if p == :else p = :true [:if, p, c, cond_to_if(cdr(cond_exp))] def cond?(exp) exp[0] == :cond 4.4 Ruby Ruby Ruby Lisp Scheme 24

4 4.5 quote () Scheme Ruby [], Ruby () Scheme _eval(parse('(define (length list) (if (null?, list) 0 (+ (length (cdr list)) 1)))'), $global_env) puts _eval(parse('(length (list 1 2 3))'), $global_env) ( ) [ ] Ruby :, def parse(exp) program = exp.strip(). gsub(/[a-za-z\+\-\*><=][0-9a-za-z\+\-=!*]*/, ':\\0'). gsub(/\s+/, ', '). gsub(/\(/, '['). gsub(/\)/, ']') eval(program) 4.5 quote quote puts _eval(parse('(length (quote (1 2 3)))'), $global_env) quote *3 quote def eval_quote(exp, env) car(cdr(exp)) def quote?(exp) exp[0] == :quote * 3 quote (quote 1 2 3) (1 2 3) quote Ruby 1.9 25

4 4.6 REPL def special_form?(exp) lambda?(exp) or let?(exp) or letrec?(exp) or if?(exp) or cond?(exp) or define?(exp) or quote?(exp) def eval_special_form(exp, env) if lambda?(exp) eval_lambda(exp, env) elsif let?(exp) eval_let(exp, env) elsif letrec?(exp) eval_letrec(exp, env) elsif if?(exp) eval_if(exp, env) elsif cond?(exp) eval_cond(exp, env) elsif define?(exp) eval_define(exp, env) elsif quote?(exp) eval_quote(exp, env) 4.6 REPL (Read) (Eval) (Print) (Loop) REPL pp *4 def repl prompt = '>>> ' second_prompt = '> ' while true print prompt line = gets or return while line.count('(') > line.count(')') print second_prompt next_line = gets or return line += next_line * 4 pretty print 26

4 4.6 REPL redo if line =~ /\A\s*\z/m begin val = _eval(parse(line), $global_env) rescue Exception => e puts e.to_s redo puts pp(val) def closure?(exp) exp[0] == :closure def pp(exp) if exp.is_a?(symbol) or num?(exp) exp.to_s elsif exp == nil 'nil' elsif exp.is_a?(array) and closure?(exp) parameter, body, env = exp[1], exp[2], exp[3] "(closure #{pp(parameter)} #{pp(body)})" elsif exp.is_a?(array) and lambda?(exp) parameters, body = exp[1], exp[2] "(lambda #{pp(parameters)} #{pp(body)})" elsif exp.is_a?(hash) if exp == $primitive_fun_env '*prinmitive_fun_env*' elsif exp == $boolean_env '*boolean_env*' elsif exp == $list_env '*list_env*' else '{' + exp.map{ k, v pp(k) + ':' + pp(v)}.join(', ') + '}' elsif exp.is_a?(array) '(' + exp.map{ e pp(e)}.join(', ') + ')' else exp.to_s >> repl >>> (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) nil >>> (fib 10) 55 27

4 4.7 4.7 named let let* Haskell 4.8 define cond quote REPL 28

5 5.1 Scheme in SchemeR Ruby Scheme Ruby Scheme Scheme SchemeR Ruby SchemeR ( Ruby )Scheme Scheme SchemeR Ruby 2 letrec define :set! define special_form? eval_special_form def eval_set!(exp, env) var, val = setq_to_var_val(exp) var_ref = lookup_var_ref(var, env) if var_ref!= nil var_ref[var] = _eval(val, env) else raise "undefined variable:'#{var}'" nil def setq_to_var_val(exp) [exp[1], exp[2]] def setq?(exp) exp[0] == :setq 29

5 5.2 SICP (let ((x 1)) (let ((dummy (set! x 2))) x)) 2 : (define (makecounter) (let ((count 0)) (lambda () (let ((dummy (set! count (+ count 1)))) count)))) (define inc (makecounter)) (inc) (inc) makecounter makecounter inc count 1 count inc makecounter inc count 5.2 SICP SICP Structure and Interpretaion of Computer Programs 2nd ed. ( 2 [1] ) SchemeR SICP Scheme 30

5 5.3 5.3 ( )? I-expression *1 Python? define (fact x) if (= x 0) 1 * x fact (- x 1) URL I-Expression SchemeR SchemeR I-expression Scheme * 1 http://srfi.schemers.org/srfi-49/srfi-49.html 31

[1],,2000 32

Ruby Scheme 2013 4 16 v1.0.0 (C) 2013 Masahiro Watanabe