ここまでのところ·この咐胳には·いくつかのプリミティブ簇眶(企灌遍换灰) しか捏丁されておらず·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