Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Lisp, the incarnation of expressiveness ...
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  21 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Lieven Marchand  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Lieven Marchand <m...@bewoner.dma.be>
Date: 1999/05/18
Subject: Re: Lisp, the incarnation of expressiveness ...

Robert Kiendl <rkie...@gmx.net> writes:
> i am pretty new to the lisp community.  someone told me that lisp is the
> language that provides quite every structural concept found in any other
> language. also Paul Grahams introductory comments in "ANSI Common Lisp"
> can get you delighted.
> as far as i got insight to lisp up to now, it really seems to satisfy
> many promises. especially in fields of versatile operator programing
> (the term "functional programing" misleads in my opinion because it is
> associated with restrictive mathematical mappings), dynamic structures
> and types.

welcome aboard ;-)

> though i quickly can find fifty items where lisp is (much) more
> "eloquent" and productive like for example c++, there remain few but
> heavy scruples.

> Besides things like

> - odd source code reading, which is a point of habit (i hope)

It is, and it is made easier by a very uniform way of indentation
among experienced Lisp programmers. Much of the homework code posted
here is simply not readable until formatted in the standard way.

> - low speed, which is not so heavy weight with modern compilers and
>   c++-interfaces (for algorithms at the low level layer of the program)

CL can be written to be very fast but the style in which you do it is
different. First you write your program as clearly as possible paying
attention to choice of algorithms, space/time trade offs etc and then,
*if* your application is too slow you can profile it and optimize the
hot spots by adding declarations or other means. There have been cases
cited on this group where a CL implementation tuned like this was
faster than a C/C++ implementation it replaced. Especially since you
cite MFC later on, MFC is many things but a speed daemon it is
certainly not ;-)

> - poor encapsulation formalism with respect to mind relieving          
> OO-thinking (automatic object context, private/protected,    
> overloading mechanisms ...), which is partially weight up by dynamic    
> features and to the other part is (probably) an inevitable tribute
> to       the versatile operator approach

Again, I think you're approaching this from the wrong angle. Yes,
there are certain features (::, SLOT-VALUE) that can be used to
violate encapsulation, but nobody is forcing you to use them. All
access to slots can be done by accessors which are an alternative mean
to encapsulation. private/... can be done by selectively exporting in
different packages. (Not that you should try to write C++ in CLOS
syntax) If you worry that some coworker might use these features to
break your classes, the same can be done in C++

#define private public
#include "class.h"

[Note to C++ language lawyers, I know about the One Definition Rule
but this has a fair chance of working in practice]

The answer to such concerns is education and code review. No useful
language can shield you from such tricks.

> there seem (to me) some "real" lacks. They mostly have to do with so
> called missing "destruction automization" and the "hiding of the pointer
> !type!"). The problem seems also to overlap with the coercion to the
> "garbage collecting".

In a way garbage collection is destruction automation. Theoretically
finalization is missing, although I wonder how useful it is in
practice. If you want to control stuff when an object becomes
unreachable, timing is usually also important. You don't want to wait
with closing file descriptors until your application exits, you want
to do it fairly soon after a stream object becomes unreachable.

And looked at in another way, everything in CL is a pointer.

--
Lieven Marchand <m...@bewoner.dma.be>
If there are aliens, they play Go. -- Lasker


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "lisp pretty printer on files?" by John Atwood
John Atwood  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: atwo...@bronze.CS.ORST.EDU (John Atwood)
Date: 1999/05/18
Subject: lisp pretty printer on files?

>> - odd source code reading, which is a point of habit (i hope)

>It is, and it is made easier by a very uniform way of indentation
>among experienced Lisp programmers. Much of the homework code posted
>here is simply not readable until formatted in the standard way.

How do I get code formatted in a standard way?
I have an editor that'll format a block of code on command, but
I often view a file, only to find that it's not formatted to my
tastes.  I've read a little about Water's XP and chapter 22 of
the HyperSpec concerning the Pretty Printer, it's too fine
grained. I'm seeking a way to format a file or list of files
according to one of a small set of pre-defined styles.  Emacs
probably does this, but I don't use emacs much; how would this
be done in emacs?

John Atwood


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Lisp, the incarnation of expressiveness ..." by Marc Battyani
Marc Battyani  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: "Marc Battyani" <Marc_Batty...@csi.com>
Date: 1999/05/18
Subject: Re: Lisp, the incarnation of expressiveness ...

Lieven Marchand <m...@bewoner.dma.be> wrote in message

news:m37lq61bt3.fsf@localhost.localdomain...

> In a way garbage collection is destruction automation. Theoretically
> finalization is missing, although I wonder how useful it is in
> practice. If you want to control stuff when an object becomes
> unreachable, timing is usually also important. You don't want to wait
> with closing file descriptors until your application exits, you want
> to do it fairly soon after a stream object becomes unreachable.

I find finalization very useful for some UI objects like fonts pens
brushes OpenGL display lists etc..
When they are collected you have to free the underlying OS object also.
It's generally not worthwhile to bother to release them as soon
as possible.

Marc Battyani


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Johan Kullstam  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Johan Kullstam <kulls...@ne.mediaone.net>
Date: 1999/05/18
Subject: Re: Lisp, the incarnation of expressiveness ...

you get used to it.  i am a lisp newbie.  now i find both lisp and C
to be weird looking.

> - low speed, which is not so heavy weight with modern compilers and
>   c++-interfaces (for algorithms at the low level layer of the
>   program)

the speed isn't as low as you seem to think.  good lisp compilers
exist.  lisp may add some overhead compared to C, but it won't
suddenly turn O(n) algorithms into O(n^2) algorithms.  you never know,
sometimes the lisp solution can be faster since you have a more simple
and direct way to express it.

> - poor encapsulation formalism with respect to mind relieving          
> OO-thinking (automatic object context, private/protected,    
> overloading mechanisms ...), which is partially weight up by dynamic    
> features and to the other part is (probably) an inevitable tribute
> to       the versatile operator approach

private/protected is imho overrated.  it just gets in your way without
helping much.  (if i could protect data in a C++ from getting nuked by
a stray pointer, *then* maybe i could see the point...)

sure.  lisp keeps track of all this for you.  basically, you just stop
refering to something and it'll get reaped by the collector.  this is
an issue that the lisp vendor takes care of for you in their
implementation of the garbage collector.

if you do make some huge data structures and need to unload them, it
can be tricky to find all the referents, however.  i think this is
what you were trying to get at in your question.  i am sure that there
are tools to find what is using memory.  perhaps someone with better
lisp knowledge/experience can comment on how to track things down.

> With my lisp knowledge i do not see a handsome way to realize that
> concept in lisp. I hope someone out there can tell me that its possible
> anyhow.

*you* don't need to realize it all.  just lay back and accept it!  ;-)

> There are some other scruples rooted mainly in the hiding of the pointer
> type in lisp. but if someone can tell me a way to realize those
> automatic links those scruples may also disapear. Bjarne Stroustroup
> said, that it is dangerous to restrict language means just for the
> intention of preventing from bugs (this prevention comes better from the
> bottom up way: restrict where you like it). This is the reason for
> example why JAVA is not a universal language suited for really complex
> structured programs, though many poeple fascinated by the great network
> and platform independent gui features think that.
> My summarizing question is: Does the hiding of the pointer type and
> garbage collection in the bottom up lisp language throw a shadow on
> the space of expressiveness (analog to an area of disclosure of
> computability in the sense of Goedel :-)) which comes apparent even
> on the high level like for example in the above mentioned problem?
> Or is it possible to enlight those area from the backdoor?

in my (limited) experience with lisp, low level cruft just doesn't
come up as an issue.  i can do what i like.  i don't worry about
memory allocation.  i have a hard enough time trying to phrase things
properly.  i find lisp to be totally backwards when coming from
languages such as C and fortran.  (i don't mean lisp is wrong, it's
just different.  i get the feeling of standing on my head since i have
spent many years hard wiring myself into C/C++.)

> Or: Lisp is great on managing symbols and semantics of symbols. This
> includes symbols which other languages have in the "code segment". But
> is Lisp also great on connections (which do not suit in the hierarchy
> paradigm)?

what do you mean `connections'?

> Robert
> delphi creativ technologies

--
johan kullstam

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 1999/05/18
Subject: Re: Lisp, the incarnation of expressiveness ...
* Robert Kiendl <rkie...@gmx.net>
| i am pretty new to the lisp community.
:
| there seem (to me) some "real" lacks.

  which other disciplines do you consider yourself sufficiently well versed
  in to judge while you admit to being pretty new to them?  would you, say,
  walk into a hospital and tell the staff how to run the place?  would you
  take over the operating theater because you had seen a better way to do
  it on Chicago Hope?  do you, say, take the control of boats or planes?

  or would you perhaps try to learn first instead of judge first in other
  disciplines?

  I think the reason people find "lacks" with Lisp is that they actually
  expect everything in computing to be so simple they can understand it
  right away, since that's how things work in the mass market segments,
  where anyone with above average IQ is ahead of the "user-friendly" baby
  talk.  Lisp, however, is not optimized for newbies and well-below-average
  mass market consumers.  Lisp has its own traditions, far removed from the
  newbiedom that Microsoft, et al, have monopolized and capitalized on.

  my advice to those who are used to understanding much more than the user
  friendly crap intended them to do and thus acquire a haughtiness and
  arrogance towards new fields in computing that they might think are as
  stupidly designed as the ones they legitimately know better than, is to
  expect something different from what _looks_ different from what they're
  used to and to seize the opportunity to learn from the different rather
  than, effectively, to dumb it down to whatever they already understand
  much better than the designers.

  (if you felt insulted by the above, please give up Lisp, too.)

#:Erik
--
@1999-07-22T00:37:33Z -- pi billion seconds since the turn of the century


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Kiendl  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Robert Kiendl <rkie...@gmx.net>
Date: 1999/05/18
Subject: Lisp, the incarnation of expressiveness ...
hi !

i am pretty new to the lisp community.  someone told me that lisp is the
language that provides quite every structural concept found in any other
language. also Paul Grahams introductory comments in "ANSI Common Lisp"
can get you delighted.
as far as i got insight to lisp up to now, it really seems to satisfy
many promises. especially in fields of versatile operator programing
(the term "functional programing" misleads in my opinion because it is
associated with restrictive mathematical mappings), dynamic structures
and types.

though i quickly can find fifty items where lisp is (much) more
"eloquent" and productive like for example c++, there remain few but
heavy scruples.

Besides things like

- odd source code reading, which is a point of habit (i hope)
- low speed, which is not so heavy weight with modern compilers and
  c++-interfaces (for algorithms at the low level layer of the program)
- poor encapsulation formalism with respect to mind relieving          
OO-thinking (automatic object context, private/protected,    
overloading mechanisms ...), which is partially weight up by dynamic    
features and to the other part is (probably) an inevitable tribute
to       the versatile operator approach

there seem (to me) some "real" lacks. They mostly have to do with so
called missing "destruction automization" and the "hiding of the pointer
!type!"). The problem seems also to overlap with the coercion to the
"garbage collecting".
Apart from simple things like e.g. a automatic CHideCursor"-object
(M...soft/MFC) i'll give an example deeper
associated with expressiveness of a computer language.

In a simulation software i wrote (c++), there exist various objects (for
example MInfoAtom), where from many locations in the program (other
dynamic objects, globals, ...) is pointed to. Sometimes there is reason
the destroy those pointed-to-objects. the locations which point to
should be informed (for example - to set the pointers to 0). Its very
hard to book-keep those widespread non-uniform connections. therefore in
c++ i created a "reflecting pointer class template" (PR<class T>).
the "PR-pointable-to" classes incorporate a simple uniform
Interface-class IPR ("class MInfoAtom: public other_base_classes, public
IPR").
If I want to define a reflective pointer i just write "PR<MInfoAtom>
mylink" instead of "MInfoAtom* mylink". the PR-Pointer class behaves
nearly like a normal pointer, i do not have to worry about during
writing code, i can also mix it with other pointers. I also use that new
pointers heavly inside of other template-containers (lists, maps,
queues, index-containers ...). they savely get informed by the mechanism
in the IPR-destructor interacting with PR<> when i make "delete myobj"
from anywhere. i also use complexer pointertypes like a PRH<class T>
which incorporates a share-holder concept. I use them all mostly like
normal pointers. The additional pointer properties are determined a the
definition location.
The software is "contaminated" with those "automatic links" and they
really do a good and efficient job preventing me from
getting jumbled in the complex connection structure of the program. Also
the robustness of the software gained very much from that concept.

I can hardly imagine to rewrite such software not having this automatic
link concept at hand.

With my lisp knowledge i do not see a handsome way to realize that
concept in lisp. I hope someone out there can tell me that its possible
anyhow.

There are some other scruples rooted mainly in the hiding of the pointer
type in lisp. but if someone can tell me a way to realize those
automatic links those scruples may also disapear. Bjarne Stroustroup
said, that it is dangerous to restrict language means just for the
intention of preventing from bugs (this prevention comes better from the
bottom up way: restrict where you like it). This is the reason for
example why JAVA is not a universal language suited for really complex
structured programs, though many poeple fascinated by the great network
and platform independent gui features think that.

My summarizing question is: Does the hiding of the pointer type and
garbage collection in the bottom up lisp language throw a shadow on the
space of expressiveness (analog to an area of disclosure of
computability in the sense of Goedel :-)) which comes apparent even on
the high level like for example in the above mentioned problem? Or is it
possible to enlight those area from the backdoor?

Or: Lisp is great on managing symbols and semantics of symbols. This
includes symbols which other languages have in the "code segment". But
is Lisp also great on connections (which do not suit in the hierarchy
paradigm)?

Robert
delphi creativ technologies


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jason Trenouth  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: ja...@harlequin.com (Jason Trenouth)
Date: 1999/05/18
Subject: Re: Lisp, the incarnation of expressiveness ...

On Tue, 18 May 1999 13:02:58 +0200, Robert Kiendl <rkie...@gmx.net> wrote:

...

> In a simulation software i wrote (c++), there exist various objects (for
> example MInfoAtom), where from many locations in the program (other
> dynamic objects, globals, ...) is pointed to. Sometimes there is reason
> the destroy those pointed-to-objects. the locations which point to
> should be informed (for example - to set the pointers to 0).

...

Perhaps you want something like weak pointers? Many GC'ed languages have a
notion of weak pointers. Basically, these pointers are not traversed for the
purposes of deciding what to retain when GCing. The result is that if you
throw away all normal references to an object, the object will be GC'ed
despite any weak references, and the weak references will be replaced by NIL
or somesuch value.

So one of your data structures might be modelled as, say, a "weak table"
containing your deleteable objects. Then when the responsible part of the
program deletes an object (e.g. by removing it from a normal table, leaving no
other references), the weak table will be updated by the GC to contain NIL.

Search your Lisp vendor's documentation for "weak".

__Jason


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options May 18 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/05/18
Subject: Re: Lisp, the incarnation of expressiveness ...

* Robert Kiendl wrote:
> I can hardly imagine to rewrite such software not having this automatic
> link concept at hand.
> With my lisp knowledge i do not see a handsome way to realize that
> concept in lisp. I hope someone out there can tell me that its possible
> anyhow.

I think what you are after is an object which keeps track of all the
objects that reference it, so that when you `destroy' the object, it
can tell all the people that refer to it that it has been destroyed so
(in C++) you don't end up with dangling pointers.

Well, in Lisp you never destroy an object or end up with dangling
pointers as a result of that, but things along these lines are still
fairly useful, so you can at some point say `I want this to be GCable
now'.

I can see several ways of doing this in Common Lisp, of slightly
varying amounts of portability.

The simplest translation of your technique is to write a class which
deals with dependencies in this way, and then mix this in to all the
classes you are interested in.  Then the `I want to make this GCable'
operation on this object would end up doing something like:

        (map-dependents #'(lambda (d)
                            (remove-reference d o))
                        o)

For this kind of thing it's quite nice if dependents are `weak' in
some way, so that an object doesn't end up holding onto references to
all sorts of transient things.  There is a dependency maintenance
protocol in the Art of the Metaobject Protocol book, and I have a
version of that somewhere if anyone is interested.

Another, slightly clunky, approach is to have the interesting object
be one extra indirection away, so you can then nullify that
indirection.  This is kind of steam weak-pointers -- the people
referencing the object still end up pointing to something, but that
something is hopefully a bunch cheaper than the original object (for
instance, a fixnum).

I often do this with hashtables (I've just typed this in, please don't
take it too seriously):

    (defvar *obhash* (make-hash-table))

    (defvar *obcount* 0)

    (defun make-avatar-for (ob)
      (setf (gethash *obcount* *obhash*) ob)
      (prog1 *obcount*
        (incf *obcount*)))

    (defun avatar-object (avatar)
      ;; 2nd value is `is it there?'
      (gethash avatar *obhash*))

    (defun remove-avatar-object (avatar)
      (remhash avatar *obhash*))

With an implementation like this, assuming you stick to less than a
fixnum-worth of objects, the avatars are pretty cheap, so the main
space cost is the hashtable, and the time cost is the hash lookup on
each reference.

Another, non-portable, approach would be to use weak pointers for the
references.  This is still quite hard work because you have to make
sure there is at least one strong reference to the object unless you
*really* want to be living in C++-land...

These approaches -- certainly the dependency stuff -- are pretty close
to some of the things that the design patterns people talk about.

> My summarizing question is: Does the hiding of the pointer type and
> garbage collection in the bottom up lisp language throw a shadow on the
> space of expressiveness (analog to an area of disclosure of
> computability in the sense of Goedel :-)) which comes apparent even on
> the high level like for example in the above mentioned problem? Or is it
> possible to enlight those area from the backdoor?

No, I don't think it does.

--tim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "lisp pretty printer on files?" by Christopher R. Barry
Christopher R. Barry  
View profile  
 More options May 19 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: cba...@2xtreme.net (Christopher R. Barry)
Date: 1999/05/19
Subject: Re: lisp pretty printer on files?

atwo...@bronze.CS.ORST.EDU (John Atwood) writes:
> I'm seeking a way to format a file or list of files according to one
> of a small set of pre-defined styles.  Emacs probably does this, but
> I don't use emacs much; how would this be done in emacs?

Emacs will _indent_ an entire buffer if you do C-x h to mark the
buffer and then C-M-\ to indent the region.

Christopher


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Lisp, the incarnation of expressiveness ..." by Lieven Marchand
Lieven Marchand  
View profile  
 More options May 19 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Lieven Marchand <m...@bewoner.dma.be>
Date: 1999/05/19
Subject: Re: Lisp, the incarnation of expressiveness ...

"Marc Battyani" <Marc_Batty...@csi.com> writes:
> I find finalization very useful for some UI objects like fonts pens
> brushes OpenGL display lists etc..
> When they are collected you have to free the underlying OS object also.
> It's generally not worthwhile to bother to release them as soon
> as possible.

Is there a limit on the number of allocated stuff like that? The main
problem I always saw was that if your OS had a limit, you could reach
that limit before garbage collection. But I agree when that's not the
case it can be useful.

--
Lieven Marchand <m...@bewoner.dma.be>
If there are aliens, they play Go. -- Lasker


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options May 20 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 1999/05/20
Subject: Re: Lisp, the incarnation of expressiveness ...
* Lieven Marchand <m...@bewoner.dma.be>
| Is there a limit on the number of allocated stuff like that? The main
| problem I always saw was that if your OS had a limit, you could reach
| that limit before garbage collection. But I agree when that's not the
| case it can be useful.

  if the OS has such a limit, you should get an OS, or make the functions
  that allocate such objects cause a garbage collection, if you can't get
  an OS.  other people's limitations are to be overcome, not succumbed to.

#:Erik
--
@1999-07-22T00:37:33Z -- pi billion seconds since the turn of the century


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options May 20 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/05/20
Subject: Re: Lisp, the incarnation of expressiveness ...

* Lieven Marchand wrote:
> Is there a limit on the number of allocated stuff like that? The main
> problem I always saw was that if your OS had a limit, you could reach
> that limit before garbage collection. But I agree when that's not the
> case it can be useful.

However it's essentially trivial to cause hitting that limit to invoke
a GC.

--tim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lieven Marchand  
View profile  
 More options May 20 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Lieven Marchand <m...@bewoner.dma.be>
Date: 1999/05/20
Subject: Re: Lisp, the incarnation of expressiveness ...

Erik Naggum <e...@naggum.no> writes:
> * Lieven Marchand <m...@bewoner.dma.be>
> | The main problem I always saw was that if your OS had a limit, you
> | could reach that limit before garbage collection.

>   if the OS has such a limit, you should get an OS, or make the
>   functions that allocate such objects cause a garbage collection,
>   if you can't get an OS.  other people's limitations are to be
>   overcome, not succumbed to.

The OS I'm currently using (Linux) has for instance, maximum number of
open files per process, maximum number of child processes per process,
and a whole number of similar limits, the values of some of which can
be queried by sysconf() and the value of others who can only be
guessed at. Is your limitless OS available somewhere?

--
Lieven Marchand <m...@bewoner.dma.be>
If there are aliens, they play Go. -- Lasker


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Kiendl  
View profile  
 More options May 21 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Robert Kiendl <rkie...@gmx.net>
Date: 1999/05/21
Subject: Re: Lisp, the incarnation of expressiveness ...

> > In a way garbage collection is destruction automation. Theoretically
> > finalization is missing, although I wonder how useful it is in
> > practice. If you want to control stuff when an object becomes
> > unreachable, timing is usually also important. You don't want to wait
> > with closing file descriptors until your application exits, you want
> > to do it fairly soon after a stream object becomes unreachable.

> I find finalization very useful for some UI objects like fonts pens
> brushes OpenGL display lists etc..
> When they are collected you have to free the underlying OS object also.
> It's generally not worthwhile to bother to release them as soon
> as possible.

so ANSI common lisp really seems not to have means for real destruction
automation.
in fact that UI object example was just a hook for triggering the right
focus:
determinism. it misses the point discussing if we can release such
object sooner or
later.

that PR-thing i mentioned uses the destruction automatism for data
structural purposes. deterministic finalization is used there to rise
essential information!
also this PR-thing was just one example. PR is not just used for set
references to nil, but also for more complex signals.
the second point was that PR is a type-expansion of a c++-pointer type.
so both things i wanted to mainly discuss in that letter come togehter
in that PR-example. thats why i brought this example: Both things -
destruction automation and the bottom up exposial of the pointer type to
the hands of the programmer - especially if they are used together they
provide some new space of expressiveness in the computer language.

a few other guys brought into play that weak-vectors and so .... those
are not much more than fine excuse.
1. they do not allow that program driven kill action. you'd have to have
alle "normal" references "weak" except one which "holds" and wich you
have again to publish widely to allow that kill access (indexes ...
§=$%?!). thats not applicable.
2. you have to worry about those special weak things (vectorref. even
for one element, ...). every location where you reference the object to
get into trouble. you cannot even automate this things completely by a
macro, because in lisp you cannot automate the behaviour of the type. so
you have to fumble in every sourcecode location, you cannot automate
this by one declaration (->hiding of the pointer type).
3. it is not ANSI - by good reason. it is thought for memory management
not as a structural mean.

in fact i still have no idea how to transfer essential data structure
concepts of the simulation-code i mentioned into lisp without giving up
all the elegance
- strange that those problems are not a point of speed or low-level.

one little help would be at least if lisp would allow to explitely kill
a thing, setting all references to nil by force. because of the GC the
information for the necessary backlinks should be present in nearly
every implementation (am i right?). this capability would catch at least
the simplest behaviour of that PR-example.

so after receiving tons of new capabilities turning to lisp i'am getting
aware of some essential lacks (im comparison to e.g. c++) which you
cannot excuse with a c++-mindset. those lacks arise from
- weak destruction automation
- hiding of the nature of pointers
- mostly missing type-automation at the point of
declaration/instantiation
also some bad encapsulation in CLOS (especially: no implizit object
context in methods) forces you to write some things redundantly, but
this is minor

robert


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steve Gonedes  
View profile  
 More options May 21 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Steve Gonedes <sgone...@worldnet.att.net>
Date: 1999/05/21
Subject: Re: Lisp, the incarnation of expressiveness ...

Robert Kiendl <rkie...@gmx.net> writes:

< that PR-thing i mentioned uses the destruction automatism for data
< structural purposes. deterministic finalization is used there to rise
< essential information!

There is a program that allows common lisp to be `deterministic', but
I cannot remeber the name right now - it's very popular and mentioned
quite often on this news group though...

[...]

< one little help would be at least if lisp would allow to explitely kill
< a thing, setting all references to nil by force.

(defvar *thing* "this is a thing")

(setq *thing* nil).

< so after receiving tons of new capabilities turning to lisp i'am getting
< aware of some essential lacks (im comparison to e.g. c++) which you
< cannot excuse with a c++-mindset. those lacks arise from
< - weak destruction automation

What is `weak destruction automation'?

< - mostly missing type-automation at the point of [...]

Could you give an example of `type-automation'? I have read the phrase
`type-automation', before but could not make sense of it. Have you
tried using the macro facility for automation of `type'?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options May 21 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/05/21
Subject: Re: Lisp, the incarnation of expressiveness ...

* Robert Kiendl wrote:
> one little help would be at least if lisp would allow to explitely kill
> a thing, setting all references to nil by force. because of the GC the
> information for the necessary backlinks should be present in nearly
> every implementation (am i right?). this capability would catch at least
> the simplest behaviour of that PR-example.

I still don't see why you can't do this with a dependency mechanism,
which must be basically similar to what you are doing in C++:

(defun kill (x &rest args)
   (map-dependents #'(lambda (d)
                       (apply #'release d x args))
                   x)
   (arrange-for-os-stuff-to-be-freed-for x)
   (values))

X may actually not go away at this point, but all the people who
referenced it no longer do so (assuming that's what RELEASE does).

--tim


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Marc Battyani  
View profile  
 More options May 21 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: "Marc Battyani" <Marc_Batty...@csi.com>
Date: 1999/05/21
Subject: Re: Lisp, the incarnation of expressiveness ...

Robert Kiendl <rkie...@gmx.net> wrote in message

news:37459292.C5AD9287@gmx.net...
> that PR-thing i mentioned uses the destruction automatism for data
> structural purposes. deterministic finalization is used there to rise
> essential information!
> also this PR-thing was just one example. PR is not just used for set
> references to nil, but also for more complex signals.
> the second point was that PR is a type-expansion of a c++-pointer type.
> so both things i wanted to mainly discuss in that letter come togehter
> in that PR-example. thats why i brought this example: Both things -
> destruction automation and the bottom up exposial of the pointer type to
> the hands of the programmer - especially if they are used together they
> provide some new space of expressiveness in the computer language.

....

I don't see the point of all this. If you want to keep references to
parent/child
or friend objects you can. I do this very often. Then when you destroy/close
/modify etc this object you can have the other ones receive notifications
automatically .

> in fact i still have no idea how to transfer essential data structure
> concepts of the simulation-code i mentioned into lisp without giving up
> all the elegance

I've done it and now it's much more elegant than in C++.(and without bugs)

> so after receiving tons of new capabilities turning to lisp i'am getting
> aware of some essential lacks (im comparison to e.g. c++) which you
> cannot excuse with a c++-mindset. those lacks arise from
> - weak destruction automation

No see above.

> - hiding of the nature of pointers

Good!

> - mostly missing type-automation at the point of
> declaration/instantiation

Good too. In Lisp type information is used when needed. You don't
have to bother with this if you don't want to.

> also some bad encapsulation in CLOS (especially: no implizit object
> context in methods) forces you to write some things redundantly, but
> this is minor

This is not a lack but a feature. Generic functions are not methods on an
object.

Marc Battyani


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Kiendl  
View profile  
 More options May 24 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Robert Kiendl <rkie...@gmx.net>
Date: 1999/05/24
Subject: Re: Lisp, the incarnation of expressiveness ...
i hope it is not too boring for you all but my
problems representing some structures in lisp are still pending.
(maybe i should read more books, but if one puts my nose on the
right point ...)

so i have to bring up some simple c++ example which lights one
of the problems. the world of anmials often best animates
programmers understanding so ...

[
the points of attention should be my skruples/concerns
about lisp mentioned in the last mail:

>- weak destruction automation
>- hiding of the nature of pointers
>- mostly missing type-automation at the point of

   declaration/instantiation
]

//(some Pxx code is at the end of the file if necessary)

//in our model we have birds

class MBase : public IPR, public IPH, public ... {...};
class MBird : public MBase
{
  ...

};

// we also have some world containers like
class MSky : public ...
{
  ...
  map<int, PRH<MBird> > birds ;              // here they are
  d3_dictionary<MXYZ, PR<MBase> > space; // another index
  pqueue<double, PR<MBird> > interesting; // some of them i'm working on

  // we have some nice access:

  MBird* lookup(int id);
  list<MBase*> lookup(MShere& s) { ... care a little about NULL birds ... }

  // we do some normal work

  void step() { forall(MBird* it, birds) if (it) it->fly(); }

  ...

};

// somewhere is a camera
class VSky : public CView ...
{
  P<MSky> sky;                    // we hold a sky
  // we have marked some
  class VMark {
     ...
     list<PR<MBird> > birds;        
  } mark;
  ...

};

// somewhere is a hunter
class MHunter
{
  PE<MGun> gun;
  PR<MBird> focus;
  P<MBird> cage;
  MBird* aim() { return focus ? focus->danger++, focus : NULL };
//// speed annot.: if p is of type PR<> "p->a++" still compiles
//// to one machine instruction "inc  dword ptr [eax+4]" with -O2
//// despite of all that template stuff the compiler has to digest
  bool shoot(MBird* bird) {
    ...
    bird->pr_message("quiiick");
    return gun ? delete bird, true : false; // occasionally one disapears
  }
  ...

};

// there is also some global listener
static class __TEMP__ : public PR<MBird>
{
  virtual void message(char* s) {... protocol << s;  ...}
  ...
} microphone;

//////////////// birds birds birds ... //////////////////////

there are just few points that interest me about that shit:

- wenn sky terminates all birds also disapear immediately:
  no sky no birds. no one can even "quiick" any more.
  the thing that makes it is the "..PRH.." in the map-definition.
  it says: you map will hold the birds.
  [ in case a Java&Basic-GC-fan is out there: there is not any single
    bird-delete in any of the "..."s. map<> and PRH<> do that;
    and please do not rise the circular-list-discussion here; if i
    say hold i mean hold and not "don't worry"
  ]
  sometimes this is not totally correct; a bird can be both in the
  sky and in a cage, in case such bird persists though there is no
  sky (the ecologist may excuse that strange model but i want so).

  in lisp - shure - i know how to hold: the GC does it by default
  anyway.
  [ i am just concerned a little bit about that uncertainty at the falling
    edge. may be spreading some gc-calls helps. someone told from other
    deterministic programs for lisp ...? but all this can discussed
    after first reading the rest ...
  ]
  but look at all the other bird-refs beside that single PRH. if i
  do them in lisp as normal things they all hold: the marker, the focus
  (, the index containers if not sky completely destructs), ...
  i do not want them to hold and
  i do not get rid of that shit 100's of cross referenced birds. the hunter
  aims at that virtual reality bird and so on ...
  so i have to act:
  the only way _not_ to hold (99% of the other references above :-)) i
  know now is using that non-ANSI weak stuff.
  [ if i use that, do i have to everywhere fumble
    svref's on the tables where i access
    that references? (macro or not, i have to act at the access
    points?)  your weak-let i think is for traversed functional
    bodies. or also for closures? but that temp and local locations are
    not so troubling here.
    can i also do so at object positions [CLOS-slots, lying arround lists,
    ...] and let automate at the access points: e.g. using
    (slot-value c 'my-variable) somewhere 5 kilometers source code away
    not knowing if a weak-vector is in or not when passing to the next
    action?! (the opposite i meant
    with "fumble": you have to at least trigger a read-char-macro, use special
    access functions (-> i constantly must know about the weak nature)
    or so near the access point)
    but anyway who wants express such essential stuff non-ANSI ?    
  ]
  or may be someone lateron tells me how to completely rearrange that whole
  shit totally different in a lisp-oo-way, and all i said here about
  holding and reflecting is completely unnecessary. so lets go further ...

- in that code above everywhere i handle and move around the birds by
  simply by using them in the natural way (it->fly(), focus ? ,
  assignments, constructions, intermediate lists, p->a++, if (gun) ... .
  special behaviour is expressed solely at the definition point.
  i think e.g.: my bird-refs in VMark must be informed, i use PR<>;
  my cage must share-hold the bird, i use P<>; my gun belongs to MHunter,
  so use PE<>; ...
  i feed this concepts in once (in an aspect-oriented programming
  style!?) and do not think a lot about at the other 1000 times i access
  and use the variables.

- i can shoot down a bird somewhere in the code in a consistent manner.
  [
    thats why i asked in the last mail for a _kill_ for lisp things and for
    that backlinks in the GC-mechanism
    i think the backlinks exist at least in case of that weak stuff?
  ]
  [ this is not done by (defvar *thing* "this is a thing") (setq *thing* nil)
    like someone mentioned; that doesn't kill the thing but the reference.
    its of course also not automated to do "delete" in the shoot-func,
    i am not willing to automate a thing i intentionally want to rise.
    a future AI program may be able to automate this but not this simple
    code. what's automated is what happens in response to delete bird:
  ]
  the whole shit is informed of the disapearing bird (immediatly).
  neither in the shoot func nor in MBird-class i made explicite control
  for the necessary backlinks. i just fed in the above mentioned concepts
  at some declaration points. elsewhere i just wrote normal natural c++.
  [ microphone is also informed with other stuff than "delete"
    though it is just a type-expansion of a pointer; this is just an
    example to show what i mean with hiding of pointer in lisp.
    the pointer-thing in c++ can be treated as real type; of course one
    can do that message shit other ways by writing some extra
    complex protocol code into MBird and a Listener Class, establishing
    that multiple doubly link stuff, and so on. but the normal pointers
    are already there anyway and i simple type-expand that PR-mechansim in
    three local lines not fumbling anywhere else and can route the message
    through the same infrastructure than the delete.
  ]
- because mentioned things are automated in the types it is hard
  to write bugs concerning the interconnection properties.
  if a basic/java programmer wants to represent above simple structure
  - for example that shoot-capability - he gets crazy keeping track
  of the interconnection semantics.
  this guides to that question in my first mail: "But is lisp also great
  on connections (which do not suit in the hierarchy paradigm)?" in my
  first mail.

so looking for example at that shit c++-example above and wanting to convert
the structes (in a nonredundant style! if i have to explicitely write out
interconnection semantics throughout the code or spread macro-chars and
special access-operators selectively over the mass of the code i am
not far from Basic&Java.) to lisp there must be done something. may be
in a completely different lisp way? how to ... thats was and is my
question and i still don't see the way.
in some real c++ programs also some other aspectes of that 3
mentioned points on the top of this file are important, but the key i think
is rooted in that bird example.

the lisp macros - down to the read-char-dispatch macros - are the best things
in lisp. allowing nearly everything in the functional sense. here they
must be drilled to make data-type-automation. and perhaps they must be
drilled to trick the limitation introduced by the coercion to the garbage
collecting (at least in ANSI CL). must they? if yes how?

robert

PS:
weaved in the above example is a way C++-mm resembles and even
overcomes GC (by pure c++), thereby differentiating on the needs of
the objects. that is possible because c++ is providing languange level
access to the pointer type (some overloading features) and allows
to really expand behaviour of types especially that pointer type.
in opposite to for example java which has to live in the sandbox of
wood-blocks-LEGO(R)-OOP.
so it is also possible to bring up destruction automation for high-level
purposes stressed in the above example.

this 3 (or 4) things discussed in this file are of course only 3 of lets say
100 things a good programming language has to feature, most of them
best occupied by lisp (for a programmer who needs / wants / can deal with
those feateares in order to gain extra speeed)
thats why i use lisp. my question is if those things i stressed above form
a sort of "base vector" for programming languages which is not (so
easily) substituable by combinations of other "vectors". (i am not
a mathematician!)

i really don't give up lisp. i just want discuss 3 aspects.
and i think lisp is a living language: you can discuss
about or at least ask questions.

------------------------------
Paul Foley schrieb:

...

read more »


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steve Gonedes  
View profile  
 More options May 24 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Steve Gonedes <sgone...@worldnet.att.net>
Date: 1999/05/24
Subject: Re: Lisp, the incarnation of expressiveness ...

Robert Kiendl <rkie...@gmx.net> writes:

< - i can shoot down a bird somewhere in the code in a consistent manner.
<   [
<     thats why i asked in the last mail for a _kill_ for lisp things and for
<     that backlinks in the GC-mechanism
<     i think the backlinks exist at least in case of that weak stuff?
<   ]
<   [ this is not done by (defvar *thing* "this is a thing")
<        (setq *thing* nil)

<     like someone mentioned; that doesn't kill the thing but the reference.
<     its of course also not automated to do "delete" in the shoot-func,
<     i am not willing to automate a thing i intentionally want to rise.
<     a future AI program may be able to automate this but not this simple
<     code. what's automated is what happens in response to delete bird:
<   ]

I don't understand C++, so I don't know what your code does, but I
think I understand what you're trying to say. What I was trying to
demonstrate was that lisp provides no explicit, automatic pointer
manipulation; they're just handled automatically.

Perhaps this is more along the lines of what you're looking for?

(defclass object () ())
(defclass killed-object (object) ())
(defclass active-object (object) ())

(defmethod kill-object ((object object))
  (change-class object 'killed-object))

(defvar *object-x* (make-instance 'active-object))
(defvar *objects* (vector *object-x* *object-x*))
(defvar *object-x-ref* *object-x*)

*object-x*     => #<ACTIVE-OBJECT @ #x204f076a>
*objects*      => #(#1=#<ACTIVE-OBJECT @ #x204f076a> #1#)
*object-x-ref* => #<ACTIVE-OBJECT @ #x204f076a>

(kill-object *object-x*) => #<KILLED-OBJECT @ #x204f076a>

*object-x*     => #<KILLED-OBJECT @ #x204f076a>
*objects*      => #(#1=#<KILLED-OBJECT @ #x204f076a> #1#)
*object-x-ref* => #<KILLED-OBJECT @ #x204f076a>

The object has been killed. All references to the killed object refer
to the killed object.

You could of course define a method called delete on `object' if it
suits your needs better.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kenny Tilton  
View profile  
 More options May 24 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Kenny Tilton <t...@liii.com>
Date: 1999/05/24
Subject: Re: Lisp, the incarnation of expressiveness ...
Robert,

Robert Kiendl wrote:

> i hope it is not too boring for you all but my
> problems representing some structures in lisp are still pending.
> (maybe i should read more books, but if one puts my nose on the
> right point ...)

Well, I will suggest two solutions, both of which you invite! :)

First, "more books": The Art of the Metaobject Protocol, ISBN
0-262-61074-4. That and a Lisp that fully supports the Metaobject
Protocol will get you going. And, FWIW, I rolled something of my own
under a Lisp that did not have such full MOP support and it would
achieve the same...Lisp can do anything. :)

With AMOP you can cook up slots that register themselves as "interested
parties" of cooperating slot-values, then write a function called
#'c++-delete to notify them when you want something to be forgtten.

Second, "may be someone lateron tells me how to completely rearrange
that whole..."

Hello! :) It strikes me you are mixing inappropriately wildly different
levels of expression. Specifically, you think the C++ 'delete' operator
is a way to kill a virtual bird.

No way! But C/C++ are so close to the hardware--and efficiency has
historically been so important--that programmers have always not only
expressed virtual states as machine states, but they make the natural
mistake of then thinking the machine impelementation is the same as the
virtual implementation, such that, getting back to the bird,
'delete-ing' it should kill it (in the virtual world).

I could not follow all of what you wrote (I am doing this on company
time) but I also wonder why you have so many pointers to this bird lying
around, but that doesn't matter.

Anyway, to a certain extent your question was not about how to kill
birds nor even how to manage internal dependencies, but about what Lisp
can do, so I think you might want to dig into AMOP if you have not
already.

Cheers,

kt


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options May 26 1999, 3:00 am
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: 1999/05/26
Subject: Re: Lisp, the incarnation of expressiveness ...
I didn't really understand the C++ stuff in this thread (it's over 10
years since I did anything with C++ other than stare horrified at
it).  However I was inspired to try and see if I understood what was
going on, as some of it seems to be reasonably close to things I
already have.

Unfortunately the code I actually use is not releasable -- it doesn't
actually quite do this stuff and in any case it's pretty crufty stuff
I'm not that proud of. The attached code is just something I typed in
last night and shouldn't be taken very seriously. There's 2 layers of
it and a trivial example which uses the upper layer.

The bottom layer is a simple dependency class -- you can add & remove
(slowly) dependents and map over them.

The next layer is a class which can be told about people who `know
about it' and on being told to remove itself it will tell them do do
the appropriate thing (this uses double dispatch to avoid something
like the awful visitor pattern).  This also has a scope macro --
WITH-REMOVABLE-OBJECTS which will call the REMOVE-OBJECT GF at the end
of the dynamic scope of the macro.  Of course they still actually get
heap-allocated, perhaps some DYNAMIC-EXTENT declarations and a very
bright compiler could eliminate this (if you even wanted to).

Anyway, here it is, warts & all.

--tim

--cut--
;;; -*- Mode: LISP; Base: 10; Syntax: Ansi-common-lisp; Package: CL-USER -*-

;;;; Objects which have dependents.
;;; A fairly rudimentary implementation.
;;;

(defgeneric add-dependent (thing dependent)
  (:documentation
    "Register DEPENDENT as a dependent of THING, a subclass of DEPENDENCY-MIXIN.
Return DEPENDENT."))

(defgeneric remove-dependent (thing dependent)
  (:documentation
    "Remove a dependent of THING, a subclass of DEPENDENCY-MIXIN.
Return non-NIL if the thing was actually a dependent, tested with EQL"))

(defgeneric map-dependents (fn thing)
  (:documentation
    "Map FN, a function of one argument, over the dependencies of THING.
Return THING."))

(defclass dependency-mixin ()
    ((dependents :initform '())))

(defmethod add-dependent ((thing dependency-mixin) dependent)
  (push dependent (slot-value thing 'dependents))
  dependent)

(defmethod remove-dependent ((thing dependency-mixin) dependent)
  (with-slots (dependents) thing
    (let ((removedp nil))
      (setf dependents (delete dependent dependents
                               :test #'(lambda (x y)
                                         (if (eql x y)
                                               (setf removedp t)
                                               nil))))
      removedp)))

(defmethod map-dependents (fn (thing dependency-mixin))
  (mapc fn (slot-value thing 'dependents))
  thing)

;;;; `Removable' objects (bad name).
;;; These are things which keep track of their owners and can inform
;;; them when they are removed.  They do this by virtue of being
;;; DEPENDENCY-MIXINs.
;;;

(defgeneric add-object-to (remob to)
  (:documentation
    "Add REMOB, an instance of a subclass of REMOVABLE-OBJECT, to TO.
No primary method is defined for this GF -- you need to define one for
your classes. REMOB will learn that TO knows about it via an after method.
Return value unspecified (up to you)."))

(defgeneric remove-object-from (remob from &optional internalp)
  (:documentation
    "Remove REMOB, an instance of a subclass of REMOVABLE-OBJECT, from FROM.
No primary method is defined for this GF -- you need to define one for
your classes.  The optional third argument is used internally and should
not be supplied in user-calls to this.  REMOB will already have learnt
that it is being removed when the primary method
runs.  Return value unspecified (up to you)."))

(defgeneric remove-object (remob &optional junkp)
  (:documentation
    "Remove a REMOVABLE-OBJECT.  If the optional JUNKP argument is given
then the object will be removed in a quick & dirty way, suitable if it's
about to be thrown away. No primary method is defined for this GF -- you
need to define one for your classes.  All the dependents of REMOB will
be told to remove it before the primary method runs.   Return value
unspecified (up to you)."))

(defclass removable-object (dependency-mixin)
    ())

(defmethod add-object-to :after ((remob removable-object) to)
  (add-dependent remob to))

(defmethod remove-object-from :before ((remob removable-object) from
                                       &optional junkp)
  (unless junkp
    (remove-dependent remob from)))

(defmethod remove-object :before ((remob removable-object) &optional junkp)
  (map-dependents #'(lambda (d)
                      (remove-object-from remob d junkp))
                  remob))

(defmacro with-removable-objects (bindings &body bod)
  ;; this might be better implemented in terms of a CALL-WITH-x function
  `(let ,bindings
     (unwind-protect
         (progn ,@bod)
       ,@(mapcar #'(lambda (n)
                     `(remove-object ,n t))
                 (mapcar #'car bindings)))))

;;;; Example use.
;;;

(defclass named-object ()
    ;; the standard thing-wth-a-name, to make tracing a bit nicer
    ((name :initform nil
           :initarg :name
           :reader name-of)))

(defclass bird (named-object removable-object)
    ()
  (:default-initargs
    :name "Edward"))

(defmethod remove-object ((b bird) &optional junkp)
  ;; Must define this.
  (declare (ignorable junkp))           ;need to do this better
  (values))

(defclass birded-object ()
    ;; something that contains birds, like a sky or cage.
    ((birds :initform '()
            :accessor birds)))

(defmethod add-object-to ((b bird) (to birded-object))
  ;; double dispatch, this whole thing would be a pain without this, you'd need
  ;; something like visitor.
  (push b (birds to)))

(defmethod remove-object-from ((b bird) (from birded-object)
                               &optional secret)
  ;; REMOVE-OBJECT-FROM' contract is buggy, either the optioal argument
  ;; needs better explained or it needs better concealed.
  (declare (ignorable secret))
  (setf (birds from) (delete b (birds from))))

;;; Tracing

(defmethod add-object-to :before ((b bird) (to birded-object))
  (format t "~& Adding ~A bird to ~A~%"
          (name-of b) (name-of to)))

(defmethod remove-object-from :before ((b bird) (to birded-object)
                                       &optional annoying)
  (declare (ignorable annoying))
  (format t "~& Removing ~A bird from ~A~%"
          (name-of b) (name-of to)))

(defclass sky (birded-object named-object)
    ()
  (:default-initargs
    :name "the sky"))

(defclass cage (birded-object named-object)
    ()
  (:default-initargs
    :name "a golden cage"))

(defun test-bird ()
  (let ((s (make-instance 'sky
                          :name "cloudy sky"))
        (c (make-instance 'cage
                          :name "rusty cage")))
    (with-removable-objects ((b (make-instance 'bird
                                               :name "Louise")))
      (add-object-to b s)                       ;the bird is in the sky
      (add-object-to b c)                       ;and the cage
      (remove-object-from b s)
      (add-object-to b s)
      (values s c)
      ;; (and here the bird gets removed from the sky and the cage)
      )))


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »