From: Glenn Burnside
Subject: .NET style events in Lisp
Date: 
Message-ID: <uu4n8ga5l7n0bb@corp.supernews.com>
So, I'm learning .net as part of a work project, and I'm a little bit
enamored on the idea of events as supported there - namely the ability to
create multicast events that broadcast notification to multiple listeners,
simply by having those listeners add themselves to the list of event
delegates.  this struck me as (very) similar to Emacs' hooks, and I thought
I might to try and use something like that as part of a system I'm working
on.  So, I took a look at the implementation of hooks in emacs lisp, and it
looked to me like they were inextricably tied to being bound to symbols, and
I never did figure out how a hook actually got called as a function.  I'm
wondering if anyone has implemented anything like this for Common Lisp, and
if so where could I find it, and if not, is it because the use of multicast
functions is better handled by some other mechanism in Lisp?

Thanks,
    Glenn Burnside

From: Tim Bradshaw
Subject: Re: .NET style events in Lisp
Date: 
Message-ID: <ey3smxp7d2z.fsf@cley.com>
* Glenn Burnside wrote:
> So, I took a look at the implementation of hooks in emacs lisp, and it
> looked to me like they were inextricably tied to being bound to symbols, and
> I never did figure out how a hook actually got called as a function.  I'm
> wondering if anyone has implemented anything like this for Common Lisp, and
> if so where could I find it, and if not, is it because the use of multicast
> functions is better handled by some other mechanism in Lisp?

I have an implementation of hooks for a CL-based system, but it's
mostly inspired by Emacs's one.  The purpose is to allow various code
to run at known points - pre boot, post boot, and so on, without
having to define everything up front.

I have: named hooks, which are symbols, and correspond to well-known
`times' or `events' in the system.  Anyone who wants to register an
entry on a hook does so by defining a hook function, which is
associated with the named hook and also has a name of its own (this
allows redefinition to be easier).  I think the implementation is by
some kind of two-layered alist - each hook is a key, the value of that
key is an alist of (function-name . function).  But I could be wrong,
it's some time since I wrote it.  Hooks are called with arguments
(unlike Emacs) and each function on a hook should have a congruent
arglist.  Finally there are a couple of ways of running a hook - the
default which doesn't do anything special about errors, and an `ignore
errors and blunder on' way, which is useful in emergency.  Generally
each hook gets run only in one of these ways - so I have an `exit
application hook' which is run normally and an `emergency exit
application hook' which gets run with suppressed errors if the normal
hook got errors.

I could *probably* make this code freely available (it depends how
much other functionality it depends on).

This is fine for fairly static things - my system has modules that get
loaded at runtime, and these typically register themselves on various
hooks so they can get initialized and reset appropriately at good
times.  But it's not designed for things that come and go all the time
- for instance there's no way of *unregistering* a function from a
hook, and everything looks like a top-level definition.

For that kind of thing, I think you want some kind of dependency
protocol.  I have one of those too, actually, but it's seen hardly any
use.  it's fairly standard - there are things-that-depend-on-things
and things-that-have-dependencies as mixins, and you can add and
remove dependencies.  The only useful thing (which in your context
might actually be interesting) is that the arcs in the dependency
graph have labels - symbols - and you can map over just one kind of
dependency, or many.  These names might correspond to event names, for
instance. I don't remember the interface well enough to describe it -
it was designed to be used outside its original bit of the code, but
it never actually has one, unlike hooks.

--tim
From: Jochen Schmidt
Subject: Re: .NET style events in Lisp
Date: 
Message-ID: <artosv$sac$06$1@news.t-online.com>
Glenn Burnside wrote:

> So, I'm learning .net as part of a work project, and I'm a little bit
> enamored on the idea of events as supported there - namely the ability to
> create multicast events that broadcast notification to multiple listeners,
> simply by having those listeners add themselves to the list of event
> delegates.  this struck me as (very) similar to Emacs' hooks, and I
> thought I might to try and use something like that as part of a system I'm
> working
> on.  So, I took a look at the implementation of hooks in emacs lisp, and
> it looked to me like they were inextricably tied to being bound to
> symbols, and
> I never did figure out how a hook actually got called as a function.  I'm
> wondering if anyone has implemented anything like this for Common Lisp,
> and if so where could I find it, and if not, is it because the use of
> multicast functions is better handled by some other mechanism in Lisp?

The concept is just an application of the "Observer Pattern".

I personally like Lispworks concept of "Action Lists" - though I have not 
used them very much.

  http://www.lispworks.com/reference/lwl42/LWUG-U/html/lwuser-u-45.htm

What I would find more interesting in regard to events would be a portable 
and lightweight networked event distribution service for Common Lisp. 
Clients of such a service can register themselves either in a connected way 
by establishing a TCP connection or in a disconnected way by submitting 
connection related information (host, port...) and then accepting incoming 
connections.

There are many uses for such an notification mechanism:

Notification of:
- Start and stop of services in other processes or on other machines
- Requests on particular ressources
- User logins/logoffs
- changes in shared databases
- ...

One could imagine it as similar to syslog logging mechanisms in Linux with 
the difference of being not only for a single machine but for a whole LAN
and with structured event objects instead of strings of characters. 

ciao,
Jochen

--
http://www.dataheaven.de