Riccardo GUIDA wrote:
> 
> Hi!
> 
> I'm playing with a weird anonymous function (motivation below)
> and I'm stumbling on a weird error, like if information
> on a local variable y is exiting from an anonymous function,
> only in a specific case.
> 
> I'm reporting this to you in case it was a bug.
> 
> (1) -> (():Void +-> {free x; x:=1; local y; y:= 1; output( sin(x+y)); 
> output("ciao"); ()})() -- no problem
>     sin(2)
>     ciao
>                                                                     Type: Void
> (2) -> (():Void +-> {free x; x:=1; local y; y:= 1; output( sin(x+y)); 
> output("ciao"); ()})(); output(x+1) -- no problem
>     sin(2)
>     ciao
>     2
>                                                                     Type: Void
> (3) -> (():Void +-> {free x; x:=1; local y; y:= 1; output( sin(x+y)); 
> output("ciao"); ()})();y --problem
>     sin(2)
>     ciao
>   
>     y is declared as being in PositiveInteger but has not been given a
>        value.
> 
> 
> Why? In the global scope, y should have been valued to a symbol or 
> Variable(y) with NO type declaration.
>

Yes, this is a bug.  This one is fixed by recent commit.  But this
is only partial fix (more see below).
 
> PS
> Motivation for the weird anonymous function above (Thanks for any feedback)
> 
> I'm looking for a scoping construct that could keep clean the global 
> environment
> from a proliferation of temporary variables in interpreter computations / 
> input files.
> 
> The body of functions is obviously one solution, but it is slightly boring
> to define and immediately execute:
> 
> hereIDoThis(globalPars) == {...body with temporary, local variables...}
> hereIDoThis(globaPars)
<snip> 
> So, I was trying to implement a block macro that could execute a sequence of 
> statements
> inside the body of an anonymous function and call it immediately.
> Compared to plain functions this would avoid the explicit execution.
> Compared to Mathematica Block, Module this would have the advantage
> that undeclared variables in RHS of statements are local.
> 
> I ended with:
> 
> macro block(statements) == (():Void +-> { statements; () })()
> 
> ... but I had the aforementioned error:
> 
> (3) ->  x:=1; y:=1; z:= 1; t:=1; block(free x; local y; x:=2; y:=2; z:=2; t:= 
> 2; w:=2; output([x,y,z,t])); [x,y,z,t,w]
>     [2, 2, 2, 2]
>   
>     y is declared as being in PositiveInteger but has not been given a
>        value.

Scope in "interpreter" (compiler for .input files) is kind of "broken
by desion" (or maybe lack of design).  Basically, "interpreter"
works with two scopes: "global" one and local scope.  But we
should have several different local scopes and this is done
in hackish way.  In particular, anonymous functions frequently
need access to surrounding variables.  This access is done
essentialy leaking inner scope to outside.  The patch I commited
fixes worst leak.  But this does not fix core problem and
you are likely to see other symptoms.  AFACIS for examle
nesting your block macro will lead to a leak.

In a sense proper fix is easy, good methods to handle scope
are known for decades.  But that requires structuring
"interpreter" in a different way, probably a complete
rewrite.  "interpreter" handles several things in ad hoc
way and fitting this adhockery into different structure
is somewhat tricky.  So good fix will take time.

-- 
                              Waldek Hebisch

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/fricas-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to