Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!rochester!cornellcs!newsstand.cit.cornell.edu!portc01.blue.aol.com!news-peer.gsl.net!news.gsl.net!howland.erols.net!netcom.com!wnewman
From: wnewman@netcom.com (Bill Newman)
Subject: How to do this in Lisp?
Message-ID: <wnewmanDyzL1p.BFJ@netcom.com>
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
X-Newsreader: TIN [version 1.2 PL1]
Date: Wed, 9 Oct 1996 02:17:49 GMT
Lines: 65
Sender: wnewman@netcom18.netcom.com

In the last few days I have been thinking that it might be neat to do
a new version of a pet project of mine using Common Lisp instead of
C++.  (The recent appearance of CMUCL for Linux brings this to mind.)
While thinking about this, I thought of a problem which I solve easily
in C++ but which I can't think of a good Lisp-y solution for.  Does
anyone who's more knowledgeable about Lisp have suggestions?

(One suggestion might be "if it hurts, then don't do that": it's 
not natural to do this in Lisp and that's a Good Thing because
this is about as far from functional programming as you can get.)

Anyway, the problem is this..

I have a program to play the game of Go.  Part of the program does
tactical search.  For the purposes of this part of the program, you
needn't be familiar with Go; the algorithms are similar to search
algorithms in other games.  Basically, I have a function which is a
crude approximation to the goodness of the position, and the
approximation gets better as I search deeper and minimax the 
results.  At any given move, most of the board configuration does
not change, and most of the terms in the approximation
do not change.  Therefore, I can gain a large efficiency advantage (on
the order of tenfold) by avoiding copying the board
and exhaustively recalculating the approximate score.
Instead, I modify the board in place and update only those score
terms which are changed.

Now, if I do this when I am searching down various branches of the
tree, what do I do when I come back up the tree?  In C++, I define the
variables which change in the search to be of class Remembered<FOO>,
e.g. Remembered<int>, and I overload the assignment operator so that
it remembers the old value whenever the object is modified, and puts
it into a stack of changes to be undone.  When I come back up the
tree, I unwind the stack and undo the changes.  This works cleanly and
reasonably efficiently even when the Remembered<FOO> objects are used
as data members of other classes.

This seems like a reasonably natural and concise solution to the
problem.  However, I can't see how to express it elegantly in Common
Lisp.  All the ways that I can think of require references to members
of structures, so it would be impossible to implement the undo stack.

Any comments or suggestions?

  Bill Newman
  wnewman@netcom.com

PS.  I have also been thinking about the possible benefits of run-time
typing for my program.  I have functions which operate e.g. upon
objects representing squares of the board and return lists of e.g. all
adjacent squares.  Those are implemented in terms of a basic Square
class, which subsequently is used as the base class for
e.g. Square_With_Tactical_Analysis_Data.  The way that the program is
implemented, I know that all neighbors of
Square_With_Tactical_Analysis_Data will be of type
Square_With_Tactical_Analysis_Data, but since they are returned as
Square instead, my C++ program ends up littered with dynamic casts to
do run-time typing on a case-by-case basis.  Presumably CLOS would
handle this, but I hardly know anything about it.  Would the overhead
be low?  (A lot of the operations that I do get reduced to very simple
assembly language, e.g.  walking a list of objects containing pointers
and counting nonzero values pointed to.  It wouldn't be hard for fancy
calling conventions to increase the cost of such operations by an
order of magnitude.)

