From: glauber
Subject: Q: "on exit" processing
Date: 
Message-ID: <900h6f$qfc$1@nnrp1.deja.com>
Hello,

is there a way in Common Lisp to trap program termination (like you can do in
C with atexit() or an END block in Perl)?

I thought there might be a condition for program exit, but didn't find it.

These things are useful for doing cleanup, writing to a log file, etc.

I imagine, though, you could wrap your program in an unwind-protect block to
get the same effect...

--
Glauber Ribeiro
··········@my-deja.com    http://www.myvehiclehistoryreport.com
"Opinions stated are my own and not representative of Experian"


Sent via Deja.com http://www.deja.com/
Before you buy.

From: Kent M Pitman
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <sfw1yvww0iv.fsf@world.std.com>
glauber <··········@my-deja.com> writes:

> is there a way in Common Lisp to trap program termination (like you can do in
> C with atexit() or an END block in Perl)?
> 
> I thought there might be a condition for program exit, but didn't find it.
> 
> These things are useful for doing cleanup, writing to a log file, etc.
> 
> I imagine, though, you could wrap your program in an unwind-protect block to
> get the same effect...

I think most implementations will try to run your process
unwind-protect's on exit from an image.  It's beyond the scope of the
language to require this, though, since it would involve talking about
what it means to exit the lisp image, and without careful terminology
it would have been possible to have a program that doesn't and can't
exit.

In the early days of CLTL1, I was maintaining Macsyma and got myself in
a mess when I wrote something that did something vaguely like:

 (defun macsyma-top-level ()
   (unwind-protect (macsyma) (macsyma-top-level)))

 or

 (defun macsyma-top-level ()
   (tagbody restart
     (unwind-protect (macsyma)
       (go restart))))

 ...or some such...

to make sure no one fell out into lisp in Vaxlisp, since there was no
way for me that I could find in the documentation to set the top level
read eval print loop in a dumped image.  It had the side-effect in Vaxlisp,
though, and perhaps other implementations, that I couldn't exit Lisp.
(I believe this led to a clarification of the meaning of throw/go from
unwind clauses.  A lot of the cleanups that I initiated came from my notes
about all the various Macsyma non-portabilities.)

Or, put more succinctly, anyone who thinks it's unconditionally good
to run the unwind protects before shutting down probably needs to
rewatch The Forbin Project. :-)

In practice, I think most implementations provide two ways to exit.  I think
the Lisp machine doesn't, though...
From: Joe Marshall
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <n1ekf337.fsf@content-integrity.com>
Kent M Pitman <······@world.std.com> writes:

> In practice, I think most implementations provide two ways to exit.  I think
> the Lisp machine doesn't, though...

Unfortunately, the LMI Lispms provided *numerous* ways to quit lisp,
synchronously, asynchronously, and unexpectedly.

The Lambdas also had a `suicide' cable that could turn off the power.
It is not in the spirit of a Lisp machine to deny any conceivable
functionality to the user, so you could invoke  (sys::%power-off) to
power down the machine (it would not run your unwind-protects,
though).  I think this was available on the system menu as well.

This sort of construct is a little too difficult to use properly,
so there was the more convenient

SYS:WITHOUT-POWER &body body

macro that would wrap your code with the appropriate cleanup forms.


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Tim Bradshaw
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <nkju28sj9kq.fsf@tfeb.org>
Joe Marshall <···@content-integrity.com> writes:

> This sort of construct is a little too difficult to use properly,
> so there was the more convenient
> 
> SYS:WITHOUT-POWER &body body
> 
> macro that would wrap your code with the appropriate cleanup forms.
> 

You mean it ran BODY with the power off?  Cool!

--tim
From: Kent M Pitman
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <sfwbsv0ypi2.fsf@world.std.com>
Joe Marshall <···@content-integrity.com> writes:

> This sort of construct is a little too difficult to use properly,
> so there was the more convenient
> 
> SYS:WITHOUT-POWER &body body
> 
> macro that would wrap your code with the appropriate cleanup forms.

Heh.  Frankly, I can't tell if this is a joke or not.

PDP10 Maclisp had an operator that would return a float number of
seconds until the system was due to go down, or 0.0 if the system was
not due to go down, or -1.0 if the system was already down.  I laughed
at this and someone dragged me to the system console and showed me it
really was serious.  If you took down the system, it went into single
user mode.  If you were running in single user mode, it did in fact
return -1.0 because timesharing was off.

Who knows what future computers will do when their power is off.  I
just got UPS boxes for several of my computers, and I know they don't
just twiddle their thumbs when unplugged...
From: Barry Margolin
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <4RQU5.5$Ha.307@burlma1-snr2>
In article <············@nnrp1.deja.com>,
glauber  <··········@my-deja.com> wrote:
>Hello,
>
>is there a way in Common Lisp to trap program termination (like you can do in
>C with atexit() or an END block in Perl)?
>
>I thought there might be a condition for program exit, but didn't find it.

The Common Lisp standard doesn't have anything like C's exit(), so it's
hard to see where it could define how to hook into what happens when that
nonexistent function is called.  Since program exiting is an
implementation-dependent extension, any mechanism to trap it should also
be.

>These things are useful for doing cleanup, writing to a log file, etc.
>
>I imagine, though, you could wrap your program in an unwind-protect block to
>get the same effect...

It's not obvious to me that an implementation would unwind all the stacks
when exiting.  But if you exit from your application by using RETURN-FROM
or THROW to return from its top-level function, UNWIND-PROTECT is the right
way to clean up.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Mike McDonald
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <wPXU5.511$OC.154794@typhoon.aracnet.com>
In article <············@nnrp1.deja.com>,
	glauber <··········@my-deja.com> writes:
> Hello,
> 
> is there a way in Common Lisp to trap program termination (like you can do in
> C with atexit() or an END block in Perl)?
> 
> I thought there might be a condition for program exit, but didn't find it.
> 
> These things are useful for doing cleanup, writing to a log file, etc.
> 
> I imagine, though, you could wrap your program in an unwind-protect block to
> get the same effect...

  How about wrapping the exit/quit implementation specific function with your
own code? (In addition to the unwind-protect.)

  Mike McDonald
  ·······@mikemac.com
From: glauber
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <9036eb$vnf$1@nnrp1.deja.com>
In article <···················@typhoon.aracnet.com>,
  ·······@mikemac.com wrote:
[...]
>   How about wrapping the exit/quit implementation specific function with your
> own code? (In addition to the unwind-protect.)


How do you do that? For example, in CLISP, the exit function is (lisp:exit).
How can i redefine (lisp:exit) so that it does something and then calls the
original definition?


--
Glauber Ribeiro
··········@my-deja.com    http://www.myvehiclehistoryreport.com
"Opinions stated are my own and not representative of Experian"


Sent via Deja.com http://www.deja.com/
Before you buy.
From: Barry Margolin
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <ucaV5.35$Ha.1177@burlma1-snr2>
In article <············@nnrp1.deja.com>,
glauber  <··········@my-deja.com> wrote:
>In article <···················@typhoon.aracnet.com>,
>  ·······@mikemac.com wrote:
>[...]
>>   How about wrapping the exit/quit implementation specific function with your
>> own code? (In addition to the unwind-protect.)
>
>
>How do you do that? For example, in CLISP, the exit function is (lisp:exit).
>How can i redefine (lisp:exit) so that it does something and then calls the
>original definition?

Don't call lisp:exit, call the wrapper instead:

(defun my-exit ()
  (mapc #'funcall *my-exit-handlers*)
  (lisp:exit))

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Hannah Schroeter
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <9039ab$950$1@c3po.schlund.de>
Hello!

In article <············@nnrp1.deja.com>,
glauber  <··········@my-deja.com> wrote:
>In article <···················@typhoon.aracnet.com>,
>  ·······@mikemac.com wrote:
>[...]
>>   How about wrapping the exit/quit implementation specific function with your
>> own code? (In addition to the unwind-protect.)


>How do you do that? For example, in CLISP, the exit function is (lisp:exit).
>How can i redefine (lisp:exit) so that it does something and then calls the
>original definition?

How about

; ... package definition
(in-package :myown)
(defvar *exit-hook*)
(defun exit (&rest a)
 (mapc #'funcall *exit-hook*)
 (apply #'lisp:exit a))

And replace all calls to lisp:exit to myown:exit

Regards,

Hannah.
From: Erik Naggum
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <3184585037217223@naggum.net>
* glauber <··········@my-deja.com>
| How do you do that? For example, in CLISP, the exit function is
| (lisp:exit).  How can i redefine (lisp:exit) so that it does something
| and then calls the original definition?

  I don't know about CLISP, but in several other Lisps, you can add
  _advice_ to functions.  Even Emacs Lisp has such a feature.

  I frankly don't see why unwind-protect around the function that is
  supposed to be run before exiting can't take care of these things.
  This whole thing feels like a stop-gap solution to a more fundamental
  problem.  Is the real problem that CLISP terminates uncontrollably?
  If so, that should be a high-priority bug report and serious attention
  to a fix, not some user somewhere crying over crashing software in the
  sadly misguided belief that he just has to live with it.  Again if so,
  users should stop accepting that software crashes, like they would
  never accept to come home to a house in rubbles one afternoon and be
  explained that random crashes are to expected with modern buildings.
  If the problem is not that CLISP terminates uncontrollably, there must
  be a reason why the function that runs this program cannot take care
  of its cleanup stuff itself.

#:Erik
-- 
  Solution to U.S. Presidential Election Crisis 2000:
    Let Texas secede from the Union and elect George W. Bush their
    very first President.  All parties, states would rejoice.
From: glauber
Subject: Re: Q: "on exit" processing
Date: 
Message-ID: <905v7r$8hn$1@nnrp1.deja.com>
In article <················@naggum.net>,
  Erik Naggum <····@naggum.net> wrote:
> * glauber <··········@my-deja.com>
> | How do you do that? For example, in CLISP, the exit function is
> | (lisp:exit).  How can i redefine (lisp:exit) so that it does something
> | and then calls the original definition?
>
>   I don't know about CLISP, but in several other Lisps, you can add
>   _advice_ to functions.  Even Emacs Lisp has such a feature.


Very interesting. Is this in the Common Lisp spec, or is it
implementation-specific?

I thought about this problem more and this is my opinion now: C is the
extension language for the Unix system, so C programs running in Unix are
"like" lisp functions running in a Lisp machine. A Lisp system like CLisp
emulates a Lisp machine "hosted" in a non-lisp environment.

So, the Lisp equivalent of trapping exit would be to have a fail-safe way to
execute code at the end of a function call (or right after that function
call, maybe). Unwind-protect provides a way to do this.

Moreover, it's probably better not to call (lisp:exit) or its equivalent
directly. With CLisp, you can do clisp file.lsp and it will load and run
file.lsp, then exit. If there is a need to "abend" within the program, the
correct way to do that should be to use error or throw to go back to the
top-level.

(This is similar to the way error handling and cleanup are done in Java and
C++.)


>   I frankly don't see why unwind-protect around the function that is
>   supposed to be run before exiting can't take care of these things.

I think it does.


>   This whole thing feels like a stop-gap solution to a more fundamental
>   problem.  Is the real problem that CLISP terminates uncontrollably?

There's no such problem i'm aware of. I'm just trying to translate an useful
concept i learned with C to Common Lisp. [...]


> --
>   Solution to U.S. Presidential Election Crisis 2000:
>     Let Texas secede from the Union and elect George W. Bush their
>     very first President.  All parties, states would rejoice.

Or, about 50.05% of the people, 33.33333% of the parties and a minority of
the states would rejoice.

--
Glauber Ribeiro
··········@my-deja.com    http://www.myvehiclehistoryreport.com
"Opinions stated are my own and not representative of Experian"


Sent via Deja.com http://www.deja.com/
Before you buy.