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
|