Я соглашусь прямо перед тем, что следующее довольно ужасное описание того, что я хочу сделать. Извиняюсь заранее. Пожалуйста, задавайте вопросы, чтобы помочь мне объяснить. :-)Общая система состояния Lisp для передачи управления
я написал ETLs (Extract, Transform, Load) на других языках, которые состоят из отдельных операций, которые выглядят примерно так:
// in class CountOperation
IEnumerable<Row> Execute(IEnumerable<Row> rows) {
var count = 0;
foreach (var row in rows) {
row["record number"] = count++;
yield return row;
}
}
Затем строка число этих операций вместе, и вызовите Диспетчер, который отвечает за вызов Операций и нажатие данных между ними.
Я пытаюсь сделать что-то подобное в Common Lisp, и хочу использовать ту же базовую структуру, то есть каждая операция определяется как нормальная функция, которая вводит список и выводит список, но лениво.
Я могу define-condition
условие (have-value
) использовать для поведения yield
, и я могу запустить его в одном цикле, и он отлично работает. Я определения операций, точно так же, перекручивание через входы:
(defun count-records (rows)
(loop for count from 0
for row in rows
do (signal 'have-value :value `(:count ,count @,row))))
Беда в том, если я хочу, чтобы соединить вместе несколько операций, и запускать их. Моя первая попытка написать диспетчер для них выглядит примерно так:
(let ((next-op ...)) ;; pick an op from the set of all ops
(loop
(handler-bind
((have-value (...))) ;; records output from operation
(setq next-op ...) ;; pick a new next-op
(call next-op)))
Но перезагружается имеет только динамическую степень: каждая операция будет иметь те же имена рестарта. Перезапуск не является объектом Lisp, который я могу сохранить, чтобы сохранить состояние функции: это то, что вы вызываете по имени (символу) внутри блока обработчика, а не продолжение, которое вы можете сохранить для последующего использования.
Возможно ли сделать что-то вроде этого? Или мне лучше просто заставить каждую операционную функцию явно смотреть на входную очередь и явно помещать значения в очередь вывода?