Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Why my DEFMACRO fails?

Name: Anonymous 2012-02-27 10:19


(defmacro call/cc (f)
  (let ((l (gensym))
        (r (gensym))
        (v (gensym)))
   `(let ((,r nil))
      (tagbody (setf ,r (funcall ,f (lambda (,v)
                                   (setf ,r ,v)
                                   (go ,l))))
                ,l)
      ,r)))


It works in some cases but fails on (let ((k nil)) (call/cc (lambda (c) (setf k c))) (print 123) (funcall k nil))

How do I fix it?

Name: Anonymous 2012-02-27 10:26

>>1
I tried

(defun call/cc (f)
  (let ((r nil))
    (tagbody (setf r (funcall f (lambda (v)
                                  (setf r v)
                                  (go l))))
             l)
      r))


and it fails too! (call/cc #'call/cc) works, but produces garbage.

Name: Anonymous 2012-02-27 10:28

>>2
"(funcall (call/cc #'call/cc) 123)" says

Unhandled memory fault at #x0.
   [Condition of type SB-SYS:MEMORY-FAULT-ERROR]


SBCL sucks.

Name: Anonymous 2012-02-28 2:18

>>3
nice

Name: Anonymous 2012-02-28 3:33

>>1

You can't implement continuations with a shitty little macro that spits out a TAGBODY.

That's your main problem; everything else is a red herring.

Name: Anonymous 2012-02-28 3:55

>>5
The problem is that compiler frees tagbody labels after the upward funarg.

Name: Anonymous 2012-02-28 10:11

>>1-3
If you want call/cc in CL you either need to write a code walker which transforms the code using Continuation Passing Style or by using some low-level heap-copying tricks - it's also how Scheme implementations do it. There's a portable library that does it in the first way and there's some implementation forks/extensions that do it in the second way.
Doing it using a tagbody like that won't work as it does something similar, but different from the real call/cc.

Name: Anonymous 2012-02-28 10:34

>>7
Doing it using a tagbody like that won't work as it does something similar, but different from the real call/cc.
Semantically GOTOs work the same way, but ignore a few advanced cases, which crashes SBCL. Dunno why it allows that at all.

Name: Anonymous 2012-02-28 10:35

>>8
I think a revised standard could fix tagbody by stack copying or like that.

Name: Anonymous 2012-02-28 11:59

>>8
Tags only allow unwinding the stack (a bit above C's goto which is basically just a jump with a bit of cleanup). You can't expect it to do anything as heavy in overhead as copying the entire stack/thread context.
>>9
Maybe, although, it would be high overhead and call/cc and unwind-protect don't fit will together.

Name: Anonymous 2012-02-28 12:12

>>9
Hardware stack pointers considered harmful. If you used branch and link you could allocate a block for each function call and have the garbage collector delete them. Stack copying becomes completely unnecessary. A hardware stack isn't even good for C because people have to worry about allocating local arrays and structs that are too big.

Don't change these.
Name: Email:
Entire Thread Thread List