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

2000-09-20 Thread Damian Conway

I haven't (and won't) have time to go into this in detail :-(

I feel that this proposal is solving the wrong problem. The issue is
that the original Forest and Frog (or DBI and DBI::st) classes are not
*designed* for user-definable Frogs (DBI::st's). If that functionality
is widely needed, the Forest should be redesigned with *configurable*
Frogs.

But even if you can't redesign the forest, Perl still makes it easy to
impose a Japanese accent on Frogs wherever you need to:

my $forest = Forest-new();

if (can_see_Mt_Fuji()) {
local *Frog::speak = sub { "kerokero" };
# or:
# local *Frog::speak = \Frog::Japanese::speak;

print $forest-make_noise();# "kerokero"
}

print $forest-make_noise();# "ribbit-ribbit"

Damian



Re: RFC 265 (v1) Interface polymorphism considered lovely

2000-09-20 Thread Damian Conway

Thanks for getting this RFC together, Piers.

A few comments:

* I suggest you remove my alternative C:must(Foo) suggestion.
  It's too ugly to live, inless you just want to use it as a
  scare tactic to encourage Larry to chose the Cinterface
  syntax instead ;-)


* The new Cinterface keyword would be unnecessary if *package
  specifications* could take attributes:

interface Fetcher;

  would then become:

package Fetcher : interface;


* There's also no need to distinguish Cuse base and Cuse interface,
  since you've previously distinguished them by keyword. I would
  suggest that either Cuse base be used for both types of
  inheritance, or else the definition of an interface specification
  just be a regular Cpackage.


* Interfaces will also need to honour Cuse delegation
  (RFC 193), which provides yet another way of *not* actually
  specifying a method, yet still having it callable.


* The Cuse deferred pragma seems unnecessary, as it is sufficient
  to *declare* the autoloaded method, rather than *define* it.
  That is:

use deferred 'rollover';

  is really just:

sub rollover;

  BTW, this trick already works in Perl 5 (for making Ccan
  acknowledge autoloaded methods).


Damian



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

2000-09-19 Thread Damian Conway

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.

Damian



Re: RFC - Interpolation of method calls

2000-09-18 Thread Damian Conway

   my $weather = new Schwern::Example;
   print "Today's weather will be $weather-{temp} degrees and sunny.";
   print "And tomorrow we'll be expecting ", $weather-forecast;
   
You are wicked and wrong to have broken inside and peeked at the
implementation and then relied upon it.

I think the issue is: *what* tempted them to be so wicked and wrong.
It is the fact that iniquitous direct access interpolated easily, whereas
virtuous accessor access didn't.

Perhaps this RFC should be subtitled: "Ne nos inducas in tentationem..."

:-)

Damian



Re: RFC 218 (v1) Cmy Dog $spot 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 Cuse base 'Interface' 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 Cinterface 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 Ccan
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 Cfetch 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 189 (v2) Objects : Hierarchical calls to initializers and destructors

2000-09-14 Thread Damian Conway

 =head2 The CBUILD method
 =head3 The CREBUILD 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



Re: RFC 218 (v1) Cmy Dog $spot is just an assertion

2000-09-13 Thread Damian Conway

I was hoping Damian would be able to suggest a Perlish way of handling
typechecking and polymorphism. 

If you mean static typechecking, then it is the natural enemy of polymorphism.
Either you give up interface polymorphism (a grievous loss) or you give
up static type-checking.
   
Interface polymorphism leads to a proliferation of pointless classes.

Actually, it's inheritance polymorphism that proliferates pretend classes
like Pet.

Perhaps instead of using inheritance for this, just have "implements"
and formal interfaces.  Then associate a variable with an interface
instead of an object type.

  package Cat implements Pet;
  package Dog implements Pet;

  my Pet $foo;
  $foo-feed();


Not bad. Though I'd suggest a pragma:

package Cat;
use interface 'Pet';

my Pet $foo;
$foo-feed();


Alternatively, one might imagine an attribute C:must that tells a variable
that anything assigned to it must provide certain methods:

my $foo : must(feed water play poop);

$foo = Manager-new();  # die "Manager object can't play".

An interface then becomes an alias for a particular Cmust:

use attr_alias Pet = qw(feed water play poop);

my $foo : must(Pet)


Not sure which I like better. :-)

Damian



Re: Draft RFC: my Dog $spot is just an assertion

2000-09-12 Thread Damian Conway

Piers wrote:

The behaviour of the my Dog $spot syntax should simply be an
assertion of the invariant: 

   (!defined($spot) || (ref($spot) $spot-isa('Dog)))

(!defined($spot) || (ref($spot)  $spot-isa('Dog')))


Otherwise, AMEN!

Damian



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

2000-09-10 Thread Damian Conway

 Also notice that I suggested the TIE be called as a method,
 so that it can be inherited if necessary (maybe you had that idea
 already???)

The tie *can* currently be inherited.

Yes, I was aware. It's just that you  wrote:


tie Some::Class $foo, @args;

 would produce:

TIE('SCALAR', 'Some::Class', @args);


and I was concerned that we were planning to remove the polymorphic dispatch.

(You may have to cut me some slack over the next few days if I say
stupid things or jump to unwarranted conclusions -- I am very ill and my
brain is not functioning properly %-)


Damian



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

2000-09-06 Thread Damian Conway

  print keys %hash, "\n";
  exists $hash{key}{subkey};
  print keys %hash, "\n";

Or did that get fixed when I wasn't looking?

No, the - operator has not been changed to do lazy evaluation.

That's not required. All that is necessary is for Cexists nodes
in the op tree to propagate a special non-autovivifying context to 
subordinate nodes.

E.g. exists $hash{key}{subkey}

exists
   \
  entry
  /   \
  entry   "subkey"
  /   \
  %hash   "key"


Is preprocessed to:

exists
   \
  entry(na)
  /   \
  entry(na)   "subkey"
  /  \
  %hash(na)  "key"

which prevents %hash from autovivifying, which causes the left-most
branch to fail (without autovivifying) when asked for "key", which in
turn causes the entire exists to fail without autovivifying.


I just don't like reading "exists causes autovivification" when it
doesn't.

Sorry, I was being philosophically sloppy. A call to Cexists can
*result* in autovivification (of something), though it does not itself
*cause* autovivification.

;-)


Damian



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

2000-09-06 Thread Damian Conway

Why can't we just apply the same warnings on hashes as we do on
variables in Perl?  Maybe a new lexical pragma:

no autoviv; # any autovivification carps (not just
# hashes)

no autoviv 'HASH';  # no new keys may spring into existence on
# any hash from this point forward

I don't appose these, but I don't think they solve the problem.
For a start they're compile-time, not run-time.


no autoviv '%hash'; # same but for a specific hash
no autoviv '@array';# same but for a specific array

These won't work, since most of the hashes were interested in
controlling autovivification on are anonymous (blessed) ones.


Regardless, I feel that "no autovivification" and "private-ization"
are orthogonal and should be treated as such in the languge.

private @person{'fname','lname'};  # make these private
   freeze %person; # no new keys

But that's two keywords rather than one (and the second keyword isn't
that great for those people who already use FreezeThaw ;-)

I think that would prove annoying. Though I certainly don't oppose some
separate method to shut off autovivification (which Cprivate would
then be considered to call automatically).


P.S. BTW, I used Text::Autoformat for the first time on this very email.
Thanks Damian!

You're most welcome. I note that you didn't use it on the P.S. itself,
as Autoformat would have given you:

P.S. BTW, I used Text::Autoformat for the first time on this very
 email. Thanks Damian!

As, indeed, it just did! ;-)


Damian



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

2000-09-05 Thread Damian Conway

 When you want to turn off an inherited delegation in an ISA situation?

Um, I don't think I understand the question.
   
I'm confused by the question, too.


Delegation is not inherited. Any module you inherit from you won't
use for delegation, AFAIK. They're two different beasts.

But from outside the class, you can't tell whether a method was
inherited or delegated. Derived classes inherit whatever behaviour the
base class provides (method dispatch to ancestors or method delegation
to attributes). If your base class delegates calls to Cdelmeth, you
can prevent that delegation by defining a Cdelmeth method in the
derived class.

Is that what you meant?

Damian



Re: RFC 189 (v1) Objects : Hierarchical calls to initializersanddestructors

2000-09-04 Thread Damian Conway

Given that is happens when bless is called and that all other builtin
methods are anmed after what is being called, not what it is being used
for, then I would say that it should be called BLESS for consistancy reason.

this may seem confusing because you are thinking of one particular use
that you have in mind for this, but in a generic sense it is a method
that is called when bless is called.

To me this points out the flaw in the entire naming scheme, not in my 
dissent :-)

I would much prefer to see:

PRINT   become  PRINTINGor  ONPRINT
PRINTF  become  PRINTFING   or  ONPRINTF
DESTROY become  DESTROYING  or  ONDESTROY
BLESS   be  BLESSINGor  ONBLESS

I realize this won't happen, but one can dream.

As it is, I intend to propose BUILD and REBUILD as the initializer
names, and mention BLESS/REBLESS as popular alternatives.

Ah, well, if worst comes to worst I can always (under RFC 128) write:

sub on (""subname, subbody) {
*{caller()."::$name"} = $subbody
};


on BLESS {
...
}

on PRINT {
...
}

on DESTROY {
...
}


:-)


Damian



Re: RFC 189 (v1) Objects : Hierarchical calls to initializersanddestructors

2000-09-04 Thread Damian Conway

Damian, I think it would be worth at least mentioning BLESS and REBLESS
in an "Alternative Names" section in the RFC. Enough people have voiced
concerns over this that I think these two are worth putting in there.

As I mentioned in another message, I'll be doing that.
   

Then Larry can make the call.

As always.

Damian



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

2000-09-04 Thread Damian Conway

  PRL One powerful application of delegation is as a replacement for
  PRL inheritance where the internals of a prospective base class are
  PRL inaccessible or inconvenient, or the base class was not designed
  PRL to be inherited and yet it must be.

isn't this a HAS_A type of relationship?
   
Yep.


i have plenty of these in my new project and it is a pain.

Yep. Hence this RFC.


  PRL use Class::Delegation

shouldn't that be use delegation? i think you have a cut and paste
error.

You're correct. Many thanks.
(That's what I get for pre-testing all the code in my RFCs! ;-)

   
  
  PRL in  = [qw( getline getlines getc ungetc eof read sysread
  PRLinput_record_separator input_line_number )],

what about a way of delegating ALL the methods of an object? any way to
signify that?

   in = 'ALL',
   
will look up all current methods (maybe tagged?) from the class 'in' and
handle that. then you don't have to update all the delegation calls each
time the 'in' object changes.

Specifying Cin = [] does that. See the description of "catch-alls"
below the bit you've quoted.


Damian



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

2000-09-02 Thread Damian Conway

 private $self-{data} = $derdata;
   
  should be $derdatum here?

Yes. Thanks.

Damian



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

2000-09-02 Thread Damian Conway

I'm still not totally convinced that its so horrid to make the
File::LockAndKey DESTROY call $self-SUPER::DESTROY manually...
   
Believe me, it is in a large, deep, and/or MI hierarchy!


but it does break encapsulation.

Exactly.


If you can figure a way out of the dilema I proposed above, I suppose
this makes sense.

Easy. Don't let File::Lock::Mac inherit from File::Lock. Have it *delegate*
to File::Lock instead. See my forthcoming Cuse delegation RFC.

Damian



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

2000-09-02 Thread Damian Conway

The "multiple inheritance paths" one is good. I like that part a lot.
But the rest makes me really nervous if there's no way to override or
change it.

There is. I'll try and get the Cuse delegation RFC out today.


One thing nobody's brought up is this: What if you decide you want the
standard Perl 5 bless behavior, and you want to tweak the order of
calls. So, you don't define a SETUP. BUT, the author of a module you're
inheriting from defined a SETUP, not to your knowledge? This gets called
automatically by bless(), with no way to override it, either making you
manually undo it all or decide not to subclass it anymore. This is bad.

Delegation support will make "not subclassing" it trivial.

Damian



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

2000-09-02 Thread Damian Conway

Also, its not entirely clear why method chaining is desired only for
constructor and destructors.  What about every other method?

Constructors and destructors are special. They're not about *doing*
something; they're about *being* (or not being) something.

A "doing" method *may* wish to make the object do everything its hierarchy
allows it to do: that's why I proposed CNEXT.

A "being" method *must* make the object be everything its hierarchy requires
it to be: that's why I proposed hierarchical constructors and destructors.


Damian



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

2000-09-01 Thread Damian Conway

What happens on reblessing?

An excellent question, and one that has been exercising my mind for
some time now.

I have come to the conclusion that a reblessing must either:

* invoke the old class's DESTROY(s) and then invoke the
  new class's SETUP(s), or

* invoke some other hierarchy of automagic methods
  (REFIT? RESHAPE? MORPH? TRANSMOGRIFY?), or

* do nothing.

The first behaviour is by far the safest, but would seem to defeat the entire
purpose of reblessing.

The last behaviour is the most flexible but forfeits guaranteed clean-up.

The middle option is annoying because it adds yet another magic method.
But suspect it is the correct response.

Damian



RE: RFC 152 (v1) Replace $self in @_ with self() builtin (not $ME )

2000-08-28 Thread Damian Conway

What I meant to say was more along the lines of "if this could be done as a
macro, does it need to be a pragma, or could it be part of a standard macro
package?"

And, secondly, "if this *is* part of a standard macro package, wouldn't it
be cool to let it shove arbitrary code around rather than just doing
invocant access syntax?"

Sure. *If* the hypothetical macro package comes to be, this and many other
proposals could be subsumed by it. But that's a mighty big "if" :-)

Damian