From: Rui Maciel on
Alex Mizrahi wrote:

> I'm not sure I undertstand your question correctly. Do you want
> to recieve some sort of notification when something changes
> list entries?

Yes, that's basically it. To give you some insight, as a pet project I'm designing a script-able
application which does some 3D visualization. As Lisp is one of the candidate scripting languages (thanks
to ecl) and the 3D models will consist basically of a set of lists, I'm exploring the idea of using ecl to
store the entire model as a set of basic Lisp data structures.

The downside is that in order for that to work it must be possible to have a way to re-render the model
when the model's data structures happen to be tweaked. Also, I believe it would be a nice feature to have
if it was possible to handle those data structures as if they were regular, no-frills, basic Lisp data
structures. That way it would be possible to operate on the model and extract any info the user may wish to
extract by relying only on simple Lisp scripts that implement basic Lisp functions.


> It is possible to do this by re-implementing lists in CLOS.
> Here's example how one can implement observable conses
> and some list API on top of them: http://paste.lisp.org/display/89244
>
> Then it will sort of work:

<snip code/>

Thanks for the example, Alex. I'm just starting out at Lisp and so I'm still trying to figure out some
stuff. Yet, I've ran it both in clisp and ecl and your example runs as expected. Nicely done!


<snip/>

> But I hope you've got an idea -- if you want to track writes to some slots
> via accessors,
> implement (setf accessorname) :before or :after method.

Interesting. Is it also possible to trigger a notification when an instance of a custom class is
created/deleted?


> This won't work with (setf (slot-name ....)) though, if you want it to
> work then
> you probably need to deal with metaclasses or something like that.
>
> Also there are few libs which can help with observers and stuff. Cells
> among them.

I've browsed through a few Cells examples and it appears it does exactly what I'm looking for. Nonetheless,
I would prefer, for simplicity's sake, if it was possible to implement that feature without having to rely
on a 3rd party component.


Thanks for the help,
Rui Maciel
From: Alex Mizrahi on
??>> I'm not sure I undertstand your question correctly. Do you want
??>> to recieve some sort of notification when something changes
??>> list entries?

RM> Yes, that's basically it. To give you some insight, as a pet project
RM> I'm designing a script-able application which does some 3D
RM> visualization.

Great, I have some background in 3D stuff, so maybe I can recommend
you something...

RM> As Lisp is one of the candidate scripting languages (thanks to ecl)
RM> and the 3D models will consist basically of a set of lists, I'm
RM> exploring the idea of using ecl to store the entire model as a set of
RM> basic Lisp data structures.

Aha, now I see...

RM> The downside is that in order for that to work it must be possible to
RM> have a way to re-render the model when the model's data structures
RM> happen to be tweaked.

Unfortunately there are no way to implement modification notifications
neither for conses nor for arrays. But usually Lisp implementation are
pretty hackable, so probably you can implement this yourself, for
arrays at least. (Working on cons level is too low-level to do it in
meaningful
way, I'm afraid.)

But I do not think you're losing a lot using custom data containers instead
of standard ones. Sure, functions like map, dolist and loop...across won't
work for your container, but I'd say indexed access is already good enough.
Just implement functions like length, aref, (setf aref) for your data
structures,
and that will be fine, probably.

As I've said, Lisp is pretty hackable, so you can teach LOOP (or maybe
ITERATE if you wish) to work with your data structures.
Or you can make convenience macros -- that is what Lisp is especially
good at.

But note that singly-linked lists or plain arrays might not be the best
way to work with 3D data -- s.l. lists are actually PITA when you do
something
other than sequential iteration or some recursive functions. E.g. there
is no functions to delete some element in the middle, or insert something
into the middle -- one needs to find relevant cons and work with it.
And arrays just do not provide such functions at all.

So if inserting/deleting stuff in the middle is relevant to your
application,
using some custom data containers might be a good thing.

??>> But I hope you've got an idea -- if you want to track writes to some
??>> slots via accessors, implement (setf accessorname) :before or :after
??>> method.

RM> Interesting. Is it also possible to trigger a notification when an
RM> instance of a custom class is created/deleted?

Created -- yes. There is initialize-instance generic function which
is useful in this situation (add :after method).

Deleted -- not really. There is no such concept as "deleting" object
in Common Lisp as in garbage collected language -- at some point
object becomes inacessible, then at some other point GC might
detect this and deallocate it.

Some implementation allow hooking into GC, so you'll get notification
when object is about to be deallocated. (IIRC they are called finalizers.)
But you have no guarantee when that will happen. In some cases it
might never happen -- convservative GC might leave some amount of garbage.

So if you want to track deletes, you'd better track container for that
object, i.e. objects which typically point to it.


From: Rui Maciel on
Alex Mizrahi wrote:

> Great, I have some background in 3D stuff, so maybe I can recommend
> you something...

Sounds great. Could you please share any advice on the subject?


<snip/>

> Unfortunately there are no way to implement modification notifications
> neither for conses nor for arrays. But usually Lisp implementation are
> pretty hackable, so probably you can implement this yourself, for
> arrays at least. (Working on cons level is too low-level to do it in
> meaningful way, I'm afraid.)
>
> But I do not think you're losing a lot using custom data containers
> instead of standard ones. Sure, functions like map, dolist and
> loop...across won't work for your container, but I'd say indexed access is
> already good enough. Just implement functions like length, aref, (setf
> aref) for your data structures,
> and that will be fine, probably.

Bummer. The main point of relying on basic Lisp data structures to hold the model's data is to be able to
manipulate the model through basic Lisp functions such as those you pointed out. As soon as that is taken
away then the concept doesn't look as good as it did.

In that case would it be possible to write a base class that implements a generic accessor method that,
when called, triggers the Model's re-rendering? If that works then would it be possible to inherit that
class and trigger the update whenever that method is called?


> As I've said, Lisp is pretty hackable, so you can teach LOOP (or maybe
> ITERATE if you wish) to work with your data structures.
> Or you can make convenience macros -- that is what Lisp is especially
> good at.
>
> But note that singly-linked lists or plain arrays might not be the best
> way to work with 3D data -- s.l. lists are actually PITA when you do
> something
> other than sequential iteration or some recursive functions. E.g. there
> is no functions to delete some element in the middle, or insert something
> into the middle -- one needs to find relevant cons and work with it.
> And arrays just do not provide such functions at all.

That isn't good news. The insert/delete operations, along with the ability to reset values, would be
fundamental to what I'm trying to build. Does Lisp have a data structure that supports those operations?


> So if inserting/deleting stuff in the middle is relevant to your
> application,
> using some custom data containers might be a good thing.

Sounds good. It's in fact important to insert/delete elements on those lists. I'll look into that and see
if I'll come up with something.


> Created -- yes. There is initialize-instance generic function which
> is useful in this situation (add :after method).
>
> Deleted -- not really. There is no such concept as "deleting" object
> in Common Lisp as in garbage collected language -- at some point
> object becomes inacessible, then at some other point GC might
> detect this and deallocate it.
>
> Some implementation allow hooking into GC, so you'll get notification
> when object is about to be deallocated. (IIRC they are called finalizers.)
> But you have no guarantee when that will happen. In some cases it
> might never happen -- convservative GC might leave some amount of garbage.
>
> So if you want to track deletes, you'd better track container for that
> object, i.e. objects which typically point to it.

OK I'll look into that.


Thanks for the help,
Rui Maciel
From: Alessio Stalla on
On Oct 27, 8:40 am, Rui Maciel <rui.mac...(a)gmail.com> wrote:
> Alex Mizrahi wrote:
> > Great, I have some background in 3D stuff, so maybe I can recommend
> > you something...
>
> Sounds great. Could you please share any advice on the subject?
>
> <snip/>
>
> > Unfortunately there are no way to implement modification notifications
> > neither for conses nor for arrays. But usually Lisp implementation are
> > pretty hackable, so probably you can implement this yourself, for
> > arrays at least. (Working on cons level is too low-level to do it in
> > meaningful way, I'm afraid.)
>
> > But I do not think you're losing a lot using custom data containers
> > instead of standard ones. Sure, functions like map, dolist and
> > loop...across won't work for your container, but I'd say indexed access is
> > already good enough. Just implement functions like length, aref, (setf
> > aref) for your data structures,
> > and that will be fine, probably.
>
> Bummer. The main point of relying on basic Lisp data structures to hold the model's data is to be able to
> manipulate the model through basic Lisp functions such as those you pointed out. As soon as that is taken
> away then the concept doesn't look as good as it did.

Be aware that at least SBCL allows you to implement user-defined
sequences that will work with every CL function dealing with sequences
(e.g. ELT, MAP, SUBSEQ).
Alternatively, another common solution adopted in Lisp is to provide a
thin layer of abstraction over bare lists; there's even the built-in
possibility to use structures backed by cons lists. Then, you can
place your observing code in your own accessor functions, and provided
everyone uses them instead of the basic ones, which would violate
abstraction, it will work. You'll have to define yourself things like
MAP-3D-MODEL and use that instead of, say, MAPCAR, but it will be
probably a very thin layer over MAPCAR, and have the same interface,
so it should not be a big deal. As a plus, should you later choose to
use another data structure instead of conses, you'll be able to a
degree to keep the interface intact while changing the implementation;
had you used CAR, CDR, MAPCAR etc. directly, every user of your data
structures would have to change his/her code.

[snip]

hth,
Alessio