¤³¤³¤Þ¤Ç¤Î¤È¤³¤í¡¤¤³¤Î¸À¸ì¤Ë¤Ï¡¤¤¤¤¯¤Ä¤«¤Î¥×¥ê¥ß¥Æ¥£¥Ö´Ø¿ô(Æó¹à±é»»»Ò) ¤·¤«Ä󶡤µ¤ì¤Æ¤ª¤é¤º¡¤ML¥×¥í¥°¥é¥Þ¤¬(¥×¥ê¥ß¥Æ¥£¥Ö¤òÁȤ߹ç¤ï ¤»¤Æ)¿·¤·¤¤´Ø¿ô¤òÄêµÁ¤¹¤ë¤³¤È¤Ï¤Ç¤¤Ê¤«¤Ã¤¿¡¥ML3 ¤Ç¤Ï¡¤fun¼° ¤Ë¤è¤ë´Ø¿ôÃê¾Ý¤È¡¤´Ø¿ôŬÍѤòÄ󶡤¹¤ë¡¥
¤Þ¤º¤Ï¡¤ML3 ¤Î¼°¤Îʸˡ¤ò¼¨¤¹¡¥
|
¹½Ê¸¤Ë´Ø¤¹¤ë¥¤¥ó¥¿¥×¥ê¥¿¡¦¥×¥í¥°¥é¥à¤Ï¡¤¿Þ8¤Ë¼¨¤¹¡¥ ŬÍѼ°¤Ïº¸·ë¹ç¤Ç¡¤Â¾¤ÎÁ´¤Æ¤Î±é»»»Ò¤è¤ê¤â·ë¹ç¤¬¶¯¤¤¤È¤¹¤ë¡¥
syntax.ml:
type exp = ... | FunExp of id * exp | AppExp of exp * exp
parser.mly:
%token RARROW FUN Expr : ... | FunExpr { $1 } MExpr : MExpr MULT AppExpr { BinOp (Mult, $1, $3) } | AppExpr { $1 } AppExpr : AppExpr AExpr { AppExp ($1, $2) } | AExpr { $1 }
lexer.mll:
let reservedWords = [ ... ("fun", Parser.FUN); ... ] ... | "=" { Parser.EQ } | "->" { Parser.RARROW }
Figure 8: ´Ø¿ô¤ÈŬÍÑ(1)
¤µ¤Æ¡¤Objective Caml¤ÈƱÍÍ¡¤ML3 ¤Ë¤ª¤¤¤Æ¤â¡¤´Ø¿ô¤Ï¼°¤òɾ²Á¤·¤¿·ë²Ì¤È¤Ê ¤ë¤À¤±¤Ç¤Ê¤¯¡¤ÊÑ¿ô¤Î«ÇûÂоݤˤâ¤Ê¤ëÂè°ìµé¤ÎÃÍ(first-class value)¤È¤·¤Æ°·¤¦¡¥¤½¤Î¤¿¤á¡¤expressed value, denoted value ¤È¤â¤Ë ´Ø¿ôÃͤò²Ã¤¨¤Æ³ÈÄ¥¤¹¤ë¡¥
|
¤µ¤Æ¡¤´Ø¿ôÃͤò¤É¤Î¤è¤¦¤Ëɽ¸½¤¹¤ë¤«¤ò¹Í¤¨¤ë¡¥fun ¼°¤¬Å¬ÍѤµ¤ì¤¿»þ¤Ë¤Ï¡¤¥Ñ¥é¥á¡¼¥¿¤ò¼Â°ú¿ô(¤ÎÃÍ)¤Ë«Çû¤·¡¤´Ø¿ôËÜÂΤòɾ²Á ¤¹¤ë¤Î¤Ç¡¤¾¯¤Ê¤¯¤È¤â¥Ñ¥é¥á¡¼¥¿¤Î̾Á°¤È¡¤ËÜÂΤμ°¤Î¾ðÊó¤¬É¬ÍפǤ¢¤ë¡¥¤·¤«¤·¡¤ °ìÈÌŪ¤Ë¤Ï¡¤°Ê²¼¤ÎÎã¤Î¤è¤¦¤Ë¡¤´Ø¿ôËÜÂΤμ°¤Ë¥Ñ¥é¥á¡¼¥¿°Ê³°¤ÎÊÑ¿ô(¤Ä¤Þ ¤ê¼«Í³ÊÑ¿ô)¤¬½Ð¸½¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¢¤ë¡¥
let x = 2 in let addx = fun y → x + y in addx 4
x ¤ÎÀÅŪ«Çû¤ò¼Â¸½¤¹¤ë¤¿¤á¤Ë¤Ï¡¤¤³¤Î addx ¤ÎŬÍѤò¹Ô¤¦ºÝ¤Ë¤Ï ËÜÂÎÃæ¤Î x ¤¬ 2 ¤Ç¤¢¤ë¤³¤È¤òµÏ¿¤·¤Æ¤ª¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥ ¤È¤¤¤¦¤ï¤±¤Ç¡¤°ìÈÌŪ¤Ë´Ø¿ô¤¬Å¬ÍѤµ¤ì¤ë»þ¤Ë¤Ï¡¤
¤¬É¬Íפˤʤ롥¤³¤Î3¤Ä¤òÁȤˤ·¤¿¥Ç¡¼¥¿¤ò´Ø¿ôÊÄÊñ¡¦¥¯¥í¡¼¥¸¥ã(function closure) ¤È¸Æ¤Ó¡¤¤³¤ì¤ò´Ø¿ôÃͤȤ·¤ÆÍѤ¤¤ë¡¥¤³¤³¤ÇºîÀ®¤¹¤ë¥¤¥ó¥¿¥×¥ê ¥¿¤Ç¤Ï¡¤ËÜÂÎÃæ¤Î¼«Í³ÊÑ¿ô¤Î«Çû¾ðÊó¤È¤·¤Æ¡¤fun¼°¤¬É¾²Á¤µ¤ì¤¿»þÅÀ ¤Ç¤Î´Ä¶Á´ÂΤò»ÈÍѤ¹¤ë¡¥¤³¤ì¤Ï¡¤ËÜÂÎÃæ¤Ë¸½¤ì¤Ê¤¤ÊÑ¿ô¤Ë´Ø¤¹¤ë;·×¤Ê«Çû ¾ðÊó¤ò´Þ¤ó¤Ç¤¤¤ë¤¬¡¤¤â¤Ã¤È¤âñ½ã¤Ê´Ø¿ôÊÄÊñ¤Î¼Â¸½ÊýË¡¤Ç¤¢¤ë¡¥
°Ê¾å¤òƧ¤Þ¤¨¤¿ eval.ml ¤Ø¤Î¼ç¤ÊÊѹ¹ÅÀ¤Ï¿Þ9¤Î¤è¤¦¤Ë¤Ê¤ë¡¥ ¼°¤ÎÃͤˤϡ¤´Ä¶¤ò´Þ¤à¥Ç¡¼¥¿¤Ç¤¢¤ë´Ø¿ôÊÄÊñ¤¬´Þ¤Þ¤ì¤ë¤¿¤á¡¤exval ¤È dnval ¤ÎÄêµÁ¤¬(Áê¸ß)ºÆµ¢Åª¤Ë¤Ê¤ë¡¥´Ø¿ô ÃÍ¤Ï ProcV ¥³¥ó¥¹¥È¥é¥¯¥¿¤Çɽ¤µ¤ì¡¤¾å¤Ç½Ò¤Ù¤¿¤è¤¦¤Ë¡¤¥Ñ¥é¥á¡¼¥¿Ì¾¤Î ¥ê¥¹¥È¡¤ËÜÂΤμ°¤È´Ä¶¤ÎÁȤòÊÝ»ý¤¹¤ë¡¥eval_exp ¤Ç FunExp ¤ò½èÍý¤¹ ¤ë»þ¤Ë¤Ï¡¤¤½¤Î»þÅÀ¤Ç¤Î´Ä¶¡¤¤Ä¤Þ¤êenv ¤ò»È¤Ã¤Æ´Ø¿ôÊÄÊñ¤òºî¤Ã¤Æ¤¤¤ë¡¥ ŬÍѼ°¤Î½èÍý¤Ï¡¤Å¬ÍѤµ¤ì¤ë´Ø¿ô¤Îɾ²Á¡¤¼Â°ú¿ô¤Îɾ²Á¤ò¹Ô¤Ã¤¿¸å¡¤ËÜÅö¤ËŬ ÍѤµ¤ì¤Æ¤¤¤ë¼°¤¬´Ø¿ô¤«¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤ò¤·¤Æ¡¤ËÜÂΤÎɾ²Á¤ò¹Ô¤Ã¤Æ¤¤¤ë¡¥ ËÜÂΤÎɾ²Á¤ò¹Ô¤¦ºÝ¤Î´Ä¶ newenv ¤Ï¡¤´Ø¿ôÊÄÊñ¤Ë³ÊǼ¤µ¤ì¤Æ¤¤¤ë´Ä¶¤ò¡¤¥Ñ ¥é¥á¡¼¥¿¡¦¼Â°ú¿ô¤Ç³ÈÄ¥¤·¤ÆÆÀ¤Æ¤¤¤ë¡¥
eval.ml:
type exval = IntV of int | BoolV of bool | ProcV of id * exp * dnval Environment.t and dnval = exval let rec eval_exp env = function ... | FunExp (id, exp) -> ProcV (id, exp, env) | AppExp (exp1, exp2) -> let funval = eval_exp env exp1 in let arg = eval_exp env exp2 in (match funval with ProcV (id, body, env') -> let newenv = Environment.extend id arg env' in eval_exp newenv body | _ -> err ("Non-function value is applied"))
Figure 9: ´Ø¿ô¤ÈŬÍÑ(3)
let threetimes = fun f → fun x → f (f x x) (f x x) in threetimes (+) 5¤Ï¡¤20¤ò½ÐÎϤ¹¤ë¡¥
fun x1 ... xn → ... let f x1 ... xn = ...¤È¤¤¤Ã¤¿´ÊάµË¡¤ò¥µ¥Ý¡¼¥È¤»¤è¡¥
let makemult = fun maker → fun x → if x < 1 then 0 else 4 + maker maker (x + -1) in let times4 = fun x → makemult makemult x in times4 3
let a = 3 in let p = fun x → x + a in let a = 5 in a * p 2¤È¤¤¤¦¥×¥í¥°¥é¥à¤Ç¡¤´Ø¿ôpËÜÂÎÃæ¤Î a ¤Ï 3 ¤Ç¤Ï¤Ê¤¯ 5 ¤Ë«Çû¤µ¤ì¤ë¡¥¥¤¥ó¥¿¥×¥ê¥¿¤ò²þ¤¤·¡¤Æ°ÅªÂ«Çû¤ò ¼Â¸½¤»¤è¡¥
let fact = fun n → n + 1 in let fact = fun n → if n < 1 then 1 else n * fact (n + -1) in fact 5