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

2000-09-05 Thread Piers Cawley

Michael Fowler [EMAIL PROTECTED] writes:

 On Mon, Sep 04, 2000 at 10:34:37AM +0100, Piers Cawley wrote:
   Well then, that's one nay vote.  :)
   
   Make that two.
  
  Three. But I think Michael already knew about mine and forgot to count
  it.
 
 Heh, I am not counting votes.  That was simply me acknowledging his dislike
 for the idea.  I wish you guys would stop, too; you're depressing me.

Well, you keep advancing this idea which has, as far as I can tell, no
upside apart from the reduction in keystrokes required to instantiate
an object. And in doing that you remove useful functionality from a
bunch of other cases. 

No wonder we're down on the idea.

-- 
Piers




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

2000-09-04 Thread Michael Fowler

Well, unless there are any wildly different points someone hasn't mentioned
until now, I'm going to freeze this RFC as it is (with a few minor tweaks). 
Various alternate syntaxes have been suggested, but I still rather like
mine.  Let Larry do with it what he will.  Hopefully he can take something
useful from the suggestion, and the ensuing discussion.


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



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

2000-09-04 Thread Piers Cawley

Michael Fowler [EMAIL PROTECTED] writes:

 On Fri, Sep 01, 2000 at 10:22:49AM +0100, Piers Cawley wrote:
  And then there's:
  
- Makes factory methods impossible.
 
 my Dog $spot;
 my $pub = $spot-procreate;
 
 Sure looks like a factory method to me.  Just because you don't get to say
 my Dog $pup for some optimization doesn't mean they're impossible.

Given that Cmy Dog $pup would appear to be (currently) the only way
to get any optimization at compile time then I submit that the ability
to optimize all method calls at compile time by declaring typed
variables for stuff is *far* more important than the questionable
gains to be had from implicit instantiation. I can think of *far* more
occasions where I want the optimization than occasions where I don't.

Maybe a compromise along the lines of:

   my Dog $spot = LIST; # $spot = Dog-new(LIST)
   my Dog $patches; # $patches is undefined but we assert that
# it'll be a Dog. (Whether you can do
# $patches-new is left as an exercise)

Where the first element of LIST is not a Dog. If you want to
autocreate a null object then you can do Cmy Dog $spot = ()


 
 
- Conveniently forgets all about polymorphism.
 
 package Mammal;
 
 sub hair_color { ... }
 
 
 package Dog;
 use base qw(Mammal);
 
 sub CREATE { bless({}, "Dog") }
 
 
 package main;
 
 my Dog $spot;
 $spot-hair_color("blue");  # works just fine

That's not polymorphism, that's inheritance.

Polymorphism is: 

try { 

}
catch Exception::SelfHandler {
$!-handle_self
}

Note that in this context CException::SelfHandler is an abstract
superclass. The precise behaviour of the handler is defined by its
subclasses.

Another example:

package MailorderPetshop;

sub make_ad {
my MailorderPetshop $self = shift;

$self-stock_iterator-reset;

try {
STOCKLOOP: while (my Pet $pet = $self-stock_iterator-next) {
print $pet-describe, "\t", $pet-price;
}
}
catch Exception::WrongType {
# Oops, we're not looking for cages etc, skip that
next STOCKLOOP;
}
}

Again, the various C$pets are instances of classes which are
subclasses of Pet, but in the context of the Cmake_ad all we care
about is that they are pets.

 I'm not proposing revamping the entire OO system, and I'd like to know what
 made you think I was.

No, but you are proposing the removal of a behaviour which has the
potential to be *very* useful when it gets better optimized, in favour
of something of questionable benefit. However, see my suggestion at
the top of this reply for something that may prove to be a useful
compromise.

Also, if you're really proposing this as a way of saving typing,
consider the idea that got floated on p5p a while back:

use shortcut;

with Long::Package::Base;

my ::Dog $spot = ::Dog-new('Fido');

Which has the advantage of being useful all over the place...

-- 
Piers




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

2000-09-04 Thread Piers Cawley

Michael Fowler [EMAIL PROTECTED] writes:

 On Sun, Sep 03, 2000 at 12:42:52PM +0200, Bart Lateur wrote:
  But now you're throwing away the kid with the bathwater.
  
  my Dog $spot;
  
  initially was syntax invented so that $spot was marked as only been ably
  to reference a Dog, with as a result that code internally could be
  optimized, by doing things at compile time why otherwise would need to
  be dealt with at runtime. (use fields, as the most notable example).
  Don't throw that away.
 
 Just to be clear, I'm not throwing it away.  Nothing's preventing the
 compiler from still doing that optimization.  I'm simply tacking on
 additional meaning, that it creates a Dog object out of $spot.

You are throwing it away because your proposal means we don't get to
use the optimization in a whole bunch of places where we could before.

-- 
Piers




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

2000-09-04 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
  
   First off, I think everyone is reading this RFC with the wrong mindset,
   forgetting the concept of embedded objects in Perl 6.
  
  Ah, that dumb idea again.
 
 Well, if you disagree with this idea, you probably won't agree with much
 else I have to say on this subject. Just calling something "dumb" isn't
 very productive, though. Maybe an explanation of *why* you think it's
 "dump"? Who knows, you might convince me and all the other "loons" that
 want vtable stuff in core...

Ah... light dawns... from reading further down I think I finally
understand where you're coming from with that RFC and it's not as dumb
as I thought it was, though I still wonder what happens when you
assign a 'Dalmation' to a 'Dog' shaped variable.

  But you're creating the wrong bloody thing. And then you're throwing
  it away. Now that's what I call a win. In this scenario what will
  
 my Dog $spot;
 print defined($spot)
  
  return? If it's *not* 'undef' there'd better be a bloody good reason
 
 This should definitely return undef.

That's not the impression I got from reading Michael's RFC.

  See that
  
  my Dog $patches = $dog_factory-make_me_a_dog
  
  That's a factory method that is, returns a Dog of some sort, but you
  don't know of what breed.
 
 Ok, then again I don't see what your problem with this RFC is.

Because Cref($patches) could easily be 'Dalmation'.

 Maybe Michael and I are on different wavelengths,

Actually, I think you may be.

 so I don't want to rewrite his RFC involuntarily through this
 discussion. *MY* take on CREATE is that it's all taken care of for
 you, unless you override it, in which case you can do special stuff.
 Increased flexibility, but doesn't get in the way. Don't use it if
 you don't want to. Just like DESTROY.
 
 -Nate




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

2000-09-04 Thread Piers Cawley

Damian Conway [EMAIL PROTECTED] writes:

  But I agree that anything beyond that is simply horrible.
  You'll only drive more people *away* from OO, because it
  generates so horribly inefficient code. If you want a
  constructor called, than FGS *call* a constructor. Maybe you
  can reduce the syntax necessary to do that, but please don't
  do it behind our backs.
 
 Well then, that's one nay vote.  :)
 
 Make that two.

Three. But I think Michael already knew about mine and forgot to count
it.

-- 
Piers




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

2000-09-04 Thread Piers Cawley

Michael Fowler [EMAIL PROTECTED] writes:

 On Fri, Sep 01, 2000 at 05:23:27PM +0200, Slaven Rezic wrote:
  Often, there is the case that "my" is used before actually assigning a
  value to it. For example:
  
  my Foo $foo;
  if ($cond1) {
  $foo = new Foo 1, 2, 3;
  } else {
  $foo = new Foo 2, 4, 6;
  }
  
  If we have implicit constructors, will this cause unnecessary
  overhead, that is, calling the implicit constructor and then the real
  one?
 
 Yes, so don't do that.  If you want optimization, I've been suggesting my
 $spot : isa(Dog) (actually, I've been suggesting my $spot isa(Dog), which
 was a typo):


But that's *so* ugly for the (In my code at least) more common case.
If all you want this behaviour for is to save typing, what about
simply *extending* the current syntax so you'd one of:


my new Dog $spot;# Not sure the parser'd like that.
my Dog $spot : from(new); # same as 'my Dog $spot = Dog-new

Actually, I kind of like the second one (though I'm not sure 'from' is
the right name) as it allows you to specify the appropriate
constructor. The advantage of this is that the existing syntax still
works so that those of us who are already using it in anticipation of
the glorious day when we finally get some optimization from it won't
have to rethink the way we do things. Okay, if you want the new
behaviour you have to learn the new syntax, but hey, that's why it's
new. 

-- 
Piers




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

2000-09-03 Thread Bart Lateur

On Fri, 1 Sep 2000 11:59:15 -0800, Michael Fowler wrote:

   my Dog $spot;
   if ($input eq 'Collie') {
   $spot = Collie-new;
   } elsif ($input eq 'Dalmation') {
   $spot = Dalmation-new;
   }
 
 Becuase we're creating two objects when we really only want one.

Yes.  That my Dog $spot should be either my $spot or my $spot : isa(Foo)
(which I just recently made up) in this case.

But now you're throwing away the kid with the bathwater.

my Dog $spot;

initially was syntax invented so that $spot was marked as only been ably
to reference a Dog, with as a result that code internally could be
optimized, by doing things at compile time why otherwise would need to
be dealt with at runtime. (use fields, as the most notable example).
Don't throw that away.

Your proposed isa(Dog) syntax is supposed to replace that syntax, while
the old syntax would get new functionality. It doesn't look nice, for a
start. The idea breaks the "if it does something else, give it a new
name" rule. How about:

my new Dog $spot;

which creates a new instance of Dog, while

my Dog s$pot;

doesn't.

-- 
Bart.



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

2000-09-03 Thread Michael Fowler

On Sun, Sep 03, 2000 at 12:42:52PM +0200, Bart Lateur wrote:
 But now you're throwing away the kid with the bathwater.
 
   my Dog $spot;
 
 initially was syntax invented so that $spot was marked as only been ably
 to reference a Dog, with as a result that code internally could be
 optimized, by doing things at compile time why otherwise would need to
 be dealt with at runtime. (use fields, as the most notable example).
 Don't throw that away.

Just to be clear, I'm not throwing it away.  Nothing's preventing the
compiler from still doing that optimization.  I'm simply tacking on
additional meaning, that it creates a Dog object out of $spot.

It's been something of a struggle to word the RFC correctly so that it
properly conveys that the old usage of my Dog $spot won't work as used
currently, but the optimization can still be done.  Does that make any
sense?

 
 Your proposed isa(Dog) syntax is supposed to replace that syntax, while
 the old syntax would get new functionality. It doesn't look nice, for a
 start. The idea breaks the "if it does something else, give it a new
 name" rule. How about:
 
   my new Dog $spot;

That's definitely an alternative.  I don't particularly like it, but it's an
alternative.  That is, assuming we all (or at least, most of us) want an
implicit construction mechanism.  From the discussion, that doesn't seem to
be the case.


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



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

2000-09-02 Thread David E. Wheeler

On Sat, 2 Sep 2000, Nick Ing-Simmons wrote:

 Damian Conway [EMAIL PROTECTED] writes:
  But I agree that anything beyond that is simply horrible. You'll only
  drive more people *away* from OO, because it generates so horribly
  inefficient code. If you want a constructor called, than FGS *call* a
  constructor. Maybe you can reduce the syntax necessary to do that, but
  please don't do it behind our backs.
 
 Well then, that's one nay vote.  :)
 
 Make that two.
 
 Three.

I was hoping to be strike three!

Four.

David




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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 12:20:34PM +0100, Hildo Biersma wrote:
 Michael Fowler wrote:
  
  On Fri, Sep 01, 2000 at 08:31:17AM +0100, Hildo Biersma wrote:
   My previous concerns have not been adressed:
   - There may not be a default constructor
  
  If there is no implicit constructor method defined by the class, and the my
  Dog $spot syntax is used, a fatal exception is raised.  The RFC mentions
  this.  This exact thing is also currently being discussed.
 
 In OO vocabulary, a 'default constructor' is one that has been declared
 to take no arguments.  If a class defines a constructor that requiers
 arguments, it cannot be called implicitly.

This is not true.  In C++, if a class constructor that requires a single
argument is defined, and without the keyword explicit, it can be called
implicitly in type conversions.

However, I fail to see how this definition of 'default constructor' makes it
a requirement that there be one.  There must be one for my Dog $spot to not
raise a fatal exception, but if it's not defined and my Dog $spot is never
used, there is no requirement that there be an implicit constructor.

 
   - This makes creations of Singleton classes impossible
  
  In what way?  The implicit constructor method can return anything it likes,
  just as current constructors can.
 
 Singleton classes can have a private constructor, and a class method
 that conditionally invokes the constructor _once_, then re-uses the
 reference when this makes sense.  That does not make the class method
 the constructor - and there might be multiple, different, of these class
 methods.

my Dog $spot does not preclude the use of explicit constructors.  All it
does is call a constructor implicitly.  I guess I still fail to see how this
makes singleton classes any less possible than current Perl makes them.


  
   - There is a good reason to created typed, but undef, references
 and fill them in later.
  
  What is this reason?  Can you give some examples?
 
 You need to be able to create a scoped and typed object reference that
 starts out undefined, then is filled in depending on various arguments,
 and then is used safely afterwards.
 
 sub BuyDog {
 my ($budget, $age) = @_;
 
 my Dog $retval;
 if ($budget  100) {
$retval = ExpensiveDog-new(  blabla ---);
 } elsif ($age  12) {
$retval = BigDog-new(--- blabla ---);
 } else {
$retval = MangyDog-new(--- blabla ---);
 }
 $retval-feed();
 fill_in_forms($retval);
 return $retval;
 }
 
   Could such a thing fit
  cleanly and unambiguously in with the rest of this idea?  If so, do you have
  an idea how?
 
 I think not - creating objects implicitly is *wrong*, unless we start to
 allow creating Objects on the stack, such as C++ does.

Well, I've been giving examples of using:

my $spot isa(Dog);

today.  This does fit cleanly and unambiguously.

As for creating objects implicitly, this doesn't do that.  The constructor
is called implicitly, the my Dog $spot syntax is fairly explicit.


  
   Based on my C++ experience, this should only be allowed if the
   constructor has been marked as 'implicit construction safe'.
  
  It is assumed that the method is "implicit construction safe", if by that
  you mean suitable to be called implicitly to construct an object.  Since the
  methods are uniquely named, or specified by the author, I don't think this
  is assuming too much.
 
 Let me reiterate.  One of the issues in C++ is that
 
   Dog spot = 5;
 
 means 
   
   Dog spot = Dog(5);

Actually, it's:

Dog spot;
spot.overload=(5);

assuming there's an operator=(int) defined.  If there's only a Dog(int)
defined, and an operator=(Dog), then yes, the 5 is implictly converted.

I am not proposing we implement implicit conversions.

 
 Merely naming a method as a constructor does not mean implicit object
 creation is a good idea.  Creating objects can be quite expensive, and
 one of the biggest drags on program performance is unexpected object
 creation.

Is getting an object out of my Dog $spot unexpected?  What about if you were
to forget what my Dog $spot means currently?


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



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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 05:23:27PM +0200, Slaven Rezic wrote:
 Often, there is the case that "my" is used before actually assigning a
 value to it. For example:
 
 my Foo $foo;
 if ($cond1) {
   $foo = new Foo 1, 2, 3;
 } else {
   $foo = new Foo 2, 4, 6;
 }
 
 If we have implicit constructors, will this cause unnecessary
 overhead, that is, calling the implicit constructor and then the real
 one?

Yes, so don't do that.  If you want optimization, I've been suggesting my
$spot : isa(Dog) (actually, I've been suggesting my $spot isa(Dog), which
was a typo):

my $foo : isa(Dog);
if ($cond1) {
$foo = new Foo 1, 2, 3;
} else {
$foo = new Foo 2, 4, 6;
}


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



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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 11:41:47AM -0700, David E. Wheeler wrote:
 Michael Fowler wrote:
  
  my Dog $spot;   # $spot is now a blessed Dog object
  $spot-name("Fido");# $spot-{'name'} eq "Fido"
  
  print ref $spot;# yes, "Dog"
  
  $spot = new Dalmation;  # now $spot is a Dalmation object
 
 Yes, but the Dalmation $spot will *not* have the name "Fido," will it?

Nope, $spot is now an entirely new object.


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



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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 10:58:36AM -0800, Michael Fowler wrote:
 my $spot isa(Dog);

This should be my $spot : isa(Dog);


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



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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 09:09:15AM -0700, Nathan Wiger wrote:
 First off, I think everyone is reading this RFC with the wrong mindset,
my Dog $spot;
print ref $spot;# 'Dog'
$spot = new Dalmation;
 
 No reason this wouldn't still work. The term 'constructor' here is
 misleading. 'creator' is what I prefer, and that's also why I prefer
 CREATE.

It will work, but not the way you're expecting (I don't think).

Given:

package Dog;

sub CREATE { bless({ name = undef }, shift) }
sub name   {
my $self = shift;
if (@_) {
return $self-{'name'} = shift;
}

return $self-{'name'};
}


I've annotated what the code does:

my Dog $spot;   # $spot is now a blessed Dog object
$spot-name("Fido");# $spot-{'name'} eq "Fido"

print ref $spot;# yes, "Dog"

$spot = new Dalmation;  # now $spot is a Dalmation object


 At least, this is my take on it. CREATE would border right on the edge
 of internals, taking care of stuff that you normally wouldn't handle
 with new() anyways. Since it's a sub, you can put whatever you want into
 it, but CREATE != new() philosophically.

Unfortunately (because everyone seems to disagree with me) CREATE (or
PREPARE, or NEW, or author-defined) is new().

 
 And of course, Me != Michael, so I don't want to put too many words in
 his RFC. However, this is my take on it. I'm writing a massive RFC right
 now that tries to tie this all together. It's actually quite coherent,
 but when little bits and pieces are leaked admittedly it sounds
 disjointed.

Well, I guess I'll wait until that RFC comes out before asking you what
CREATE does, exactly, in your world.  :)


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



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

2000-09-01 Thread David E. Wheeler

Michael Fowler wrote:
 
 On Fri, Sep 01, 2000 at 11:41:47AM -0700, David E. Wheeler wrote:
  Michael Fowler wrote:
  
   my Dog $spot;   # $spot is now a blessed Dog object
   $spot-name("Fido");# $spot-{'name'} eq "Fido"
  
   print ref $spot;# yes, "Dog"
  
   $spot = new Dalmation;  # now $spot is a Dalmation object
 
  Yes, but the Dalmation $spot will *not* have the name "Fido," will it?
 
 Nope, $spot is now an entirely new object.

Well then, that makes this example rather wasteful, doesn't it?

  my Dog $spot;
  if ($input eq 'Collie') {
  $spot = Collie-new;
  } elsif ($input eq 'Dalmation') {
  $spot = Dalmation-new;
  }

Becuase we're creating two objects when we really only want one.

David



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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 12:35:24PM -0700, David E. Wheeler wrote:
 Well then, that makes this example rather wasteful, doesn't it?

It wasn't an example of how my Dog $spot should be used.  I was explaining
to Nate what his code was doing.

 
   my Dog $spot;
   if ($input eq 'Collie') {
   $spot = Collie-new;
   } elsif ($input eq 'Dalmation') {
   $spot = Dalmation-new;
   }
 
 Becuase we're creating two objects when we really only want one.

Yes.  That my Dog $spot should be either my $spot or my $spot : isa(Foo)
(which I just recently made up) in this case.


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



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

2000-09-01 Thread Michael Fowler

On Fri, Sep 01, 2000 at 10:22:49AM +0100, Piers Cawley wrote:
 And then there's:
 
   - Makes factory methods impossible.

my Dog $spot;
my $pub = $spot-procreate;

Sure looks like a factory method to me.  Just because you don't get to say
my Dog $pup for some optimization doesn't mean they're impossible.


   - Conveniently forgets all about polymorphism.

package Mammal;

sub hair_color { ... }


package Dog;
use base qw(Mammal);

sub CREATE { bless({}, "Dog") }


package main;

my Dog $spot;
$spot-hair_color("blue");  # works just fine

I'm not proposing revamping the entire OO system, and I'd like to know what
made you think I was.


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



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

2000-09-01 Thread Hildo Biersma

Bart Lateur wrote:
 
 First: I don't like the idea of some user supplied code being called
 whenever you declare a new variable, *unless* the author of the class
 created a sub *especially written* for this purpose.

Exactly.  Even then, the arguments must match.

So, if Dog::new() takes one argument, and has also been declared to
be the 'implicit constructor', then:

  my Dog $spot;

is a syntax error.

  my Dog $spot = 'hungry';

is allowed.

 
 Suppose all you want is a variable that can reference existing Dog
 objects, I definitely do not want that a new object that I don't need is
 created, every time I get to the declaration.
 
 Do you really want:
 
 for (1..1000) {
 my Dog $spot;
 }
 
 to create 1 unused Dog objects? Ugh! (not "Ug")

Agree.  I think the RFC confuses the notion of object with the notion of
reference.

 
 But I agree that anything beyond that is simply horrible. You'll only
 drive more people *away* from OO, because it generates so horribly
 inefficient code. If you want a constructor called, than FGS *call* a
 constructor. Maybe you can reduce the syntax necessary to do that, but
 please don't do it behind our backs.

Agree.  Either learn from C++ or don't go this route.

Hildo



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

2000-09-01 Thread Hildo Biersma

Michael Fowler wrote:
 
 On Fri, Sep 01, 2000 at 08:31:17AM +0100, Hildo Biersma wrote:
  My previous concerns have not been adressed:
  - There may not be a default constructor
 
 If there is no implicit constructor method defined by the class, and the my
 Dog $spot syntax is used, a fatal exception is raised.  The RFC mentions
 this.  This exact thing is also currently being discussed.

In OO vocabulary, a 'default constructor' is one that has been declared
to take no arguments.  If a class defines a constructor that requiers
arguments, it cannot be called implicitly.

  - This makes creations of Singleton classes impossible
 
 In what way?  The implicit constructor method can return anything it likes,
 just as current constructors can.

Singleton classes can have a private constructor, and a class method
that conditionally invokes the constructor _once_, then re-uses the
reference when this makes sense.  That does not make the class method
the constructor - and there might be multiple, different, of these class
methods.

 
  - There is a good reason to created typed, but undef, references
and fill them in later.
 
 What is this reason?  Can you give some examples?

You need to be able to create a scoped and typed object reference that
starts out undefined, then is filled in depending on various arguments,
and then is used safely afterwards.

sub BuyDog {
my ($budget, $age) = @_;

my Dog $retval;
if ($budget  100) {
   $retval = ExpensiveDog-new(  blabla ---);
} elsif ($age  12) {
   $retval = BigDog-new(--- blabla ---);
} else {
   $retval = MangyDog-new(--- blabla ---);
}
$retval-feed();
fill_in_forms($retval);
return $retval;
}

  Could such a thing fit
 cleanly and unambiguously in with the rest of this idea?  If so, do you have
 an idea how?

I think not - creating objects implicitly is *wrong*, unless we start to
allow creating Objects on the stack, such as C++ does.

 
  Based on my C++ experience, this should only be allowed if the
  constructor has been marked as 'implicit construction safe'.
 
 It is assumed that the method is "implicit construction safe", if by that
 you mean suitable to be called implicitly to construct an object.  Since the
 methods are uniquely named, or specified by the author, I don't think this
 is assuming too much.

Let me reiterate.  One of the issues in C++ is that

  Dog spot = 5;

means 
  
  Dog spot = Dog(5);

which will always call Dog::Dog(int) (or a promotable version), unless
this constructor has been marked 'explicit'.  Many people feel this
default should have been reversed: the constructor should only have been
called if marked 'implicit', i.e. the default is wrong.

Merely naming a method as a constructor does not mean implicit object
creation is a good idea.  Creating objects can be quite expensive, and
one of the biggest drags on program performance is unexpected object
creation.

Hildo



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

2000-09-01 Thread Slaven Rezic

Often, there is the case that "my" is used before actually assigning a
value to it. For example:

my Foo $foo;
if ($cond1) {
$foo = new Foo 1, 2, 3;
} else {
$foo = new Foo 2, 4, 6;
}

If we have implicit constructors, will this cause unnecessary
overhead, that is, calling the implicit constructor and then the real
one?

Regards,
Slaven

-- 
use Tk;$c=tkinit-Canvas(-he,20)-grid;$x=5;map{s!\n!!g;map{create$c 'line'=
map{$a=-43+ord;($x+($a3)*2=5+($a7)*2)}split''}split"!";$x+=12}split/_/='K
PI1_+09IPK_K;-OA1_+K!;A__1;Q!7G_1+QK_3CLPI90,_+K!;A_+1!KQ!.N_K+1Q!.F_1+KN.Q__1+
KN._K+1Q!.F_1+KN.Q_+1Q__+1!KQ!.N_1;Q!7G_K3,09Q_+1!K.Q_K+1Q!.F_1+KN.Q_';MainLoop



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

2000-09-01 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:

 First off, I think everyone is reading this RFC with the wrong mindset,
 forgetting the concept of embedded objects in Perl 6.

Ah, that dumb idea again.

 I believe the idea would be that CREATE is a *fundamental* method, like
 DESTROY, that would do basic declaration, creation, allocation, etc. So:
 
my Dog $spot;
print ref $spot;# 'Dog'
$spot = new Dalmation;
 
 No reason this wouldn't still work. The term 'constructor' here is
 misleading. 'creator' is what I prefer, and that's also why I prefer
 CREATE.

But you're creating the wrong bloody thing. And then you're throwing
it away. Now that's what I call a win. In this scenario what will

   my Dog $spot; 
   print defined($spot)

return? If it's *not* 'undef' there'd better be a bloody good reason,
otherwise:

package Hades;
{ 
my Dog $cerberus; #There can only be one
   
sub get_guard_dog {
$cerberus ||= Hellhound::ThreeHeaded-new(name =
  'Cerberus');
return $cerberus;
}
}

Doesn't work. Nor does any other creator of singletons come to that.

- Makes factory methods impossible.
 
 A little clarification on what specifically constitutes a "factory
 method" would be great.

See that 

my Dog $patches = $dog_factory-make_me_a_dog

That's a factory method that is, returns a Dog of some sort, but you
don't know of what breed.

-- 
Piers




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

2000-09-01 Thread Nathan Wiger

Piers Cawley wrote:
 
  First off, I think everyone is reading this RFC with the wrong mindset,
  forgetting the concept of embedded objects in Perl 6.
 
 Ah, that dumb idea again.

Well, if you disagree with this idea, you probably won't agree with much
else I have to say on this subject. Just calling something "dumb" isn't
very productive, though. Maybe an explanation of *why* you think it's
"dump"? Who knows, you might convince me and all the other "loons" that
want vtable stuff in core...

 But you're creating the wrong bloody thing. And then you're throwing
 it away. Now that's what I call a win. In this scenario what will
 
my Dog $spot;
print defined($spot)
 
 return? If it's *not* 'undef' there'd better be a bloody good reason

This should definitely return undef.

 See that
 
 my Dog $patches = $dog_factory-make_me_a_dog
 
 That's a factory method that is, returns a Dog of some sort, but you
 don't know of what breed.

Ok, then again I don't see what your problem with this RFC is.

Maybe Michael and I are on different wavelengths, so I don't want to
rewrite his RFC involuntarily through this discussion. *MY* take on
CREATE is that it's all taken care of for you, unless you override it,
in which case you can do special stuff. Increased flexibility, but
doesn't get in the way. Don't use it if you don't want to. Just like
DESTROY.

-Nate



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

2000-09-01 Thread Piers Cawley

Hildo Biersma [EMAIL PROTECTED] writes:

 Perl6 RFC Librarian wrote:
  =head1 DESCRIPTION
  
  What is currently an optimization for pseudo-hashes:
  
  my Dog $spot = Dog-new();
  
  should be replaced with:
  
  my Dog $spot;
  
  which calls an implicit constructor (discussed further in the IMPLEMENTATION
  section).  The optimization behaviour can be retained in some form (see the
  MIGRATION section).
 
 My previous concerns have not been adressed:
 - There may not be a default constructor
 - This makes creations of Singleton classes impossible
 - There is a good reason to created typed, but undef, references
   and fill them in later.

And then there's:

  - Makes factory methods impossible.
  - Conveniently forgets all about polymorphism.

It's *horrible* I tell you. *HORRIBLE*

-- 
Piers





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

2000-09-01 Thread Bart Lateur

On 01 Sep 2000 10:22:49 +0100, Piers Cawley wrote:

 My previous concerns have not been adressed:
 - There may not be a default constructor
 - This makes creations of Singleton classes impossible
 - There is a good reason to created typed, but undef, references
   and fill them in later.

And then there's:

  - Makes factory methods impossible.
  - Conveniently forgets all about polymorphism.

It's *horrible* I tell you. *HORRIBLE*

I haven't followed this discussion up too closely, as the subject
doesn't really interest me. However, I have a few outsider remarks.

First: I don't like the idea of some user supplied code being called
whenever you declare a new variable, *unless* the author of the class
created a sub *especially written* for this purpose.

Suppose all you want is a variable that can reference existing Dog
objects, I definitely do not want that a new object that I don't need is
created, every time I get to the declaration.

Do you really want:

for (1..1000) {
my Dog $spot;
}

to create 1 unused Dog objects? Ugh! (not "Ug")

Furthermore, I think it would be rather neat if

my Dog $spot;
print ref $spot;

would indeed print "Dog". But that is as far as it should go. At worst,
in special cases (with "use Fields;", for example), it may be
initialized to an empty but pre-keyed blessed "hash". Well, that is in
the view of current class implementation practices. If the objects
internals for Perl6 become radically different, these ideas should be 

But I agree that anything beyond that is simply horrible. You'll only
drive more people *away* from OO, because it generates so horribly
inefficient code. If you want a constructor called, than FGS *call* a
constructor. Maybe you can reduce the syntax necessary to do that, but
please don't do it behind our backs.

-- 
Bart.



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

2000-09-01 Thread Damian Conway

 But I agree that anything beyond that is simply horrible. You'll only
 drive more people *away* from OO, because it generates so horribly
 inefficient code. If you want a constructor called, than FGS *call* a
 constructor. Maybe you can reduce the syntax necessary to do that, but
 please don't do it behind our backs.

Well then, that's one nay vote.  :)

Make that two.

Damian



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

2000-08-31 Thread Michael Fowler

On Thu, Aug 31, 2000 at 09:45:52PM -0600, Tom Christiansen wrote:
 Well, remember that BEGIN{} blocks are just subs too, with an optional
 'sub'.
 
 Not exactly.  They are not callable, as they disappear immediately.
 More importantly, they have no @_, and things like pop and shift
 act upon @ARGV from within them.
 
 The compilerish chapter of the Camel calls them blocks.

Well this is good to know (and I should have known it, too).  I will remove
them as alternatives.


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



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

2000-08-31 Thread Nathan Wiger

  Besides, what would be the alternative, BEGIN{} - like blocks?
 
 Such blocks are put forth as an alternative:

Well, remember that BEGIN{} blocks are just subs too, with an optional
'sub'.

But that aside, I don't think a block is what we want to connote. A
block implies "this is evaluated here", not "this is a member method".
That's a sub. Maybe a special sub, like DESTROY, but it's still just a
sub.

 Being able to call these as normal methods may be desirable, or it may not
 be.  Personally, I will likely never call $spot-PREPARE, just as I never
 call tied(%ixhash)-STORE("foo" = "bar"). 

I want to be able to. I call -STORE and -DESTROY all the time, because
it's faster than having to go through tie:

   $object = tie %ignoreme, 'Some::Class';
   $object-STORE('key', 'val');
   $object-DESTROY;

 So the object would be left undefined?  That means this code:

No, not at all. Remember, everything's going to inherit from CORE, at
the very least, which would have to provide a CREATE method which just
instantiates a simple object. So, if no Dog::CREATE exists, then $spot
becomes a regular old scalar. I see many many uses for this. For
example, maybe you have a class that you just want to add a STRING sub
to, so it prints out nice. Forcing a CREATE sub to be defined here is a
needless restriction.
 
 However, consider existing tied classes, for example IO::File; it must
 provide duplicate methods, lowercase for users, uppercase for the tied
 interface.  Would it really be less consistent or readable if, say, the
 getline() method was able to be called when a user said either $fh, or
 $fh-getline?

I'll soon have an RFC coming up that proposes a way to "fix" this, but
implements it differently. I think you'll like it.

I disagree vehemently that users should be able to name all this stuff.
If they're really bothered by it, that's what typeglobs are for.
Infinite flexibility == Infinite confusion. And I don't think simply
choosing variable and sub names counts as dictating style. So on this
point you and I will have to disagree.

-Nate



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

2000-08-31 Thread Tom Christiansen

Well, remember that BEGIN{} blocks are just subs too, with an optional
'sub'.

Not exactly.  They are not callable, as they disappear immediately.
More importantly, they have no @_, and things like pop and shift
act upon @ARGV from within them.

The compilerish chapter of the Camel calls them blocks.

--tom



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

2000-08-31 Thread Michael Fowler

On Thu, Aug 31, 2000 at 07:56:24PM -0700, Nathan Wiger wrote:

  So the object would be left undefined?  That means this code:
 
 No, not at all. Remember, everything's going to inherit from CORE, at
 the very least, which would have to provide a CREATE method which just
 instantiates a simple object.

Don't you mean UNIVERSAL, or did I miss an RFC?


 So, if no Dog::CREATE exists, then $spot becomes a regular old scalar. I
 see many many uses for this. For example, maybe you have a class that you
 just want to add a STRING sub to, so it prints out nice. Forcing a CREATE
 sub to be defined here is a needless restriction.

How is a regular scalar any better than undef?  It's actually worse,
potentially creating bugs that are even more difficult to spot.

my Dog $spot = "Spot";  # no CREATE, $spot is now just "Spot"
$spot-type("collie");  # Spot-type("collie") !


If you meant a reference, that's even worse.  Consider the DBI class; a
user, neglecting to read the documentation, tries:

my DBI $dbh ($database_dsn, $database_username, $database_password);
my $sth = $dbh-prepare( ... );

$dbh was blessed into the DBI class, but as a simple scalar.  Now the
prepare method gets a scalar reference where it was expecting a hash
reference.  I know of few classes that test their object to see if it's the
proper underlying reference, and I doubt DBI is any different.  It tries to
do something like $self-{'database_username'} and blows up rather
spectacularly, and the user sees an error deep inside of DBI.

If you meant a hash reference, there's a similar problem, though you'll see
warnings instead of fatal errors.  That is, assuming DBI uses a hash
reference (which it does, last time I checked, but this is just an example).

So, DBI is forced to provide a CREATE method if bugs are to be made easy to
track.  I would much rather the my DBI $dbh blow up then and there, so the
user gets instant feedback that they shouldn't do that with DBI.

DBI is a good example in another way; DBI-connect() returns a reference
blessed into the DBI::db class.  The default CREATE, if it returns a
reference, can only think to bless it into the DBI class.


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



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

2000-08-31 Thread Nathan Wiger

First off, nice additions to the RFC. 

 Listed below are constructor alternatives.  If a sub is chosen (as in sub
 PREPARE {}) it will suffer from the disadvantage of potentially causing
 problems with current Perl modules.

I don't really think this is a valid concern. We can have p52p6 warn
them, and all other Perl stuff (tie's STORE/FETCH, Perl's DESTROY, etc)
are already done by ALLCAPS subs, just like global vars are $ALLCAPS.

Besides, what would be the alternative, BEGIN{} - like blocks? I think
these should just be subs, that way the user can call them at will as
well. It also makes the implementation easier, just call the appropriate
sub if it exists.

 If an appropriate constructor is not provided a fatal exception should be
 raised when the syntax is used.

Naw, I don't think we should go this route. If it's not a valid imported
package, then the statement should die. But not defining a constructor
should only yield a warning with -w:

   No implicit constructor defined by package Dog at line 47.

At the very most.

 This definition would probably be best provided through a pragma:
 
 use constructor qw(new);

I also don't think we should do this. There's nothing more special about
CREATE/PREPARE/NEW than DESTROY, STORE, or FETCH. We should provide what
we think is a good name (and perhaps some alternatives), and let Larry
decide. 

I'm very much against allowing people to tweak absolutely everything.
There are minimal gains for marked losses in consistent, readable,
maintainable code. See this link for a rant on how this can go really
bad really quickly:

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

-Nate



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

2000-08-31 Thread Michael Fowler

On Thu, Aug 31, 2000 at 05:15:34PM -0700, Nathan Wiger wrote:
 First off, nice additions to the RFC. 

Thanks.  :)

 
  Listed below are constructor alternatives.  If a sub is chosen (as in sub
  PREPARE {}) it will suffer from the disadvantage of potentially causing
  problems with current Perl modules.
 
 I don't really think this is a valid concern. We can have p52p6 warn
 them, and all other Perl stuff (tie's STORE/FETCH, Perl's DESTROY, etc)
 are already done by ALLCAPS subs, just like global vars are $ALLCAPS.

You don't consider warnings from an otherwise working module a problem?  I
do.  It's an issue, and should be mentioned.

 
 Besides, what would be the alternative, BEGIN{} - like blocks?

Such blocks are put forth as an alternative:

 =item sub PREPARE {} or PREPARE {}


 I think these should just be subs, that way the user can call them at will
 as well. It also makes the implementation easier, just call the
 appropriate sub if it exists.

Being able to call these as normal methods may be desirable, or it may not
be.  Personally, I will likely never call $spot-PREPARE, just as I never
call tied(%ixhash)-STORE("foo" = "bar").  If the module is intended to
have such things explicit methods should be provided, preferably lowercase
ones.  That is not to say PREPARE (or whatever is chosen) should not be a
sub, I'm just questioning the practice of calling them directly.


  If an appropriate constructor is not provided a fatal exception should be
  raised when the syntax is used.
 
 Naw, I don't think we should go this route. If it's not a valid imported
 package, then the statement should die. But not defining a constructor
 should only yield a warning with -w:
 
No implicit constructor defined by package Dog at line 47.
 
 At the very most.

So the object would be left undefined?  That means this code:

my Dog $spot;

... intervening space ...

$spot-collar("studded");

emits a warning when there's no Dog-$METHOD, and then promptly dies when
you try to call a method on an undef object.  The two constructs could be
quite a distance apart.  I would rather have a fatal error at the source,
not the symptom.


  This definition would probably be best provided through a pragma:
  
  use constructor qw(new);
 
 I also don't think we should do this. There's nothing more special about
 CREATE/PREPARE/NEW than DESTROY, STORE, or FETCH. We should provide what
 we think is a good name (and perhaps some alternatives), and let Larry
 decide. 

Which is what I'm doing.  I'm providing alternatives, including one
where the module author is allowed to name the implicit constructor.  :)

 
 I'm very much against allowing people to tweak absolutely everything.
 There are minimal gains for marked losses in consistent, readable,
 maintainable code. See this link for a rant on how this can go really
 bad really quickly:

Sure, taken to the extreme, anything can be bad.  There is more than a
little ugly Perl code out there (*gasp* blasphemer!) because some
programmers take certain features and idioms to the extreme.  The same can
be said of any language.

However, consider existing tied classes, for example IO::File; it must
provide duplicate methods, lowercase for users, uppercase for the tied
interface.  Would it really be less consistent or readable if, say, the
getline() method was able to be called when a user said either $fh, or
$fh-getline?

I'd say do both; provide some default method, and provide a way to specify
it when it makes sense.


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