[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon May 7 09:09:22 1997 
Subject:puzzle about dlocal and input locals 
From:Aaron Sloman see below for reply address 
Volume-ID:970507.01 

I have a puzzle about dlocal and input local variables. I am aware
that access code for dlocal expressions is run before formal arguments
get their values, but that's not the problem here, as I am using only an
exit action, i.e. update code in an dlocal expression.

Basically it seems to be possible in a dlocal expression (e.g. an exit
action) to refer to a local lvars variable but not to an input local
even though input locals (since V15) are supposed to be equivalent to
local lvars variables, except that that they get their values from the
stack.

For example suppose I want a procedure temporarily to change the head of
a list, but to ensure that it restores the head on exit. I can do this
as follows, using dlocal to define an exit action.

vars animals = [cat mouse dog];

define temp_change(list, newval);
    ;;; this version works fine
    lvars
        oldlist = list, ;;; NB this does not copy the list as some think

        ;;; save the old head
        oldval = hd(list);

    ;;; define exit action to update hd of list. see HELP DLOCAL
    dlocal 0 % , oldval -> hd(oldlist) %;

    ;;; change the hd of list temporarily
    newval -> hd(list);     ;;; could have been -> hd(oldlist)

    ;;; print out the altered list
    list =>
enddefine;

;;; test it
temp_change(animals, "pig");
** [pig mouse dog]

;;; Make sure the head was restored on exit
animals =>
** [cat mouse dog]

However, if you try to simplify the above, as follows, by getting rid of
the apparently redundant local variable oldlist, it doesn't work:

define temp_change(list, newval);
    lvars
        oldval = hd(list);

    ;;; define exit action to update hd of list.
    dlocal 0 % , oldval -> hd(list) %;

    ;;; change the hd of list temporarily
    newval -> hd(list);     ;;; could have been -> hd(oldlist)

    list =>
enddefine;

Then you get a compilation warning:

;;; DECLARING VARIABLE list
;;; IN FILE /home/staff/axs/news/dlocal
;;; LINE 50

And attempting to run it produces a mishap

temp_change(animals, "pig");
;;; MISHAP - LIST NEEDED
;;; INVOLVING:  <undef list>
;;; FILE     :  dlocal   LINE NUMBER:  66
;;; DOING    :  mishap hd temp_change ...


However, if I put in an explicit local declaration of "list", thus,
then it works.

define temp_change(list, newval);
    lvars
        ;;; apparently redundant declaration of list
        list,
        oldval = hd(list);

    ;;; define exit action to update hd of list. see HELP DLOCAL
    dlocal 0 % , oldval -> hd(list) %;

    ;;; change the hd of list temporarily
    newval -> hd(list);

    list =>
enddefine;

;;; test it, and it works
temp_change(animals, "pig");
** [pig mouse dog]


IS THIS A BUG IN THE IMPLEMENTATION OF INPUT LOCALS OR AN OBSCURE
FEATURE THAT I'VE FAILED TO UNDERSTAND???

I thought that since V15.0 the default for input locals was supposed to
be exactly the same as if they had been declared explicitly as lvars?

Aaron
===
-- 
Aaron Sloman, ( http://www.cs.bham.ac.uk/~axs )
School of Computer Science, The University of Birmingham, B15 2TT, UK
EMAIL A. Sloman @ cs. bham.ac uk(||| MAKE BULK EMAIL ADVERTS ILLEGAL |||)
Phone: +44-121-414-4775 (Sec 3711)       Fax:   +44-121-414-4281