неопределенный оператор после быстрой загрузки LISP - PullRequest
0 голосов
/ 26 сентября 2019

Функция find-data-from-command отлично работает, когда я запускаю ее без предварительной «быстрой загрузки» пакета.Если я загружаю пакет, он выдает ошибку, что split-sequence не определена.

Я попытался перезагрузить split-sequence после загрузки пользовательского пакета.Не работает

(ql:quickload :<a-custom-package>)

(defun find-data-from-command (x desired-command)
  (setq desired-data ())
  (loop for line = (read-line x nil)
    while (and line (not desired-data)) do 
        (progn 
          (setq commands (first (split-sequence ":" line)))
          (setq data (split-sequence "," (first (rest (split-sequence ":" line)))))
          (print (cons "command:" commands))
          (cond
                ((equal commands desired-command) (return-from find-data-from-command data))))))
FIND-DATA-FROM-COMMAND

SIGMA 24 > 
  (setq obj-type (find-data-from-command (open "log.txt") "types"))

Error: Undefined operator SPLIT-SEQUENCE in form (SPLIT-SEQUENCE ":" LINE).

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Проблема не в Quicklisp, а в пакете, который вы определили где-то под названием SIGMA.В частности, где-то в вашем коде есть форма, которая выглядит следующим образом:

(defpackage "SIGMA"                     ;or :sigma or :SIGMA or #:sigma or ...
  ...
  (:use ...)
  ...)

А потом позже

(in-package "SIGMA")

И проблема в том, что в вашем определении пакета есть явное (:use ...)

defpackage, а базовая функция make-package имеет несколько интересное поведение для предложения :use (или аргумента ключевого слова в случае make-package):

  • , если ничего не задано, то существует определяемое реализацией default;
  • , если оно задано, оно отменяет значение по умолчанию.

Идея, я думаю, заключается в том, что реализации могут захотеть предоставить набор дополнительных функций, которые доступны по умолчанию, и эта функциональность не может быть в пакете CL, так как содержимое этого пакетаопределяется в стандарте.Поэтому, если вы просто скажете

(defpackage "FOO")

, тогда реализация будет разрешена (и, возможно, поощрена), чтобы список использования FOO содержал несколько полезных пакетов.Эти пакеты могут быть теми же, что и в списке использования по умолчанию CL-USER, но я не уверен, что это необходимо: все это несколько недооценено.

Конечный результат этогочто если вы хотите определить пакеты, которые оба используют функциональность, определяемую реализацией и , имеют явные списки использования, вы должны прибегнуть к небольшому обману.То, как вы это делаете, зависит от вас, но, поскольку вы по определению пишете код, зависящий от реализации, для которого вы определяете пакеты, подобные этому, вы, вероятно, хотите прояснить, что то, что вы делаете, зависит от реализации, в некоторой форме, такой как

(defpackage :foo
  (:use ...)
  #+LispWorks
  (:use :lispworks :harlequin-common-lisp :cl)
  ...)

Или, если вы просто хотите какой-то определенный набор символов

(defpackage :foo
  (:use ...)
  #+LispWorks
  (:import-from :lispworks #:split-sequence))

Обратите внимание, что это не совсем то же самое, что использовать пакет, содержащий символ.

Во всех этих случаях, если у вашего кода есть претензии на переносимость, должны быть соответствующие предложения для других реализаций и способ узнать, когда вы пытаетесь запустить реализацию, которую вы еще не видели: как это сделать,Я думаю, что вне рамок этого ответа.

0 голосов
/ 26 сентября 2019

Решено.

Быстрая загрузка пользовательского пакета забирала меня в пакет.Я этого не осознавал.Поэтому мне пришлось указать split-sequence is from outside.Итак, я заменил все вхождения split-sequence в определении функции на

LISPWORKS:split-sequence

Тогда это сработало.

Если у кого-то есть лучшее решение, пожалуйста, сделайтедайте мне знать.Спасибо

...