僕は素人なので、Lisp処理系作ったらとりあえずYコンビネータ動かしてみたくなる。ってことで、scallopでもやろうとして、間違って次のようなコードを評価してしまった。
(define Y (lambda (f) ((lambda (g) (g g)) (lambda (g) (f (lambda (x) ((g g) x))))))) (Y Y)
これは評価が停止しないはずだけど、segmentation faultで異常終了してしまった。調べてみると、投げられたStackOverflowExceptionが捕捉されていない。
一番外側のevalをtry-catchしてるにも関わらず捕捉されないので悩んでいたら、StackOverflowExceptionはtry-catchでは捕捉できないそうだ*1。
scallop - チキン煮込みチーズミックス4辛で書いたとおり、Lispの手続きに対応するC#のメソッドを単に実行しているだけなので、必然的にこうなってしまうのかな。
以下のようなコードで実験してみた。結果はこちら→http://ideone.com/ij9BM
using System; namespace EternalCall { class Program { static void Main(string[] args) { try { Func(); } catch (System.OverflowException) { Console.WriteLine("catched!! : Func()"); } try { Eternity(); } catch (System.OverflowException) { Console.WriteLine("catched!! : Eternity()"); } } static void Func() { throw new OverflowException(); } static void Eternity() { Eternity(); } } }
自分で投げたStackOverflowExceptionは捕捉できるけど、システムが投げたのはできないみたい。