From: Mike
Subject: controlling the Lisp debugger
Date: 
Message-ID: <1141536016.225247.257130@p10g2000cwp.googlegroups.com>
Hello everyone,

I've been flailing about miserably, trying to get the CL debugger to
conform to my will. Hopefully someone here can stear me in the right
direction.

In short, I want to interfere with CL dropping to the debugger when it
finds unbound symbols or functions. In the long term, I'd like to have
my Lisp query a SQL database for such unknowns (the DB will return a
text S-expression with the required data for the variable, or a
pathname to a FASL to load to provide the required function).

But after this has been taken care of, I need the undlying EVAL context
to 'try again' .. and this is where I get clobbered.

If someone could provide a toy example where unbound variables are
auto-bound to, say 42, I would
greatly appreciate it.

I'd prefer a solution in straight CL (maybe this is where I'm getting
hung up?) but if an SBCL or CMUCL solution is offered, thats OK too.

Thank you,

Mike

From: Bill Atkins
Subject: Re: controlling the Lisp debugger
Date: 
Message-ID: <877j79720i.fsf@rpi.edu>
"Mike" <···········@yahoo.com> writes:

> Hello everyone,
>
> I've been flailing about miserably, trying to get the CL debugger to
> conform to my will. Hopefully someone here can stear me in the right
> direction.
>
> In short, I want to interfere with CL dropping to the debugger when it
> finds unbound symbols or functions. In the long term, I'd like to have
> my Lisp query a SQL database for such unknowns (the DB will return a
> text S-expression with the required data for the variable, or a
> pathname to a FASL to load to provide the required function).
>
> But after this has been taken care of, I need the undlying EVAL context
> to 'try again' .. and this is where I get clobbered.
>
> If someone could provide a toy example where unbound variables are
> auto-bound to, say 42, I would
> greatly appreciate it.
>
> I'd prefer a solution in straight CL (maybe this is where I'm getting
> hung up?) but if an SBCL or CMUCL solution is offered, thats OK too.
>
> Thank you,
>
> Mike

Are you familiar with conditions and restarts?

 < http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html >

HTH,
Bill
From: Alan Crowe
Subject: Re: controlling the Lisp debugger
Date: 
Message-ID: <86fylwdguu.fsf@cawtech.freeserve.co.uk>
"Mike" <···········@yahoo.com> writes:
> In short, I want to interfere with CL dropping to the debugger when it
> finds unbound symbols or functions. In the long term, I'd like to have
> my Lisp query a SQL database for such unknowns (the DB will return a
> text S-expression with the required data for the variable, or a
> pathname to a FASL to load to provide the required function).

> If someone could provide a toy example where unbound variables are
> auto-bound to, say 42, I would
> greatly appreciate it.

I'm not too sure about this, but I think that one issue is
that specification doesn't require implementations to
provide a suitable restart, so if you want to be able to
carry straight on in a portable manner, you need to wrap the
accesses in a suitable restart. eg instead of using
symbol-value directly, wrap it up:

CL-USER> (defun look-for (variable-name)
           (restart-case (symbol-value variable-name)
             (use-value (initial-value)
               (setf (symbol-value variable-name)
                     initial-value))))

Then you need to run your code inside a suitable
handler. This toy example is a higher order function, but a
macro might be more suitable.

CL-USER> (defun initialise-unbound-variables (function default-value)
           (handler-bind ((unbound-variable 
                           (lambda (condition)
                             (use-value default-value))))
             (funcall function)))

Now a calculation

CL-USER> (defun test-function ()
           (list (look-for 'x)
                 (look-for 'y)))

can be executed like this:

CL-USER> (initialise-unbound-variables #'test-function 42)

; In: LAMBDA #'DEFAULT-VALUE

;   (LAMBDA (CONDITION) (USE-VALUE DEFAULT-VALUE))
; ==>
;   #'(LAMBDA (CONDITION) (USE-VALUE DEFAULT-VALUE))
; Note: Variable CONDITION defined but never used.
; 

(42 42)

CL-USER> (makunbound 'x)
X
CL-USER> (set 'y 10)
10
CL-USER> (initialise-unbound-variables #'test-function 24)
(24 10)

Notice the complaint that I ignored the condition. You will
probably want to get the name of the unbound variable from
the condition using cell-error-name

Alan Crowe
Edinburgh
Scotland
From: Mike
Subject: Re: controlling the Lisp debugger
Date: 
Message-ID: <1141594932.006808.213240@v46g2000cwv.googlegroups.com>
Alan,

Thank you for your reply. Maybe I can use this as a starting point for
something workable.

The thing is, though -- I don't want to have to wrap my variable or
function accesses. I need Lisp to do this transparently for me. That
is, I'd like the following
behavior at the REPL:

> (set-default-value 42)    ;; sets the default value of an unbound variable to 42
42
> (makunbound 'X)
X
> X
42
>

To give you, and the rest of the group, context for what I'm trying to
do:

I have a SQL database that is accessible by CMUCL/SBCL  on 4 networked
machines. I want to startup CMUCL/SBCL on all 4 of these machines, with
sockets open on port 1024. These four Lisp cores will share code. One
machine will be the master, the other the slaves. The slave machines
recieve a block of code from the master, evaluate it, and send the
return value back to the master.

When eval'ing a code block, it is likely that the slave lisp will not
have all the required information to run the code. It will need
functions, and data. I want the
unbound functions autoloaded from disk, and I want unbound variables to
be set to quantities known to the DB, and then I want the evaluation to
proceed as if nothing irregular has happened. I intend to provide a
glue wrapper that will allow Lisp threads to be spawned off to entirely
seperate networked machines, communicating via sockets and sharing data
via SQL. It is important to me that it be made possible to port
threaded Lisp applications to this architecture simply by
search/replacing the package names of the threading layers, therefore
requiring that possibly unbound variables be wrapped in a restart is no
good.

I had been hoping to find a way to do this via the Lisp debugger. After
all, breaking the computation, prompting the user for keyboard entry of
the unbound
variable, and then continuing along the way is the norm for Lisp, and
is not substantially different than breaking the computation, grabbing
the value for the unbound variable from the DB, and continuing along
the way. Yet I cannot seem to achieve this seemingly simple goal.

Perhaps I ought to just write a code-walker?

Mike
From: Andreas Thiele
Subject: Re: controlling the Lisp debugger
Date: 
Message-ID: <dugru4$fmj$01$1@news.t-online.com>
I did not read your description very well but I remember a friend of mine who put some research
efforts in a similar subject. Do you know NetCLOS?

http://www.cliki.net/NetCLOS

Andreas
From: Marco Baringer
Subject: Re: controlling the Lisp debugger
Date: 
Message-ID: <m2acc2qy96.fsf@bese.it>
"Mike" <···········@yahoo.com> writes:

> Alan,
>
> Thank you for your reply. Maybe I can use this as a starting point for
> something workable.
>
> The thing is, though -- I don't want to have to wrap my variable or
> function accesses. I need Lisp to do this transparently for me. That
> is, I'd like the following
> behavior at the REPL:
>
>> (set-default-value 42)    ;; sets the default value of an unbound variable to 42
> 42
>> (makunbound 'X)
> X
>> X
> 42

this breaks a fundamental lisp assumption.

> When eval'ing a code block, it is likely that the slave lisp will
> not have all the required information to run the code. It will need
> functions, and data. I want the unbound functions autoloaded from
> disk, and I want unbound variables to be set to quantities known to
> the DB, and then I want the evaluation to proceed as if nothing
> irregular has happened. I intend to provide a glue wrapper that will
> allow Lisp threads to be spawned off to entirely seperate networked
> machines, communicating via sockets and sharing data via SQL. It is
> important to me that it be made possible to port threaded Lisp
> applications to this architecture simply by search/replacing the
> package names of the threading layers, therefore requiring that
> possibly unbound variables be wrapped in a restart is no good.

you could use symbol-macros or special variables to achive 'default
value' effect. autoloaded function can be done throguh a
macro. personally i think that explicitly stating which variables may
be known/unkown or which functions may be autoloaded is much better
than hacking the debugger (in the later case how do you distinguish
between an as-yet-unknown variable value and an actual programming
error?)

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen