On Sat, Nov 23, 2002 at 08:46:03PM -0600, Me wrote:
: First, I'd like to confirm I've understood
: C<temp> and C<let> right:
: 
: 1. C<temp> dynamically scopes changes to a
:    variable's value to the enclosing block.
:    It does not dynamically scope the name.
:    The variable can obviously be a global.
:    It can also make sense if it is lexical.
:    Is the latter currently allowed?

I'm planning to allow it unless someone can come up with a good reason not to.

: 2. C<let> is a conditional C<temp>; it only
:    restores a variable's value if, on exit
:    from the enclosing block, the block is
:    somehow considered to have "failed". It
:    can be applied to a global or lexical.

At the moment, it doesn't apply to either.  It applies only to the
current regex's variables.  It is a bit of an inconsistency that
in the current model, regex variables are lexically scoped but not
actually declared.  This may be a mistake.

: The above two features are basically sugar
: for what would otherwise be achieved with
: paired FIRST/LAST/UNDO blocks.

Well, there's no UNDO defined for regex backtracking unless we define
some kind of BACK block, but conceptually you're basically right.

: Both must be applied to an existing variable.

Not strictly true.  if you say

    /foo bar { let $baz = 2 } /

the $baz is creating a new variable within the scope of the surrounding regex.

: Next, I want to do a better job of stating
: a problem I wonder about:
: 
: Consider "environmental" values such as
: "screen sizes, graphics contexts, file
: handles, environment variables, and
: foreign interface environment handles." [1]
: 
: Consider a sub One that is going to call
: a 10 deep stack of subs such that sub Ten
: needs to access one of these environmental
: values. How do you pass the data?
: 
: A. Globals. Bad. Disastrous in threads.
: 
: B. Passed as args to all intervening subs.
:    Verbose. Sometimes incredibly verbose.
: 
: C. Aggregate info into objects. But then
:    you still have to do either 1 or 2 above
:    with the object references. And it's a
:    shame to be forced to the object paradigm
:    unnecessarily.
: 
: D. Use $CALLERS::. Relatively succinct, but
:    definitely error-prone and ugly.

But you haven't mentioned what's really going on with package
variables:

E. Passed via thread-local storage.  Under I-threads, package variables
are *not* shared by default among threads, so they can be scoped
dynamically without the threading problems of A.  Package variables
are global only if you squint really hard.

: Given what I understand of Perl 6 syntax,
: Parrot, and Perl philosophy, I suspect P6
: should, and could fairly easily, provide a
: good solution to the problem outlined above.
: 
: Does anyone agree the problem I've outlined
: is inadequately addressed by $CALLERS::?

The real question is, do I agree.  :-)

: In previous emails I've suggested:
: 
: 1. The notion of something like attaching
:    a C<passed> property on variables, and
:    picking appropriate defaults for its
:    args (not/ro/rw), to allow the writer
:    of a sub to easily strictly limit what
:    a called sub can access.

I think the granularity is wrong on this.  Trying to mesh the
namespaces of caller and callee is a big problem as soon as you
have multiple callees with different ideas.  In other words, I think
it's probably a mistake to try to generalize implicit $_ passing to
any name.

: 2. The notion of args that are explicitly
:    defined in a sub's sig but implicitly
:    passed. This kills most of the verbosity
:    of B above, while, in combination with
:    the previous point, being otherwise just
:    as safe as passing args explicitly all
:    the way down the call stack.

We already have currying, and I think that notion should be extended to 
handle any caller-instituted defaulting.  The granularity can be controlled
on a sub-by-sub or on a class-by-class basis.

    # curry sub
    my $DBhandle = mumble();
    my &shortcut ::= &longcut.assuming(handle => $DBhandle);

    # curry all methods of a class
    use Dog.assuming(tail => "cut_short", ears => "cut_long");
    my $little_dog = Dog.where_oh_where();

or some such.  If there are early-binding/late-binding issues we
should address those as part of the currying design.  For instance,
it's not clear above whether $DBhandle is evaluated at compile time
or run time.  I think we have to say that it's a binding, which means
the value of handle depends on the *current* value of $DBhandle each
time the shortcut is called.

Basically, the parameter list of the subroutine is already providing a
limited namespace to be shared by caller and callee.  If the caller really
wants to bind to a variable of the same name, they can always say

    my $bar;
    &foo.assuming(bar => $bar)

But I think it would be wrong for the callee to start forcing its
namespace into the namespace of the caller beyond what we already do
with named parameter syntax (and $_).

Larry

Reply via email to