From: ···············@gmail.com
Subject: condition system
Date: 
Message-ID: <3feafae3-495a-4baa-987b-922cd9c93242@k7g2000hsd.googlegroups.com>
I am copying interceptors from the java struts framework:
A stack of functions where one can call (next-interceptor) to call the
next function in stack. Returning from the next function means
resuming just after (next-function) call.
Same thing you find in MOP with (next-method)

How would i implement this? I tried with handler-bind and signals:
(defparameter *stack* (list #'(lambda ()
        	                             (pprint "begin f1")
        			             (next-interceptor)
	        			     (pprint "end f1"))
        			       #'(lambda ()
	        			     (pprint "begin f2")
				             (next-interceptor)
				             (pprint "end f2"))
			              #'(lambda ()
			                     (print "begin f3")
				             (next-interceptor)
				             (pprint "end f3"))))

(define-condition next-interceptor (error)
  ())

(defun next-interceptor ()
  (restart-case (signal 'next-interceptor)
    (return-to-this-interceptor () nil)))

(defun call-nth-interceptor (stack n)
  (if (= (1+ n) (length stack))
      (pprint "THE END")
      (funcall (nth n stack))))

(defun run-stack (functions)
  (let ((stack functions)
	 (i 0))
    (handler-bind ((next-interceptor #'(lambda (c)
					 (call-nth-interceptor stack (1+ i))
					 (invoke-restart 'next-interceptor))))
      (call-nth-interceptor stack 0))))

(run-stack *stack*)
=> "begin f1"
"begin f2"
"end f2"
and error: No restart NEXT-INTERCEPTOR is active.
However, It should print
begin f1
begin f2
THE END
end f2
end f1

What am i missing?
And yes, i start learning those control structures.
Thanks for any pointer

--
olivier buechel

From: Pascal Costanza
Subject: Re: condition system
Date: 
Message-ID: <6jkh92F3p0vpU1@mid.individual.net>
May I suggest a solution that avoids an overly complex control flow due 
to the use of conditions?

(defun next-interceptor (&rest args)
   (declare (ignore args))
   (error "Illegal call to next-interceptor."))

(defmacro ilambda ((&rest parameters) &body body)
   (let ((next-interceptors (gensym)))
     `(lambda (,next-interceptors ,@parameters)
        (flet ((next-interceptor (&rest args)
                 (if ,next-interceptors
                   (apply (first ,next-interceptors)
                          (rest ,next-interceptors)
                          args)
                   (pprint "THE END"))))
          ,@body))))

(defparameter *stack* (list (ilambda ()
                               (pprint "begin f1")
                               (next-interceptor)
                               (pprint "end f1"))
                             (ilambda ()
                               (pprint "begin f2")
                               (next-interceptor)
                               (pprint "end f2"))
                             (ilambda ()
                               (print "begin f3")
                               (next-interceptor)
                               (pprint "end f3"))))

(defun run-stack (functions &rest args)
   (apply (first functions) (rest functions) args))



Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: ···············@gmail.com
Subject: Re: condition system
Date: 
Message-ID: <dd8a451e-14a8-4f06-8014-6617d19c5239@w7g2000hsa.googlegroups.com>
On Sep 20, 4:56 pm, Pascal Costanza <····@p-cos.net> wrote:
> May I suggest a solution that avoids an overly complex control flow due
> to the use of conditions?
Your code has the flaw that (next-interceptor) must be called in
textual context of ilambda.

I tested  this statement

(defun p () (pprint "begin p1")
            (next-interceptor)
            (pprint "end p1"))
and changed *stack* to let an ilambda call p.
A call to (run-stack *stack*) gives a error. by your defun of next-
interception. How intriguing.

However, after a bit thinking: Having (next-interceptor) only in
ilambda doesn't seem to be a superflue restriction after all, but has
two advantages:
i) readability: You see where in ilambda the next interceptor is
called
ii) much more simple, somehow.
I don't understand your ilambda macro, how does it the magic? It
doesn't seem that you are parsing the code? Must study ilambda..
thanks

--
olivier buechel

Which is why you defined next-interceptor
From: Pascal Costanza
Subject: Re: condition system
Date: 
Message-ID: <6jmpq5F3t935U1@mid.individual.net>
···············@gmail.com wrote:
> On Sep 20, 4:56 pm, Pascal Costanza <····@p-cos.net> wrote:
>> May I suggest a solution that avoids an overly complex control flow due
>> to the use of conditions?
> Your code has the flaw that (next-interceptor) must be called in
> textual context of ilambda.

I don't consider that a flaw.

> I tested  this statement
> 
> (defun p () (pprint "begin p1")
>             (next-interceptor)
>             (pprint "end p1"))
> and changed *stack* to let an ilambda call p.
> A call to (run-stack *stack*) gives a error. by your defun of next-
> interception. How intriguing.
> 
> However, after a bit thinking: Having (next-interceptor) only in
> ilambda doesn't seem to be a superflue restriction after all, but has
> two advantages:
> i) readability: You see where in ilambda the next interceptor is
> called
> ii) much more simple, somehow.
> I don't understand your ilambda macro, how does it the magic? It
> doesn't seem that you are parsing the code? Must study ilambda.

Yes, study it. It's not that hard, actually.

Here is a more dynamic version:

(defvar *current-interceptors* '())

(defun next-interceptor (&rest args)
   (if *current-interceptors*
     (let ((current-interceptor (first *current-interceptors*))
           (*current-interceptors* (rest *current-interceptors*)))
       (apply current-interceptor args))
     (pprint "THE END")))

(defparameter *stack* (list (lambda ()
                               (pprint "begin f1")
                               (next-interceptor)
                               (pprint "end f1"))
                             (lambda ()
                               (pprint "begin f2")
                               (next-interceptor)
                               (pprint "end f2"))
                             (lambda ()
                               (print "begin f3")
                               (next-interceptor)
                               (pprint "end f3"))))

(defun run-stack (functions &rest args)
   (let ((*current-interceptors* functions))
     (apply #'next-interceptor args)))


The two versions are actually not that different. The ilambda version 
passes around the interceptors as additional arguments - that's one of 
the typical ways to implement dynamic scoping (aka special variables), 
and is called environment-passing style. Understanding the similarities 
and differences of the two styles can be illuminating.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rainer Joswig
Subject: Re: condition system
Date: 
Message-ID: <joswig-DC4AE1.17394620092008@news-europe.giganews.com>
In article 
<····································@k7g2000hsd.googlegroups.com>,
 ···············@gmail.com wrote:

> I am copying interceptors from the java struts framework:
> A stack of functions where one can call (next-interceptor) to call the
> next function in stack. Returning from the next function means
> resuming just after (next-function) call.
> Same thing you find in MOP with (next-method)
> 
> How would i implement this? I tried with handler-bind and signals:
> (defparameter *stack* (list #'(lambda ()
>         	                             (pprint "begin f1")
>         			             (next-interceptor)
> 	        			     (pprint "end f1"))
>         			       #'(lambda ()
> 	        			     (pprint "begin f2")
> 				             (next-interceptor)
> 				             (pprint "end f2"))
> 			              #'(lambda ()
> 			                     (print "begin f3")
> 				             (next-interceptor)
> 				             (pprint "end f3"))))
> 
> (define-condition next-interceptor (error)
>   ())
> 
> (defun next-interceptor ()
>   (restart-case (signal 'next-interceptor)
>     (return-to-this-interceptor () nil)))
> 
> (defun call-nth-interceptor (stack n)
>   (if (= (1+ n) (length stack))
>       (pprint "THE END")
>       (funcall (nth n stack))))
> 
> (defun run-stack (functions)
>   (let ((stack functions)
> 	 (i 0))
>     (handler-bind ((next-interceptor #'(lambda (c)
> 					 (call-nth-interceptor stack (1+ i))
> 					 (invoke-restart 'next-interceptor))))
>       (call-nth-interceptor stack 0))))
> 
> (run-stack *stack*)
> => "begin f1"
> "begin f2"
> "end f2"
> and error: No restart NEXT-INTERCEPTOR is active.
> However, It should print
> begin f1
> begin f2
> THE END
> end f2
> end f1
> 
> What am i missing?
> And yes, i start learning those control structures.
> Thanks for any pointer
> 
> --
> olivier buechel


Why shouldn't it be:

"begin f1"
"begin f2"
"begin f3" 
"end f3"
"end f2"
"end f1"

???


How about something like this:

(defun next-interceptor ()
  (declare (special the-stack))
  (if  the-stack
      (let ((function (first the-stack))
            (the-stack (rest the-stack)))
        (declare (special the-stack))
        (funcall function))
    (print "the end")))

(defun run-stack (stack)
  (let ((the-stack stack))
    (declare (special the-stack))
    (next-interceptor)))

CL-USER 163 > (run-stack *stack*)

"begin f1"
"begin f2"
"begin f3" 
"the end" 
"end f3"
"end f2"
"end f1"

-- 
http://lispm.dyndns.org/
From: Madhu
Subject: Re: condition system
Date: 
Message-ID: <m3y71mx5gq.fsf@moon.robolove.meer.net>
* olivier.buechel Wrote on Sat, 20 Sep 2008 07:02:14 -0700 (PDT):

| I am copying interceptors from the java struts framework:

[I assume you know exactly what you're doing]

| How would i implement this? I tried with handler-bind and signals:
| (defparameter *stack* (list #'(lambda ()
|         	                             (pprint "begin f1")
|         			             (next-interceptor)
| 	        			     (pprint "end f1"))
|         			       #'(lambda ()
| 	        			     (pprint "begin f2")
| 				             (next-interceptor)
| 				             (pprint "end f2"))
| 			              #'(lambda ()
| 			                     (print "begin f3")
| 				             (next-interceptor)
| 				             (pprint "end f3"))))
|
| (define-condition next-interceptor (error)
|   ())

;; No need to subclass ERROR. just CONDITION should be sufficient.

|
| (defun next-interceptor ()
|   (restart-case (signal 'next-interceptor)
|     (return-to-this-interceptor () nil)))

You named the restart RETURN-TO-THIS-INTERCEPTOR

|
| (defun call-nth-interceptor (stack n)
|   (if (= (1+ n) (length stack))
|       (pprint "THE END")
|       (funcall (nth n stack))))
|
| (defun run-stack (functions)
|   (let ((stack functions)
| 	 (i 0))
|     (handler-bind ((next-interceptor #'(lambda (c)
| 					 (call-nth-interceptor stack (1+ i))
| 					 (invoke-restart 'next-interceptor))))

But here you are doing a non local transfer of control to a non-existant
restart named NEXT-INTERCEPTOR

|       (call-nth-interceptor stack 0))))
|
| (run-stack *stack*)
| => "begin f1"
| "begin f2"
| "end f2"
| and error: No restart NEXT-INTERCEPTOR is active.
| begin f1
| begin f2
| THE END
| end f2
| end f1
|
| What am i missing?

Nothing :) --- Just change `return-to-this-interceptor' to
`next-intercepor'.

--
Madhu
From: Rainer Joswig
Subject: Re: condition system
Date: 
Message-ID: <joswig-75A88E.17404620092008@news-europe.giganews.com>
In article <··············@moon.robolove.meer.net>,
 Madhu <·······@meer.net> wrote:

> * olivier.buechel Wrote on Sat, 20 Sep 2008 07:02:14 -0700 (PDT):
> 
> | I am copying interceptors from the java struts framework:
> 
> [I assume you know exactly what you're doing]
> 
> | How would i implement this? I tried with handler-bind and signals:
> | (defparameter *stack* (list #'(lambda ()
> |         	                             (pprint "begin f1")
> |         			             (next-interceptor)
> | 	        			     (pprint "end f1"))
> |         			       #'(lambda ()
> | 	        			     (pprint "begin f2")
> | 				             (next-interceptor)
> | 				             (pprint "end f2"))
> | 			              #'(lambda ()
> | 			                     (print "begin f3")
> | 				             (next-interceptor)
> | 				             (pprint "end f3"))))
> |
> | (define-condition next-interceptor (error)
> |   ())
> 
> ;; No need to subclass ERROR. just CONDITION should be sufficient.
> 
> |
> | (defun next-interceptor ()
> |   (restart-case (signal 'next-interceptor)
> |     (return-to-this-interceptor () nil)))
> 
> You named the restart RETURN-TO-THIS-INTERCEPTOR
> 
> |
> | (defun call-nth-interceptor (stack n)
> |   (if (= (1+ n) (length stack))
> |       (pprint "THE END")
> |       (funcall (nth n stack))))
> |
> | (defun run-stack (functions)
> |   (let ((stack functions)
> | 	 (i 0))
> |     (handler-bind ((next-interceptor #'(lambda (c)
> | 					 (call-nth-interceptor stack (1+ i))
> | 					 (invoke-restart 'next-interceptor))))
> 
> But here you are doing a non local transfer of control to a non-existant
> restart named NEXT-INTERCEPTOR
> 
> |       (call-nth-interceptor stack 0))))
> |
> | (run-stack *stack*)
> | => "begin f1"
> | "begin f2"
> | "end f2"
> | and error: No restart NEXT-INTERCEPTOR is active.
> | begin f1
> | begin f2
> | THE END
> | end f2
> | end f1
> |
> | What am i missing?
> 
> Nothing :) --- Just change `return-to-this-interceptor' to
> `next-intercepor'.
> 
> --
> Madhu

Still, the third function will not run?

-- 
http://lispm.dyndns.org/
From: ···············@gmail.com
Subject: Re: condition system
Date: 
Message-ID: <45b68c15-7d30-4603-b64b-ff6b8d4fdb47@k37g2000hsf.googlegroups.com>
On Sep 20, 5:40 pm, Rainer Joswig <······@lisp.de> wrote:
> In article <··············@moon.robolove.meer.net>,
>
>
>
>  Madhu <·······@meer.net> wrote:
> > * olivier.buechel Wrote on Sat, 20 Sep 2008 07:02:14 -0700 (PDT):
>
> > | I am copying interceptors from the java struts framework:
>
> > [I assume you know exactly what you're doing]
>
> > | How would i implement this? I tried with handler-bind and signals:
> > | (defparameter *stack* (list #'(lambda ()
> > |                                       (pprint "begin f1")
> > |                                       (next-interceptor)
> > |                                       (pprint "end f1"))
> > |                                 #'(lambda ()
> > |                                       (pprint "begin f2")
> > |                                       (next-interceptor)
> > |                                       (pprint "end f2"))
> > |                                #'(lambda ()
> > |                                       (print "begin f3")
> > |                                       (next-interceptor)
> > |                                       (pprint "end f3"))))
> > |
> > | (define-condition next-interceptor (error)
> > |   ())
>
> > ;; No need to subclass ERROR. just CONDITION should be sufficient.
>
> > |
> > | (defun next-interceptor ()
> > |   (restart-case (signal 'next-interceptor)
> > |     (return-to-this-interceptor () nil)))
>
> > You named the restart RETURN-TO-THIS-INTERCEPTOR
>
> > |
> > | (defun call-nth-interceptor (stack n)
> > |   (if (= (1+ n) (length stack))
> > |       (pprint "THE END")
> > |       (funcall (nth n stack))))
> > |
> > | (defun run-stack (functions)
> > |   (let ((stack functions)
> > |   (i 0))
> > |     (handler-bind ((next-interceptor #'(lambda (c)
> > |                                   (call-nth-interceptor stack (1+ i))
> > |                                   (invoke-restart 'next-interceptor))))
>
> > But here you are doing a non local transfer of control to a non-existant
> > restart named NEXT-INTERCEPTOR
>
> > |       (call-nth-interceptor stack 0))))
> > |
> > | (run-stack *stack*)
> > | => "begin f1"
> > | "begin f2"
> > | "end f2"
> > | and error: No restart NEXT-INTERCEPTOR is active.
> > | begin f1
> > | begin f2
> > | THE END
> > | end f2
> > | end f1
> > |
> > | What am i missing?
>
> > Nothing :) --- Just change `return-to-this-interceptor' to
> > `next-intercepor'.
>
> > --
> > Madhu
>
> Still, the third function will not run?
>
Correct output should be, as you remarked correctly:

"begin f1"
"begin f2"
"begin f3"
"the end"
"end f3"
"end f2"
"end f1"

You code is even shorter than Pascal Costanza's. And yours I have been
able just to look through, somehow.
I'm not sure about the special variables: Do you really need to
(declare (special the-stack)) three times? Once you declare the-stack
special, from that point of time (=extend) the-stack keeps being
special.
Ooops, just removed the special declarations from next-interceptor,
only left the declaration in run-stack.. and tried (run-stack *stack*)
and what surprise
got a stack-overflow
Thanks;)

Hmm, I thought I could lisp.
Very sublime your code.
So with each call to next-interception the (declare (special the-
stack)) creates a new special the-stack??

--
olivier buechel

So each call to your next-interceptor
From: John Thingstad
Subject: Re: condition system
Date: 
Message-ID: <op.uhsqc5zput4oq5@pandora.alfanett.no>
P� Sat, 20 Sep 2008 21:47:27 +0200, skrev <···············@gmail.com>:

>
> Hmm, I thought I could lisp.
> Very sublime your code.
> So with each call to next-interception the (declare (special the-
> stack)) creates a new special the-stack??
>

No it declares it a dynamic variable. Lexical variables are only seen  
within the scope of the function. Dynamic variables exist until they go  
out of scope. But more importantly ALL functions that get called before  
the variable goes out of scope also see it. And the functions that get  
called from the functions. The whole call tree. It is the 'let' that  
creates the variable. The following declaration makes it dynamic (or  
special if you will). The declaration in the other function  
('next-interceptor') just tells the compiler that it's there so it won't  
warn you about "variable 'something' assumed special."

Variables further up in the call tree can change the variable, but it has  
a different meaning.
Consider:

(let ((*print-length* 3))
    (format stream "~{~A~}" list))

Here '*print-length*' gets the value 3. 'format and the functions 'format'  
calls like 'princ' also see it. When it finishes with format and goes out  
of scope it goes back to whatever value it had before.

Note that all top level variables are dynamic. That is the ones declare  
with 'defvar' or 'defparameter'. The *name* convention is there to  
indicate that they are dynamic (special) and behave differently from  
lexical variables (created with let, let* etc).

--------------
John Thingstad
From: Rainer Joswig
Subject: Re: condition system
Date: 
Message-ID: <joswig-491667.22490820092008@news-europe.giganews.com>
In article 
<····································@k37g2000hsf.googlegroups.com>,
 ···············@gmail.com wrote:


> You code is even shorter than Pascal Costanza's. And yours I have been
> able just to look through, somehow.
> I'm not sure about the special variables: Do you really need to
> (declare (special the-stack)) three times? Once you declare the-stack
> special, from that point of time (=extend) the-stack keeps being
> special.
> Ooops, just removed the special declarations from next-interceptor,
> only left the declaration in run-stack.. and tried (run-stack *stack*)
> and what surprise
> got a stack-overflow
> Thanks;)
> 
> Hmm, I thought I could lisp.
> Very sublime your code.
> So with each call to next-interception the (declare (special the-
> stack)) creates a new special the-stack??

(defun next-interceptor ()
  (declare (special the-stack))
  (if the-stack
      (let ((function (first the-stack))
            (the-stack (rest the-stack)))
        (declare (special the-stack))
        (funcall function))
    (print "the end")))

(defun run-stack (the-stack)
  (declare (special the-stack))
  (next-interceptor)))

Above version is a bit shorter.

Let's look.



(defun run-stack (the-stack)
  (declare (special the-stack))
  (next-interceptor)))


The special declaration means that
binding the-stack to an argument of
the function will create a dynamic binding.
Note that the declaration is strictly local
to RUN-STACK and the declaration
has no effect on other definitions
of a variable THE-STACK.


Then:

(defun next-interceptor ()
  (declare (special the-stack))
  (if the-stack
      (let ((function (first the-stack))
            (the-stack (rest the-stack)))
        (declare (special the-stack))
        (funcall function))
    (print "the end")))

The first declaration ensures that THE-STACK
is not a lexical, but a special variable. So
it will look up the dynamic binding.

Then the LET function rebinds the special
declared variable THE-STACK. It creates
a new dynamic binding - for that we need
to declare the variable THE-STACK of the
LET expression SPECIAL, too.


Two things are unusual when you may have used
mostly lexical variables (the default in Common Lisp):

1) you can declare parameters of functions to be special
2) you can declare SPECIAL with a local effect. There
is no need to introduce a global special variable.


The really funny thing: before Common Lisp (and Scheme)
dynamic binding was the default. So it worked this way by default.
Emacs Lisp is still using dynamic binding like that.
I think it is clear why dynamic binding CAN be
useful (see the example) - but it is equally clear why
lexical binding is to be preferred as the default.



> --
> olivier buechel
> 
> So each call to your next-interceptor

-- 
http://lispm.dyndns.org/
From: ···············@gmail.com
Subject: Re: condition system
Date: 
Message-ID: <2e88c1f4-362f-4fc0-8c26-54e21f020c13@m45g2000hsb.googlegroups.com>
On Sep 20, 10:49 pm, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@k37g2000hsf.googlegroups.com>,
>
>
>
>  ···············@gmail.com wrote:
> > You code is even shorter than Pascal Costanza's. And yours I have been
> > able just to look through, somehow.
> > I'm not sure about the special variables: Do you really need to
> > (declare (special the-stack)) three times? Once you declare the-stack
> > special, from that point of time (=extend) the-stack keeps being
> > special.
> > Ooops, just removed the special declarations from next-interceptor,
> > only left the declaration in run-stack.. and tried (run-stack *stack*)
> > and what surprise
> > got a stack-overflow
> > Thanks;)
>
> > Hmm, I thought I could lisp.
> > Very sublime your code.
> > So with each call to next-interception the (declare (special the-
> > stack)) creates a new special the-stack??
>
> (defun next-interceptor ()
>   (declare (special the-stack))
>   (if the-stack
>       (let ((function (first the-stack))
>             (the-stack (rest the-stack)))
>         (declare (special the-stack))
>         (funcall function))
>     (print "the end")))
>
> (defun run-stack (the-stack)
>   (declare (special the-stack))
>   (next-interceptor)))
>
> Above version is a bit shorter.
>
> Let's look.
>
> (defun run-stack (the-stack)
>   (declare (special the-stack))
>   (next-interceptor)))
>
> The special declaration means that
> binding the-stack to an argument of
> the function will create a dynamic binding.
> Note that the declaration is strictly local
> to RUN-STACK and the declaration
> has no effect on other definitions
> of a variable THE-STACK.
>
> Then:
>
> (defun next-interceptor ()
>   (declare (special the-stack))
>   (if the-stack
>       (let ((function (first the-stack))
>             (the-stack (rest the-stack)))
>         (declare (special the-stack))
>         (funcall function))
>     (print "the end")))
>
> The first declaration ensures that THE-STACK
> is not a lexical, but a special variable. So
> it will look up the dynamic binding.
>
> Then the LET function rebinds the special
> declared variable THE-STACK. It creates
> a new dynamic binding - for that we need
> to declare the variable THE-STACK of the
> LET expression SPECIAL, too.
>
> Two things are unusual when you may have used
> mostly lexical variables (the default in Common Lisp):
>
> 1) you can declare parameters of functions to be special
> 2) you can declare SPECIAL with a local effect. There
> is no need to introduce a global special variable.
>
> The really funny thing: before Common Lisp (and Scheme)
> dynamic binding was the default. So it worked this way by default.
> Emacs Lisp is still using dynamic binding like that.
> I think it is clear why dynamic binding CAN be
> useful (see the example) - but it is equally clear why
> lexical binding is to be preferred as the default.
>
> > --
> > olivier buechel
>
> --http://lispm.dyndns.org/

Commenting the code:
(defun next-interceptor ()
  (declare (special the-stack)) ;;referencing the-stack means look for
dynamic variable
  (if the-stack                 ;;the-stack is reference to place
established
                                ;;along callers execution path
      (let ((function (first the-stack))   ;;dito
            (the-stack (rest the-stack)))  ;;the-stack in (rest the-
stack) refers to
                                           ;;allready establish
dynamic binding
                                           ;;the let form generates a
new location and
                                           ;;binds it to the symbol
the-stack
        (declare (special the-stack))  ;;from here-on the new location
bound to the-stack
                                       ;;shadows other the-stack
bindings
        (funcall function))
    (print "the end")))

The point is dynamic bindings can be shadowed just as static bindings
can be shadowed

Well, anyway, that's what I was missing, thanks
And there is still pascal constanza solution: I think I will opt for a
combination where (next-interceptor) is only meaningfull in some kind
of interceptor environment
From: Madhu
Subject: Re: condition system
Date: 
Message-ID: <m3tzcax3oi.fsf@moon.robolove.meer.net>
* Madhu <··············@moon.robolove.meer.net> :
Wrote on Sat, 20 Sep 2008 19:52:13 +0530:
| * olivier.buechel Wrote on Sat, 20 Sep 2008 07:02:14 -0700 (PDT):
| | (run-stack *stack*)
| | => "begin f1"
| | "begin f2"
| | "end f2"
| | and error: No restart NEXT-INTERCEPTOR is active.
| | begin f1
| | begin f2
| | THE END
| | end f2
| | end f1
| |
| | What am i missing?
|
| Nothing :) --- Just change `return-to-this-interceptor' to
| `next-intercepor'.

Actually there are a couple of serious mistakes that I didn't notice at
first glance:

If (signal 'next-interceptor) is not handled, it returns NIL.

This is the reason why only the first two functions in your stack ever
get called.  Change SIGNAL to ERROR to get a backtrace in your debugger,
to see where the condition is signalled but not handled.

Note you want every call of next-interceptor to happen inside a
handler-bind.

Given the approach you have already taken, I would suggest something
recursive like this:

(defun run-stack (&optional (stack *stack*))
  (unless (endp stack)
    (handler-bind ((next-interceptor (lambda (c)
				       (declare (ignore c))
				       (run-stack (cdr stack))
				       (invoke-restart 'next-interceptor))))
	  (funcall (car stack)))))

[You could use TRACE to see calls and arguments.  This is probably not
how I would implement it myself]

--
Madhu