
不可能的程式
|
277
程式可以自我參照
does_it_say_no.rb
使用的自我參照技巧,雖然取決於我們所構建的程式能力(此程式可
以讀取它自己的原始碼),但它似乎有點像是要欺騙來假設這永遠都可能發生。多虧了
周圍環境(也就是殼層)提供的功能,我們範例裡的程式才能接收它自己的原始碼作為
輸入;若無此選項,它也能利用 Ruby 的檔案系統 API 和永遠都包含目前檔案名稱的特
殊
FILE
常數,透過
File.read(__FILE__)
直接從磁碟讀取資料。
但是我們應當提出全面性的論證,它只取決於 Ruby 的通用性,而不是作業系統或
File
類別的能力。執行時可能無法存取它們原始碼的編譯語言(像是 Java、C)呢?透過網
路連線而載入記憶體,而且根本不會儲存在本機檔案系統的 JavaScript 程式呢?諸如圖
靈機和 lambda 演算這類自我包含的通用系統,『檔案系統』和『標準輸入』的概念在
這些系統都不存在嗎?
所幸
does_it_say_no.rb
引數經得起這樣的異議,因為程式能從標準輸入讀取自己的原始
碼,只是所有通用系統都能做的方便速記,而且不論其環境或其他功能如何。這是
克
雷尼第二遞迴定理
(
Kleene's second recursion theorem
)的基本數學結果的推論,它保
證任何程式皆可轉換成能運算它自己原始碼的等效版本。這項遞迴定理保證我們的速
記完全合理:我們可以用一些程式碼換掉這行
program = $stdin.read
,來產生
does_it_
say_no.rb