Upgrade to Pro — share decks privately, control downloads, hide ads and more …

kontlang-shift-reset-lisp

 kontlang-shift-reset-lisp

「Kontlang - shift/resetのあるLisp あるいはインタプリタを継続渡しスタイルで書くと何が嬉しいのか」
限定継続を扱えるようにする言語機能shift/resetを持つLispインタプリタを実装した話。
インタプリタを継続渡しスタイルとdefunctionalizationを使って書くことで継続をより簡単に制御することができた。

zehnpaard

May 28, 2020
Tweet

More Decks by zehnpaard

Other Decks in Programming

Transcript

  1. ܧଓ w ʮ͋ΔܭࢉΛ࣮ߦͨͦ͠ͷޙΛද͢΋ͷʯ w ʮ͜Ε͔ΒߦΘΕΔͰ͋Ζ͏ܭࢉΛύοέʔδԽͨ͠΋ ͷʯ w ʮϓϩάϥϜͷ جຊతʹ͸τοϓϨϕϧʹ໭Δ·Ͱͷ 

    ࢒Γͷॲཧʯ ʮϞφυΛͭ͘Ζ͏ʯɹ!EJDP@MFRVFࢯ ʮͳΜͰ΋ܧଓʯɹ!BOPIBOBࢯ ʮ4DIFNFͱܧଓʯɹ!IBUTVHBJࢯ ϓϩάϥϛϯάͷੈքͷ֓೦ʹ͸ɺષͷެҊͷΑ͏ͳ΋ͷ͕͋Δɻ ͦΕΛઆ໌͢Δจষ͸΄ΜͷҰจͳͷʹɺ࠷ॳʹ໨ ʹ͢Δ࣌ɺ ͦͷจ͸શ͘ҙຯΛͳ͞ͳ͍ɺ҉߸ͷΑ͏ʹײ͡ΒΕΔɻ ͕ͩͻͱͨͼͦͷ֓೦Λཧղ͢Δͱɺ ͦͷ֓೦ ͷઆ໌͸͔֬ʹͦͷҰจͰઆ໌͞Ε͍ͯΔͷ͕Θ͔ΔͷͩɻɹʮͳΜͰ΋ܧଓʯɹ@anohanaࢯ https://www.slideshare.net/dico_leque/ss-14149810 http://practical-scheme.net/docs/cont-j.html http://lqtmirage.hatenablog.com/entry/2017/05/23/101744
  2. ܧଓ (+ 1 2 (* 3 4) (+ 5 6))

    ྫ͑͹͜Μͳ͕ࣜ͋Δͱͯ͠
  3. ܧଓ (+ 1 2 (* 3 4) (+ 5 6))

    ͜ͷ෦෼ࣜͷධՁΛߟ͑Δͱ
  4. ܧଓ (+ 1 2 X (+ 5 6))) (fn [X]

    ͦͷपғʹ͋Δ࢒Γͷ͕ࣜͦͷ ෦෼ࣜͷʮܧଓʯͱͳΔɻ ͜ͷΑ͏ͳؔ਺Ͱ  ͷܧଓ ͕දݱͰ͖Δ
  5. &P1-ͷݴޠબ୒ ϗετݴޠɿ3BDLFU ιʔεݴޠɿ.-ͬΆ͍ let rec even x = if zero?(x)

    then 1 else (odd -(x,1)) and odd x = if zero?(x) then 0 else (even -(x,1)) in odd 13 (define value-of (exp env) (cases expression exp (const-exp (num) (num-val num)) (var-exp (var) (apply-env env var)) (diff-exp (exp1 exp2) (let ((val1 (value-of exp1 env)) (val2 (value-of exp2 env))) (let ((num1 (expval->num val1)) (num2 (expval->num val2))) (num-val (- num1 num2))))) ...))
  6. ,POUMBOHͷݴޠબ୒ ϗετݴޠɿ0$BNM let rec eval env e = match e

    with | Exp.Int n -> Val.Int n | Exp.Var s -> Env.find env s | Exp.Call(e1, e2) -> let v1 = eval env e1 in let v2 = eval env e2 in call v1 v2 ... ιʔεݴޠɿ$MPKVSFͬΆ͍ (letfn [double [x] (* x 2)] (letrec [map [f xs] (if (nil? xs) nil (cons (f (car xs)) (map f (cdr xs))))] (map double (list 1 2 3 4 5))))
  7. ίʔυαϯϓϧ (letfn [double [x] (* x 2)] (letrec [map [f

    xs] (if (nil? xs) nil (cons (f (car xs)) (map f (cdr xs))))] (map double (list 1 2 3 4 5))))
  8. ࣜͱ஋ module Env = struct type t = (string *

    Val.t) list let rec find env s = match env with | [] -> failwith "Not found" | (s',v)::env' -> if s = s' then v else find env' s end let rec eval env e = match e with | Exp.Int n -> Val.Int n | Exp.Var s -> Env.find env s | Exp.Call(e1, e2) -> let v1 = eval env e1 in let v2 = eval env e2 in call v1 v2 module Exp = struct type t = | Int of int | Var of string | Call of t * t end module Val = struct type t = | Int of int | Op of string * (Val.t -> Val.t) end
  9. ී௨ͷΠϯλϓϦλ let rec eval env e = match e with

    | Exp.Int n -> Val.Int n | Exp.Var s -> Env.find env s | Exp.Call(e1, e2) -> let v1 = eval env e1 in let v2 = eval env e2 in call v1 v2
  10. ܧଓ౉͠ελΠϧ let rec eval env cont e = match e

    with | Exp.Int n -> cont (Val.Int n) | Exp.Var s -> cont (Env.find env s) | Exp.Call(e1, e2) -> let cont’ v = let cont’’ w = cont (call v w) in eval env cont’’ e2 in eval env cont’ e1
  11. %FGVODUJPOBMJ[BUJPO let rec eval env cont e = match e

    with | Exp.Int n -> apply_cont env cont (Val.Int n) | Exp.Var s -> apply_cont env cont (Env.find env s) | Exp.Call(e1, e2) -> eval env (Cont.Call1(e2)::cont) e1 and apply_cont env cont v = match cont with | [] -> v | Cont.Call1(e)::cont' -> eval env (Cont.Call2(v)::cont') e | Cont.Call2(v')::cont' -> apply_cont env cont' (call v' v) module Cont = struct type t' = | Call1 of Exp.t | Call2 of Val.t type t = t' list end
  12. τϥϯϙϦϯԽ let eval env cont e = match e with

    | Exp.Int n -> Res.ApplyCont(env, cont, Val.Int n) | Exp.Var s -> Res.ApplyCont(env, cont, Env.find env s) | Exp.Call(e1, e2) -> Res.Eval(env, Cont.Call1(e2)::cont, e1) let apply_cont env cont v = match cont with | [] -> Res.Done v | Cont.Call1(e)::cont' -> Res.Eval(env, Cont.Call2(v)::cont', e) | Cont.Call2(v')::cont' -> Res.ApplyCont(env, cont', call v' v) let rec trampoline r = match r with | Res.Done v -> v | Res.Eval(env, cont, e) -> trampoline (eval env cont e) | Res.ApplyCont(env, cont, v) -> trampoline (apply_cont env cont v) module Res = struct type t = | Done of Val.t | Eval of Env.t * Cont.t * Exp.t | ApplyCont of Env.t * Cont.t * Val.t end
  13. εςοϓ࣮ߦ ௨ৗͷΠϯλϓϦλͱ͸ผʹɺεςοϓ͝ͱʹΠϯλϓϦλ ͷঢ়ଶΛදࣔ͢ΔTUFQXJTFΠϯλϓϦλ͕͋Δ let rec trampoline’ r = match r

    with | Res.Done v -> v | Res.Eval(env, cont, e) -> pause_and_display r; trampoline (eval env cont e) | Res.ApplyCont(env, cont, v) -> pause_and_display r; trampoline (apply_cont env cont v)
  14. ຤ඌݺͼग़͠࠷దԽ ຤ඌ࠶ؼ (letrec [f [acc xs] (if (nil? xs) acc

    (f (+ acc (car xs)) (cdr xs)))] (f 0 (list 1 2 3))) ඇ຤ඌ࠶ؼ (letrec [f [xs] (if (nil? xs) 0 (+ (car xs) (f (cdr xs))))] (f (list 1 2 3))) w φΠʔϒͳ࣮૷ͩͱ຤ඌ࠶ؼͰ΋࠶ ؼ͢Δ͝ͱʹܧଓελοΫɺม਺ε λοΫͱ΋ʹੵΈ্͕ͬͯ͠·͏ w ؔ਺͕຤ඌݺͼग़͠ͷܗʹͳͬͯ ͍Δ৔߹ɺؔ਺ద༻ͷ࣌఺Ͱܧଓ ελοΫͷઌ಄ʹ$POU&OW͕ࡌͬ ͍ͯΔɻͦΕʹରԠ͢Δม਺؀ڥ ͱͱ΋ʹελοΫ͔Β֎ͯ͠΍Δͩ ͚Ͱ຤ඌݺͼग़͠࠷దԽ͕࣮૷Ͱ ͖Δ