1.  Are local variables created using bind within a function body,
      locally scoped to that function?
2.  Are function argument names locally scoped to that function?
 
By "locally scoped", I mean the usual lexical scoping, i.e.
a)  A distinct new variable is created on entry to the function's scope,
    and is "destroyed" on exit.
b)  Within the function's scope, a local variable hides any top-level
     variable of the same name.
c)  Changing the local var doesn't change the top-level var.
d)  The local var isn't changed by side-effect as a result of calling any
    other function(s) that also use the same name as a local var in their
    own bodies.
 
I just encountered cross-scope variable trashing, i.e. Jess is violating
(c) and (d).
 
Violates (c):
- At the top level, while "poor man's single-stepping" through my code
    (by pasting it line-by-line), I do (bind ?t triple).
- I then call a function (deffunction foo (?t) ...), passing a jess.Token.
- On return from foo, the top-level ?t has changed to that token.
    (This causes amusing exceptions to be thrown when I paste the next
    line that assumes the top-level ?t is still a symbol.)
 
Violates (d):
- Function f1 allocates a java.Util.Vector: (bind ?U (new Vector))
- f1 then calls f2, and adds its return value to ?U.
- Function f2 also allocates its own Vector: (bind ?U (new Vector)),
    and returns it.
- f2's use of the name ?U is the same object as f1's use of the name ?U.
    Hence, (i) when f2 does its own thing, it already trashes f1's ?U by
    overwriting it, and (ii) when f2 returns ?U, f1 tries to add ?U to itself.
    Evidently, a Vector is smart about this, and quietly does nothing.
- The result is that f1 returns, not a 2D Vector of Vectors as I expected,
    but a 1D Vector.
 
Fixing (d):
- I renamed f1's ?U to ?U1, and f2's ?U to U2.  And now it works.
 
The weird thing is that this entire call chain of several functions was
working flawlessly yesterday, even with the same variable names.
 
3.  [Insight!] If a top-level variable ?X already exists, then does
    (bind ?X ...) within a function body simply re-use the top-level variable,
    instead of creating a new one (and destroying it on exit)?
 
That would explain it!  The difference between today and yesterday is
that in today's intensive debugging session, I've "polluted" my Jess
image's top-level namespace with about 50 global vars --
most of which are identical to local var names in my functions.
Then all of my functions that share that local variable name are really
sharing the same top-level variable.  So they'll trash it, each other, yadda
yadda ...
 
That means I have to radically change my "poor man's debugging"
strategy.  It mean Jess violates lexical scoping properties (a) and (b).
 
Is this explained in the Jess book?  I didn't notice any discussion of scoping
issues, and just assumed that it implemented lexical scoping.
--
Eric Wang
CAD Lab, School of Mechanical Engineering, Sungkyunkwan University
 

Reply via email to