Re: RFC 319 (v1) Transparently integrate Ctie

2000-09-26 Thread Nathan Wiger

 I'm kind of curious to know what you think would happen with the
 following. I've commented where I'm confident...
 
 interface Number;
 sub TIESCALAR;
 sub STORE;
 sub FETCH;
 
 package integer implements Number; # I really like this notation

Tangentially, yes, it is nice to read, but it prevents multiple
interface specifications. "use interface" is more consistent.

 sub TIESCALAR {...};
 sub STORE {...};
 sub FETCH {...};
 
 my Number $i;   # Number is an interface, so just an assertion
 my integer $n;  # integer-TIESCALAR($n);
 my non_tied $object;# Just an assertion
 defined($n);# Should be false

Yes. The only potential gotcha is if the user decides to do something
Really Evil and stores a value as part of their TIESCALAR method. Then
$n-FETCH will return that value and defined($n) will be true.

However, this is not the purpose of tie, and I think an appropriate
response is: Don't Do That. I agree with both you and Damian that TIE*
should be called on declaration for consistency. If a person doesn't
know how to use tie, well, that's not our problem. ;-)

 $n = 5;
 $i = $n;
 $n = 10;
 print $i;
 $i = $object;   # Assertion fails

Assuming you've set up your Cuse optimize restrictions appropriately,
then yes. The key is really what 'non_tied' is setup as. If this is a
builtin type that optimizes itself to be a string object, then yes it
will fail. However, if 'non_tied' is just a synonym for 'float' (for
some odd reason) then the last line will be ok.

 my int @b :64bit;   # again, just an assertion
 
 Asserting what? That's not valid syntax at the moment.

But it will be. :-) See RFC 279.
 
 @c = @b;# empty list passed still
 @b = (1,2); # int-TIEARRAY(@a, '64bit'); @b-CLEAR(...);
 
 Hmm... I think this is somewhat ugly. Assuming that you want
 Cmy int @b to imply CUNIVERSAL::isa(all(@a), 'int') then tying the
 entire array seems a bit weird.

Not necessarily. The key is: *how* would you implement the assertion
check? 

If you use tie, then your int class STORE method can do something like
this:

   package int;
   use base 'var';
   # take defaults from var class
   STORE {
  if ( self-isa($_[1]) ) {
 SUPER-STORE($_[0], $_[1]);   # internally store
  } else {
 die "Bad data $_[1]" if ( $under_strict_types );
  }
   }

Now, there's a difference between _could_ do this and _must_ do this.
The idea here is that you could do this, and users wouldn't see any
difference between your custom types and builtin types.

 Er... You seem to be implying here that *all* classes should have TIE
 methods. Which is not good.

No, I wasn't trying to imply that, I'll clarify this point. TIE methods
are still completely optional. 

 Err... Specifying which classes implement an interface in the
 interface specification is Wrong Wrong Wrong.

Yes, you're right, and it's way outside of this scope of this RFC,
actually. Your idea:

 my Pet $spot : isa(any(qw/Dog Cat/)) = new Camel; # oops!

is much better for this application.
 
 Can I just point out that nobody has yet proposed that you can attach
 attributes to a package?

Didn't Damian propose Cpackage Foo : interface already? ;-)

 I'm not entirely sure what you're driving at here. I thought you were
 arguing that *all* packages that created objects would use tie magic,
 in which case the new attribute becomes unnecessary. And if you're not
 proposing that then :tie is too general in the cases where the module
 can only tie to specific variable types. I think you get better
 granularity with interfaces, which are way more general than a special
 new attribute.

No, let me back up a little. The idea is to make it so that tied
interfaces - which are really different beasts from OO interfaces
altogether because of their purpose - should be more closely integrated
into Perl 6. This would allow you to create custom, optimized,
strongly-typed variables that would function just like builtins:

   my Matrix @a = ([1,2,3], [4,5,6]);
   my NISMap %map :passwd = read_passwd_file();
   my Apache::Session %session :transaction;

However, this is not to overshadow OO interfaces, which are needed for
functional methods, as you note.

The :tie attribute is a poorly chosen name. The original name was
:implicit, and was going to be attached to the TIE subs:

   package Demo;
   sub TIESCALAR : implicit { ... }
   sub TIEHASH : implicit { ... }
   sub TIEARRAY { ... }

So in this example, a user can say:

   my Demo $x;
   my Demo %x;
   my Demo @x;   # TIEARRAY not called

However, after thinking about this, I decided this was not a worthwhile
distinction. How often would you want this behavior? So I decided to
attach the attribute to the package:

   package Demo : implicit;

But that really didn't connote what was going on. So I changed it to:

   package Demo : autotie;

But then decided the 'auto' was redundant. However, the more 

Re: RFC 265 (v1) Interface polymorphism considered lovely

2000-09-23 Thread Nathan Wiger

 package Doggie;
 
 sub isborn {
 bless { @_ }, self;   # ;-)
 }
 sub scratches ($\@;@) {
 ...
 }
 
 
 package Doggie::Cute;
 
 use base 'Doggie';
 use interface 'Pet';
 
 # Our base class is 'Doggie', which does not use the 'Pet'
 # interface (perhaps unbeknownst to us!). Nonetheless, we use
 # the 'Pet' interface to make sure that our class is implemented
 # correctly.
 
 # code would follow...
 
 This could still be Cuse base 'Pet' and it would work you know.

No, it couldn't - notice that Doggie does not inherit from Pet. Unless
there's something about OO inheritance that I'm really missing...

 reasoning behind seperating Cuse base and Cuse interface (for me)
 is simply because of the mnemonic assistance to the programmer.
 interface.pm could easily be a duplicate of base.pm with the added
 restriction that that the package so included *must* be an interface.

Yes, and I think that's a very worthwhile distinction. It also allows
you to mandate that you use multiple interfaces and a different base to
boot. This is a stretch but you should get the idea:

   package Solaris::Devices::Ethernet::GigEther;

   use base 'Solaris::Devices::Ethernet';
   
   use interface 'Solaris::Kernel::Kmem';
   use interface 'Solaris::Devices::Devtree';

But maybe I'm barkings up a different tree from you. But it seems that
interfaces don't have to be constrained to just stub base class
definitions. Instead, they can serve as specifications for class
interaction as well as class implementation. If we keep "use interface"
and "use base" separate then this becomes trivial to do (compile-time
checks for proper method declarations/etc).

-Nate



Re: RFC 200 (v2) Objects: Revamp tie to support extensibility(Massive tie changes)

2000-09-20 Thread Nathan Wiger

Damian Conway wrote:
 
 I didn't see any mention of my plea that Ctie should pass the
 original variable being tied as one of its arguments. :-(

That's because it's a dumb idea!!

**Kidding!**

I forgot about this, sorry. I'll add it to the next version ;-)

 my $x = 10;
 tie $x, 'ReadOnly';
 print $x;   # still prints 10
 
 I feel that additional functionality is *very* important.

Yes, so do I.

-Nate



Re: FYI: Ruby 1.6.0 - An object-oriented language for quick and easy programming

2000-09-19 Thread Nathan Wiger

 What sets Ruby apart is a clean and consistent
 language design where everything is an object.

I like this part. Assuming I ever finish my last RFC I'd like Perl to
have embedded objects as well. The difference being Perl's wouldn't get
in the way, unlike Python's.

Of particular interest seems to be this link:

   http://www.ruby-lang.org/en/compar.html

Which has a somewhat poignant analysis of Perl's OO:

   Ruby was a genuine easy-to-use object-oriented language from the
   beginning; whereas Perl's OOP features were added to non-OO Perl,
   so that these features are (unlike the rest of Perl) very clumsy
   and hard to use correctly and effectively. For many people and
   purposes, Ruby is a better OO Perl than Perl. 

And then there's the lexical variable issue too:

   The default variable scope rules for Ruby (default: local) are
   much better suited for medium-to-large scale programming tasks;
   no "my, my, my" proliferation is needed for safe Ruby programming

Food for though at least. 

-Nate



Re: RFC 188 (v2) Objects : Private keys and methods

2000-09-19 Thread Nathan Wiger

 This RFC proposes two new keywords -- Cprivate and Cpublic -- that limit
 the accessibility of keys in a hash, and of methods.

I still think these should be attributes across the board:

   my $hash{$key} : private = $val;
   my @hash{qw(_name _rank _snum)} : public;
   sub dostuff : private { }

I'd be interested what others think.

-Nate



Re: RFC 188 (v2) Objects : Private keys and methods

2000-09-19 Thread Nathan Wiger

Damian Conway wrote:
 
 The problem with specifying them as attributes is that I do not believe
 there is any way (or even any proposed way) of applying attributes to
 a hash entrie or a hash slice, nor is there any way of *retrospectively*
 applying an attribute to a hash that has already been declared elsewhere.

You're correct. I personally think there should be. My examples have
been based on the idea that this could be possible in Perl 6.

I'm going to post a Nat-inspired 'IDEA' to perl6-language in a little
bit (if my head doesn't explode first) and see how much it's shot at.

-Nate



Re: RFC 163 (v2) Objects: Autoaccessors for object data structures

2000-09-18 Thread Nathan Wiger

 How about also just ":access" to do both?  It would seem to be the
 most common case.

I was trying to conserve keywords, but I'm not opposed to this.
 
  =head2 Mixing autoaccessors and real subs
 
 I really don't see how this is necessary.  If you have to write a
 custom accessor, you might as well write the whole thing.
 
 I also don't see that the optimization of one half of the accessor vs
 the other is worth the trouble.

Well, it depends on how much faster the autoaccessor is. If it is much
faster, and you need to access a whole bunch of data repeatedly, then
this makes sense. But if the autoaccessor is about the same as a sub
speed-wise, then screw it, I agree.

 While in general this might be a good idea, is it really necessary for
 this proposal?  How about this:
 
 package Foo;
 use laccess qw(this);
 use raccess qw(foo);
 use access  qw(up);

I think attributes are a nicer way of handling stuff attached to data,
because it's right there by the data looking at you. But this:

 This also means accessors are defined on a per class basis rather than
 per object (which is potentially extremely confusing and difficult to
 implement).

Is a good point. I could see something like:

   use accessor (name = '$SELF-{DATA}-{C_name}', 'lvalue');

But I'll have to think about this a little more.

 $r-method;
 1. Look for a declared autoaccessor for the given context.
 
 Context.  I hope this means context of the object $r?

Yep. Will clarify.
 
 2. readonly rvalue subs
 
 http://www.mail-archive.com/perl6-language-objects@perl.org/msg00096.html
 implies that this isn't needed because of the proposed :constant hash
 attribute.  This isn't enough. 

Yeah, check out this email:

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

The idea I originally had was that :raccess would specify something was
an rvalue accessor which only returned a value, and couldn't take
arguments. I think this is probably the way to go, otherwise we have to
start adding other keywords, properties, etc, which really complicate
things too much.

 I was about to say that :deref wouldn't be a bad idea, but that would
 just be shifting the problem from pass-by-reference to pass-by-value.

Couldn't quite see what you were getting at here - maybe a little
clarification. I'm pretty sure I understand ("autoderef bad, but forced
copy bad too") but want to make 100% sure.

-Nate



Re: RFC 254 (v1) Class Collections: Provide the ability to overload classes

2000-09-18 Thread Nathan Wiger

 [From DBI-connect()]
 
 # XXX this is inelegant but practical in the short term, sigh.
 if ($installed_rootclass{$class}) {
 $dbh-{RootClass} = $class;
 bless $dbh = $class.'::db';
 my ($outer, $inner) = DBI::_handles($dbh);
 bless $inner = $class.'::db';
 }
 
 It works, but to quote Tim Bunce there... *sigh*.
 
 So anyhow, yes, this is a big, icky problem.

I wonder if this problem couldn't be solved with a proper combination of
@ISA, SUPER::, NEXT::, and use delegation? (calling Damian... :-)

   http://dev.perl.org/rfc/190.pod  (NEXT:: pseudoclass)
   http://dev.perl.org/rfc/193.pod  (use delegation)

Or perhaps a @HASA array or a better way of specifying multiple
inheritance than a serial @ISA array are needed. Perhaps we need
something as flexible as use delegation for inheritance?

   use inheritance parent = DBI;
   {
   use inheritance parent = DBI::db;
   SUPER-do_stuff;
   }
   use inheritance peer = DBI::st

That's just braindump, and I'm not sure what it even means, but figured
I'd write it down before I forgot.

-Nate



Re: RFC 163 (v2) Objects: Autoaccessors for object data structures

2000-09-18 Thread Nathan Wiger

All-

As the sublist chair, I politely ask you to please table this
discussion. Time is running short and this is really a digression.

Glenn, if you have a proposal, please put one together in RFC format and
post it to -objects.

-Nate



Specific RFC comments for -objects

2000-09-18 Thread Nathan Wiger

All-

In an attempt to nudge things in the right direction (wrap-up), I've
gone through and made some specific comments on RFC's. These are my
opinions from monitoring the discussions on this list since its
inception. I do not claim to be infallible, but feel I have a pretty
good idea of what's been said.

Below are specific suggestions as to what should be done with specific
RFCs. These are my suggestions; you may feel free to disagree with or
ignore them. I am basing these suggestions off what I have seen on the
list and other RFCs.

Please do not take offense if I suggest your RFC be retracted. This
email is an attempt to pare down the number of conflicting RFCs based on
community consensus and/or reality.

Note: Some of the RFCs discussed here are do not have -objects as the
Mailing-List because they predate it. However, I will still comment on
these where they're relevant to OO.

RFCs that should be Retracted
---
RFC 95: Object Classes
   The consensus appeared to be against this, which provided for
   radical changes to Perl OO and use of . to separate classes.
   Many of the key points were covered by later RFCs on private
   methods and class delegation.

RFC 171: my Dog $spot should call a constructor implicitly
   Again, the overwhelming consensus was against this. The later
   RFC claiming "my Dog $spot is just an assertion" was accepted
   as the way this should work.

RFC 77: Suggested isa() operator
   Most of these changes are already handled by UNIVERSAL::isa, 
   albeit with a different syntax. If an inline-style assertion is
   desired, the indirect object syntax can be used.

RFC 108: Scope of Polymorphic References and Objects
   No discussion was recorded on either version of this RFC, and it
   appears to duplicate features that were more fully explored in
   subsequent -objects RFCs. If this is incorrect, a clarified
   version should be reposted by Wed. Otherwise, it should be
   retracted.

RFC 103: Fix C$pkg::$var precedence issues with parsing of C::
   This is unrealistic and unimplementable without causing major
   problems.


And that last one's mine, just so you know I don't consider myself above
honest evaluation.


RFCs that should be Frozen
---
RFC 153: Replace $self in @_ with self() builtin (not $ME)
   Some clarification of usage, syntax, and scope must be added.

RFC 161: Everything in Perl becomes an object
   This is a philosophical document which has garnered no true
   support nor detraction. Some clarification of *why* this would
   be good should be added.

RFC 128: Cmy Dog $spot is just an assertion
   Pretty much everyone seems to be in agreement.

RFC 223: Objects: Cuse invocant pragma
   The mailing list should be changed to -objects, but I did not
   hear any specific clarifications that were needed.


The remaining -objects RFCs should be clarified and reposted by
Wednesday.

Finally, in the only effort towards facism I will take on this issue, if
I do not hear otherwise by next Friday, Sep 30th, I will request that
the above RFCs be retracted/frozen under the assumption that you
implicitly agree with my analyses. This is not an attempt to force my
will on others, but rather try to wrap things up and present Larry with
a set of at least somewhat cohesive RFCs. 

Thanks,
Nate



Re: RFC - Interpolation of method calls

2000-09-17 Thread Nathan Wiger

Tom Christiansen wrote:
 
 print "Today's weather will be $weather-temp degrees and sunny.";
 
 So, the - operator is supposed to get expanded in dq strings, eh?

It already does, or at least appears to to users:

print "Today's weather will be $weather-{temp} degrees and sunny.";
print "Today's weather will be $weather-[0] degrees and sunny.";
 
 Isn't it inconsistent to do this?

I think it's far more inconsistent to have the above work but not have
methods interpolate. And yes, I realize they're different thingies but
they're very close syntactically and cognitively, especially for data
access (which is really what we're talking about here).

I've always found it quite surprising and cumbersome to have to do this:

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

When the above two work fine.

-Nate



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: Cuse namespace

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.

backtracking...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 189 (v2) Objects : Hierarchical calls to initializers and destructors

2000-09-14 Thread Nathan Wiger

 =head2 The CBUILD method
 =head3 The CREBUILD method

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

-Nate



Re: Draft RFC: new pragma: Cuse namespace

2000-09-13 Thread Nathan Wiger

 use namespace 'Big::Long::Prefix';
 my ::Class $object = ::Class-new;

Anyone mentioned that this:

   $SHORT = 'Some::Huge::Obnoxious::Ridiculous::Term';
   $SHORT-member;
   $stuff = new $SHORT;

Already works? The only problem is that this:

   $SHORT::stuff(@args);

Doesn't, but this is a precedence issue with :: and variable
interpolation which I actually submitted RFC 103 on. You could still
write this currently:

   {"${SHORT}::stuff"}(@args);

But admittedly this is not pretty to look at.

Assuming repairing :: precedence is a reality I don't think this
proposal buys us anything. I had actually seen the p5p thread before,
and it seems like a neat idea on the surface, but it's a real special
case and syntax for something that can be solved with simple variables.

-Nate



Re: RFC 101 (v2) Handlers and Pseudo-classes

2000-09-13 Thread Nathan Wiger

[added -io cross-post]

John Porter wrote:
 
 Just MHO, but I don't think this is the kind of thing that should
 go in the core.  Just MHO.

I think I agree. Just to clarify, the only reason it's an RFC and not
just a Perl 5 module is because RFC 14 (the one on a new open()) relies
on a handler concept for dealing with different file types:

   open file "/etc/motd";  # file handler (default)
   open dir "/usr/local/bin"; # dir handler
   open http "http://www.yahoo.com";   # http handler

This type of abstraction would allow you to import custom modules and
register them as http handlers without having to change your main code.
It also prevents bloat in the IO routines which would otherwise have
hardwired-in ways of dealing with this. Modularization lets us update
modules that do http manipulation via CPAN without having to release a
new version of Perl.

Nonetheless, this may not be the best way to go. Perhaps by default, an
"http.pm" is provided which allows basic http operations, and is
automatically imported, allowing you to say:

   open http "http://www.foobar.com"

natively without having a bunch of "use" statements at the top of your
code. Then, if you wanted to override this you could:

   use Class::Handler;
   handler http = 'LWP::UserAgent';

   open http "http://www.foobar.com";  # now uses the http handler
   # instead of native http.pm

Comments welcome.

-Nate



Re: RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)

2000-09-10 Thread Nathan Wiger

Michael Fowler wrote:
 
  =head3 Merge CTIESCALAR, CTIEHASH, and CTIEARRAY into CTIE

 I'm not so sure about this.

I'm not either anymore. This will probably be removed from the next
version.

  Instead, this RFC proposes that Ctie's operation become much more
  fundamental, simply translating functions via the existing indirect
  object syntax:
 
 tie Transaction %trans;# indirect object constructor
 $trans{$var} = $value ;# $obj-STORE($var, $value);
 lock $trans{$var}; # $obj-lock($var);
 
 Ignoring for a moment the ambiguities inherent in indirect object syntax
 (which we should all be aware of), what says $trans{$var} is not an object
 in itself, on which we want to call the lock method?

Well, currently indirect objects would not be called in the syntax
above. You would have to write:

   lock {$trans{$var}};

Because an indirect object can only be a scalar, block, or bareword. So
I would say keeping a similar idea in place - if you want to use the
object method instead of the tied method, use braces - might be the best
way to disambiguate these. And remember you can also do this:

   $trans{$var}-lock

If you want to make sure that the call is completely unambiguous.

However, one thing RFC 174 tries to accomplish is getting Perl to NOT
need the braces in these circumstances, which opens this whole can of
worms right back up. My current thinking is precedence rules:

   1. tied object
   2. indirect object
   3. package function
   4. CORE function

You could then use braces or - if you wanted to force the indirect
object, as the above examples show (and how currently Perl 5 works).

I think this is actually the behavior you'd want. For example, imagine a
tied class whose purpose is to maintain filesystem objects. You'd want
the tied calls to take precedence, since you might have a special way of
sort'ing or push'ing your objects around. And force-disambiguating them
becomes pretty simple and consistent:

   lock $trans{$var};  # use precedence rules
   lock {$trans{$var}};# indirect object (like Perl 5)
   lock ($trans{$var});# package or CORE function

This is actually pretty much how Perl 5 works already. The only thing
we've added is that the tied check is done in a slightly different way.

  =head3 Cuntie should take all references out of scope
 
 I would argue that this should be handled with weak references, and not
 enforced by untie().  I don't necessarily want Perl deleting my object
 behind my back because I untied a variable.

Yeah, I agree with you, and I suspect that this problem will be
implicitly resolved by not having to mix object and tied calls. This'll
get the axe too.

-Nate



Re: RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)

2000-09-10 Thread Nathan Wiger

Michael G Schwern wrote:
 
 sub lock { print "Hello!" }
 $trans = new Lock::Ness; 
 lock $trans;   # $trans-lock
 
 That's not right.

You're correct. Sorry for not double-checking my examples.

 the same reasons I've already pointed out.  You don't want adding a
 method to a class to suddenly alter the behavior of distant code.

Regardless of my huge error above, this doesn't change the fact that
this is exactly what tie() does currently in Perl 5. That is:

   tie @a, 'Matrix';
   push @a, $stuff;

Now changes the meaning of push() in the current package. So the only
real difference in this situation from a user standpoint is that "PUSH"
becomes "push" per the RFC, plus they can now do this with any function
they please.
 
 Yes, it does help solve those problems.  The dangling untie() will
 happen less frequently, and you can customize the hell out of your
 tied class.  But you're trading those problems for a new set of
 ambiguities!

I think your concerns are worthwhile. However, I think the "ambiguities"
part can be resolved through precedence rules and similar constructs. I
think there are many more potential upsides than downsides Iassuming a
careful implementation. By v2 I expect to have a considerably better
implementation section, complete with examples, specific code, rules,
and so forth that should help alleviate any potential ambiguities.

Also, little attention has been paid to operator overloading, which is
another huge deal. Per this RFC, we can now integrate operator
overloading and higher-order variables like @ and %, meaning we can add
custom matrix math classes, special %hashes that do neat stuff in string
contexts, and more.

-Nate



Re: RFC 193 (v1) Objects : Core support for method delegation

2000-09-05 Thread Nathan Wiger

Damian Conway wrote:
 
   attr3 = [ALL]
 
 It was (and is) a good suggestion. I suspect however that it should be
 
  attr3 = [__ALL__]

Any consideration given to the :all export-like tag?

   attr3 = [:all]# could be uppercase too

-Nate



Non-inheritable and cascading methods

2000-09-04 Thread Nathan Wiger

All-

I've been toying with this for a while, and I'm looking for others'
input. I'm not RFC'ing it yet because (a) I already have 25 others to
maintain and (b) I'm not sure if this might be covered by "my sub" or
one of Damian's future RFC's.

Currently, there are two big problems in defining subs that override
inherited ones:

   1. Once you override one, then all classes derived from you get yours
  by default, and not the parent's. Hence having to have a special
  dispatch for UNIVERSAL::can and friends if you override them.

   2. It is not easy to have them automatically cascaded; you must call
  SUPER:: (or NEXT::) manually.

This becomes a big problem with polymorphic objects, since you might
want an ADD routine that just twiddles one thing, but then cascades down
(for example, bigint::ADD might override int::ADD, but you might still
want int::ADD and UNIVERSAL::ADD automatically called always).

The solutions I've been thinking about to these two problems are the
following:

   1. Make it so a given sub cannot be inherited, for example:

 sub mymethod : noinherit { }

  I suspect this may be handled by "my sub", but I couldn't find
  enough info on p5p to tell for sure. This might also be handled
  by the "private" keyword Damian proposes, but I couldn't tell
  for sure.

   2. Make it so a sub can automatically cascade and call all subs by
  the same name in parent classes:

 sub dostuff : cascade { }

  I'm pretty sure I haven't seen anything that suggests this yet.

Clarification/input/etc is appreciated as always.

Thanks,
Nate



Re: RFC 188 (v1) Objects : Private keys and methods

2000-09-04 Thread Nathan Wiger

 private $hash{key};
 private $hash{$key};
 private $hashref-{key};
 
 or to a hash slice:
 
 private @hash{qw(_name _rank _snum)};
 
 or to a complete hash (either directly, or via a reference):
 
 private %hash;
 private { _name = "demo", _rank = "private", _snum = 123 };
 private bless { @attrs }, $class;
 bless private { @attrs }, $class;


Will "private" be a true scoping keyword? Or under strict would you have
to do this:

   private my %hash;


 Note: an alternative would be to make Cprivate a subroutine attribute:
 
 sub check : private { ... }


Has any consideration been given to consistently applying "private" as
an attribute throughout?
   
   my %hash : private;
   $hash{$key} : private = "5";  # I know, I made this up. :-)

   sub dostuff : private { }
   my sub dostuff : private { }

Personally, it reads better to me. I know that the "$hash{$key} :
private" syntax doesn't work (yet, AFAIK), but I'd rather keep the
scopes out front:

   my %STATE;
   our $DEBUG;

And the attributes in back:

   my %STATE : private;
   our $DEBUG : public; # "public" implied and default

Also, on a related issue, any reason why we shouldn't make this:

   my $hash{$key} = $val;

Automatically scope %hash lexically in Perl 6?

-Nate



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

2000-09-02 Thread Nathan Wiger

Michael G Schwern wrote:
 
 Derived classes will never have to override a base's implementation,
 and all member variables should be private, and everyone will always
 use an accessor, and the UN will bring about world peace, and as long
 as I'm wishing for a perfect world, I'd like a pony. ;)
 
 I'm still not totally convinced that its so horrid to make the
 File::LockAndKey DESTROY call $self-SUPER::DESTROY manually... but it
 does break encapsulation.

I'm inclined to agree here. I thought about this overnight, and I'm
nervous about it again. It doesn't seem that it's that hard to add a
single line to your SETUP or BLESS or whatever method that calls
SUPER::SETUP.

Remember, for all other methods you'd still have to do this manually. If
you wanted to modify ADD or STORE, for example, just tweaking a few
things, you'd have to manually call SUPER::STORE. I'm not convinced that
this proposal saves enough typing to justify the problems that Michael
mentions.

Plus, what if you want to call a SUPER::'s DESTROY *not* at the start or
end?

   sub DESTROY {
   my $self = self; # :-)
   # do a bunch of stuff here
   $self-SUPER::DESTROY(@_);
   # do a bunch more stuff here
   }

It seems like this RFC enforces stuff that makes subclassing
unnecessarily hard in some cases. At the very least, there should be a
way to turn this off:

   sub SETUP : nocascade { }

But then, if you're going to turn it off, why not just leave as-is and
have the person turn it on manually by calling SUPER::? Your other RFC
proposes calling NEXT:: manually, so the same philosophy I think should
apply here.

You could still have hooks for BLESS and REBLESS in bless(), but just
make people manuallly call SUPER::BLESS and SUPER::REBLESS if they want.
People doing Perl OO understand SUPER:: already.

-Nate



Re: RFC 189 (v1) Objects : Hierarchical calls to initializers anddestructors

2000-09-01 Thread Nathan Wiger

 I haven't commented on RFC 171 because I assumed it would be shot down
 quickly by the Major Contibutors(tm), but let me just say now that I'm
 firmly in this camp:

Funny, I don't see much difference between RFC 171 and this RFC:

   171: constructor called on object creation
   189: constructor called on object blessing

Both of them suffer from involuntary method calls and no way to prevent
them.

 And I'll further add that I like Damian's RFCs on the topic, having
 essentially duplicated that functionality "by hand" myself at various
 times, and found it to be very useful and friendly.  (Although I
 used "init" instead of "SETUP" but I guess there already is an "INIT")

I like the *idea* to a lot. But I don't like the hooks being in bless.
What if you want to bless something but not call all its cascading
SETUPs? I'd much rather the hooks be somewhere else, like new builtin.
Maybe 'setup'?

 sub new { setup {}, @_ }

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

setup() could do the blessing + call recursive SETUPs. Just calling
bless() would retain the Perl 5 behavior.

-Nate



Re: RFC 171 (v1) my Dog $spot should call a constructor implicitly

2000-08-30 Thread Nathan Wiger

 What, then, happens to the following code:
 
 my Dog $spot;
 if ($age  12) {
 $spot = new Doberman();
 } else {
 $spot = new Corgi();
 }

This is a tricky case that deserves a lot of attention, but not exactly
as written. Imagine this code block:

   my int ($x, $y, $z) = (4, 5, 6);
   if ( $x  $y ) {
  $x = $z;
   }

That seems like simple enough code. But what would that = line do?

   $x = $z; # $x-STORE($z)

That doesn't make any sense, because $z is an object of class int, and
not a number.

I'd propose the following precedence rules for assignment:

   1. If it's an object being assigned, then the old object
  gets overwritten

   2. If it's a simple value being assigned, then -STORE
  is called

So for example:

   my int ($x, $y, $z) = (4, 5, 6);
   if ( $x  $y ) {
  $x = $z;   # $x overwritten
  $y = "15"; # $y-STORE(15)
   }

That's off the top of my head. Any input? This point should probably be
addressed in the RFC in one way or another.

-Nate



Re: RFC 161 (v2) OO Integration/Migration Path

2000-08-29 Thread Nathan Wiger

"Randal L. Schwartz" wrote:
 
 That's my first gut reaction to this proposal.  "If you like Python,
 you know where to find it, but let us have some primitive data types
 in Perl that act primitive so we can optimize things."

Well, we're on a border here. What this RFC is really referring to is
embedded objects, which are wholly different from objects stacked on top
of simple variables.

If everything uses these methods, then these methods *are* the internal
representation of data, meaning there's no slow down with builtin data
types. If you add your own class that grabs these methods, you pay when
you override one, but you don't when you don't. 

These messages talk about this concept thoroughly:

http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00097.html
http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00106.html
http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00112.html

Perl != Python. Perl != Python. Perl != Python... ;-)

-Nate



Re: RFC 161 (v2) OO Integration/Migration Path

2000-08-27 Thread Nathan Wiger

Nathan Torkington wrote:
 
 Are you proposing making even "normal" scalar, hash, and array access
 go through these methods?  Wouldn't that slow everything way down?

Glad you brought this up, Nat!

I would say "yes and no". The reason I'd say this is because Dan S. and
the internals guys are doing a lot of interesting stuff down these
lines. I would also note say that if we had *one* single scalar data
representation, this could be even FASTER than currently, because
everything would be the same.

That being said, you are right in that if this was stuck on top of Perl
5, things would be so ridiculously, terribly slow as to be unusable. If
that looks like it's still going to be the case with Perl 6, then I'll
be the first to drop the idea.
 
 It's like you're proposing an extension to the current tie system to
 deal with more operators, and then saying "no variable can have a
 value, they all have to be ties to objects".  Is that what you're
 suggesting?

Basically, yeah. Sort of. Maybe. I hate putting the word "tie" in there
anywhere, because my goal would be to make default Perl flexible enough
that tie() could be dropped altogether.

In my "vision" (disclaimer: just because it's a vision doesn't mean it's
a GOOD one), Perl 6 is a world where objects are embedded at the lowest
level. You can define specialized accessors methods, like those defined
in RFC 159, to override the default behaviors. If you don't provide
these methods, default ones are provided for you out of CORE.

So, everything is passed around as an object - albeit most of them are
extremely lightweight objects, with only one or two methods and a
single, simple value (like "5"). However, with one common data
representation, there is an amazing amount of consistency, no more
OO-slapped-on-as-an-afterthought, etc.

Remember: All this assumes it's feasible internally. If not, it gets
dropped. But I'd rather work out the kinks of the idea, give it to Larry
and the internals guys, then have them say "What are you, nuts?".
Because if we're not nuts, this would be really cool...

-Nate



Re: RFC 159 (v1) True Polymorphic Objects

2000-08-25 Thread Nathan Wiger

Oh geez! I'm sorry, I forgot to mention David Nicol in the REFERENCES,
who also gave great input, especially on the BOOLEAN accessor. Thanks
David! I swear I'll put you in v2. :-{

-Nate

Perl6 RFC Librarian wrote:
 
 This and other RFCs are available on the web at
   http://dev.perl.org/rfc/
 
 =head1 TITLE
 
 True Polymorphic Objects
 
 =head1 VERSION
 
Maintainer: Nathan Wiger [EMAIL PROTECTED]
Date: 25 Aug 2000
Mailing List: [EMAIL PROTECTED]
Version: 1
Number: 159
Status: Developing
 
 =head1 ABSTRACT
 
 Currently, using objects in numeric and string contexts is not very
 useful or easy:
 
$r = new CGI;
$z = $r + $x;  # oops
print "$r\n";  # double-oops
 
 You can use facilities such as Ctie to help fix this issue, but Ctie
 is limited and slow. You can also overload operators, but this is not
 flexible enough for many applications since it applies to a package (and
 not individual objects).
 
 This RFC proposes the concept of Btrue polymorphic objects, which are
 objects that can morph into numbers, strings, booleans, and much more
 on-demand. As such, objects can be freely passed around and manipulated
 without having to care what they contain (or even that they're objects).
 
 =head1 DESCRIPTION
 
 =head1 Overview
 
 The top-level syntax remains the same. As such, transition to Perl 6 is
 very smooth for most people, and in fact most users don't have to care
 about any of the following details. To them, this script will "just
 work":
 
$y = Math-data(7);
$x = 3;
$name = getname("Nate");
if ( $x  5 ) {
   $y += $x;
   if ( ! $name ) {
  $name = "The math whiz";
   }
}
print "$name got $y";   # "Nate got 10"
 
 However, under the hood things might work drastically differently. In
 fact, C$y and C$name might well be polymorphic objects:
 
$y = Math-data(7);  # $y-CREATE, $y-STORE(7)
$x = 3;  # $x = 3
$name = getname("Nate"); # $name-CREATE, $name-STORE("Nate")
if ( $x  5 ) {  # $x  5
   $y += $x; # $y-STORE($y-NUMBER-PLUS($x))
   if ( ! $name ) {  # $name || $name-BOOLEAN
 $name = "The math whiz";# $name-STORE("...")
   }
}
print "$name got $y";# $name-STRING , $y-STRING
 
 Here, C$y and C$name are objects, but we don't have to care. These
 objects have a key property: Icontext sensitivity. They have numerous
 different methods which are each called only in specific instances. So,
 being called in a numeric context calls CNUMBER, whereas being called
 in a string context would call CSTRING.
 
 Plus, operators are overloadable as well. This means that we might
 decide to overload C+ to become a Java-like concatenation operator on
 our objects:
 
$string = $name + "Wiger";   # $name-STRING-PLUS("Wiger")
 
 Yuck. :-) But it can be done, and that's pretty cool.
 
 =head2 Polymorphic Methods
 
 The following are the proposed methods for Perl 6 objects.  Note that
 these methods are completely Ioptional for a class to define. If they
 are not defined, the object would retain its current behavior. The hooks
 are in Perl if you want them, otherwise they don't get in the way.
 
 Note that CSTRING, CNUMBER, and CBOOLEAN are specialized forms of
 CFETCH. If you define them, they are used instead of CFETCH in the
 given context, otherwise CFETCH is used. Also note that the operators,
 when overloaded, behave similarly to 'use overload', but on an
 Iobject-by-object basis, rather than package-wide.
 
Data Conversion and Access
-
STRING   Called in a string context
NUMBER   Called in a numeric context
BOOLEAN  Called in a boolean context
 
Operator Overloading
-
PLUS Called in + context
MINUSCalled in - context
TIMESCalled in * context
DIVIDED  Called in / context
MODULUS  Called in % context
 
NUMCMP   Called in = context
NUMEQCalled in == context
NUMNECalled in != context
NUMLTCalled in   context
NUMGTCalled in   context
NUMLECalled in = context
NUMGECalled in = context
 
STRCMP   Called in cmp context
STREQCalled in eq context
STRNECalled in ne context
STRLTCalled in lt context
STRGTCalled in gt context
STRLECalled in le context
STRGECalled in ge context
 
BITAND   Called in  context
BITORCalled in | context
BITXOR   Called in ^ context
BITNOT   Called in ~ context
 
Assignment and Existenc

PLEASE DISCUSS ON -objects!! (was Re: RFC 161 (v1) OO Integration/Migration Path)

2000-08-25 Thread Nathan Wiger

Please discuss this RFC on the -objects sublist. Thanks.

Matt, you should probably update the Mailist List to
perl6-language-objects for v2.

-Nate

Perl6 RFC Librarian wrote:
 
 This and other RFCs are available on the web at
   http://dev.perl.org/rfc/
 
 =head1 TITLE
 
 OO Integration/Migration Path
 
 =head1 VERSION
 
   Maintainer: Matt Youell [EMAIL PROTECTED]
   Date: 25 Aug 2000
   Mailing List: [EMAIL PROTECTED]
   Version: 1
   Number: 161
 
 =head1 ABSTRACT
 
 Allow Perl 6 to benefit more directly from object orientation and object
 syntax while leaving a bridge to Perl 5.
 
 =head1 DESCRIPTION
 
 =head2 Overview
 
 Everything in Perl becomes an object, using existing object-syntax. Out of
 plain sight, there would be essentially three base classes: Scalar, List,
 and Hash. Stricter typing would be imposed (as needed) at the object level
 without the need for new keywords. The Scalar base class would know about a
 fixed number of types, perhaps: ref, int, long, bool, and string. Other
 types could be added by subclassing Scalar.
 
 =head2 Examples
 
 For example, rather than:
 
  my int $intVal = 0;
 
 you would say:
 
  my $intVal = 0;
 
  $intVal-asInt;
 
 Or possibly even:
 
  my $invVal-asInt = 0;
 
 for simplicity.
 
 Unary operations could also be made the Scalar object's responsibility in
 the same style:
 
  $record-chop;
 
 Or even possibly controversial things like:
 
  $value-undef;
 
 Finally, some of the more domain-specific features being requested of the
 language could be added in a subclass of Scalar. For example,
 transaction-friendly variables might be subclassed:
 
  use Transactions;
 
  my $firstName = "Bob";
 
  # ... (transaction happens) ...
 
  $firstName-commit; # or -rollback
 
 (Of course, transaction vars might be in their own, independent, class ala
 TMTOWTDI.)
 
 =head2 Wrap-up
 
 What this gives us is a means for adding functionality while leaving the
 basic language structure alone. This way we don't interfere with
 improvements happening elsewhere in the language, and we leave a clean
 migration path for Perl 5.
 
 Also, by allowing lower-level extensibility, many language-feature requests
 may become moot.
 
 =head1 IMPLEMENTATION
 
 Most of the tools required to implement this system are already there.
 
 - Scalar values already have Perl Doing The Right Thing for type conversion.
 Providing the user with methods to activate type conversion explicitly
 shouldn't be a major chore. In fact it could lighten Perl's load in many
 cases by eliminating guess work about when to convert.
 
 - The existing bless-based object system provides most (if not all) of the
 tools needed to implement this system. For example, if I create my own
 scalar class in Perl 5, I can say:
 
  $myScalar-chop;
 
 or
 
  chop $myScalar;
 
 and Perl automagically knows what I mean, barring namespace considerations.
 
 It could work the same way in Perl 6. That would mean that older code could
 very easily get along with newer code, because all of the same operators
 would still be there and they would still work as expected.
 
 =head1 MISC
 
 This approach may also allow for better organization of Perl's internals,
 specifically if the plan is to move toward a Topaz-style (C++)
 implementation. Also, by organizing responsibilities into explicit classes,
 the "mind-reading" load might lighten for the Perl interpreter. At least it
 looks that way from outside.
 
 =head1 REFERENCES
 
 RFC 4:   "Type Inference"
 
 RFC 49:  "Objects should have builtin stringifying STRING method"
 
 RFC 89:  "Controllable Data Typing"
 
 RFC 137: "Overview: Perl OO should Inot be fundamentally changed."
 (specifically the EXECUTIVE SUMMARY)
 
 http://www.perl.com/pub/1999/09/topaz.html : "Topaz: Perl for the 22nd
 Century" - Chip Salzenberg
 
 http://www.youell.com/matt/perlstring/ - A C++ string class that emulates
 Perl's scalar manipulation tools. Bears some similarity to the Scalar object
 described here.



Re: RFC for $ME class variable (was Re: RFC 124 (v1) Sort order forany hash)

2000-08-23 Thread Nathan Wiger

 You can have your cake, but not force us to eat it too...
 
 Like $AUTOLOAD, $ME would be dynamically scoped:

The first time I saw the bareword "self" keyword I almost wet myself in
horror, but I would say that $AUTOLOAD is a disaster that should not be
repeated. And that's the way that this $ME thing is headed...
 
 We seem to cope with $AUTOLOAD okay, without the need to:

I hate it, it's miserable. Too much hidden trickery and special cases. I
could deluge you with examples but I'd rather not. A sub call would
probably be better.

We have ref(), want(), and other calls to find out context, why not
self() to backtrace package context?

-Nate