跳轉到內容

Common Lisp/實現問題

來自 Wikibooks,開放世界中的開放書籍

Common Lisp 是一種規範,它有許多實現。這些實現中的每一個都以不同的方式滿足了 CL 規範。這意味著,幾乎可以肯定,Lisp 實現執行某些任務(啟動、關閉、除錯、交付、指令碼等)的方式將不同。此外,某些實現通常具有某些特殊功能,這些功能尚未被整個 CL 社群採用,但在它們本身卻非常有用。本章將提供使用流行的 Common Lisp 實現和常見用法的簡短/選擇性示例。

應用程式交付

[編輯 | 編輯原始碼]

開源社群在 Common Lisp 世界中非常活躍(就像在“駭客”語言中一樣)。因此,分發 Common Lisp 軟體最常見的方式是透過原始碼存檔。這些原始碼存檔通常使用 ASDF 包管理器。這有一個小缺點,即使用者必須足夠熟練才能安裝 Lisp 實現並構建包。此外,有些人希望將他們的程式閉源。出於這些目的,還有其他分發程式的方法。

轉儲 Lisp 映象

[編輯 | 編輯原始碼]

交付 Lisp 應用程式的一種方法是提供 Lisp 映象的轉儲。傳統上,這是向用戶提供“完成”程式的途徑。這基本上與提供程式的可執行檔案相同。通常,您只會看到一個不透明的單片檔案,其中包含您的程式(幾乎普遍存在整個 Lisp 系統)。雖然這允許開發人員向用戶隱藏應用程式原始碼,但它也解決了使用者必須查詢和安裝 Lisp 實現的問題。由於應用程式只是一個可執行檔案,使用者只需執行該程式即可。然而,Lisp 映象不可移植,需要為要支援的每個系統型別構建。

要在 SBCL 中生成 Lisp 映象,請使用 SAVE-LISP-AND-DIE。

;; Make a Lisp image.  Execute with sbcl --core lisp-image.core
(save-lisp-and-die #p"lisp-image.core")
;; Make an executable Lisp image.  Execute with ./lisp-image
(save-lisp-and-die #p"lisp-image" :executable t)

在構建映象時,您可以使用許多其他選項。請參閱使用者手冊以瞭解它們的作用。

要載入 Lisp 映象,在 Lisp 啟動時使用執行時選項 

--core corefilename

因此在控制檯中 

/usr/local/bin/sbcl—core lisp-image.core

要在 CLISP 中儲存映象,請使用 :[1][2]

(saveinitmem "/home/you/yourLispDir/lispImage.mem")

之後,如果您要使用它,請像這樣載入它(在控制檯中) 

clisp -M lispImage.mem

可移植位元組碼

[編輯 | 編輯原始碼]

一些 Lisp,例如 CLISP,會生成可移植位元組碼。這意味著您可以在一個系統上構建程式,並將其傳送給使用者,使用者然後可以在他們的 CLISP 實現上執行它。這解決了向用戶隱藏原始碼的問題。當然,使用者仍然需要安裝 CLISP,但幸運的是,它是安裝最簡單的 Lisp 實現之一。

指令碼

[編輯 | 編輯原始碼]

人們經常希望像 Perl、Python 和 Bash 一樣編寫 Common Lisp “指令碼”。對於這樣的應用程式,您經常需要擔心 Common Lisp 使用者通常不會擔心的某些因素,例如

  • 啟動時間需要非常快。指令碼通常在簡單的問題上執行小型輸入,因此啟動 Lisp 映象必須很快,否則它將成為瓶頸。
  • 記憶體使用量需要非常低。使用者通常會一次執行數十到數百個指令碼。

這兩個因素在生成 Lisp 系統時通常會被忽略。畢竟,Lisp 系統通常是長時間執行的(因此啟動速度無關緊要)並且形成他們自己的計算環境(因此一次只需要執行一個例項,使記憶體使用無關緊要)。但是,有一些實現可以充當指令碼平臺。經過適當配置,SBCL、CCL 和 CLISP 都具有相對較快的啟動時間。CLISP 和 ECL 的記憶體佔用率相當低。

呼叫 Common Lisp 伺服器

[編輯 | 編輯原始碼]

這個問題在某些新聞組中時不時地出現:“我如何透過呼叫 Lisp 伺服器而不是啟動新程序來規避 Lisp 過度的啟動時間和/或記憶體使用量?”通常,使用者沒有充分利用 Lisp 實現的功能,這導致他們想到這個解決方案。通常,建立 Common Lisp 伺服器實際上並不必要,因為“指令碼”或“轉儲 Lisp 映象”部分中演示的技術足以解決這些問題。但是,有些時候這實際上會對您有益。Common Lisp 系統非常龐大;僅僅載入這樣一個龐大的東西可能會被證明對某些應用程式來說是一個瓶頸。

將 Common Lisp 嵌入到其他語言中

[編輯 | 編輯原始碼]

從 C 呼叫 Lisp

[編輯 | 編輯原始碼]

ECL 是一個完整的獨立 CL 實現,它還具有可以嵌入到任何可以進行 C 函式呼叫的專案中的附加功能。它最初被設想為一種在 C 應用程式中獲取一些 Lisp 而不會留下巨大佔用的方法,但它迅速發展成為一個完整的功能齊全的實現。

呼叫底層 VM

[編輯 | 編輯原始碼]

很少有 Common Lisp 在虛擬機器之上執行。那些能夠使用其他語言的庫,這些庫也使用該 VM。ABCL 是一個在 Java VM 上執行的 Common Lisp。ABCL 能夠訪問 Java 的任何部分,這意味著您可以使用大量的流行庫。

在 ABCL 中使用 Java

[編輯 | 編輯原始碼]

參考資料

[編輯 | 編輯原始碼]
華夏公益教科書