[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Closure failure? [ How they work ]



On Wed, Feb 16, 2000 at 07:30:12PM -0500, Nathan J. Williams wrote:
> 
> Greetings. I'm trying to use Beanshell as part of an introductory Java
> teaching environment. The goal is to let the students write simple
> expressions to solve a problem without making them deal with the full
> overhead of class and method syntax, as well as to have a GUI
> environment that can give them rapid feedback on what their code is
> doing.

Great.  I'd love to hear more about your project as you get it going.

> In porting this environment to use bsh, I've run into a problem with
> closures. The system wants some variable to be persistent across
> function calls, but I seem to be getting copy-on-write semantics
> instead of normal access semantics. My minimal test case is:

[ example moved to the bottom of this email ]

I can see how this would be confusing, but I'm afraid that it's currently
the expected behavior.  The problem with loosening up the language such that
you don't have to declare variables is that you don't have a clear way to
determine where they are intended to be declared vs. where they are simply
being assigned.  The most general solution (and the one that BeanShell
currently uses) is that variablas are declared wherever they are assigned
and if you want to assign a variable in a parent scope you have to use a
modifier...

I agree that this is not linguistically pleasant and it bothers me that it
diverges from Java in a sense...  however Java doesn't allow defining methods
within methods, so it's not entirely divergent.

I agree that forcing students to learn a new (or at least non-standard usage) 
keyword is not ideal...   I'll have to think about a suggestion for you.  

[ The example ]

> ctest() {
> 
>     int x;
>     x = 5;
> 
>     print("Start. X is " + x);
> 
>     subfunc() {
>   print ("Subfunc. X is " + x);
>   x = x + 1;
>   print ("X is now " + x);
>     }
>     return this;
> }
> 
> I would expect that creating a ctest() object and callung subfunc()
> twice would print 5,6 and then 6,7. Instead:
> 
> bsh % source("closure.bsh");
> bsh % obj=ctest();
> Start. X is 5
> bsh % obj.subfunc();
> Subfunc. X is 5
> X is now 6
> bsh % obj.subfunc();
> Subfunc. X is 5
> X is now 6
> 
> ... indicating that the change to x isn't being made in the ctest()
> environment. 
> 
> I can get the behaviour I want if I change the references to x in
> subfunc() to super.x, but that both seems linguistically wrong and
> adds different, extraneous syntax to the code the students have to write.


Thanks,
Pat 

P.S. I apologize again to people who get this twice (one for users@ and
once for developers@) I will work out a solution as soon as possible.