Hi,
I'm looking into a type secure error handling mechanism for Qi, using
the resources within CL.
I defined a macro called trap as follows.
(DEFMACRO trap (X F Y)
`(HANDLER-CASE ,X (ERROR (C) (apply (apply ,F (FORMAT NIL "~A"
C)) ,Y))))
** The apply apply bit is Qi apply. The currying is done by hand here
because I'm writing in Lisp - ignore this. **
My notes say
Evaluates its first argument X and returns it if no error is raised.
Otherwise, the error message is passed to the second argument F as a
string S together with the third argument Y. F is applied to S and Y
to give an object of type A.
Effectively - return the first object of type A if no error. Otherwise
use the second argument to build a substitute value of type A from the
default case and the error string.
Since trap is a macro defined through Lisp it does not sustain
currying and is therefore a special form (like let etc.) and is
declared as such to Qi..
(specialise trap)
Here is its type theory.
(datatype trap
X : A; F : (string --> B --> A); Y : B;
___________________________
(trap X F Y) : A;)
A test run:
(13+) (/ 4 0)
division by zero
Now do the same but trap the error, ignore the error string and return
the default.
(14+) (trap (/ 4 0) (/. X (/. Y Y)) 3)
3 : number
Now trap the error, print the error string and return the result
(15+) (trap (/ 4 0) (/. X (/. Y (let Message (print X) Y))) 3)
"division by zero
"3 : number
Now here is the problem. I want to define simple trap
(define simple-trap
{A --> A --> A}
X Y -> (trap X (/. Error (/. Default Default)) Y))
simple-trap just traps the error and returns the result (the same as
in 14+).
(17+) (define simple-trap
{A --> A --> A}
X Y -> (trap X (/. Error (/. Default Default)) Y))
simple-trap : (A --> (A --> A))
(18+) (simple-trap (/ 4 0) 7)
division by zero
Uh oh. simple-trap insists on eagerly evaluating its arguments before
doing any trapping. The Lisp code from simple-trap is
(DEFUN simple-trap (V41 V42)
(trap V41 #'(LAMBDA (Error) #'(LAMBDA (Default) Default)) V42))
Is there any nice way of defining trap which will avoid this result?
Mark
Mark Tarver wrote:
> (18+) (simple-trap (/ 4 0) 7)
>
> division by zero
>
> Uh oh. simple-trap insists on eagerly evaluating its arguments before
> doing any trapping. The Lisp code from simple-trap is
>
> (DEFUN simple-trap (V41 V42)
> (trap V41 #'(LAMBDA (Error) #'(LAMBDA (Default) Default)) V42))
>
> Is there any nice way of defining trap which will avoid this result?
Add something like delay/force? (See R5RS.)
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/