develooper Front page | perl.perl6.internals | Postings from March 2008

pct tutorial notes - variable scope

Thread Next
From:
Patrick R. Michaud
Date:
March 28, 2008 23:04
Subject:
pct tutorial notes - variable scope
Message ID:
20080329060422.GA7241@host.pmichaud.com
First, kudos and compliments to Klaas-Jan Stol on the excellent
PCT tutorial.  I have some comments; the minor ones (typos, etc.)
I'll send off-list, but others may merit some discussion and
PCT implementation changes so I'll put them here.

This message has to do with scope handling of variables in Episode 6
of the tutorial (the 'identifier' method for Squaak).  The tutorial
points out an area where PCT doesn't yet work the way I had
envisioned and solicits opinions on possible fixes.

My intention for PCT is that an action method for a simple 
variable reference could look something like:

    method identifier($/) {
        my $name := ~$<ident>;
        make PAST::Var.new( :name($name),
                            :viviself('Undef'),
                            :node($/) );
    }

Note that in this idealized version the PAST::Var node doesn't
need to carry an explicit :scope attribute, because we expect to
retrieve the appropriate scope from an outer block's symbol table.

This works just fine for languages like Perl 6 where all variables
are declared before use, and therefore have entries in an outer
block's symbol table.  It doesn't quite work for other
languages where undeclared variables are valid and have some
assumed scope (such as 'global').  In these cases PCT throws
an exception of "no 'scope' attribute found" and thus the
compiler writer has to write code to search outer blocks
for the symbol and default a scope if not present.  In Squaak,
undeclared variables are assumed to have package scope, thus
it has:

        $scope := 'package';
        for @?BLOCK {
            if $_.symbol($name) {
                $scope := 'lexical';
            }
        }

I think that PAST ought to be sophisticated enough to handle
scoping for undeclared variables without requiring an action
method to perform an explicit scope search as above.  In other 
words, there should be something that says that any PAST::Var
nodes that don't otherwise have a 'scope' value should default
to 'package' scope.


Approach #1:  Default 'scope' to 'package'

This is the approach that the original PAST-pm took -- any
PAST::Var node that didn't provide a scope attribute was
automatically assumed to be 'package' scope.  This would
likely solve the problem for most languages (including
Squaak) where variables don't have to be predeclared 
before use.  However, defaulting to 'package' feels a bit
arbitrary (some languages might prefer a different default), 
which leads me to ...

Approach #2:  Define default scope values somewhere in the PAST tree.

A slightly more flexible approach would be to allow the
PAST tree itself to specify a default scope value for 
PAST::Var nodes.  Overall I like this better (as it
provides more flexibility), but I'm not sure where such
a 'default' value should be held.  It could be an explicit
attribute of PAST::Block, or perhaps we should have a
place in PAST::Block's symbol table for storing "default"
values for things within the block.  I somewhat like
this latter approach.

For example, the top-level block in a program could have

    $?BLOCK.symbol( '*', :scope('package'), :viviself('Undef') );

This would tell the PAST compiler that the default scope is
'package' and the default vivification is 'Undef'.  Nested
PAST::Var and PAST::Block nodes would then only need to
have scope attributes for variables that differ from these
default values.

Of course, the above approach implies that '*' is not otherwise
being used as a variable identifier -- perhaps using the
null string to mean "default values" would be better:

    $?BLOCK.symbol( '', :scope('package'), :viviself('Undef') );

Comments, suggestions?

Pm

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About