Re: How to write a self.pm (Re: method calls on $self)

2005-07-12 Thread TSa (Thomas Sandlaß)

Autrijus Tang wrote:

The compiler, in turn inspect whether there's an bound $_ in scope
with $?SELF set.  It is not trivial, because this should work:

sub baz (c) { c() }
method foo { baz { .bar } } # $_ is free in inner closure

But this needs to fail:

sub baz (c) { c(1) }
method foo { baz { .bar } } # $_ is bound in inner closure


I might still not understand topic, $_ or lexical vars in general.
But why does the fact that c is called with a parameter
in the second case and without one in the first example make a
difference? Isn't $_ always coming in out of band? So .bar is always
invoked on the invocant of foo if we think that there is an implicit
$_ := $?SELF before the call to baz in foo.  And I hope the binding
of $_ to $?SELF is a read-only binding!
--
TSa (Thomas Sandlaß)




Re: How to write a self.pm (Re: method calls on $self)

2005-07-12 Thread Larry Wall
On Tue, Jul 12, 2005 at 12:36:23PM +0800, Autrijus Tang wrote:
: On Mon, Jul 11, 2005 at 09:04:54PM -0700, Larry Wall wrote:
:  On Tue, Jul 12, 2005 at 10:17:01AM +0800, Autrijus Tang wrote:
:  : On Mon, Jul 11, 2005 at 06:29:28PM -0700, Larry Wall wrote:
:  : The obvious thought is to have yet another magical, $^H like flag, to
:  : denote the current dialect.  If it is set, then the parser can emit
:  : .method as $_.method, instead of $?IMPLICIT_INVOCANT.method.
:  
:  The parser always emits .method as $_.method under any dialect, or
:  fails.  What has changed is whether $_ sometimes means the invocant.
: 
: But the compiler needs to trigger ambiguity resolution -- i.e. check
: for $?SELF agreement with $_ -- when it sees $?IMPLICIT_INVOCANT.
: 
: No need to do that if it sees $_.method.  So they need to be different.

Well, another approach is to treat .method as invariably $_.method,
and catch the problem at the attempt to rebind $_.  Thomas seems to
think it should already be doing that.  Of course, that would make it
impossible to use given or for inside a method at all...

So the other approach is to give up on compile-time checks and say
that $?IMPLICIT_INVOCANT.method in a method's lexical scope (and
in the absence of use self) turns into

($_ =:= $?SELF ?? $_.method :: fail Phooey)

:  In any event, SMD methods always have a first argument, so you're never
:  in doubt at that point.  And since .bar always means $_.bar, I don't
:  think you really have a problem here that's any harder than you already
:  had with $_.
: 
: The problem here is for the compiler to detect whether $_ agrees
: with $?SELF, when it sees $?IMPLICIT_INVOCANT.  If they agree,
: $?IMPLICIT_INVOCANT gets replaced by $_; otherwise it is an error.
: 
: Consider this construct:
: 
: method foo {
:   $_ := $something_else if rand(2)1;
:   .bar;
: }
: 
: That's one case where it's not possible to detect at compile time,
: so it needs to silently let .bar go thru as $_.bar.

Though Thomas's constant binding notion would presumably catch that.
But then we're getting into the noalias zone that Dennis Ritchie hates.
On the other hand, I can see lots of uses for variables that may
not be rebound, at least in terms of reassuring the optimizer that
Weird Things Can't Happen.

:  : Clearly we need a way to statically determine statement:given
:  : and statement:for will always assign at least one argument to
:  : its block argument.  Without that, the compile-time analysis mandated by
:  : Larry is infeasible.
:  
:  I think you can assume that given and for always bind at least one
:  argument.  In particular, a for that binds 0 arguments will never
:  progress, plus you can recognize it:
: 
: But what in given and for signify that?  I do not want to special
: case based on function names, and statement:given may be rebound
: to something else.

I understand the desire for generality, but that road also leads to
error messages that are completely opaque to naive users, who are
pretty accurate in their view that features like given and for
will Stay Put in the normal course of events.  Many of the most useful
diagnostics in Perl 5 are the ones that are guessing based on common
usage patterns.  Users can't do much with messages that when deciphered
come out to mean something like you called a function passing as
its first argument another function whose first argument's declared
type allows it to be optionally bound to $_ but if we actually try to
make use of that we'll get some ambiguity further on down the road,
and that's bad.  They'd much rather chuck the generality and have
You can't say .foo inside given where the topic could be either $_
or the method's invocant.  Or in the absense of that just blow up
at run time.

Of course, I'm just restating your problem here...

: How does that something else signify that it will
: at least bind at least one argument to its code argument?  Via the
: signature of the code argument, i.e. the Any in codeAny?
: 
: sub statement:given (Any $topic, codeAny) { ... }

Maybe something like:

sub statement:given (Any $topic, *code:(Any is topic)) { ... }

: If so, what is the signature of for?  I can't seem to write it down.

Good question.  I suppose the signature wants to guarantee minimum arity
of 1 somehow.  Maybe

sub statement:for (Lazy [EMAIL PROTECTED], *code:(Any is topic, *)) { 
... }

or some such.  But whether the outer function is actually functioning
as a topicalizer would still depend on the innards of your function.
Hmm.  We might settle for declaring such functions with a special trait
that indicates that they are *intended* to function as topicializers.
And then maybe the compiler could just depend on those declarations
for its static analysis:

sub statement:given (Any $topic, *code:(Any)) is topicalizer { ... }

Other that that we rely on the run-time check.  (Which hopefully common
code analysis can factor out multiple copies of.)

:  : Then, 

How to write a self.pm (Re: method calls on $self)

2005-07-11 Thread Autrijus Tang
(Cross-posting the new ruling from p6l to p6c to discuss implementation 
strategy)

On Mon, Jul 11, 2005 at 06:29:28PM -0700, Larry Wall wrote:
 {
 let $Larry.decisive = 1;
 
 Okay, this is what we're gonna do.  We're gonna go back pretty close to
 where we were originally, but with a twist.  That is, .foo is always
 a call on the current topic, but the invocant is (again) always the
 topic in the outer scope of a method.  The difference from before
 is that we simply outlaw .foo notation at *compile* time in those
 scopes where we know (at compile time) that $_ and $?SELF diverge.
 In such a scope you *must* specify $_ or $?SELF (or equivalent).
 (If necessary we can also compile .foo inside methods down to code
 that checks at runtime whether $_ has diverged from $?SELF and pitch
 a run-time fit for those situations we can't detect at compile time.
 Or we can just declare it erroneous.)  Basically, you can't use .foo
 inside a given or a for inside a method.
 
 That's the default, and I'm not changing my mind ever again, at least
 till next week.  That being said, if you mutate your language with
 anything like:
 
   use self this;
   use self self;
   use self o;
   use self ./;
   use self ;
   ...
 
 then the pragma is allowed to warp .foo semantics to make it *always*
 refer to $_ everywhere, provided it *also* undoes the default binding
 of $_ := $?SELF, so people that people aren't tempted to use .foo to
 mean $?SELF.foo in that scope.
 
 Yes, this is possibly a hazard for cut-n-pasters.  But then,
 you weren't supposed to be cutting-n-pasting anymore, were you?
 Shame on you.  Move the common code to a role, or a base class.
 }

Normally, I try to comply with new rulings as soon as they become
available, but the implementation of this is nontrivial, so I'd welcome
more input.

The obvious thought is to have yet another magical, $^H like flag, to
denote the current dialect.  If it is set, then the parser can emit
.method as $_.method, instead of $?IMPLICIT_INVOCANT.method.  If it is
not set, the parser needs to emit this as the first statement in any
method body:

$_ := $?SELF

The compiler, in turn inspect whether there's an bound $_ in scope
with $?SELF set.  It is not trivial, because this should work:

sub baz (c) { c() }
method foo { baz { .bar } } # $_ is free in inner closure

But this needs to fail:

sub baz (c) { c(1) }
method foo { baz { .bar } } # $_ is bound in inner closure

Clearly we need a way to statically determine statement:given
and statement:for will always assign at least one argument to
its block argument.  Without that, the compile-time analysis mandated by
Larry is infeasible.

Then, we need to figure out the structure for the magic flag set by
self.pm on behalf of its caller.  We are not using $^H anymore, so
there needs to be a way to pass lexical settings to the caller.

To use MJD's lexical pragma design:

module self;
use pragma;
sub import ($caller, $dialect) {
install_pragma_value('$?SELF_MAGICAL', $dialect);
}

This will create a lexically scoped hint in the importer's scope;
the parser and compiler will be hard-wired to recognise that magic
and act accordingly.

Does this seem sane?  The static detection of $_ is the showstopper
currently, and Pugs will need to separate the compiler with PIL evaluator
to implement the pragma.pm above.  Before that happens, I'll still
pretend that:

use self './';

is in scope.  If people are uncomfortable with that, maybe we can
retrofit all tests and examples using the ./ syntax to add that dummy
line on top of their code, and ship with a stub self.pm that does
nothing.  Will that do as a interim solution?

Thanks,
/Autrijus/


pgpN8udhQ2SUX.pgp
Description: PGP signature


Re: How to write a self.pm (Re: method calls on $self)

2005-07-11 Thread Larry Wall
On Tue, Jul 12, 2005 at 10:17:01AM +0800, Autrijus Tang wrote:
: On Mon, Jul 11, 2005 at 06:29:28PM -0700, Larry Wall wrote:
: The obvious thought is to have yet another magical, $^H like flag, to
: denote the current dialect.  If it is set, then the parser can emit
: .method as $_.method, instead of $?IMPLICIT_INVOCANT.method.

The parser always emits .method as $_.method under any dialect, or
fails.  What has changed is whether $_ sometimes means the invocant.

: If it is
: not set, the parser needs to emit this as the first statement in any
: method body:
: 
: $_ := $?SELF

That is the part that has to be conditional on the dialect.

: The compiler, in turn inspect whether there's an bound $_ in scope
: with $?SELF set.  It is not trivial, because this should work:
: 
: sub baz (c) { c() }
: method foo { baz { .bar } }   # $_ is free in inner closure
: 
: But this needs to fail:
: 
: sub baz (c) { c(1) }
: method foo { baz { .bar } }   # $_ is bound in inner closure

The compiler is free to treat any undecidable binding as ambiguous
and die of uncertainty.  Though we should probably make some official
rule so that different compilers don't end up with different definitions
of undecidable.

In any event, SMD methods always have a first argument, so you're never
in doubt at that point.  And since .bar always means $_.bar, I don't
think you really have a problem here that's any harder than you already
had with $_.

: Clearly we need a way to statically determine statement:given
: and statement:for will always assign at least one argument to
: its block argument.  Without that, the compile-time analysis mandated by
: Larry is infeasible.

I think you can assume that given and for always bind at least one
argument.  In particular, a for that binds 0 arguments will never
progress, plus you can recognize it:

for @foo - {...}

And a given that doesn't bind $_ isn't worth much either.

Or is that what you're asking?

: Then, we need to figure out the structure for the magic flag set by
: self.pm on behalf of its caller.  We are not using $^H anymore, so
: there needs to be a way to pass lexical settings to the caller.

Perhaps hints should just be considered lexically scoped $? variables.
You export them lexically just the same way you export any other lexically
scoped things, however that is. 

: To use MJD's lexical pragma design:
: 
: module self;
: use pragma;
: sub import ($caller, $dialect) {
:   install_pragma_value('$?SELF_MAGICAL', $dialect);
: }
: 
: This will create a lexically scoped hint in the importer's scope;
: the parser and compiler will be hard-wired to recognise that magic
: and act accordingly.

How will you handle:

use Foo :my$x;

Seems like this is just a kind of

use Foo :my$?MYHINT

thingy, only perhaps you're just setting $?MYHINT rather than aliasing
it back into a Foo variable.

: Does this seem sane?  The static detection of $_ is the showstopper
: currently, and Pugs will need to separate the compiler with PIL evaluator
: to implement the pragma.pm above.

I suspect you're making it complicateder than it needs to be, but
perhaps I don't understand the problem fully.  Of course, the two are
not mutually exclusive...

: Before that happens, I'll still pretend that:
: 
: use self './';
: 
: is in scope.  If people are uncomfortable with that, maybe we can
: retrofit all tests and examples using the ./ syntax to add that dummy
: line on top of their code, and ship with a stub self.pm that does
: nothing.  Will that do as a interim solution?

That's fine for the short term.

Larry


Re: How to write a self.pm (Re: method calls on $self)

2005-07-11 Thread Autrijus Tang
On Mon, Jul 11, 2005 at 09:04:54PM -0700, Larry Wall wrote:
 On Tue, Jul 12, 2005 at 10:17:01AM +0800, Autrijus Tang wrote:
 : On Mon, Jul 11, 2005 at 06:29:28PM -0700, Larry Wall wrote:
 : The obvious thought is to have yet another magical, $^H like flag, to
 : denote the current dialect.  If it is set, then the parser can emit
 : .method as $_.method, instead of $?IMPLICIT_INVOCANT.method.
 
 The parser always emits .method as $_.method under any dialect, or
 fails.  What has changed is whether $_ sometimes means the invocant.

But the compiler needs to trigger ambiguity resolution -- i.e. check
for $?SELF agreement with $_ -- when it sees $?IMPLICIT_INVOCANT.

No need to do that if it sees $_.method.  So they need to be different.

 In any event, SMD methods always have a first argument, so you're never
 in doubt at that point.  And since .bar always means $_.bar, I don't
 think you really have a problem here that's any harder than you already
 had with $_.

The problem here is for the compiler to detect whether $_ agrees
with $?SELF, when it sees $?IMPLICIT_INVOCANT.  If they agree,
$?IMPLICIT_INVOCANT gets replaced by $_; otherwise it is an error.

Consider this construct:

method foo {
$_ := $something_else if rand(2)1;
.bar;
}

That's one case where it's not possible to detect at compile time,
so it needs to silently let .bar go thru as $_.bar.

 : Clearly we need a way to statically determine statement:given
 : and statement:for will always assign at least one argument to
 : its block argument.  Without that, the compile-time analysis mandated by
 : Larry is infeasible.
 
 I think you can assume that given and for always bind at least one
 argument.  In particular, a for that binds 0 arguments will never
 progress, plus you can recognize it:

But what in given and for signify that?  I do not want to special
case based on function names, and statement:given may be rebound
to something else.  How does that something else signify that it will
at least bind at least one argument to its code argument?  Via the
signature of the code argument, i.e. the Any in codeAny?

sub statement:given (Any $topic, codeAny) { ... }

If so, what is the signature of for?  I can't seem to write it down.

 : Then, we need to figure out the structure for the magic flag set by
 : self.pm on behalf of its caller.  We are not using $^H anymore, so
 : there needs to be a way to pass lexical settings to the caller.
 
 Perhaps hints should just be considered lexically scoped $? variables.
 You export them lexically just the same way you export any other lexically
 scoped things, however that is. 
 
 How will you handle:
 
 use Foo :my$x;
 
 Seems like this is just a kind of
 
 use Foo :my$?MYHINT
 
 thingy, only perhaps you're just setting $?MYHINT rather than aliasing
 it back into a Foo variable.

Yes, that's the main difference.  How does the :my form of export work
in the exporter's end?

sub foo is exportmy { ... }

Will that work?

 : Does this seem sane?  The static detection of $_ is the showstopper
 : currently, and Pugs will need to separate the compiler with PIL evaluator
 : to implement the pragma.pm above.
 
 I suspect you're making it complicateder than it needs to be, but
 perhaps I don't understand the problem fully.  Of course, the two are
 not mutually exclusive...

Indeed I suspect both are true. :)

Thanks,
/Autrijus/


pgpUx78e7n7vf.pgp
Description: PGP signature