Как стать автором
Обновить

Комментарии 7

Мне всегда казалось, что смысл генераторов именно в функции yield, когда код генератора непрерывен и может возвращать данные из любой точки, продолжая выполнение с того же места по вызову next. В CL есть некоторые проблемы с таким подходом, так как для его реализации нужен call/cc, а он конфликтует с unwind-protect и простого решения тут нет. Именно по этой причине генераторов нет в CL.

Я с рестартами пока не разобрался, но из того, что слышал: они, вроде, позволяют продолжить исполнение там, где оно прервалось. На их основе нельзя что-то типа yield сделать?

Или на каком-то хитром замыкании, которое позволит извне вернуться и продолжить исполнять там, где закончили

С рестартами вряд ли получится. Они позволяют, например, вместо выражения, вызвавшего исключение, выполнить другое и продолжить выполнение. Сохранить контекст и потом восстановить его в произвольный момент времени они не могут.

CL-USER> (next *x*)
1
NIL
CL-USER> (next *x*)
2
NIL
Вроде как анти-паттерн в ФП, когда одно и то же выражение вычисляется по-разному?

Common Lisp мультипарадигменный. В нём нет нет необходимых вещей, чтобы называться сильным функциональным ЯПом (контроль эффектов, иммутабельность, сильная система типов). А слабыми фунциональными (есть функции как объекты первого порядка) являются почти все современные языки

Просто можно это было бы сделать чисто, например
(setq mygen (create-gen))
(setq next (next-gen mygen))
(setq val (car next)) ; --> 1
(setq mygen (cdr next))
(setq next (next-gen mygen))
(setq val (car next)) ; --> 2
...

О, вместе со значением возвращать новое состояние генератора. Встречал такое в хаскеле, но тут не додумался использовать. Изящное решение, надо будет попробовать

Возможно, так даже проще будет добавить рекуррентные генераторы

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории