From: Mark Tarver
Subject: type secure error handling
Date: 
Message-ID: <1179825181.801448.239710@h2g2000hsg.googlegroups.com>
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
From: Pascal Costanza
Subject: Re: type secure error handling
Date: 
Message-ID: <5bftotF2sjn3nU1@mid.individual.net>
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/