歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> newLISP 初級教程

newLISP 初級教程

日期:2017/3/1 9:44:00   编辑:Linux編程

目錄
newLISP — 交互式教程
Hello World!
代碼和數據是可以互換的
函數的參數
副作用和 Contexts
表達式序列
可執行文件和動態鏈接(Executables and Dynamic Linking)
在 OSX, Linux 或其他 UNIX 系統:
在 Windows 系統上目標文件需要 .exe 後綴
綁定(Binding)
List 是一種遞歸結構
函數(Functions)
高階函數
lambda 列表
動態范圍(Dynamic Scope)
函數參數列表

Contexts
局部作用域(Lexical Scope)

newLISP — 交互式教程

這份文檔於 2006 年 5 月被 Rick Hanson ([email protected]) 做了一些修正和更新後被轉換成 html 文檔。2008 年 12 月被 L.M 更新到 v.10.0 版本. 版權所有 John W. Small 2004。

你可以到 newLISP 官方網站 www.newLISP.org 下載和安裝這門語言.

關於這個教程的任何意見和問題請發郵件到 [email protected]

中文版翻譯時 newLISP 的版本已經到了 10.6 這和當時撰寫文檔的時候,已經相隔甚遠。一些內置函數的名稱發生了變化,語言的功能也擴展了很多。我根據實際的情況修改了相應的章節,這樣所有的代碼就都可以在新的版本上進行測試運行了。

中文翻譯:宋志泉(ssqq) QQ: 104359176 電子郵件:[email protected]

Hello World!

在你的系統上安裝 newLISP 之後, 在 shell 命令行下輸入 newlisp 就可以啟動 REPL (讀取,計算,打印循環).

在 Linux 系統中,你的界面看起來像這樣:

1 $ newlisp 2 > _

如果是在 Windows 平台上,它會是這個樣子:

1 c:\> newlisp 2 > _

在 REPL 啟動後,newLISP 會出現一個響應輸入的提示:

1 > _

在下面的提示中輸入如下表達式,就可以在屏幕上打印出 “Hello World!“.

1 > (println "Hello World!")

newLISP 打印出輸入在 REPL 中提示符後的表達式結果,並等待下一次輸入.

1 > (println "Hello World!") 2 Hello World! 3 "Hello World!" 4 > _

為什麼會打印出兩次呢?

函數 println 的執行結果在屏幕上打印出第一行:

1 Hello World!

函數 println 然後返回字符串 “Hello World!“. 這是它最後一個參數,會返回給 REPL, REPL 會把它顯示在屏幕上,這是第二行的由來。

1 "Hello World!"

REPL 會計算任何表達式,不單單計算函數.

1 > "Hello World!" 2 "Hello World!" 3 > _

如果你輸入上面的表達式 "Hello World!", 它只是返回表達式本身,如果輸入數字結果也是一樣.

1 > 1 2 1 3 > _

現在你可能會想,成對的括號怎麼沒用到呢?如果你以前使用主流的計算機語言,像下面的函數調用看起來是不是更自然一點:

1 println("Hello World!")

我相信過段時間你會喜歡下面的寫法:

1 (println "Hello World!")

而不是:

1 println("Hello World!")

因為一些原因,不能詳細解釋,等到你看到更多的關於處理列表和符號的 newLISP代碼後,也許就會明白。

代碼和數據是可以互換的

Lisp 的本意是列表處理(List Processor). Lisp 使用 lists 同時表示代碼和數據,它們彼此之間是可以互相轉換的。

以前的 println 表達式是一個真正的擁有兩個元素的列表。

1 (println "Hello World!")

第一個元素是:

1 println

第二個元素是:

1 "Hello World!"

Lisp 總是會將列表作為函數調用進行執行,除非你引用它,從而表明它只是一個字面形式的符號表達式,也就是 – 數據。

1 > '(println "Hello World!") 2 (println "Hello World!") 3 > _

一個符號表達式可以再次被當成代碼運行,比如:

1 > (eval '(println "Hello World!")) 2 Hello World! 3 "Hello World!" 4 > _

Lisp 程序可以在運行時構建數據的字面量,然後執行它們!

1 > (eval '(eval '(println "Hello World!"))) 2 Hello World! 3 "Hello World!" 4 > _

通常單引號 ' 是引用 quote 簡寫形式.

1 > (quote (println "Hello World!")) 2 (println "Hello World!") 3 > _

你可以想象引用 quote 將它的參數當成字面量返回, 也就是符號化參數.

1 > 'x 2 x 3 > (quote x) 4 ' x 5 > '(1 2 three "four") 6 (1 2 three "four") 7 > _

符號,例如上面的 xthree, 還有符號列表(symbolic lists)在人工智能領域起著舉足輕重的角色。這個教程不會探討人工智能,但是一旦你學會用 Lisp 編程,你將能明白許多人工智能的教科書的 Lisp 的代碼含義了。

讓我們看看下面的例子:

1 > 'Hello 2 Hello 3 > "Hello" 4 "Hello" 5 > _

符號 'Hello 和字符串字面量 "Hello" 不同. 現在你就會明白為什麼在 REPL 中使用雙引號來標注一個字符串,這樣是為了和有著相同字母的符號進行區分。

函數的參數

println 函數可以擁有任意個數的參數。

1 > (println "Hello" " World!") 2 Hello World! 3 " World!" 4 > _

上面的代碼中,參數一個接一個的合並後,輸出到屏幕,最後一個參數的值作為函數的返回值進行返回給 REPL。

通常,參數是從左到右進行計算的,然後將結果傳遞給函數。傳遞給函數的參數可以說被完全的計算過了,這就是大家所說的應用序求值(applicative-order evaluation).

但是請注意,函數 quote 並不是這樣.

1 > (quote (println "Hello World!")) 2 (println "Hello World!") 3 > _

如果它的參數是這個:

1 (println "Hello World!")

如果它被完全解釋後傳遞,我們將會在屏幕上看到:

1 Hello World!

事實並不是這樣,函數 quote 是一種特殊的函數,通常被稱為特殊形式函數 “special form”.

你可以在 newLISP 中設計自己的特殊形式函數,這種函數叫做宏(macro), 它的參數能以字面量被調用。這就是正則序求值(normal-order evaluation),我們說這種順序是惰性的。也就是說,一個宏的參數在傳遞過程中並不會被直接計算(我們將在下面了解具體情況)。

因此,函數 quote 將參數按字面量傳遞並返回。在某種意義上,引用 quote 代表了典型的惰性計算原則。它並不對參數做任何運算,只是單單的按照字面量返回它。

如果沒有特殊形式函數,其他函數中的流程控制,是不能在只有列表語法的語言中實現的。例如,看看下面的 if 函數.

1 > (if true (println "Hello") (println "Goodbye")) 2 Hello 3 "Hello" 4 > _

特殊形式函數 if 接受三個參數:

1 語法: (if condition consequence alternative) 2 3 condition(條件) => true 4 consequence(結果) => (println "Hello") 5 alternative(替代) => (println "Goodbye")

參數 condition 總是被完全的計算,但參數 consequencealternative 的表達式是惰性的。因為參數 alternative 的表達式可能根本不需要計算.

請注意 if 這個表達式. 它返回的值到底是 consequence 還是 alternative, 依賴於 condition 是真還是假. 在以上的例子中,alternative 表達式沒有後被計算,因為打印到屏幕 “Goodbye” 的副作用永遠都不會出現.

如果一個 if 表達式的條件 condition 表達式測試為假,但又沒有 alternative 語句,那麼它就會返回 nil. nil 的意思根據不同的環境可能解釋為空值(void)或假(false).

注意:在大多數主流計算機語言中,if 只是一個語句,並不會產生返回值。

如果 Lisp 缺乏這個惰性計算特性,它就無法用來實現特殊形式函數或宏(macro)。如果沒有惰性計算,大量額外的關鍵字 and/or 語法就會不得不加入到語言中。

直到現在,��看到幾種語法?括號和引用?哦,似乎有點少!

惰性計算帶給你的就是,我們自己可以在語言中添加個性化的流程控制方式,來擴展這門語言,訂制自己的專用語言。函數和宏的書寫將在本教程的後面部分。

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-05/102252p2.htm

newLISP 的詳細介紹:請點這裡
newLISP 的下載地址:請點這裡

為Emacs配置newLISP開發環境 http://www.linuxidc.com/Linux/2013-01/78463.htm

newLISP做GitLab系統備份 http://www.linuxidc.com/Linux/2013-01/78464.htm

newLISP 遍歷目錄樹,清理編譯目錄 http://www.linuxidc.com/Linux/2013-08/88954.htm

Copyright © Linux教程網 All Rights Reserved