2014-09-03 96 views
3

因此,在我遇到這種奇怪的行爲之前,做一些常見的lisp練習和一切都很順利。我從文件(brown.txt)讀取文本到變量語料庫,它應該被存儲爲一個列表。但是,我懷疑它不是,即使它有時像一個工作,但在其他時間失敗。Common Lisp從文件中讀取和存儲爲列表

下面是從文件中的基本的讀 - >添加一個列表 - >商店列表中語料庫東西(分流/上空格記號化):

(defun tokenize (string) 
    (loop 
    for start = 0 then (+ space 1) 
    for space = (position #\space string :start start) 
    for token = (subseq string start space) 
    unless (string= token "") collect token 
    until (not space))) 

(defparameter *corpus* 
    (with-open-file (stream "./brown.txt" :direction :input) 
    (loop for line = (read-line stream nil) 
      while line 
      append (tokenize line)))) 

及以下2個表達式應該都工作,但只有後者(語料庫之一)。第一個返回NIL。

(loop for token in *corpus* do 
    (print token)) 
*corpus* 

我懷疑它與從文件中讀取作爲對象做,那(追加...)不會創建此流的列表,而是懶等待,直到我想以後評估或總結,並在晚些時候它只是決定不再工作? (對我來說沒什麼意義)。

+0

沒有標準的Common Lisp函數是懶惰的。 – Barmar 2014-09-03 19:18:08

+0

'APPEND'不能分辨清單來自何處。列表是列表是列表。 – Barmar 2014-09-03 19:20:15

+2

'LOOP'返回'NIL',除非它有一個'RETURN '聲明或使用其中一個集合動詞。你爲什麼期望第一個表達式返回一些東西?它將打印列表元素作爲副作用,但不會返回它們。 – Barmar 2014-09-03 19:29:18

回答

8

該表達式:

(loop for token in *corpus* do 
    (print token)) 

返回NIL因爲它沒有RETURN條款或累加條款(例如COLLECTAPPEND)。它只是簡單地調用PRINT,但放棄其返回值。