Why does SBCL bail out in case of symbol list in lambda expression?

Asked by Michael Conrad

Hello,

SBCL bails out with the following source code

(defun bad-ingredients (order)
  (mapcan (lambda (burger)
            (case burger
              (single '(patty))
              (double '(patty patty))
              (double-cheese '(patty patty cheese))))
    order))

if called e.g. via (bad-ingredients '(single single)), i.e. I have to interrupt execution, since it never comes to an end!

On the other hand, the following works without problems:

(defun ingredients (order)
  (mapcan (lambda (burger)
            (case burger
              (single (list 'patty))
              (double (list 'patty 'patty))
              (double-cheese (list 'patty 'patty 'cheese))))
    order))

But why doesn't "bad-ingredients" work as expected? Why is the result an endless loop?
Is it because it creates and returns locally bound symbols?

Is this a bug or is the behavior just undefined?

Kind regards

Michael

Question information

Language:
English Edit question
Status:
Solved
For:
SBCL Edit question
Assignee:
No assignee Edit question
Solved by:
Nikodemus Siivola
Solved:
Last query:
Last reply:
Revision history for this message
Best Nikodemus Siivola (nikodemus) said :
#1

Argh. I thought I'd turned Questions off here. sbcl-help mailing list is the correct channel for help questions.

  https://lists.sourceforge.net/lists/listinfo/sbcl-help

Anyways, this has nothing to do with locally bound anything.

MAPCAN catenates the lists destructively using NCONC. So (BAD-INGREDIENTS '(SINGLE SINGLE)) ends up doing essentially

   (let ((list '(patty)))
      (nconc list list))

which produces a circular list: #1=(PATTY #1#). Following this MAPCAN tries to find the last element of the list in preparation for the next round (which doesn't occur in this case) -- and ends up endlessly traversing the circular list.

Be careful when using constants like quoted lists, and don't use them with destructive operations.

Apropos, in case you're not familiar with it, you might find http://www.gigamonkeys.com/book/ useful.

Cheers,

 -- nikodemus

Revision history for this message
Michael Conrad (michael-conrad) said :
#2

Hello Nikodemus,

thank you very much for the quick answer!

Now I understand the issue.

> Argh. I thought I'd turned Questions off here.
> sbcl-help mailing list is the correct channel for help questions.
> https://lists.sourceforge.net/lists/listinfo/sbcl-help

I will post my questions in future there - I simply did not find it...

Kind regards

Michael

> Your question #169503 on SBCL changed:
> https://answers.launchpad.net/sbcl/+question/169503
>
> Status: Open => Answered
>
> Nikodemus Siivola proposed the following answer:
> Argh. I thought I'd turned Questions off here. sbcl-help mailing list is
> the correct channel for help questions.
>
> https://lists.sourceforge.net/lists/listinfo/sbcl-help
>
> Anyways, this has nothing to do with locally bound anything.
>
> MAPCAN catenates the lists destructively using NCONC. So (BAD-
> INGREDIENTS '(SINGLE SINGLE)) ends up doing essentially
>
> (let ((list '(patty)))
> (nconc list list))
>
> which produces a circular list: #1=(PATTY #1#). Following this MAPCAN
> tries to find the last element of the list in preparation for the next
> round (which doesn't occur in this case) -- and ends up endlessly
> traversing the circular list.
>
> Be careful when using constants like quoted lists, and don't use them
> with destructive operations.
>
> Apropos, in case you're not familiar with it, you might find
> http://www.gigamonkeys.com/book/ useful.
>
> Cheers,
>
> -- nikodemus

Revision history for this message
Michael Conrad (michael-conrad) said :
#3

Hello Nikodemus,

thank you very much for the quick answer!

Now I understand the issue.

> Argh. I thought I'd turned Questions off here.
> sbcl-help mailing list is the correct channel for help questions.
> https://lists.sourceforge.net/lists/listinfo/sbcl-help

I will post my questions in future there - I simply did not find it...

Kind regards

Michael

Revision history for this message
Michael Conrad (michael-conrad) said :
#4

Forget it - I just tried to acknowledge closure...