Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Fun with Typed Objects 1

by John M. Dlugosz (Monsignor)
on Apr 02, 2003 at 19:54 UTC ( [id://247577]=perlmeditation: print w/replies, xml ) Need Help??

In learning C#, I was (among other things) annoyed at having to write
Dog skip = new Dog();
while in C++,
Dog skip;
is sufficient. But before getting very far, I realized that in Perl we have to call new (or whatever) on everything, too. Ah, but the type is still named only once:
my $skip= Dog->new;
since the variable is not typed.

So, if Perl 6 is going to have much stronger compile-time awareness of types, perhaps we should have (to use the familiar Perl 5 syntax)

my Dog $skip; $skip->bark;
work properly.

How?

My first thought was to have a typed variable autovivify to a reference of the proper type. So, since bark() is called on undef, it creates one first. Assigning a value to $skip at any point before its used would suppress that behavior.

We already autovivify undef's based on how they are used: $x->[$y] will create an array ref, and we don't hear any cries from users about "well, maybe we wanted it to be undefined to indicate an error!" as in $x= find_my_array(); $x->[$y]; so extending this to members should not be any different conceptually. If you want to allow undef to mean an exception, check for it!

Another idea is to have a typed variable use a default initializer if one is not specified in the statement. So,

my Dog $skip;
would, as part of the "my" processing, call Dog->CREATE or somesuch. If you really wanted my Dog $skip= undef; you could say so.

—John

Replies are listed 'Best First'.
Re: Fun with Typed Objects 1
by chromatic (Archbishop) on Apr 02, 2003 at 20:43 UTC

    You're right in that C# and Java have a lot of duplication in this case. It'd certainly be nice to have to type what I mean only once. Here's some food for thought, though.

    A good type-inferring system can gather, at compile time, the type of $dog in this construct:

    my $dog = Dog->new();

    I'll probably write much, much more code that actually works with a Dog than code that instantiates a Dog. It seems more valuable to have the option to strictify your type checking these situations, where type inference really can't help:

    method bark_at (Dog $some_other_dog, $message) { # horrible Perl6y pseudo-code print "$.name says to $some_other_dog.name, '$message'\n"; };

    I wouldn't expect bark() to autoinstantiate a Dog object, but effectively it's declaring a lexical $some_other_dog that somehow conforms to Dog.

    It'd also be weird to say:

    class DogShow { my Dog @showdogs; }

    and fill an array with placeholder Dogs. I might want to throw a robot dog in there, or a Puppy, or something that's not specifically a Dog.

      A good type-inferring system can gather, at compile time, the type of $dog in this construct:
      my $dog = Dog->new();
      No, no it can't. Alas. You have no idea how much I'd like that to be the case.

      It's perfectly valid to redefine, at runtime, Dog::new to return a Cat object. Or a FlatTire object.

      Good compile-time type inferencing with a language as dynamic as perl is very difficult.

        Good point. Perl is rather different from type inferring languages, isn't it?

      Faced with the alternative I'm glad Perl isn't typed much (just scalars et al). Think about your snippets above for a bit and then be glad we don't have to worry about interfaces and up/down casting. Its because of this casting that we have so much verbosity in Java and C# in the first place.

      Imagine something like this:
      my $skip = (Dog) Animal->new; or my Dog $skip = Animal->new;
      I think you hit the nail on the head with your:
      my Dog @showdogs;
      After all. Java has had to use Object with its collections to keep them generic. This leaves it to the programmer to *know* what to cast to when fetching the contents. Imagine this in Perl:
      foreach my $dog(Dog @showdogs) { print $dog->bark(),"\n"; }
      Eeeew. However, on the flip side perhaps some kind of autotesting at debug run time to see if an object can do what you want would be nice. So when you do the following:
      method bark_at ($some_other_dog, $message)
      You can specify debug code to run that uses isa() and can() on the references of your choice to test that you are passing the right stuff around.

      However, I've only just thought of that and I don't know how valid or useful such an approach would be. What do you think? Example:
      sub method bark_at ($some_other_dog, $message) { if(DEBUG) { die "Not valid class" unless is_obj_instance("Dog", $some_other_ +dog); } }
      This function returning ok if the var is either an instance of Dog or can do all of Dogs methods. However, in this case its more like an assertation. You could then also create your own $! if you wished.

      I'm not convinced of the usefulness of this though.
Re: Fun with Typed Objects 1 (topicalize the class)
by Aristotle (Chancellor) on Apr 02, 2003 at 22:16 UTC

    I disagree. There are many cases where a default constructor taking zero arguments would be pointless.

    I think a better approach would be to allow on-the-fly topicalization of the class in the declaration so you could say something close to

    my Dolphin $friend is topic = .new("Flipper");

    Admittedly verbose, but there's no duplication.

    I've no doubt the real Perl6 heads would come up with a different solution yet, but I believe something along these lines would work better than just plain autovivification.

    Makeshifts last the longest.

Re: Fun with Typed Objects 1
by erikharrison (Deacon) on Apr 03, 2003 at 06:07 UTC

    Actually, there was some talk of a solution to this. It works in this, somewhat handwavy way.

    The declaration my Dog $spot is not enough to instantiate the object itself. After all, you might want my Dog $spot = new Poodle.

    But it might be enough typing to allow you to call Dog class methods on it, assuming that it is still undef. Which ties in with a somewhat bizzare use of an augmented assignment operators for the method call operator . resulting in  my Dog $spot .= new (name=>"Fido");

    I could live with that . . .

    Cheers,
    Erik

    Light a man a fire, he's warm for a day. Catch a man on fire, and he's warm for the rest of his life. - Terry Pratchet

      I like the way that is going. I thought about class methods after reading Aristotle's post. I think what you describe is very well defined, too: the .= notation means to use the declared type of a variable and call a class method. To prevent surprises in a more general use, perhaps .= should use the actual object if it exists, but allow undef value to pull the declared type.

Re: Fun with Typed Objects 1
by dragonchild (Archbishop) on Apr 02, 2003 at 23:51 UTC
    Can you, in C#, write something like Animal woofer = new Dog()? If so, then the typing of the variable and the name of the class being instantiated need to be separated.

    Also, in C++, Dog skip doesn't do the same thing as Dog *skip = new Dog(). The first create an object and the second creates a pointer to an object. Very different beast, completely. So, you're kinda comparing apples and tires.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Fun with Typed Objects 1
by jkahn (Friar) on Apr 04, 2003 at 00:12 UTC
    I had to do some digging, but Larry's Apocalypses, especially Apocalypse Two have the answer, at least as phrased by The Great One in 2001.

    To wit:

    RFC 218: my Dog $spot Is Just an Assertion I expect that a declaration of the form: my Dog $spot; is merely an assertion that you will not use $spot inconsistently with it being a Dog.

    Later, he says that:

    This bare declaration does not call a constructor; however, there may be forms of declaration that do.

    Of course, they say "The Devil can quote Scripture for his own purposes."

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://247577]
Approved by sschneid
Front-paged by djantzen
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-26 06:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found