Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!nntp.sei.cmu.edu!news.psc.edu!wink.radian.com!gatech!csulb.edu!hammer.uoregon.edu!news-peer.gsl.net!news.gsl.net!news.maxwell.syr.edu!cpk-news-hub1.bbnplanet.com!news.bbnplanet.com!rill.news.pipex.net!pipex!warwick!bris.ac.uk!usenet
From: Nathan Sidwell <nathan@pact.srf.ac.uk>
Subject: Re: Lisp version of asserta(x).
X-Nntp-Posting-Host: talisker.pact.srf.ac.uk
Content-Type: text/plain; charset=us-ascii
To: Jeremiah Thomas Isaacs <jti0001@jove.acs.unt.edu>
Message-ID: <33292758.51F1@pact.srf.ac.uk>
Sender: usenet@fsa.bris.ac.uk (Usenet)
Content-Transfer-Encoding: 7bit
Organization: Partnership In Advanced Computing Technologies
References: <5g9nbp$qg6@hermes.acs.unt.edu>
Mime-Version: 1.0
Date: Fri, 14 Mar 1997 10:24:24 GMT
X-Mailer: Mozilla 3.0 (X11; I; SunOS 5.5 sun4u)
Lines: 78

Jeremiah Thomas Isaacs wrote:
> 
> Ive been programming in lisp more and more, and find one thing id like to
> do.  In prolog it is fairly easy to use asserta/assertz, but I have failed
> to see a way to do this in Lisp.  a horrible workaround is to format text
> to a file, and then evaluate the file.  and (although I havent tried it)
> another way would  be eval '... (and printing to a file also, to see what
> it was asserting at runtime)  but why does using eval make me feel like

What you need is a macro, which works by processing its args before they
are
evaluated, the form produced by the macro is evaluated. And conditions
are
a way of adding new error types.

Here are the conditions and macros I use. The names are as they are,
because they're part of a compiler -- modify at your desire.

;;{{{  diagnostics
;;; condition we add
;;{{{  (define-condition compiler-logic (control-error)
(define-condition compiler-logic (control-error)
  ((string :initarg :string))
  (:report
    (lambda (condition stream)
      (format stream "Logic failure '~a'" (slot-value condition
'string)))))
;;}}}
;;{{{  (define-condition compiler-assert (compiler-logic)
(define-condition compiler-assert (compiler-logic)
  ((form :initarg :form))
  (:report
    (lambda (condition stream)
      (format stream "Assertion failure '~@w'" (slot-value condition
'form)))))
;;}}}

;;; macros to invoke these
;;{{{  (defmacro compiler-assert (expr)
(defmacro compiler-assert (expr)
  `(if (not ,expr)
    (error 'compiler-assert :form ',expr)))
;;}}}
;;{{{  (defmacro compiler-logic (string)
(defmacro compiler-logic (string)
  `(error 'compiler-logic :string ',string))
;;}}}

;;}}}

use is
(compiler-assert (this-must-be-non-nil))
will produce an error if the condition is not met.
(compiler-logic "This can't happen")
will always produce an error, use when you think you can't get somewhere

Conditions are described in chapter 29 of cltl2

I have an outermost handler-case wrapper, to catch all these things,
when the code is not being debugged, so I can produce a sensible user
visible diagnostic,

(handler-case
  (my-main-func)
  (error (condition)
    (let ((*print-length* 3) (*print-level* 2))
      (format *error-output* "~&Compiler bug!~&~a~&" condition))
    (compiler-bug-report)
    nil))

hope this helps
nathan

-- 
Nathan Sidwell                    The windy road is more interesting
Chameleon Architecture Group at SGS-Thomson, formerly Inmos
http://www.pact.srf.ac.uk/~nathan/                  Tel 0117 9707182
nathan@pact.srf.ac.uk or nathan@bristol.st.com
