RFC - Interpolation of method calls

2000-09-14 Thread Michael G Schwern

=head1 TITLE

Interpolation of method calls

=head1 VERSION

Maintainer: Michael G Schwern <[EMAIL PROTECTED]>
Date:   14 Sep 2000
Version:1
Mailing List:   [EMAIL PROTECTED]


=head1 ABSTRACT

Method calls should interpolate in double-quoted strings, and similar
locations.

print "Today's weather will be $weather->temp degrees and sunny.";

Would deparse to:

print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.';


=head1 DESCRIPTION

=head2 The Current Problem With OO & Interpolation

Object-oriented programming encourages data-hiding, and one of the most basic
tool for this is the accessor method.  For reasons which should be obvious,
C<$obj->foo()> is usually better than C<$obj->{foo}>.  However, there are
several barriers to using an accessor method as simply as one does a hash
lookup.  Other RFCs deal with most of the current issues, but a basic one
still remains.

print "Today's weather will be $weather->temp degrees and sunny.";

This does not DWIM.  Instead of interpolating C<$weather->temp> as a method
call, it comes out as C<$weather.'->temp'> and is usually followed immediately
by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??"  Most
programmers learning OO Perl expect this to work and are surprised to find
that it does not.

Work arounds abound:

# If I wanted printf(), I'd have written it in C.
printf "Today's weather will be %d degrees and sunny.", $weather->temp;

my $temp = $weather->temp;
print "Today's weather will be $temp degrees and sunny.";

print "Today's weather will be @{[$weather->temp]} degrees and sunny.";

print "Today's weather will be ".$weather->temp." degrees and sunny.";

None are as simple and as obvious as:

print "Today's weather will be $weather->{temp} degrees and sunny.";

and because of this users groan at having to use accessor methods and are
often tempted to violate encapsulation for ease of use.

=head2 Proposed Solution - Interpolate Methods

Therefore, it is proposed that direct object method calls be interpolated
inside double quoted strings and similar constructs.

print "Today's weather will be $weather->temp degrees and sunny.";

should parse out as:

print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.';

thus returning DWIMness to methods and strings and removing one barrier to
accessor method's acceptance over hash lookups for objects.

Methods will be run in scalar context.  A method which returns a single scalar
is treated normally.  If a list is returned, it should be treated same as
array interpolation.  The list seperator will be applied.  In effect, the
deparsing will really work out as follows:

print 'Today\'s weather will be '.join($", $weather->temp()).
  ' degrees and sunny.';

However if temp() calls wantarray(), the result will be FALSE (scalar).

(For the remainder of the RFC, the join() will be assumed when discussing
deparsing for brevity.)

Should it be decided that a formal distinction be made between accessor
methods and other types (RFC 95), method interpolation should interpolate
B method.


=head2 Argument passing

Interpolation should also handle passing arguments to methods in a string:

print "Today's weather will be $weather->temp("F") degrees and sunny.";

This should deparse to:

print 'Today\'s weather will be '.$weather->temp("F").
  ' degrees and sunny.';

The arguments to the method are considered as normal expressions, thus:

print "There is $obj->foo(this => $yar, that => 2 + 2) in my head.";

deparses as:

print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head.";


=head1 CAVEATS

Indirect object syntax, being already ambiguous, cannot be easily be
distinguished in a string from normal text and should not be interpolated. 
This is ok, since accessors are rarely called with indirect object syntax.


Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this
need be applied?  What about inside regexes?  And if so, left and/or right
hand side?


Normally, whitespace is allowed between tokens of a method call.

$obj -> bar ("this");

and

$obj->bar("this");

are equivalent.  Whitespace between the object, '->', method name and opening
paren should be disallowed when interpolated.  This will avoid many ambiguous
cases.


Should the method not exist, Perl will throw an exception/die as usual.


C<"$var->{this}[2]{is}->{complex}->method"> should also be interpolated.  Also
C<"$obj->method->{key}"> for the case where a method returns a reference.


=head1 IMPLEMENTATION

The behavor of the parser to check for embedded variables would have to be
altered, namely the case where an embedded variable is being dereferenced.  A
case would be added to allow method calls as well as hash and array index
dereferences.  Otherwise, parsing should remain as normal.


=head1 REFERENCES

RFC 95  - Object Classes (proposes automatic a

Re: RFC - Interpolation of method calls

2000-09-14 Thread Michael Fowler

This topic is actually covered, albeit far less in-depth and lumped with an
unrelated change, by Nathan Wiger's RFC 103, just in case you weren't aware.


On Thu, Sep 14, 2000 at 03:57:41AM -0400, Michael G Schwern wrote:
> Methods will be run in scalar context.  A method which returns a single scalar
> is treated normally.  If a list is returned, it should be treated same as
> array interpolation.  The list seperator will be applied.  In effect, the
> deparsing will really work out as follows:
> 
> print 'Today\'s weather will be '.join($", $weather->temp()).
>   ' degrees and sunny.';
> 
> However if temp() calls wantarray(), the result will be FALSE (scalar).

Ok, this is very confusing.  You're saying the method is called in scalar
context, but then proceed to call it in list context, meanwhile tricking it
into thinking it's scalar context.  Interpolated method calls should behave
the same as every other method call, without extra magic.

The only decision, then, is to decide which context to use; if it deparses
to concatenation then it seems logical to use scalar context.  This also
makes sense in that you can force list context with @{[ $weather->temp ]} if
you really wanted it.


> =head2 Argument passing
> 
> Interpolation should also handle passing arguments to methods in a string:
> 
> print "Today's weather will be $weather->temp("F") degrees and sunny.";
> 
> This should deparse to:
> 
> print 'Today\'s weather will be '.$weather->temp("F").
>   ' degrees and sunny.';
> 
> The arguments to the method are considered as normal expressions, thus:
> 
> print "There is $obj->foo(this => $yar, that => 2 + 2) in my head.";
> 
> deparses as:
> 
> print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head.";

Now perl is parsing full statements within strings.  I -really- don't like
this, not only because perl is now reaching into strings to parse yet more,
but also because it's already beginning to look very difficult for me,
personally, to parse.  Not only that, it gives me the heeby-geebies (which
of course means you should all immediately agree with me :).

I'd say keep it simple, allow only simple, non-parenthetical method calls.

"foo $foo->bar bar" --> "foo " . $foo->bar . " bar"
"foo $foo->bar() bar"   --> "foo " . $foo->bar . "() bar"

Granted, it may confuse the newbies, but I think it makes things much easier
on everyone.



> Normally, whitespace is allowed between tokens of a method call.
> 
> $obj -> bar ("this");
> 
> and
> 
> $obj->bar("this");
> 
> are equivalent.  Whitespace between the object, '->', method name and opening
> paren should be disallowed when interpolated.  This will avoid many ambiguous
> cases.

This is a good idea, and has precedence (as I just discovered answering
someone's question about it in #Perl as I was writing this email, weird..):

"$hash -> {'foo'}"  --> "HASH(0x8bbf0b8) -> {k1}"



Michael
--
Administrator  www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--



Re: Draft RFC: new pragma: C

2000-09-14 Thread Graham Barr

I would suggest that anyone want to contribute to this discussion should
first read the thread about the addition of this pragma to perl5 in
the perl5-porters archives

http://www.xray.mpe.mpg.de/cgi-bin/w3glimpse/perl5-porters?query=use+namespace+pragma&errors=0&case=on&maxfiles=100&maxlines=30

Graham.



Re: Draft RFC: new pragma: C

2000-09-14 Thread Piers Cawley

Graham Barr <[EMAIL PROTECTED]> writes:

> I would suggest that anyone want to contribute to this discussion should
> first read the thread about the addition of this pragma to perl5 in
> the perl5-porters archives
> 
> 
>http://www.xray.mpe.mpg.de/cgi-bin/w3glimpse/perl5-porters?query=use+namespace+pragma&errors=0&case=on&maxfiles=100&maxlines=30

Ah. Sorry I didn't post that url with the RFC.

-- 
Piers




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Piers Cawley

Perl6 RFC Librarian <[EMAIL PROTECTED]> writes:

> This and other RFCs are available on the web at
>   http://dev.perl.org/rfc/
> 
> =head1 TITLE
> 
> C is just an assertion
> 
> =head1 VERSION
> 
>   Maintainer: Piers Cawley <[EMAIL PROTECTED]>
>   Date: 13th September 2000
>   Mailing List: [EMAIL PROTECTED]
>   Number: 218
>   Version: 1
>   Status: Developing
> 
> =head1 ABSTRACT
> 
> The behaviour of the  syntax should simply be an
> assertion of the invariant: 
> 
>(!defined($spot) || (ref($spot) && $spot->isa('Dog)))
> 
> =head1 DESCRIPTION
> 
> The syntax 
> 
> my Dog $spot = Dog->new();
> 
> currently carries little weight with Perl, often failing to do what
> one expects:
> 
> $ perl -wle 'my Dog::$spot; print "ok"' 
> No such class Dog at -e line 1, near "my Dog"
> Execution of -e aborted due to compilation errors.
> $ perl -wle 'sub Dog::new; my Dog $spot; print "ok"'
> ok
> $ perl -wle 'sub Dog::new; my Dog $spot = 1'
> ok
> 
> The first example is obvious, as is the second. The third one is
> I.  

Actually, it's *very* weird given that there's no code to print 'ok'.
Which is bad.

  $ perl -wle 'sub Dog::new; my Dog $spot = 1; print "ok"'

That's better.

-- 
Piers




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Piers Cawley

Nathan Torkington <[EMAIL PROTECTED]> writes:

> Perl6 RFC Librarian writes:
> > I therefore propose that C comes to mean that C<$spot>
> > is restricted to being either undefined or a reference to a C
> > object (or any subclasses of Dog). Simply having this implicit
> > assertion can be useful to the programmer, but I would argue that its
> > main advantage is that the compiler knows the object's interface at
> > compile time and can potentially use this fact to speed up method
> > dispatch. 
> 
> Yes!  I mentioned the hypothetical
>   use strict 'types';
> which would require all variables assigned to/from an object, and
> all variables upon which method calls are made, to be typed like
> this.  Then the compiler can:
>  (a) optimize
>  (b) check at compile-time
> 
> Your sample implementation is done through a Tie class, which is only
> runtime.  The big win is that if you check types like this (and it's
> a window into C's type-checking hell) then Perl knows types at
> compile-time.  If there's a formal interface specification for classes,
> the compiler can use this to check whether a method call is valid or
> not.  You can build calls to the correct subroutine into optree
> instead of delaying that lookup until runtime.
> 
> Every compile-time check comes at the cost of a run-time freedom,
> though.  All bets would be off if you modified @ISA, reblessed, or
> passed objects through non-strict-types-compliant code.  Polymorphic
> types also becomes a problem: how to say that it's okay for a variable
> to hold a Dog *or* a Cat, because we know that both of them have a
> "pet()" method?
> 
> I'd love to see these suggestions incorporated into your RFC.  I was
> going to do it myself, but I have a lot of other things to RFC.

TBH, I'm not sure I want to go too far down that road in this RFC. And
tbh they seem more like internals issues to me. The runtime behaviour
this change grants is good enough for me and I don't want to see the
proposal bogged down in flamage about strict types. Of course, given
this RFC it's possible to add other RFCs that deal with specific
dependent language proposals and optimizations.

> > =head1 MIGRATION
> > 
> > Migration issues should be minor, the only problem arising when people
> > have assigned things that aren't objects of the appropriate type to
> > typed variables, but they deserve to lose anyway.
> 
> Not if you made the checks and optimizations enabled by a pragma.
> Old programs wouldn't have it, so they could continue to do their
> stupid things and be fine.

Again, I'm not sure that I'd want to encourage such bogosity. After
all, if perl5 could introduce "@array" interpolation which broke stuff
I don't see why this one can't go through as the default.

-- 
Piers




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Piers Cawley

Nathan Wiger <[EMAIL PROTECTED]> writes:

> Nathan Torkington wrote:
> > 
> > Yes!  I mentioned the hypothetical
> >   use strict 'types';
> > which would require all variables assigned to/from an object, and
> > all variables upon which method calls are made, to be typed like
> > this.  Then the compiler can:
> >  (a) optimize
> >  (b) check at compile-time
> 
> Hate to add a "me too", but I think this is a great idea. Nat needs to
> be able to torture himself in whatever sick C-type ways he desires. ;-)
> ;-)
>  
> Seriously, though, this adds lots of potential benefits.
> 
> > Polymorphic
> > types also becomes a problem: how to say that it's okay for a variable
> > to hold a Dog *or* a Cat, because we know that both of them have a
> > "pet()" method?
> 
> Seems in order to satisfy this you'd have to have a common ancestor,
> Pet, which Dog and Cat inherited:
> 
>my Pet $foofoo;  # Can be Dog, Cat, or anything inherited

I'm kind of tempted to look at adding another pragma to go with 'use
base' along the lines of:

 use implements 'Interface';

Which is almost entirely like C but with
'Interface' consisting of nothing but:


 package Interface;

 sub virtual_method;
 sub virtual_method2 (#prototype);
  
 ...

 1;

This is, of course, strictly unnecessary since C could do
exactly the same thing, and it is painfully Javalike. It kind of
depends on whether or not useful compiletime optimizations become
possible if a class is flagged as being 'virtual'.

> And if you didn't want inherited classes to count, you could specify
> that as an attribute:
> 
>my Pet $foofoo : onlybase;# Must be a Pet, not Cat/Dog
> 
> Or ":only", ":nochildren", ":justme", or any other similar word...

Why on earth would I want to do that? You just shot the polymorphism
in the head.

-- 
Piers




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Piers Cawley

Michael G Schwern <[EMAIL PROTECTED]> writes:

> On Wed, Sep 13, 2000 at 08:43:43PM -, Perl6 RFC Librarian wrote:
> > The behaviour of the  syntax should simply be an
> > assertion of the invariant: 
> > 
> >(!defined($spot) || (ref($spot) && $spot->isa('Dog)))
> 
> What about the current behavior of typed pseudohashes?
> 
> package Dog;
> use fields qw(this night up);
> 
> my Dog $ph = [];
> $ph->{this} = "that";

That works? I thought you had to do:

  my Dog $self = fields::new('Dog');

(In which case, as far as I can see, the proposal makes no difference.)

-- 
Piers




Re: RFC - Interpolation of method calls

2000-09-14 Thread Nathan Wiger

> This topic is actually covered, albeit far less in-depth and lumped with an
> unrelated change, by Nathan Wiger's RFC 103, just in case you weren't aware.

Yeah, I've got to split those up. I was trying cut down on the flood of
RFC's that poor Larry has to sift through :-(, but they are both complex
issues. Schwern, if you want to take this one over, it's all yours.

There has already been some discussion on this here:

http://www.mail-archive.com/perl6-language@perl.org/msg02169.html

I would encourage people to read the thread. In particular, to be truly
consistent we should interpolate class as well as instance methods,
i.e.:

   "Hello, Class->name";

But there's a lot of problems with this and I'm not sure it's a good
idea.
 
> > print 'Today\'s weather will be '.join($", $weather->temp()).
> >   ' degrees and sunny.';
> >
> > However if temp() calls wantarray(), the result will be FALSE (scalar).
> 
> Ok, this is very confusing.

I think what he's trying to get at is that these should all work the
same:

   print "Here's some @stuff";
   print "Here's some $h->{stuff}";
   print "Here's some $r->stuff";

> > print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head.";
> 
> Now perl is parsing full statements within strings.

This already happens with:

   print "Here's some $h->{$stuff}";
   print "Here's some $a->[$stuff + $MIN]";

So it's not that confusing, and quite consistent.

> I'd say keep it simple, allow only simple, non-parenthetical method calls.

No, this makes it impossible to do this:

   print "Your name is $cgi->param('name')";

And it's also inconsistent with how hashrefs and arrayrefs work already.

-Nate



Re: Draft RFC: new pragma: C

2000-09-14 Thread Nathan Wiger

Nathan Wiger wrote:
> 
> > use namespace 'Big::Long::Prefix';
> > my ::Class $object = ::Class->new;
> 
> Assuming repairing :: precedence is a reality I don't think this
> proposal buys us anything.

...That being said, I'm not necessarily against it. I'm
just against bloat. I hadn't paid too much attention to the actual patch
the first time reading it through, but it looks like a simple thing to
add. And the one nice thing it does add is that these:

  $::stuff
  $main::stuff

don't always mean the same thing, which at least gives some real reason
for having the first version around. If this change is made, though,
then I think it should work the same way in packages:

   package Foo;
   $::bar = "stuff";  # $Foo::bar = "stuff"

For consistency. That way the rule is:

   "If no prefix is found to ::, then the current package namespace is
used. You can change the current namespace either via 'package' (if
you want to encapsulate a new package), or 'use namespace' (if you
simply want a shortcut way of referring to variables)".

This might have been discussed, but I didn't see it in the threads (I
could have missed it, though). 

For anyone looking for a direct link to the start of the patch thread:

http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-07/msg00490.html

-Nate



Re: RFC - Interpolation of method calls

2000-09-14 Thread Nick Ing-Simmons

Michael G Schwern <[EMAIL PROTECTED]> writes:
>
>print "Today's weather will be $weather->temp degrees and sunny.";
>
>This does not DWIM.  Instead of interpolating C<$weather->temp> as a method
>call, it comes out as C<$weather.'->temp'> and is usually followed immediately
>by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??"  Most
>programmers learning OO Perl expect this to work and are surprised to find
>that it does not.

I think $-> is unlikely enough in a string that this is worth considering.

>
>Work arounds abound:

 print $weather->report;

being the one I like best - avoids the un-meritted assumption 
it will be sunny ;-)



-- 
Nick Ing-Simmons <[EMAIL PROTECTED]>
Via, but not speaking for: Texas Instruments Ltd.




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Nathan Torkington

Piers Cawley writes:
> TBH, I'm not sure I want to go too far down that road in this RFC. And
> tbh they seem more like internals issues to me. The runtime behaviour
> this change grants is good enough for me and I don't want to see the
> proposal bogged down in flamage about strict types. Of course, given
> this RFC it's possible to add other RFCs that deal with specific
> dependent language proposals and optimizations.

Ok, I'll work on the RFC for the type-checking.

Nat



Re: RFC - Interpolation of method calls

2000-09-14 Thread Michael Fowler

On Thu, Sep 14, 2000 at 07:49:32AM -0700, Nathan Wiger wrote:
> > > print 'Today\'s weather will be '.join($", $weather->temp()).
> > >   ' degrees and sunny.';
> > >
> > > However if temp() calls wantarray(), the result will be FALSE (scalar).
> 
> I think what he's trying to get at is that these should all work the
> same:
> 
>print "Here's some @stuff";
>print "Here's some $h->{stuff}";
>print "Here's some $r->stuff";

That may be, but I don't think calling it in one context, accepting another,
and lying about it all is the right way to go.  I think I'll let the author
try to explain what he had intended.


> > > print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head.";
> > 
> > Now perl is parsing full statements within strings.
> 
> This already happens with:
> 
>print "Here's some $h->{$stuff}";
>print "Here's some $a->[$stuff + $MIN]";
> 
> So it's not that confusing, and quite consistent.

Well, I still find it confusing (most probably because of the length of the
examples), but it is indeed consistent.  Stupid mistake on my part.


Michael
--
Administrator  www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--



RFC 49 (v3) Objects should have builtin stringifying STRING method

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE 

Objects should have builtin stringifying STRING method

=head1 VERSION

   Maintainer: Nathan Wiger <[EMAIL PROTECTED]>
   Date: 06 Aug 2000
   Last Modified: 14 Sep 2000
   Mailing List: [EMAIL PROTECTED]
   Number: 49
   Version: 3
   Status: Frozen

=head1 ABSTRACT

Currently, $ single-whatzitz types in Perl can hold several different
things. One of the things that these are commonly used to hold are
objects, such as:

   $q = new CGI;
   $r = Apache->request;

Unfortunately, there is no easy way to tell these are actually objects
without lots of annoying ref checks throughout your code. So if you say:

   print "$q";

This prints out something like this:

   CGI=HASH(0x80ba4e8)

Which isn't very useful. This RFC attempts to fix this by providing
builtin special method C which is automatically called when an
object is "stringified".

While this can be accomplished through the use of 'use overload', a more
automatic, object-specific method has certain advantages. For more
details on this, please see RFC 159.

=head1 NOTES ON FREEZE

This RFC goes into details on the uses of C, but what you really
want to read is L, which extends
these concepts to other Perl operators and contexts.

=head1 DESCRIPTION

Currently, there is no way to easily distinguish between these two
syntaxes:

   $scalar  =  date; # scalar ctime date, same as localtime()
   $object  =  date; # date object with accessor functions

As such, there is no easy way to have the C function return both
- it must decide what to return within the general scalar context.
Damian's excellent RFC 21 on C addresses several specific cases,
several have suggested alternate syntaxes, such as:

   my Date $object = date;   # return object of class 'Date'
   my tm $object = date; # return object of struct 'tm'

However, this doesn't solve the problem, since printing out either of
these in a scalar context still results in "garbage".

I suggest that objects provide a default method called C that
determines what they produce in a string context. When stringified, an
object would automatically call its C function and return the
correct value. For example, RFC 48 describes a new C interface.
In a scalar context, it could produce a date object always:

   $date = date;

However, when you went to do anything with it in a string context, it
would call the appropriate method:

   print "$date"; # calls $date->STRING, which in this case would
  # print out a ctime formatted date string

The call to C<$object->STRING> would be a decision made by Perl, similar
to the way that C works. The object simply has to provide the
method; Perl does the rest.

This gives us several other really neat side effects. First, we can now
return a list of objects and have them act the same as a "regular old
list":

   (@objects) = Class->new;

Since, in a stringifying context, each of these objects would call their
C methods:

   print "@objects";   # calls $objects[0]->STRING, $objects[1]->STRING,
   # and so on for the whole array, thus making it
   # look like a plain old list

As such, we no longer have to distinguish between objects and "true"
scalars. Objects are automatically converted when appropriate. 

=head1 IMPLEMENTATION

All core objects should be modified to include a C function.
This function may just be a typeglob pointing to another function, or it
may be an actual separate function.

Hooks will have to be put in Perl's string context so that if something
is an object, then that object's C method is called
automatically if it exists.

=head1 MIGRATION

None. This introduces new functionality.

=head1 REFERENCES

RFC 159: True Polymorphic Objects

RFC 21: Replace wantarray with a generic want function 

RFC 48: Replace localtime() and gmtime() with date() and utcdate()

Lots of people on perl6-language for great input, thanks!




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Michael G Schwern

On Thu, Sep 14, 2000 at 02:19:38PM +0100, Piers Cawley wrote:
> Michael G Schwern <[EMAIL PROTECTED]> writes:
> > package Dog;
> > use fields qw(this night up);
> > 
> > my Dog $ph = [];
> > $ph->{this} = "that";
> 
> That works? I thought you had to do:
> 
>   my Dog $self = fields::new('Dog');

Nope.  fields::new() basically just does C, but the current pseudohash
implementation doesn't care if something is an object or not.  It just
cares about either A) its type or B) what's in $ph->[0].  I don't know
if this is a good thing or a bad thing, but there's nothing on the
table to change it (yet).

my Dog $ph = [];
$ph->{this} = "that";

deparses at compile-time to:

my Dog $ph = [];
$ph->[$Dog::FIELDS{this}] = "that";  # actually the %FIELDS lookup is also
 # done at compile time, but I left
 # it in for illustration.

-- 

Michael G Schwern  http://www.pobox.com/~schwern/  [EMAIL PROTECTED]
Just Another Stupid Consultant  Perl6 Kwalitee Ashuranse
Sometimes these hairstyles are exaggerated beyond the laws of physics
  - Unknown narrator speaking about Anime



RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Interpolation of method calls

=head1 VERSION

  Maintainer: Michael G Schwern <[EMAIL PROTECTED]>
  Date: 14 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 222
  Version: 1
  Status: Developing


=head1 ABSTRACT

Method calls should interpolate in double-quoted strings, and similar
locations.

print "Today's weather will be $weather->temp degrees and sunny.";

Would deparse to:

print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.';


=head1 DESCRIPTION

=head2 The Current Problem With OO & Interpolation

Object-oriented programming encourages data-hiding, and one of the most basic
tool for this is the accessor method.  For reasons which should be obvious,
C<$obj->foo()> is usually better than C<$obj->{foo}>.  However, there are
several barriers to using an accessor method as simply as one does a hash
lookup.  Other RFCs deal with most of the current issues, but a basic one
still remains.

print "Today's weather will be $weather->temp degrees and sunny.";

This does not DWIM.  Instead of interpolating C<$weather->temp> as a method
call, it comes out as C<$weather.'->temp'> and is usually followed immediately
by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??"  Most
programmers learning OO Perl expect this to work and are surprised to find
that it does not.

Work arounds abound:

# If I wanted printf(), I'd have written it in C.
printf "Today's weather will be %d degrees and sunny.", $weather->temp;

my $temp = $weather->temp;
print "Today's weather will be $temp degrees and sunny.";

print "Today's weather will be @{[$weather->temp]} degrees and sunny.";

print "Today's weather will be ".$weather->temp." degrees and sunny.";

None are as simple and as obvious as:

print "Today's weather will be $weather->{temp} degrees and sunny.";

and because of this users groan at having to use accessor methods and are
often tempted to violate encapsulation for ease of use.

=head2 Proposed Solution - Interpolate Methods

Therefore, it is proposed that direct object method calls be interpolated
inside double quoted strings and similar constructs.

print "Today's weather will be $weather->temp degrees and sunny.";

should parse out as:

print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.';

thus returning DWIMness to methods and strings and removing one barrier to
accessor method's acceptance over hash lookups for objects.

Methods will be run in scalar context.  A method which returns a single scalar
is treated normally.  If a list is returned, it should be treated same as
array interpolation.  The list seperator will be applied.  In effect, the
deparsing will really work out as follows:

print 'Today\'s weather will be '.join($", $weather->temp()).
  ' degrees and sunny.';

However if temp() calls wantarray(), the result will be FALSE (scalar).

(For the remainder of the RFC, the join() will be assumed when discussing
deparsing for brevity.)

Should it be decided that a formal distinction be made between accessor
methods and other types (RFC 95), method interpolation should interpolate
B method.


=head2 Argument passing

Interpolation should also handle passing arguments to methods in a string:

print "Today's weather will be $weather->temp("F") degrees and sunny.";

This should deparse to:

print 'Today\'s weather will be '.$weather->temp("F").
  ' degrees and sunny.';

The arguments to the method are considered as normal expressions, thus:

print "There is $obj->foo(this => $yar, that => 2 + 2) in my head.";

deparses as:

print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head.";


=head1 CAVEATS

Indirect object syntax, being already ambiguous, cannot be easily be
distinguished in a string from normal text and should not be interpolated. 
This is ok, since accessors are rarely called with indirect object syntax.


Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this
need be applied?  What about inside regexes?  And if so, left and/or right
hand side?


Normally, whitespace is allowed between tokens of a method call.

$obj -> bar ("this");

and

$obj->bar("this");

are equivalent.  Whitespace between the object, '->', method name and opening
paren should be disallowed when interpolated.  This will avoid many ambiguous
cases.


Should the method not exist, Perl will throw an exception/die as usual.


C<"$var->{this}[2]{is}->{complex}->method"> should also be interpolated.  Also
C<"$obj->method->{key}"> for the case where a method returns a reference.


=head1 IMPLEMENTATION

The behavor of the parser to check for embedded variables would have to be
altered, namely the case where an embedded variable is being dereferenced.  A
case would be added to allow method calls as well as hash and array index
dereferences.  Otherwise, pars

Re: RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread Dave Rolsky

First of all, I think this is a great idea

On 14 Sep 2000, Perl6 RFC Librarian wrote:

> Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this
> need be applied?  What about inside regexes?  And if so, left and/or right
> hand side?

Regexes are enough like double quoted strings that I think _not_
interpolating here would be confusing.  The same goes for backticks
(`)/qx, which is double-quote interpolated as well.

-dave

/*==
www.urth.org
We await the New Sun
==*/




RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Hierarchical calls to initializers and destructors

=head1 VERSION

  Maintainer: Damian Conway <[EMAIL PROTECTED]>
  Date: 1 September 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 189
  Version: 2
  Status: Developing

=head1 ABSTRACT

This RFC proposes a new special method called C that is 
invoked automagically whenever an object is created. Furthermore,
it proposes that both C and C methods should
be invoked hierarchically in all base classes.

=head1 DESCRIPTION

One of the major limitations of object-oriented Perl is that, unlike
most other OO languages, it does not automatically invoke the 
initializers and destructors of base classes, when initializing
or destructing an object of a derived class.

This leads to tediously complex code in constructors and destructors 
in order to manually achieve the same effect. More often, it leads to bugs.

It is proposed that Perl 6 introduce an automatic object initialization
mechanism, analogous to the automatic object clean-up mechanism 
provided by C methods. 

It is further proposed that both the initialization and destruction
mechanisms automatically call their corresponding base class versions
to ensure that complete initialization and destruction of derived
objects occurs correctly.

=head2 The C method

It is proposed that, if a class has a method named C, that method
will be invoked automatically during any call to C. It
is further proposed that C be extended to take an optional argument
list after its second argument, and that this list would be passed to
any C method invoked by the C.

The typical constructor would then be reduced to:

package MyClass;

sub new { bless {}, @_ }

with initialization handled in a separate C routine:

sub BUILD {
my ($self, @ctor_data) = @_;
# initialization of object referred to by $self occurs here
}


=head2 Hierarchical C calls

It is proposed that when an object is blessed, I of the C methods
in any of its base classes are also called, and passed the argument list
appended to the invocation of C. C methods would be called
in depth-first, left-most order (i.e. ancestral C methods would be
called before derived ones). Any given C method would only be called 
once for the same object, no matter how many separate paths its class might be 
inherited through.

For example, given the following class hierarchy:

package Base1;

sub new { bless {}, @_ }
sub BUILD { print "Base1::BUILD : @_\n" }


package Base2; 

sub BUILD { print "Base2::BUILD : @_\n" }


package Base3; 

sub BUILD { print "Base3::BUILD : @_\n" }


package Derived1; 
use base qw(Base1 Base2);

sub BUILD { print "Derived1::BUILD : @_\n" }


package Derived2; 
use base qw(Base2 Base3);

sub BUILD { print "Derived2::BUILD : @_\n" }


package Rederived1; 
use base qw(Derived1 Derived2);

sub BUILD { print "Rederived1::BUILD : @_\n" }


then the call to:

$obj = Rederived->new(1..3)

would print:

Base1::BUILD : 1 2 3
Base2::BUILD : 1 2 3
Derived1::BUILD : 1 2 3
Base3::BUILD : 1 2 3
Derived2::BUILD : 1 2 3
Rederived1::BUILD : 1 2 3

Note in particular that C is only called once (as early as
possible), even though class Rederived inherits it through two distinct paths.


=head2 Hierarchical C calls

It is further proposed that when an object's destructor is invoked, all
inherited destructors would also be invoked, in depth-I, right-most
order. Again, each C for an object would be called exactly once, 
regardless of how many different paths it is inherited through.

For example, given the following class hierarchy (with the same topology
as the example for C above):

package Base1;

sub new { bless {}, @_ }
sub DESTROY { print "Base1::DESTROY\n" }


package Base2; 

sub DESTROY { print "Base2::DESTROY\n" }


package Base3; 

sub DESTROY { print "Base3::DESTROY\n" }


package Derived1; 
use base qw(Base1 Base2);

sub DESTROY { print "Derived1::DESTROY\n" }


package Derived2; 
use base qw(Base2 Base3);

sub DESTROY { print "Derived2::DESTROY\n" }


package Rederived1; 
use base qw(Derived1 Derived2);

sub DESTROY { print "Rederived1::DESTROY\n" }


then the destruction of an object:

$obj = "something else";

would print:

Rederived1::DESTROY
Derived2::DESTROY
Base3::DESTROY
Derived1::DESTROY
Base2::DESTROY
Base1::DESTROY

Note that C is only called once (as late as possible),
even though class Rederived inherits it through two distinct paths.

Note too that the C invocation sequence is the exact reverse
of

RFC 224 (v1) Objects : Rationalizing C, C, and C

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Rationalizing C, C, and C

=head1 VERSION

  Maintainer: Damian Conway <[EMAIL PROTECTED]>
  Date: 14 September 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 224
  Version: 1
  Status: Developing

=head1 ABSTRACT

This RFC proposes that rather than three separate mechanisms (in three
separate namespaces) to determine object typing information, Perl 6
simply extend the C function to return all the necessary
information in a list context.

=head1 DESCRIPTION

In Perl 5, the class into which an object is blessed is returned by
calling C on a reference to that object. To determine the
underlying implementation type of the object, C is
used. To determine whether or not a reference refers to a blessed
object,  is used.

It is proposed that the behaviour of C be altered in Perl 6 so that
in a list context it returns up to two values: the underlying
implementation type of the object (always returned), and the class into
which the object is blessed (only if the object I blessed).

Thus:

if (builtin::blessed $ref) {
$type  = attribute::reftype $ref;
$class = ref $ref;
}
else {
$type  = ref $ref;
$class = "";
}

print "Object of type $type, blessed into $class\n";


Would become:

($type, $class) = ref($ref);
$class ||= "";

print "Object of type $type, blessed into $class\n";


=head1 MIGRATION ISSUES

All existing calls to C in a list context would have to be
translated to C.


=head1 IMPLEMENTATION

Trivial.

=head1 REFERENCES

None.




Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Damian Conway

Piers wrote:
 
   > I'm kind of tempted to look at adding another pragma to go with 'use
   > base' along the lines of:
   > 
   >  use implements 'Interface';
   > 
   > Which is almost entirely like C but with
   > 'Interface' consisting of nothing but:
   > 
   > 
   >  package Interface;
   > 
   >  sub virtual_method;
   >  sub virtual_method2 (#prototype);
   >   
   >  ...
   > 
   >  1;

You and I must have been separated at birth, Piers.

Here's what I wrote to Nat just yesterday:


There would be an C pragma or keyword (let's go
with keyword) that creates pseudo-packages with which lexicals
can be typed.

interface Fetcher;

sub fetch;

Interface specifications can only contain subroutine (method)
declarations, which describe what behaviours the interface requires.

Lexicals typed into interfaces (as opposed to packages) only require
that the objects assigned to them can satisfy the interface. I.e.
they don't care about the class of the object, only what is C
do.

my Fetcher $x;
my Dog $spot;
my NetSnarfer $z;

$x = $z;# ok because $z can fetch
$x = $spot; # ok because $spot can fetch
$x->fetch();# ok because Fetcher->can('fetch')
$x->bark(); # not ok because ! Fetcher->can('bark')


Interfaces might also act like pure abstract base classes when
inherited, so that:

package Dog;
use base 'Fetcher';

would cause a compile-time error if Dog failed to actually provide
a C method.


If you'd like to run with it, be my guest (but check with Nat first, in 
case he wants it).

Damian



Re: RFC 218 (v1) C is just an assertion

2000-09-14 Thread Buddha Buck

At 08:13 AM 9/15/00 +1100, Damian Conway wrote:
>Piers wrote:
>
>> I'm kind of tempted to look at adding another pragma to go with 'use
>> base' along the lines of:
>>
>>  use implements 'Interface';
>>
>> Which is almost entirely like C but with
>> 'Interface' consisting of nothing but:
>>
>>
>>  package Interface;
>>
>>  sub virtual_method;
>>  sub virtual_method2 (#prototype);
>>
>>  ...
>>
>>  1;
>
>You and I must have been separated at birth, Piers.
>
>Here's what I wrote to Nat just yesterday:
>




> Interfaces might also act like pure abstract base classes when
> inherited, so that:
>
> package Dog;
> use base 'Fetcher';
>
> would cause a compile-time error if Dog failed to actually provide
> a C method.

I don't like that at all...

Currently, Object implementations can be changed at will at runtime.  In 
particular, it is possible to create new methods and change the class 
hierarchy at run time.

package TextFilter;
use CryptInterface;
@ISA = qw(CryptInterface);

sub AUTOLOAD {
   my $self = shift;
   ($name = $AUTOLOAD) =~ s/.*://;
   # Cryptography is very hairy and we don't want to load it if we don't
   # have to.
   if ($name = any(qw(setkey setcrypt encode decode)) {
  require Crypt;
  import Crypt;
  push @ISA,"Crypt";
  $self->$name(@_);  # I've not tried this, it may be wrong.
   }
}

I'd hate to have that break because TextFilter isn't derived from Crypt 
unless it needs to be.

I think calling a method declared in an inherited interface but not 
implemented would be a good reason to have a descriptive run-time error, like:

Method getkey in interface Crypt not implemented in TextFilter object at 
line

Well, perhaps written better...

>If you'd like to run with it, be my guest (but check with Nat first, in
>case he wants it).
>
>Damian




Re: RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread David L. Nicol


> 
> Method calls should interpolate in double-quoted strings, and similar
> locations.
> 
> print "Today's weather will be $weather->temp degrees and sunny.";

A possibility that does not appear in RFC222.1 is to put tho whole
accessor expression inside curlies:

print "Today's weather will be ${weather->temp} degrees and sunny.";

which would follow the "You want something funny in your interpolated
scalar's name or reference, you put it in curlies" rule.  Since the contents
of that expression is not strictly \w+ it does not get interpreted as
the symbol table lookup ${'weather->temp'}, so that is not a problem, nor
are the whitespace situations listed in the CAVEATS section.





-- 
  David Nicol 816.235.1187 [EMAIL PROTECTED]
   perl -e'map{sleep print$w[rand@w]}@w=<>' ~/nsmail/Inbox



Re: RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread Michael Fowler

On Thu, Sep 14, 2000 at 06:37:22PM -0500, David L. Nicol wrote:
> A possibility that does not appear in RFC222.1 is to put tho whole
> accessor expression inside curlies:
> 
>   print "Today's weather will be ${weather->temp} degrees and sunny.";
> 
> which would follow the "You want something funny in your interpolated
> scalar's name or reference, you put it in curlies" rule.  Since the contents
> of that expression is not strictly \w+ it does not get interpreted as
> the symbol table lookup ${'weather->temp'}, so that is not a problem, nor
> are the whitespace situations listed in the CAVEATS section.

Currently, ${weather->temp} means dereference the return value of the method
'temp' in the 'weather' class as a scalar reference (or a symbolic
reference, if it's not a scalar reference and you're not using strict).  Do
you intend for this meaning to be taken away entirely, or to be
special-cased within interpolated strings?  If either I would have to
heartily disagree with you; it's inconsistent, and while special cases can
be a good thing when it comes to DWIM, I think we should DWIM on the side of
interpolating method calls, rather than taking away existing syntax.


Michael
--
Administrator  www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--



Re: RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors

2000-09-14 Thread Nathan Wiger

> =head2 The C method
> =head3 The C method

Hey! You left out the alternative names NEW / RENEW and BLESS / REBLESS
that we all like! :-(

-Nate



Re: RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors

2000-09-14 Thread Damian Conway

   > > =head2 The C method
   > > =head3 The C method
   > 
   > Hey! You left out the alternative names NEW / RENEW and BLESS / REBLESS
   > that we all like! :-(

Oops. You're correct. I will rectify that.

Damian



RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Interpolation of method calls

=head1 VERSION

  Maintainer: Michael G Schwern <[EMAIL PROTECTED]>
  Date: 14 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 222
  Version: 1
  Status: Developing


=head1 ABSTRACT

Method calls should interpolate in double-quoted strings, and similar
locations.

print "Today's weather will be $weather->temp degrees and sunny.";

Would deparse to:

print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.';


=head1 DESCRIPTION

=head2 The Current Problem With OO & Interpolation

Object-oriented programming encourages data-hiding, and one of the most basic
tool for this is the accessor method.  For reasons which should be obvious,
C<$obj->foo()> is usually better than C<$obj->{foo}>.  However, there are
several barriers to using an accessor method as simply as one does a hash
lookup.  Other RFCs deal with most of the current issues, but a basic one
still remains.

print "Today's weather will be $weather->temp degrees and sunny.";

This does not DWIM.  Instead of interpolating C<$weather->temp> as a method
call, it comes out as C<$weather.'->temp'> and is usually followed immediately
by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??"  Most
programmers learning OO Perl expect this to work and are surprised to find
that it does not.

Work arounds abound:

# If I wanted printf(), I'd have written it in C.
printf "Today's weather will be %d degrees and sunny.", $weather->temp;

my $temp = $weather->temp;
print "Today's weather will be $temp degrees and sunny.";

print "Today's weather will be @{[$weather->temp]} degrees and sunny.";

print "Today's weather will be ".$weather->temp." degrees and sunny.";

None are as simple and as obvious as:

print "Today's weather will be $weather->{temp} degrees and sunny.";

and because of this users groan at having to use accessor methods and are
often tempted to violate encapsulation for ease of use.

=head2 Proposed Solution - Interpolate Methods

Therefore, it is proposed that direct object method calls be interpolated
inside double quoted strings and similar constructs.

print "Today's weather will be $weather->temp degrees and sunny.";

should parse out as:

print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.';

thus returning DWIMness to methods and strings and removing one barrier to
accessor method's acceptance over hash lookups for objects.

Methods will be run in scalar context.  A method which returns a single scalar
is treated normally.  If a list is returned, it should be treated same as
array interpolation.  The list seperator will be applied.  In effect, the
deparsing will really work out as follows:

print 'Today\'s weather will be '.join($", $weather->temp()).
  ' degrees and sunny.';

However if temp() calls wantarray(), the result will be FALSE (scalar).

(For the remainder of the RFC, the join() will be assumed when discussing
deparsing for brevity.)

Should it be decided that a formal distinction be made between accessor
methods and other types (RFC 95), method interpolation should interpolate
B method.


=head2 Argument passing

Interpolation should also handle passing arguments to methods in a string:

print "Today's weather will be $weather->temp("F") degrees and sunny.";

This should deparse to:

print 'Today\'s weather will be '.$weather->temp("F").
  ' degrees and sunny.';

The arguments to the method are considered as normal expressions, thus:

print "There is $obj->foo(this => $yar, that => 2 + 2) in my head.";

deparses as:

print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head.";


=head1 CAVEATS

Indirect object syntax, being already ambiguous, cannot be easily be
distinguished in a string from normal text and should not be interpolated. 
This is ok, since accessors are rarely called with indirect object syntax.


Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this
need be applied?  What about inside regexes?  And if so, left and/or right
hand side?


Normally, whitespace is allowed between tokens of a method call.

$obj -> bar ("this");

and

$obj->bar("this");

are equivalent.  Whitespace between the object, '->', method name and opening
paren should be disallowed when interpolated.  This will avoid many ambiguous
cases.


Should the method not exist, Perl will throw an exception/die as usual.


C<"$var->{this}[2]{is}->{complex}->method"> should also be interpolated.  Also
C<"$obj->method->{key}"> for the case where a method returns a reference.


=head1 IMPLEMENTATION

The behavor of the parser to check for embedded variables would have to be
altered, namely the case where an embedded variable is being dereferenced.  A
case would be added to allow method calls as well as hash and array index
dereferences.  Otherwise, pars