狠狠撸

狠狠撸Share a Scribd company logo
.
                       TaPL 読書会 #9 §14 Exception
.

                                A. Miyashita (@yaggy gcv)



                                        2012.11.21




    A. Miyashita (@yaggy gcv)      TaPL 読書会 #9   §14 Exception   2012.11.21   1 / 17
そうだ、例外を使おう


   プログラムで《例外》的な状況が発生することもある
           0 除算やオーバーフローが発生した
           辞書にないキーを参照しようとした
           配列のインデックス範囲エラー
           ファイルが見つからない、開けない
           ユーザがプロセスを kill したなど致命的なエラーが発生した
   これらを毎回ロジックで回避するのは困難。
   例外を導入すると…
           プログラムを中止する
           補足して回復を試みる
           例外の発生した情報を知る
   こんなことが出来る



 A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   2 / 17
復習 ~ 型「→」(1)

Syntax

                    t ::=                                              terms:
                              t                                      variable
                              λx:T.t                              abstraction
                              t t                                 application

                    v ::=                                              values:
                              λx:T.t                         abstraction value

                    T ::=                                               types:
                              T→T                            type of functions

                    Γ ::=                                           contexts:
                              ?                               empty context
                              Γ, x:T                    term variable binding



  A. Miyashita (@yaggy gcv)        TaPL 読書会 #9   §14 Exception                   2012.11.21   3 / 17
復習 ~ 型「→」 (2)
Evaluation                                                                  t → t′
                                   t1 → t′
                                         1
                                                               (E-App1)
                                t1 t2 → t′ t2
                                         1
                                   t2 → t′
                                         2
                                                               (E-App2)
                                v1 t2 → v1 t′2
              (λx:T11 .t12 ) v2 → [x → v2 ]t12               (E-AppAbs)

Typing                                                                    Γ ? t:T
                              x:T ∈ Γ
                                                                (T-Var)
                              Γ ? x:T
                         Γ, x:T1 ? t2 : T2
                                                                (T-Abs)
                     Γ ? λx:T1 .t2 : T1 → T2
              Γ ? t1 : T11 → T1 2      Γ ? t2 : T11
                                                                (T-App)
                         Γ ? t1 t2 : T12
  A. Miyashita (@yaggy gcv)    TaPL 読書会 #9   §14 Exception           2012.11.21   4 / 17
例外 ~ error の導入
New syntactic forms
                        t ::= ...                                     terms:

                              error                           run-time error




New evaluation rules                                                                   t → t′
                    error t2 → error                              (E-AppErr1)
                    v1 error → error                              (E-AppErr2)


New typing rules                                                                    Γ?t:T
                        Γ ? error : T                             (T-Error)

  A. Miyashita (@yaggy gcv)         TaPL 読書会 #9   §14 Exception                 2012.11.21   5 / 17
E-AppErr2 の評価に関する補足 (1)

例えば
                                       (λx : Nat.0)
は、
                       (λx : Nat.0) error → error(E-AppErr2)
と (一意に) 評価される。

   error は value ではないので、E-AppAbs

                                (λx : T.t)v ?→ [x → v ] t

   は適用できず、

                     (λx : Nat.0) error → [x → error](λx : Nat.0) → 0

   と評価される心配はない。



 A. Miyashita (@yaggy gcv)         TaPL 読書会 #9   §14 Exception          2012.11.21   6 / 17
E-AppErr2 の評価に関する補足 (2)




同様に、
                             (fix(λx : Nat.x)) error
は、左側の項が value になるまで評価できないので、無限に止まらない。




 A. Miyashita (@yaggy gcv)     TaPL 読書会 #9   §14 Exception   2012.11.21   7 / 17
error の型 (T-Error) に関する補足




T-Error の規則は、error が任意の型となることを意味するが、これは、
「たかだか 1 つの型しか持たない」という定理 (9.3.3) に反してしまう。
    error を最小型 Bot とする (§15, subtyping)
    error を多相型 ?X.X とする (§23, parametric polymorphism)




  A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   8 / 17
Preservation/Progress 則




    Preservation 則は例外導入後も変わらない
    ある項が型 T を持ち、1 段階評価された場合、評価後の型も
    T である。
    Progress は多少の変更が必要
    t が閉じた、良く型付けされた正規形であるとき、t は value
    もしくは t = error である (定理 14.1.2)




  A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   9 / 17
さて、停止はできるようになったが




止まるだけじゃ芸が無い

次に、例外を補足して、処理の回復を行うようにしたい。
→ お馴染み、try...with... 文 (Java/C++の try...catch...) を導入




  A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   10 / 17
例外処理 ~ try の導入
New syntactic forms
                     t ::= ...                                      terms:

                              try t with t                      trap errors



New evaluation rules                                                                  t → t′
                               try v1 with t2 → v1                      (E-TryV)
                   try error with t2 → t2                          (E-TryError)
                      t1 → t′
                            1
                                                                          (E-Try)
          try t1 with t2 → try t′ with t2
                                1

New typing rules                                                                   Γ?t:T
                   Γ ? t1 : T    Γ ? t2 : T
                                                                  (T-Try)
                    Γ ? try t1 with t2 : T

  A. Miyashita (@yaggy gcv)       TaPL 読書会 #9   §14 Exception                 2012.11.21   11 / 17
例外の詳細情報を寄越せと




「例外発生しました」って言われても一体どうすれば良いのか見当も付
かない

→ 例外に「例外が発生し状況」を値として持たせる




 A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   12 / 17
値を持つ例外 ~ raise の導入 (1)
.
New syntactic forms

               t ::= ...                                     terms:

                        raise t                      raise exception

                        try t with t               handle exceptions



New evaluation rules                                                         t → t′

                  (raise v11 ) t2 → raise v11             (E-AppRaise1)
                v1 (raise v21 ) → raise v21               (E-AppRaise2)
                            t1 → t′ 1
                                                               (E-Raise)
                      raise t1 → raise t′ 1
             raise (raise v11 ) → raise v11              (E-RaiseRaise)
                            try v1 with t2 → v1                (E-TryV)
           try raise v11 with t2 → t2 v11                  (E-TryRaise)
                     t1 → t′
                           1
                                                                   (E-Try)
         try t1 with t2 → try t′ with t2
                               1


    A. Miyashita (@yaggy gcv)        TaPL 読書会 #9   §14 Exception                      2012.11.21   13 / 17
値を持つ例外 ~ raise の導入 (2)



New typing rules                                                       Γ?t:T

                            Γ ? t1 : Texn
                                                             (T-Exn)
                          Γ ? raise t1 : T
               Γ ? t1 : T       Γ ? t2 : Texn → T
                                                             (T-Try)
                   Γ ? try t1 with t2 : T

※ error は raise unit の構文糖衣と見なして良い?




  A. Miyashita (@yaggy gcv)    TaPL 読書会 #9   §14 Exception        2012.11.21   14 / 17
Texn の型について (1)
 . Nat 型とする (例: Unix のエラーコード)
 1

   0: 成功、0 以外: 例外発生の状況を表す
   ないよりはマシだけど、ぶっちゃけ 500 エラーって言われても困る
 .
 2 String 型とする (エラーメッセージ)

       状況を把握するために構文解析が必要になることも
 . バリアント型 (Java/C++の enum に相当) にする
 3


                        Texn = <divideByZero :                    Unit,
                                 overflow :                       Unit,
                                 fileNotFound :                 String,
                                 fileNotReadable :              String,
                                 ... >
       このままでは、「あらかじめ」全ての集合を定義 (?x) しておかなけ
       ればならないので、開発者がアプリケーション独自の例外を定義す
       る余地がない。
     A. Miyashita (@yaggy gcv)    TaPL 読書会 #9   §14 Exception       2012.11.21   15 / 17
Texn の型について (2)


 4 ユーザー定義の例外を認める拡張バリアント型にする (例: ML の
   exn 型)
           exception l of T と定義 (ただし、l は今までに定義されている
           Texn に含まれてはいけない)
           すると以降は、Texn が < l1 : T1 , ..., ln : Tn , l:T > として再定義 (let)
           される
           例外を raise l(t) で呼び出す
                       def
           raise l(t)) = raise (l=t) as Texn
           try 構文
                              def
           try t with l(x)→ h = try t with
                                    λ e:Texn .case e of
                                                 <l=x>?h
                                               | ? raise e



 A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   16 / 17
Texn の型について (3)


 5 ユーザ定義例外クラス (例: Java の Throwable)
   ラフに言えば ML の拡張バリアント型と大体同じ。異なる点は、
           サブクラスの順序づけにより、半順序関係がある (例えば
           IOException で catch すると、IOException および、その全てのサ
           ブクラス (ex. FileNotFoundException) をも処理できる)
           回復の可否で例外クラスが区別される
           Throwable
            ├ Error: 回復不能 (処理は任意だが処理すべきでない)
            │ JVM などで発生する致命的なエラー
            └ Exception: 回復可能 (処理は必須)
               │ ロジックで回避するのが面倒な例外
               └ RuntimeException: 回復可能 (処理は任意)
                   プログラムのバグに起因する例外



 A. Miyashita (@yaggy gcv)   TaPL 読書会 #9   §14 Exception   2012.11.21   17 / 17

More Related Content

TaPL読書会 #9 ~ §14 Exception

  • 1. . TaPL 読書会 #9 §14 Exception . A. Miyashita (@yaggy gcv) 2012.11.21 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 1 / 17
  • 2. そうだ、例外を使おう プログラムで《例外》的な状況が発生することもある 0 除算やオーバーフローが発生した 辞書にないキーを参照しようとした 配列のインデックス範囲エラー ファイルが見つからない、開けない ユーザがプロセスを kill したなど致命的なエラーが発生した これらを毎回ロジックで回避するのは困難。 例外を導入すると… プログラムを中止する 補足して回復を試みる 例外の発生した情報を知る こんなことが出来る A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 2 / 17
  • 3. 復習 ~ 型「→」(1) Syntax t ::= terms: t variable λx:T.t abstraction t t application v ::= values: λx:T.t abstraction value T ::= types: T→T type of functions Γ ::= contexts: ? empty context Γ, x:T term variable binding A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 3 / 17
  • 4. 復習 ~ 型「→」 (2) Evaluation t → t′ t1 → t′ 1 (E-App1) t1 t2 → t′ t2 1 t2 → t′ 2 (E-App2) v1 t2 → v1 t′2 (λx:T11 .t12 ) v2 → [x → v2 ]t12 (E-AppAbs) Typing Γ ? t:T x:T ∈ Γ (T-Var) Γ ? x:T Γ, x:T1 ? t2 : T2 (T-Abs) Γ ? λx:T1 .t2 : T1 → T2 Γ ? t1 : T11 → T1 2 Γ ? t2 : T11 (T-App) Γ ? t1 t2 : T12 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 4 / 17
  • 5. 例外 ~ error の導入 New syntactic forms t ::= ... terms: error run-time error New evaluation rules t → t′ error t2 → error (E-AppErr1) v1 error → error (E-AppErr2) New typing rules Γ?t:T Γ ? error : T (T-Error) A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 5 / 17
  • 6. E-AppErr2 の評価に関する補足 (1) 例えば (λx : Nat.0) は、 (λx : Nat.0) error → error(E-AppErr2) と (一意に) 評価される。 error は value ではないので、E-AppAbs (λx : T.t)v ?→ [x → v ] t は適用できず、 (λx : Nat.0) error → [x → error](λx : Nat.0) → 0 と評価される心配はない。 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 6 / 17
  • 7. E-AppErr2 の評価に関する補足 (2) 同様に、 (fix(λx : Nat.x)) error は、左側の項が value になるまで評価できないので、無限に止まらない。 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 7 / 17
  • 8. error の型 (T-Error) に関する補足 T-Error の規則は、error が任意の型となることを意味するが、これは、 「たかだか 1 つの型しか持たない」という定理 (9.3.3) に反してしまう。 error を最小型 Bot とする (§15, subtyping) error を多相型 ?X.X とする (§23, parametric polymorphism) A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 8 / 17
  • 9. Preservation/Progress 則 Preservation 則は例外導入後も変わらない ある項が型 T を持ち、1 段階評価された場合、評価後の型も T である。 Progress は多少の変更が必要 t が閉じた、良く型付けされた正規形であるとき、t は value もしくは t = error である (定理 14.1.2) A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 9 / 17
  • 11. 例外処理 ~ try の導入 New syntactic forms t ::= ... terms: try t with t trap errors New evaluation rules t → t′ try v1 with t2 → v1 (E-TryV) try error with t2 → t2 (E-TryError) t1 → t′ 1 (E-Try) try t1 with t2 → try t′ with t2 1 New typing rules Γ?t:T Γ ? t1 : T Γ ? t2 : T (T-Try) Γ ? try t1 with t2 : T A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 11 / 17
  • 13. 値を持つ例外 ~ raise の導入 (1) . New syntactic forms t ::= ... terms: raise t raise exception try t with t handle exceptions New evaluation rules t → t′ (raise v11 ) t2 → raise v11 (E-AppRaise1) v1 (raise v21 ) → raise v21 (E-AppRaise2) t1 → t′ 1 (E-Raise) raise t1 → raise t′ 1 raise (raise v11 ) → raise v11 (E-RaiseRaise) try v1 with t2 → v1 (E-TryV) try raise v11 with t2 → t2 v11 (E-TryRaise) t1 → t′ 1 (E-Try) try t1 with t2 → try t′ with t2 1 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 13 / 17
  • 14. 値を持つ例外 ~ raise の導入 (2) New typing rules Γ?t:T Γ ? t1 : Texn (T-Exn) Γ ? raise t1 : T Γ ? t1 : T Γ ? t2 : Texn → T (T-Try) Γ ? try t1 with t2 : T ※ error は raise unit の構文糖衣と見なして良い? A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 14 / 17
  • 15. Texn の型について (1) . Nat 型とする (例: Unix のエラーコード) 1 0: 成功、0 以外: 例外発生の状況を表す ないよりはマシだけど、ぶっちゃけ 500 エラーって言われても困る . 2 String 型とする (エラーメッセージ) 状況を把握するために構文解析が必要になることも . バリアント型 (Java/C++の enum に相当) にする 3 Texn = <divideByZero : Unit, overflow : Unit, fileNotFound : String, fileNotReadable : String, ... > このままでは、「あらかじめ」全ての集合を定義 (?x) しておかなけ ればならないので、開発者がアプリケーション独自の例外を定義す る余地がない。 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 15 / 17
  • 16. Texn の型について (2) 4 ユーザー定義の例外を認める拡張バリアント型にする (例: ML の exn 型) exception l of T と定義 (ただし、l は今までに定義されている Texn に含まれてはいけない) すると以降は、Texn が < l1 : T1 , ..., ln : Tn , l:T > として再定義 (let) される 例外を raise l(t) で呼び出す def raise l(t)) = raise (l=t) as Texn try 構文 def try t with l(x)→ h = try t with λ e:Texn .case e of <l=x>?h | ? raise e A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 16 / 17
  • 17. Texn の型について (3) 5 ユーザ定義例外クラス (例: Java の Throwable) ラフに言えば ML の拡張バリアント型と大体同じ。異なる点は、 サブクラスの順序づけにより、半順序関係がある (例えば IOException で catch すると、IOException および、その全てのサ ブクラス (ex. FileNotFoundException) をも処理できる) 回復の可否で例外クラスが区別される Throwable ├ Error: 回復不能 (処理は任意だが処理すべきでない) │ JVM などで発生する致命的なエラー └ Exception: 回復可能 (処理は必須) │ ロジックで回避するのが面倒な例外 └ RuntimeException: 回復可能 (処理は任意) プログラムのバグに起因する例外 A. Miyashita (@yaggy gcv) TaPL 読書会 #9 §14 Exception 2012.11.21 17 / 17