LINUX.ORG.RU

Баг?

 , ,


0

1

Весь код нет смысла приводить, но суть в том, что с такой функцией работает нормально -

(defun rgraph-edges (graph)
  (iter (for v in (rgraph-verticles graph))
    (appending (rgraph-v-out v))))
а с такой

(defun rgraph-edges (graph)
  (let ((vs (rgraph-verticles graph)))
    (mapcan (lambda (v) (rgraph-v-out v)) vs)))

висит, не выводя ничего в *standard-output* или точнее выводя, потому что при принудительном «Interrupt from Emacs» вывод печатается, но пока висит ничего не печатается. Причём вывод в *standard-output* производится до вызова этой функции. Не знаю как там устроена печать, но по ощущениям что-то типа flush делается только при выбрасывание ошибки. Всё это происходит при 2х вызовах rgraph-edges. То есть, если в коде rgraph-edges вызывается 1 раз, то всё нормально и печатается и работает. Если вызвать rgraph-edges 2 раза, то происходит то, что описано выше.

Две тарелки борща этому господину!

anonymous
()

mapcan деструкивный, надо смотреть, есть ли побочные эффекты от получения вершин (или ссылки на старый граф остаются). Граф не меняется после первого вызова rgraph-edges? Сравни expand макроса iter с тем, что получается в функции. Понапихай отладочную печать внутрь mapcan и посмотри, что она жуёт в процессе.

Может быть и глюк, у меня на старом Slime и новом SBCL были похожие косяки, но я обновился, нашёл другой баг и дальше не копал.

anonymous
()
Ответ на: комментарий от anonymous

Если это баг, то не интересно разбираться, а если это особенность mapcan то это необходимо знать. Почему тогда -

RECOG-PROC> (let ((l (list 1 2 3)))
              (mapcan (lambda (a) (list a)) l)
              l)
(1 2 3)

pseudo-cat ★★★
() автор топика
Ответ на: комментарий от pseudo-cat

Всё это происходит при 2х вызовах rgraph-edges.

(defvar *a* '((1 2) (3 4)))

(defun rgraph-verticles () *a*)

(defun rgraph-v-out (v) v)

> (let ((l (rgraph-verticles)))
    (mapcan (lambda (v) (rgraph-v-out v)) l)
     l)

((1 2 3 4) (3 4))

> *a*

((1 2 3 4) (3 4))

> (let ((l (rgraph-verticles)))
    (mapcan (lambda (v) (rgraph-v-out v)) l)
     l)
;; висит

Так должно быть. Или надо делать (mapcan (lambda (v) (copy-list (rgraph-v-out v)))

monk ★★★★★
()

mapcan = (iter ... (nconcing ...)), а не (iter ... (appending ...))

monk ★★★★★
()
Ответ на: комментарий от pseudo-cat

list создаёт новый список. Попробуй так:

(let ((l (list 1 2 3)))
              (mapcan (lambda (a) '( a)) l)
              l)
ados ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.