Итак, выполняя некоторые обычные упражнения на шепелявость, все шло хорошо, пока я не столкнулся с этим странным поведением. Я читаю текст из файла (brown.txt) в переменную corpus, и он должен храниться в виде списка. Однако я подозреваю, что это не так, хотя иногда он работает как один, а в другое время терпит неудачу.
Вот базовое чтение из файла -> добавление для списка -> сохранение списка в материале corpus (разделено/размечено пробелами):
(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*
Я подозреваю, что это связано с чтением из файла как объекта stream, и что (append...) не создает список из этого потока, а вместо этого лениво ждет, пока я не захочу оценить это позже или что-то в этом роде, и в это позднее время он просто решает больше не работать?? (для меня мало смысла).
APPEND
не может сказать, и ему все равно, откуда этот список. Список есть список есть список. - person Barmar   schedule 03.09.2014LOOP
возвращаетNIL
, если в нем нет инструкцииRETURN <expression>
или не используется один из глаголов коллекции. Почему вы ожидаете, что первое выражение что-то вернет? Он распечатает элементы списка как побочный эффект, но не вернет их. - person Barmar   schedule 03.09.2014TOKENIZE
возвращает список. Но в вашем выражении(loop for token...)
нетCOLLECT
, поэтому оно ничего не возвращает. - person Barmar   schedule 04.09.2014