Ken Fox wrote:
> Dave Storrs wrote:
> > On Thu, 17 Aug 2000, Jonathan Scott Duff wrote:
> > > BTW, if we define C<with> to map keys of a hash to named place holders
> > > in a curried expression, this might be a good thing:
> > >
> > > with %person {
> > > print "Howdy, ", ^firstname, " ", ^lastname;
> > > }
> > >
> > > # becomes
> > > sub {
> > > print "Howdy, ", $person{$_[0]}, " ", $person{$_[1]};
> > > }->('firstname', 'lastname');
>
> You're breaking the halting rules for figuring out the bounds of
> a curried expression.
>
> Your original code should have become:
>
> with %person {
> print "Howdy, ", sub { $_[0] }, " ", sub { $_[0] };
> }
>
I don't believe so. The rule at issue here is probably:
<quote>
=item Sub called in void context
Currying halts in the argument list of a subroutine (or method) that is
called in a void context. The tree traversal example given above shows a
method in a void context (any return value from $root->traverse is being
ignored). Therefore just its argument is curried, rather than the whole
call expression.
</quote>
I say 'probably' because it depends how 'with' is defined. Assuming that
there are no explicit curry prototypes or sub prototypes floating around in
the declaration of 'with', the commas do not limit the currying context.
> It gets worse with longer examples because each line is a separate
> statement that defines a boundary for the curry.
>
> IMHO, curries have nothing to do with this. All "with" really does is
> create a dynamic scope from the contents of the hash and evaluate its
> block in that scope.
>
> my %person = { name => 'John Doe', age => 47 };
>
> with %person {
> print "$name is $age years old\n";
> }
>
> becomes
>
> {
> my $env = $CORE::CURRENT_SCOPE;
>
> while (my($k, $v) = each(%person)) {
> $env->bind_scalar($k, $v);
> }
>
> print "$name is $age years old\n";
> }
>
The thing I don't like about either of these suggestions is that the local
scope is hidden. In <cough> VB, you can say:
dim height as double
dim ws as new Excel.worksheet // 'worksheet' has a 'height' property
with ws
print .height // Accesses ws.height
print height // Accesses me.height
end with
In Pascal, this is not possible. As a result, I find myself rarely using
'with' in Pascal, since it's rare that you do not need to access any of the
local variables within a block.