On Sat, Nov 23, 2002 at 08:46:03PM -0600, Me wrote:
: First, I'd like to confirm I've understood
: Ctemp and Clet right:
:
: 1. Ctemp 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. Clet is a conditional Ctemp; 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 Cpassed 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