One of the wise may override my evaluation, but...

On Thu, 2 Jan 2003, Dave Whipp wrote:

> Can the type of a variable vary independenty of its value?

My understanding is that the type of a variable merely restricts the type
of value you can assign to it.  (Well, it probably does more, but I'm not
clear on what or how yet.)

> Consider the following:
>
>    my @a = (1,2,3);
>    my $b := @a;
>
> @a and $b both refer to the same object. $b's object has methods such as
> PUSH, POP, etc, as does @a's.

Do they?  One is obviously an array, and one is obviously a scalar.
You may get an error (cannot alias an array as a scalar) or $b get aliased
to the array-in-scalar-context (a reference).

> So the type of the value (object) is the same in each case, but the
> variable's types are different.

OK, I'll assume $b is a reference to @a.

> The difference becomes very obvious when you start doing DWIM stuff.
>
> Consider this code:
>
>    print @a + $b
>
> This will evaluate each, in numeric context. To get at those numbers,
> Perl will translate this to something like
>
>    print @a.FETCHSIZE + $b.FETCHNUM
>
> And will promptly get a run-time error for the latter (maybe just a
> warning).

No, as smylers said, an arrayref in numeric context is the length of the
array.  (Arrays and arrayrefs behave the same in scalar context, if I'm
paraphrasing Larry correctly.)

> Now consider a more extreme (and probably very bad) example: imagine
> we want to (lexically) redefine how an array behaves in numeric context:
> Lets say that we want it to use the sum of its elements, not its size.
> We don't want to modify the object itself (except to give it the C<sum>
> method): we simply want Perl to use the object slightly differently:
>
>    my @a = (1,2,3) but implements_sum_method; # add .sum method to vtable
>    my SummingArray $b := @a;

Actually, (unless implements_sum_method is a subclass of SummingArray,) it
looks like an error to me, because @a is an array and/or an
implements_sum_method, but $b is restricted to holding a SummingArray.

We're getting into areas of "but" which I'm not sure about, but if
SummingArray is a class which impliments .sum and overrides .num to use
it, then this might work (with the same caveats about aliasing an array
to a scalar):

  my @a = (1,2,3) but SummingArray;  # or subclass of summingarray
  my SummingArray $b := @a;

> The type of $b refers to the variable's type, not the object's.

But the value's type is what will be used in vtable lookups, I assume.

> Let us
> suppose that the type-definition syntax allows us to tell perl: "when
> you use this variable in numeric context, call your object's C<sum>
> method.". now, when we code

That would happen when you override the .num method, or whatever the
value-in-numeric-context method is called.

>    print @a + $b;
>
> perl maps this to
>
>    print @a.FETCHSIZE + $b.sum;

or to:
  print @a.Array::num + $b.SummingArray::num;

> and prints 9.
>
> We don't need the variable-type magic, of course. We could have just said
>
>    print @a + @a.sum;
>
> and gotten the same result. But the ability to express the behaviour of
> variables, independently of values, could be useful (and more powerful
> than a c<tie>).

Or it might just cause confusion.  As counter-example, consider:

  my Array @array := SpecialArray.new;

Should the value in @array act like an Array or a SpecialArray?  Most
people would say SpecialArray, because a SpecialArray ISA Array.

I can interpret what you are saying as "sometimes, WIM is to act like
Array", in which case, that's not what most people mean, so you need to be
more explicit somehow.

I can also interpret what you want as saying "my SpecialArray @array :=
Array.new" should autopromote the value to a subclass somehow, which would
be very strange.  I'm no OO guru, but trying to call a method which is
only defined in a subclass of an object's class is probably not going to
work.

On the other, other hand, if the SpecialArray class has defined a
constructor or assignment operator which accepts an Array, then you have
told the compiler how to do the desired autopromotion (although I still
doubt it would work with an alias-operator), and it can mostly DWYM,
although the type of the value has actually changed in this scenario.

~ John Williams



Reply via email to