Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Variable Types Vs Value Types

20 views
Skip to first unread message

Dave Whipp

unread,
Jan 2, 2003, 7:42:05 PM1/2/03
to perl6-l...@perl.org
Can the type of a variable vary independenty of its value?

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.

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

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). The underlying object is not designed to be used in numeric
context: it relies on a variable to call the appropriate methods to get
its numeric value (Of course, an array object could define FETCHNUM to
delegate to FETCHSIZE: but that obscures the point: a variable's type
defines which methods are called in various contexts).

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;

The type of $b refers to the variable's type, not the object's. 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

print @a + $b;

perl maps this to

print @a.FETCHSIZE + $b.sum;

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>).


Dave.

Smylers

unread,
Jan 3, 2003, 8:51:11 AM1/3/03
to perl6-l...@perl.org
Dave Whipp wrote:

> 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

I thought[*0] that Larry said arrays in a scalar context are now treated
as array references, so actually both sides are array refs. Then
there's a further rule that array refs in _numeric_ scalar context yield
the number of elements in the array (since it doesn't make sense to do
arithmetic on references).

So it's C<@a> that's going through two steps to get to the size, not
C<$b>.

I'm not sure how much that effects the general point you were trying to
make.

[*0] Though this is just from memory. I've just had a brief scan
through Apocalypse 2 and can't find it, so I could be wrong.

Smylers

John Williams

unread,
Jan 3, 2003, 1:10:57 PM1/3/03
to Dave Whipp, perl6-l...@perl.org
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

Dave Whipp

unread,
Jan 3, 2003, 4:19:42 PM1/3/03
to perl6-l...@perl.org
John Williams wrote:

> 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).

This is one of those "how we think about the fundamentals" things. I am
taking the viewpoint that "everything is in object". A number is an
object; an array is an object, a hash is in object. The only thing that
differs is that they implement different interfaces.

Perl6 provides syntaxes for those interfaces. $a and @a are both holders
of objects. One of the issues I hoped to provike discussion of is the
difference between

$b = @a;
and
$c := @a;

The former obviously creates a reference to the array; but does the
latter? An ArrayRef is an object that provides indirection to an array
object. But for $c, I have requested a binding, not an assignment. $c
should hold, literally, the same object as @a. If an ArrayRef is a new
object, then we shouldn't create this new object as part of a binding
operation. But if @a is just an object -- with a vtable + data -- like
any other object, then $c should be able to hold that object.

Conversly, an C<tie> operation should be nothing more than

$obj = new ArrayLikeThing;
@a := $obj; # the tie

$b = @a; # creates arrayRef: \$obj
$c := @a; # eq:ID $obj

The abstraction I'm getting at is that the @ and $ sigils simply provide
different DWIMing behavior: there is no fundamental difference between
the objects they can hold: an object is an object.


>>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.

If only objects have types then yes, you'd override the .num method. But
that sidesteps the issue: what if a *variable* has its own behaviour.
The default scalar type might, indeed, call .num when it is used in
numeric context: but this is just a mapping between a static context and
a vtable entry. Lets avoid the question of the semantics of @ vs $: lets
assume that I can say

my Foo $a = ...;
my Bar $b := $a;

Assuming that Foo and Bar are both compatible with the referenced
object, do both $a and $b behave identically? Or can the variable's type
influence the behavior of that variable (remember that variable types
are always lexically scoped, unlike their values).

This type of thing need not be limited to the implicit method calls
introduced by perl to DWIM. It might be as simple as type Bar saying
that "a call to .aaa will actually call .bbb". So $a.aaa will invoke a
different method than $b.aaa -- even though both variables hold the same
object.

This might seem like a silly thing to want to do; but it seems to me
that there are often cases where we want different behaviors in
different contexts. Sure, we can define multiple interfaces; but then we
run into issues with namespace conflicts. I'm not sure how useful this
stuff would be; nor how bad the potential for confusion is. But it feels
like a good conceptual unification.


Dave.

Simon Cozens

unread,
Jan 5, 2003, 9:58:34 AM1/5/03
to perl6-l...@perl.org
dave_...@yahoo.com (Dave Whipp) writes:
> am taking the viewpoint that "everything is in object". A number is an
> object; an array is an object, a hash is in object. The only thing
> that differs is that they implement different interfaces.
>
> Perl6 provides syntaxes for those interfaces. $a and @a are both
> holders of objects.

In which case it makes sense, as I'm sure Larry has said at some point
in the past, just to think of the sigils as part of the name. $a[4]
and @a[4] do the same thing. If you want to think of $a[4] as doing
some dereferencing, feel free. They're both extracting an element from
an array object. If a "scalar" variable can hold an array object,
then it isn't very "scalar"; the sigils don't have much semantic value.


--
As usual, this being a 1.3.x release, I haven't even compiled this
kernel yet. So if it works, you should be doubly impressed.
(Linus Torvalds, announcing kernel 1.3.3 on the linux-kernel mailing list.)

Dan Sugalski

unread,
Jan 5, 2003, 12:10:52 PM1/5/03
to perl6-l...@perl.org
At 1:19 PM -0800 1/3/03, Dave Whipp wrote:
> I am taking the viewpoint that "everything is in object".

Then you'll likely be somewhat surprised at times.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

John Williams

unread,
Jan 5, 2003, 2:39:43 PM1/5/03
to Dave Whipp, perl6-l...@perl.org
On Fri, 3 Jan 2003, Dave Whipp wrote:
> John Williams wrote:
>
> > 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).
>
> This is one of those "how we think about the fundamentals" things. I am
> taking the viewpoint that "everything is in object".

How you or I think about the fundamentals is a moot point, really.
Objects are not covered until apocalypse 20-something, so the main thing
we have to go on is Larry's statement to the effect that things will
behave like objects if you treat them like objects.

> One of the issues I hoped to provike discussion of is the
> difference between
>
> $b = @a;
> and
> $c := @a;
>
> The former obviously creates a reference to the array; but does the
> latter?

That is a good question. Someone wiser that me will have to interpret the
true meaning of $c := @a;.

> An ArrayRef is an object that provides indirection to an array
> object. But for $c, I have requested a binding, not an assignment. $c
> should hold, literally, the same object as @a. If an ArrayRef is a new
> object, then we shouldn't create this new object as part of a binding
> operation.

Saying an Arrayef is a different object from an Array may be taking the
analogy a bit too far. They are different things, yes, but since perl6
references dereference automatically, calling an method on an ArrayRef
will be the same as calling a method on the Array it references.

> If only objects have types then yes, you'd override the .num method. But
> that sidesteps the issue: what if a *variable* has its own behaviour.

Well, I suspect that would be a bad idea. One of the really annoying
things about most OO languages is that if I call my Geo Prizm a
"Vehicle", it suddenly forgets that it is a Geo Prizm. So
$ParkingLot.Vehicle[38].door.open() would fail because not
all Vehicles (motorcycles) have doors. I really hope that a
weakly-typed, OO language will free me from type-casting hell.

If variables get to have their own behavior, then you have accomplished
the same thing in a different way. We will have to typecast our
cars/objects every time we go the the parking lot/collection, because we
want them to stop acting like generic vehicles/superclasses.

> my Foo $a = ...;
> my Bar $b := $a;
>
> Assuming that Foo and Bar are both compatible with the referenced
> object,

To be compatible, they have to be the class of the object or a superclass
of the object, right? ("Have the interface of" is like saying it's a
superclass for languages that don't have multiple inheritance.)

> do both $a and $b behave identically? Or can the variable's type
> influence the behavior of that variable

...


> This might seem like a silly thing to want to do;

Yes.

> but it seems to me
> that there are often cases where we want different behaviors in
> different contexts.

There may be cases, yes. Making it the default case is a probably a
really bad idea. Hopefully my example above illustrates why.

If you are in that case, I imagine you can just do $a.Bar::xxx() or
$a.Foo::xxx() to get what you want.

~ John Williams

Simon Cozens

unread,
Jan 5, 2003, 3:43:32 PM1/5/03
to perl6-l...@perl.org
d...@sidhe.org (Dan Sugalski) writes:
> > I am taking the viewpoint that "everything is in object".
>
> Then you'll likely be somewhat surprised at times.

Can you elucidate?

--
<Halfjack> Ah the joys of festival + Gutenburg project. I can now have
Moby Dick read to me by Stephen Hawking.

Dan Sugalski

unread,
Jan 5, 2003, 6:36:54 PM1/5/03
to perl6-l...@perl.org
At 8:43 PM +0000 1/5/03, Simon Cozens wrote:
>d...@sidhe.org (Dan Sugalski) writes:
>> > I am taking the viewpoint that "everything is in object".
>>
>> Then you'll likely be somewhat surprised at times.
>
>Can you elucidate?

(I admit to be very tempted to answer this "Yes" and leave it at that... :)

I suppose it depends on what you consider object behaviour. If that
definition is "I can call methods on it" then yeah, I guess
everything'll be "objects", but even my standards aren't that low,
and I don't *do* objects.

Things that aren't explicitly objects won't have reference semantics.
They won't have attributes. They won't do any of the other dozen or
so things objects should do. They will be neither pine fresh nor
lemony scented. I can guarantee you that *I* won't be thinking
particularly objectly (or objectively, to forestall the obvious
rejoinder) about things that aren't objects.

An object is a data type, as much as an array or hash is a data type,
but that doesn't make an array an object. [insert obligatory "all men
are Socratese" quote here)

Piers Cawley

unread,
Jan 6, 2003, 8:10:34 AM1/6/03
to Dan Sugalski, perl6-l...@perl.org
Dan Sugalski <d...@sidhe.org> writes:
> An object is a data type, as much as an array or hash is a data type,
> but that doesn't make an array an object. [insert obligatory "all men
> are Socratese" quote here)

I really hope you're wrong here Dan. At least in that particular
case. Being able to inherit from Array or Hash or whatever as a
neater way of implementing, say, Tie semantics would be remarkably useful...

Michael Lazzaro

unread,
Jan 6, 2003, 1:32:03 PM1/6/03
to Dave Whipp, perl6-l...@perl.org
On Friday, January 3, 2003, at 01:19 PM, Dave Whipp wrote:
> Conversly, an C<tie> operation should be nothing more than
>
> $obj = new ArrayLikeThing;
> @a := $obj; # the tie

I was under the impression that a more concise way of saying that would
be:

my @a = new ArrayLikeThing;
-or-
my @a is ArrayLikeThing .= new;

Where ArrayLikeThing must inherit from, or at least present the same
interface as, the built-in Array (array?) type. But that, in turn,
should just be equiv to:

my @a is ArrayLikeThing;

Oof. There might be a big problem here. If we work backward from
previously stated examples:

my int @a; # these should all be identical, right?
my @a returns int;
my @a is Array of int;
my @a is Array returns int;
my int @a is Array;

Here we're using "is" not as a property marker, but meaning "isa".
These lines all declare @a to be an array that stores ints. That would
imply that the "is Array" part is actually instantiating (C<new>ing)
the array... you're not saying that @a "can someday hold an array obj",
you're saying it already _is_ an array obj.

So we're using "is Blah" here as a method of creating an
already-instantiated object, not just typing a variable(?) But that,
in turn, would imply that:

my Foo $a; # declares $a as holding objects of type C<Foo>
my $a is Foo; # instantiates $a as a C<Foo>.

Oh dear. That looks quite wrong.

BUT we *need* to be able to explicitly say "is Array", or something
like it, if we're to be able to easily make alternate implementations
of arrays:

class MyArray is Array {
... stuff overriding the default behavior...
}
my @a is MyArray; # Boom! No C<tie> needed, ever!

or if we're to make complex constructs like:

my @a is Array of Array of Hash of str;

It also could be a cornerstone of classless OO:

my $obj is $parent;

So there appears to be either a flaw in my logic, in my syntax, or in
something bigger. Given that p6d is supposed to start working on
Arrays, I think we (or at least I) need some clarification...

MikeL

Dan Sugalski

unread,
Jan 6, 2003, 3:17:31 PM1/6/03
to Piers Cawley, perl6-l...@perl.org

Well, you'll certainly be able to use delegation to get in the way if
nothing else. Beyond that I'm not sure, but anything that's not based
on the parrot Object PMC (which we've not quite yet defined) won't
necessarily be directly inheritable from.

Doesn't mean you won't be able to build your own custom PMC types
based on existing PMC types, but I'm not really sure I'd consider
that OO or inheritance as such.

Simon Cozens

unread,
Jan 7, 2003, 4:30:25 AM1/7/03
to perl6-l...@perl.org
d...@sidhe.org (Dan Sugalski) writes:
> Well, you'll certainly be able to use delegation to get in the way if
> nothing else. Beyond that I'm not sure, but anything that's not based
> on the parrot Object PMC (which we've not quite yet defined) won't
> necessarily be directly inheritable from.

So make Hashes and Arrays based on the Parrot Object PMC. Why let
implementation get in the way of a really good language? :)

--
It's a testament to the versatility of the human mind that we're so able
to compensate for our own incompetence.
- Darrell Furhiman

Dave Whipp

unread,
Jan 6, 2003, 12:47:41 PM1/6/03
to perl6-l...@perl.org
"Piers Cawley" <pdca...@bofh.org.uk> wrote in message
news:m2el7qz...@TiBook.bofh.org.uk...

Let me suggest two interpretations of Dan's remark that seem
reasonable to me:

1. The internal implementation for an array is an optimization
beyond that of a generic object. This would not be visible to
the programmer, so isn't important wrt the language.

2. There is a primitive "array" type that is promoted to an
objectified Array class when needed. This would be analogous
to the int/Int distinction for primitive numbers. This would be
visible to programmers, but may be acceptable for the same
reason as the int/Int types are.

Of course, it's up to Dan to clarify his own intent: these are just
my opinions.


Dave.


Dave Whipp

unread,
Jan 6, 2003, 2:14:01 PM1/6/03
to Michael Lazzaro, perl6-l...@perl.org
--- Michael Lazzaro <mlaz...@cognitivity.com> wrote:
> These lines all declare @a to be an array that stores ints. That
> would imply that the "is Array" part is actually instantiating
> (C<new>ing) the array... you're not saying that @a "can someday
> hold an array obj", you're saying it already _is_ an array obj.
>
> So we're using "is Blah" here as a method of creating an
> already-instantiated object, not just typing a variable(?) But
> that, in turn, would imply that:

When you declare a variable, but don't assign to it, what value
is stored in it? This answer could be: nothing -- its autovivified
on its first use. If that first use is an assignment, then the
variable's type determines what constructor to use.

Thus:

my (@a,@b,@c) is MyArray;
...
@a = (1,2,3); # calls MyArray.new(List)
@b = Array.new(1,2,3); # calls MyArray.new(Array)
print int(@c); # calls MyArray.new()

This could easily be extended to Scalars: we could autovivify on
first use of an uninitialized variable. The default Scalar class's
.new method would create an undef value; but other classes could
do something more interesting.


Dave.

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

Dan Sugalski

unread,
Jan 7, 2003, 5:48:49 AM1/7/03
to perl6-l...@perl.org
At 9:30 AM +0000 1/7/03, Simon Cozens wrote:
>d...@sidhe.org (Dan Sugalski) writes:
>> Well, you'll certainly be able to use delegation to get in the way if
>> nothing else. Beyond that I'm not sure, but anything that's not based
>> on the parrot Object PMC (which we've not quite yet defined) won't
>> necessarily be directly inheritable from.
>
>So make Hashes and Arrays based on the Parrot Object PMC. Why let
>implementation get in the way of a really good language? :)

Ah, it's too early for a good rejoinder, but rest assured I almost had one. :)

The short answer, I suppose, is that we're not recreating
Smalltalk--at least some small nod is being made towards Practicality.

Simon Cozens

unread,
Jan 7, 2003, 5:54:55 AM1/7/03
to perl6-l...@perl.org
d...@sidhe.org (Dan Sugalski) writes:
> The short answer, I suppose, is that we're not recreating
> Smalltalk--at least some small nod is being made towards Practicality.

I really don't follow your argument here.

What's impractical about being able to inherit from Arrays?

--
Familiarity breeds facility.
-- Megahal (trained on asr), 1998-11-06

Dan Sugalski

unread,
Jan 7, 2003, 6:15:36 AM1/7/03
to perl6-l...@perl.org
At 10:54 AM +0000 1/7/03, Simon Cozens wrote:
>d...@sidhe.org (Dan Sugalski) writes:
>> The short answer, I suppose, is that we're not recreating
>> Smalltalk--at least some small nod is being made towards Practicality.
>
>I really don't follow your argument here.
>
>What's impractical about being able to inherit from Arrays?

Nothing, the impractical part is making arrays objects--they aren't,
and we're not particularly going to go out of our way to make them
so. Like I said, you can always use delegation to subclass an array,
or limit yourself to an odd and restrictive subset of behaviour.
(Basically just vtable method overriding)

I'm dropping a dump of parrot's object model thursday, at which point
everyone can rip into me properly and with good facts to back up
theories of my crack-headedness.

Simon Cozens

unread,
Jan 7, 2003, 6:20:25 AM1/7/03
to perl6-l...@perl.org
d...@sidhe.org (Dan Sugalski) writes:
> Nothing, the impractical part is making arrays objects--they aren't,

Hang on. We're saying that they should be. You're saying that they're
not. You haven't produced any reasons *WHY* they're not. Why *aren't*
they arrays?

It's perfectly practical; most other scripting languages do it. If
Parrot wants to support them, Parrot will have to do it too. So what's
the big problem?

> and we're not particularly going to go out of our way to make them
> so.

Your argument seems to be: "We can't make arrays objects because they
aren't objects and we aren't making them objects."

I don't find that a very strong argument; at best, it's a case of
imposing your particular favourite implementation method on the
language design, and at worst it's completely circular.

--
"In matters of principle, stand like a rock; in matters of taste, swim with
the current."
-- Thomas Jefferson

Simon Cozens

unread,
Jan 7, 2003, 6:22:51 AM1/7/03
to perl6-l...@perl.org
si...@simon-cozens.org (Simon Cozens) writes:
> they arrays?

Bluh, I mean objects. Getting carried away; this is something I do actually
care about, and I'll be quite unhappy if we screw it up.

--
The Blit is a nice terminal, but it runs emacs.

Rafael Garcia-Suarez

unread,
Jan 7, 2003, 6:21:48 AM1/7/03
to Dan Sugalski, perl6-l...@perl.org
Dan Sugalski <d...@sidhe.org> wrote:
> Like I said, you can always use delegation to subclass an array,
> or limit yourself to an odd and restrictive subset of behaviour.
> (Basically just vtable method overriding)

Delegation has drawbacks compared to inheritance : you can't use
a object that delegates to class Foo where an instance of Foo is
expected. Unless Foo and the class that delegates to Foo both
inherit from a common (abstract) superclass (ArrayInterface ?
Dictionary ?) (Duh, this is just starting to sound like Java.)

How do you override vtable methods from within Perl 6 ?

Dan Sugalski

unread,
Jan 7, 2003, 5:28:15 PM1/7/03
to Dave Whipp, perl6-l...@perl.org
At 9:47 AM -0800 1/6/03, Dave Whipp wrote:
>"Piers Cawley" <pdca...@bofh.org.uk> wrote in message
>news:m2el7qz...@TiBook.bofh.org.uk...
>> Dan Sugalski <d...@sidhe.org> writes:
>> > An object is a data type, as much as an array or hash is a data type,
>> > but that doesn't make an array an object. [insert obligatory "all men
>> > are Socratese" quote here)
>>
>> I really hope you're wrong here Dan. At least in that particular
>> case. Being able to inherit from Array or Hash or whatever as a
>> neater way of implementing, say, Tie semantics would be remarkably
>useful...
>
>Let me suggest two interpretations of Dan's remark that seem
>reasonable to me:
>
>1. The internal implementation for an array is an optimization
>beyond that of a generic object. This would not be visible to
>the programmer, so isn't important wrt the language.

That's sort of like saying that a pointer or a double is an
optimization beyond the general object. (Or, more succinctly, "No" :)

>2. There is a primitive "array" type that is promoted to an
>objectified Array class when needed. This would be analogous
>to the int/Int distinction for primitive numbers. This would be
>visible to programmers, but may be acceptable for the same
>reason as the int/Int types are.

Not unless Larry really insists. "Primitive" arrays aren't sub-,
super-, or side-classes of objects--they aren't objects at all.
(They're arrays, hence the name "array") You may be able to treat
them in some ways as objects, but that doesn't make them objects any
more than treating arrays like integers makes them integers.

John Williams

unread,
Jan 7, 2003, 9:29:44 PM1/7/03
to Dan Sugalski, Dave Whipp, perl6-l...@perl.org
On Tue, 7 Jan 2003, Dan Sugalski wrote:
>
> >2. There is a primitive "array" type that is promoted to an
> >objectified Array class when needed. This would be analogous
> >to the int/Int distinction for primitive numbers. This would be
> >visible to programmers, but may be acceptable for the same
> >reason as the int/Int types are.
>
> Not unless Larry really insists. "Primitive" arrays aren't sub-,
> super-, or side-classes of objects--they aren't objects at all.
> (They're arrays, hence the name "array") You may be able to treat
> them in some ways as objects, but that doesn't make them objects any
> more than treating arrays like integers makes them integers.

Perhaps you could explain how the $0 object will work in your mind.
A5 assert that $0 is a object, and it behaves as an array and a hash,
depending on how you subscript it. Typeglobs are gone, and we're all
hoping the TIE interface is gone too, so how will this effect be
accomplished?

~ John Williams


John Williams

unread,
Jan 7, 2003, 9:47:45 PM1/7/03
to Michael Lazzaro, perl6-l...@perl.org
On Mon, 6 Jan 2003, Michael Lazzaro wrote:

> So we're using "is Blah" here as a method of creating an
> already-instantiated object, not just typing a variable(?) But that,
> in turn, would imply that:
>
> my Foo $a; # declares $a as holding objects of type C<Foo>
> my $a is Foo; # instantiates $a as a C<Foo>.
>
> Oh dear. That looks quite wrong.

I'm still not buying the autoinstantiation argument. All the other
(non-M.L.) threads I have read are requiring
my $a is Foo = .new; # or some such...

Both your examples above create the varible $a, but it contains the value
of undef, not an instance of Foo.

OTOH, you can autoinstantiate arrays and hashes like this:

$a[3]{fum};

which will create an array(ref) in $a containing 3 undefs and a hash(ref)
which contains a single key "fum" with the value of undef.

It would be nice if objects could "inherit" this sort of functionality
from arrays and or hashes. Or perhaps it's a DIY thing:

class Foo {

method do_it ( $x ) {
$_ //= .new;
...
}

}

which may not be entirely syntactically correct, but hopefully you get the
idea. It would be really easy to do if something like a class invariant
existed which ran _before_ each method...

~ John Williams


Dan Sugalski

unread,
Jan 7, 2003, 10:24:48 PM1/7/03
to Rafael Garcia-Suarez, perl6-l...@perl.org
At 12:21 PM +0100 1/7/03, Rafael Garcia-Suarez wrote:
>Dan Sugalski <d...@sidhe.org> wrote:
>> Like I said, you can always use delegation to subclass an array,
>> or limit yourself to an odd and restrictive subset of behaviour.
>> (Basically just vtable method overriding)
>
>Delegation has drawbacks compared to inheritance : you can't use
>a object that delegates to class Foo where an instance of Foo is
>expected.

I don't see any good reason for that. If we're providing a delegation
scheme the delegated class should look like a subclass of the
delegatee, even if it's not really and we're actually thunking the
heck out of things)

>How do you override vtable methods from within Perl 6 ?

A package/class with properly named subs/methods will do it, though
Larry may require a property or attribute. You'll also be able to
build them by hand and swap them in and out (potentially on a
per-variable basis) if you need to.

Damian Conway

unread,
Jan 8, 2003, 4:59:14 AM1/8/03
to perl6-l...@perl.org
> One of the wise may override my evaluation,

Or I could do it. ;-)


>>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.)

There are in fact *two* types associated with any Perl variable:

1. Its "storage type" (i.e. the type(s) of value it can hold)
This is specified before the variable or after an C<of> or C<returns>.
It defaults to Scalar.

2. Its "implementation type" (i.e. the class that tells it how to act)
This is specified after an C<is>. It defaults to the type indicated
by the variable's sigil.

So:

Declaration Storage Implementation
Type Type
=========== ======= ==============

my $var; Scalar Scalar
my @var; Scalar Array
my %var; Scalar Hash

my Int @var; Int Array
my @var of Int; Int Array
my @var returns Int; Int Array

my @var is SparseArray; Scalar SparseArray

my Int @var is SparseArray; Int SparseArray
my @var is SparseArray of Int; Int SparseArray
my @var is SparseArray returns Int; Int SparseArray


BTW, the use of C<returns> may seem a little odd, until you realize that,
like a subroutine, a variable is just an access mechanism for values.
There's rather a nice node on PerlMonks just now about just that notion.

>>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).

The latter, in fact. When trying to puzzle out what any binding does
imagine that the LHS is a subroutine parameter, and the RHS the corresponding
argument.

>> 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,)

That won't help. Value (i.e. C<but>) properties don't confer class status.


> 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.

Yep.


> 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.

Weeeeeell...*I'd* say that @array should act like an Array (that is, you should
only be able to call the methods specified by the Array class), except that
any method calls should be polymorphically resolved to invoke the
equivalent SpecialArray methods.

But maybe that's just saying the same thing. Is there a linguist in the house?

;-)


> 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.

To say the least!

Damian


Damian Conway

unread,
Jan 8, 2003, 5:30:58 AM1/8/03
to perl6-l...@perl.org
John Williams wrote:

> I'm still not buying the autoinstantiation argument. All the other
> (non-M.L.) threads I have read are requiring
> my $a is Foo = .new; # or some such...

Yes. You're confusing auto-instantiation of *implementation type* (good)
with autoinstantiation of *stored value* (bad).

>
> Both your examples above create the varible $a, but it contains the value
> of undef, not an instance of Foo.

Correct. But:

my Foo $var;

is implemented by an underlying (possibly optimized-away) Scalar object.
Whereas:

my $var is Foo;

is implemented by an underlying Foo object. It's only this underlying Foo
object that is auto-instantiated.

Damian


Chromatic

unread,
Jan 8, 2003, 2:46:08 AM1/8/03
to perl6-l...@perl.org
On Tue, 07 Jan 2003 12:21:48 +0100, Rafael Garcia-Suarez wrote:

> Delegation has drawbacks compared to inheritance : you can't use
> a object that delegates to class Foo where an instance of Foo is
> expected.

That sounds more like a problem with the polymorphism implementation than an
argument against delegation (or even mixins). isa() considered harmful!

-- c

Rafael Garcia-Suarez

unread,
Jan 8, 2003, 10:02:23 AM1/8/03
to Damian Conway, perl6-l...@perl.org
Damian Conway <dam...@conway.org> wrote:
>
> There are in fact *two* types associated with any Perl variable:
>
> 1. Its "storage type" (i.e. the type(s) of value it can hold)
> This is specified before the variable or after an C<of> or C<returns>.
> It defaults to Scalar.
>
> 2. Its "implementation type" (i.e. the class that tells it how to act)
> This is specified after an C<is>. It defaults to the type indicated
> by the variable's sigil.

How does it work regarding inheritance and polymorphism ?
E.g. consider
my @a is Set of Apple;
my @b is Basket of Fruit;
with Apple isa Fruit, and Basket is a Set.

I assume I can use @a or @b where the expected type is:

@a @b
Set ok ok
Set of Fruit ok ok
Set of Apple ok no(?)
Basket no ok
Basket of Fruit no ok
Basket of Apple no no(?)

the errors being compile-time or run-time, depends on how much verification the
compiler can perform with its input. Reminds me the "Set<Apple>" C++ templates.
And the whole mess that comes with it (when you've got a statically typed language.)

Simon Cozens

unread,
Jan 8, 2003, 10:03:13 AM1/8/03
to perl6-l...@perl.org
dam...@conway.org (Damian Conway) writes:
> There are in fact *two* types associated with any Perl variable:

Is there any chance we could make this a little more confusing? One or
two people still appear to be following you.

--
You advocate a lot of egg sucking but you're not very forthcoming with the
eggs. - Phil Winterbottom (to ken)

Brent Dax

unread,
Jan 8, 2003, 12:25:17 PM1/8/03
to Simon Cozens, perl6-l...@perl.org
Simon Cozens:
# dam...@conway.org (Damian Conway) writes:
# > There are in fact *two* types associated with any Perl variable:
#
# Is there any chance we could make this a little more
# confusing? One or two people still appear to be following you.

I'll make it a little simpler. If A is the type of aggregate (Array,
Hash, RowOfKennels) and E is the type of element (Scalar, String, Dog),
here's where each goes:

my E @var; #assumes Array
my @var of E; #same
my E @var is A; #No assumption
my @var is A of E; #same

'returns' is an exact synonym of 'of', so for the same of clarity and
brevity I'll ignore it. (I would suggest, though, that anyone who uses
'returns' here in real code should be shot.)

Notice that E is always either at the front or behind an 'of', and A is
always after an 'is'. (If you think of a variable as a stack of
properties, this 'is' is just specifying the root property.)

Is that clear enough, or should I say it a little slower?

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"If you want to propagate an outrageously evil idea, your conclusion
must be brazenly clear, but your proof unintelligible."
--Ayn Rand, explaining how today's philosophies came to be

Simon Cozens

unread,
Jan 8, 2003, 12:29:25 PM1/8/03
to perl6-l...@perl.org
bren...@cpan.org (Brent Dax) writes:
> Is that clear enough, or should I say it a little slower?

Clear as it's going to get, I fear.

--
"He was a modest, good-humored boy. It was Oxford that made him insufferable."

Dan Sugalski

unread,
Jan 8, 2003, 3:39:52 PM1/8/03
to John Williams, Dave Whipp, perl6-l...@perl.org

All variables in parrot are implemented as PMCs, and all PMCs may be
accessed with a string, integer, or PMC subscript or set of
subscripts. For PMCs that don't do subscripting this will be a fatal
error, for those that do it'll do whatever the PMC is supposed to do.
(In the case of $0, do the lookup)

If you really, really, really wanted to, you could consider PMCs as
objects. You may have to squint really hard and paint them pink,
but...that PMCs do is allow you to call a method on them, which we
don't guarantee will work as we don't guarantee there's even a
package associated with a PMC)

Damian Conway

unread,
Jan 9, 2003, 5:16:55 AM1/9/03
to perl6-l...@perl.org
Rafael Garcia-Suarez asked:

> Damian Conway <dam...@conway.org> wrote:
>
>>There are in fact *two* types associated with any Perl variable
>

> How does it work regarding inheritance and polymorphism ?
> E.g. consider
> my @a is Set of Apple;
> my @b is Basket of Fruit;
> with Apple isa Fruit, and Basket is a Set.
>
> I assume I can use @a or @b where the expected type is:
>
> @a @b
> Set ok ok
> Set of Fruit ok ok
> Set of Apple ok no(?)
> Basket no ok
> Basket of Fruit no ok
> Basket of Apple no no(?)

All of these seem to make the same incorrect assumption: that the
implementation type specifies what a variable evaluates to.
It doesn't. The storage type does that.

So, saying:

my @a is Set of Apple;

doesn't make C<@a> evaluate to an object of class C<Set of Apple>.
Nor does it define that @a can store a C<Set of Apple>.

We *can* answer your real question (about inheritance and compound types), but
we have to start with the right declarations:

my $a returns Set of Apple;
my $b returns Basket of Fruit;

or:

my Set of Apple $a;
my Basket of Fruit $b;

and a generic assignment:

$c = $a;
$c = $b;

Now we can fill in your list (which is somewhat expanded):


Assignment OK? Because...
====================== === ===============================

my Set $c = $a ok $c's type: Set (of Object)
^ ^
| |
$a's type: Set of Apple

my Set $c = $b ok $c's type: Set (of Object)
^ ^
| |
$b's type: Basket of Fruit

my Set of Fruit $c = $a ok $c's type: Set of Fruit
^ ^
| |
$a's type: Set of Apple

my Set of Fruit $c = $b ok $c's type: Set of Fruit
^ ^
| |
$b's type: Basket of Fruit


my Set of Apple $c = $a ok $c's type: Set of Apple
^ ^
| |
$a's type: Set of Apple


my Set of Apple $c = $b no $c's type: Set of Apple
^ X
| |
$b's type: Basket of Fruit


my Basket $c = $a no $c's type: Basket (of Object)
X ^
| |
$a's type: Set of Apple


my Basket $c = $b ok $c's type: Basket (of Object)
^ ^
| |
$b's type: Basket of Fruit


my Basket of Fruit $c = $a no $c's type: Basket of Fruit
X ^
| |
$a's type: Set of Apple


my Basket of Fruit $c = $b ok $c's type: Basket of Fruit
^ ^
| |
$b's type: Basket of Fruit


my Basket of Apple $c = $a ok $c's type: Basket of Apple
^ ^
| |
$a's type: Basket of Apple


my Basket of Apple $c = $b no $c's type: Set of Apple
^ X
| |
$b's type: Basket of Fruit


^
As usual the | arrow between two classes represents the C<.isa> relationship.

X
And I've used the symbol | to represent the complementary C<.isnta>
relationship.


In other words, to be able to assign a C<Righty> object to a C<Lefty> variable
(or use a C<Righty> in any other context where a <Lefty> is expected):

my Lefty $var = Righty->new();

each component of type C<Righty> must be in a valid C<.isa> relationship to
the corresponding element of C<Lefty>. In other words:

my X of Y of Z $var = (A of B of C)->new();

is only permitted if:

A.isa(X) &&
B.isa(Y) &&
C.isa(Z)


Hope that helps.

Damian

Peter Haworth

unread,
Jan 9, 2003, 9:08:15 AM1/9/03
to Dan Sugalski, John Williams, Dave Whipp, perl6-l...@perl.org
On Wed, 8 Jan 2003 15:39:52 -0500, Dan Sugalski wrote:
> At 7:29 PM -0700 1/7/03, John Williams wrote:
> >Perhaps you could explain how the $0 object will work in your mind.
> >A5 assert that $0 is a object, and it behaves as an array and a hash,
> >depending on how you subscript it. Typeglobs are gone, and we're all
> >hoping the TIE interface is gone too, so how will this effect be
> >accomplished?
>
> All variables in parrot are implemented as PMCs, and all PMCs may be
> accessed with a string, integer, or PMC subscript or set of
> subscripts. For PMCs that don't do subscripting this will be a fatal
> error, for those that do it'll do whatever the PMC is supposed to do.
> (In the case of $0, do the lookup)

That's phrased like it's the type of the subscript value which determines
whether it's a hash-like or array-like access. Shouldn't it be the type of
brackets which do that?

In other words, I don't want to see this happen:

$a[1]; # array-like
$a['1']; # hash-like
$a{1}; # array-like
$a{'1'}; # hash-like

It should be like this:

$a[1]; # array-like
$a['1']; # array-like
$a{1}; # hash-like
$a{'1'}; # hash-like

Maybe it is the right way round, and I've read your remarks the wrong way.
Or maybe it is the value type which determines the type of access at the PMC
level, and it's up to the compiler to force the type based on the brackets.

--
Peter Haworth p...@edison.ioppublishing.com
"After all, what is your hosts' purpose in having a party? Surely not for
you to enjoy yourself; if that were their sole purpose, they'd have simply
sent champagne and women over to your place by taxi."
-- P J O'Rourke

John Williams

unread,
Jan 9, 2003, 10:32:58 AM1/9/03
to Peter Haworth, perl6-l...@perl.org
On Thu, 9 Jan 2003, Peter Haworth wrote:

> On Wed, 8 Jan 2003 15:39:52 -0500, Dan Sugalski wrote:
> > At 7:29 PM -0700 1/7/03, John Williams wrote:
> > >Perhaps you could explain how the $0 object will work in your mind.
> > >A5 assert that $0 is a object, and it behaves as an array and a hash,
> > >depending on how you subscript it. Typeglobs are gone, and we're all
> > >hoping the TIE interface is gone too, so how will this effect be
> > >accomplished?
> >
> > All variables in parrot are implemented as PMCs, and all PMCs may be
> > accessed with a string, integer, or PMC subscript or set of
> > subscripts. For PMCs that don't do subscripting this will be a fatal
> > error, for those that do it'll do whatever the PMC is supposed to do.
> > (In the case of $0, do the lookup)
>
> That's phrased like it's the type of the subscript value which determines
> whether it's a hash-like or array-like access. Shouldn't it be the type of
> brackets which do that?

Yes, that's what I meant, even if I didn't say it clearly. "How you
subscript it" would be either "with brackets" or "with braces".

~ John Williams

Attriel

unread,
Jan 9, 2003, 10:53:18 AM1/9/03
to perl6-l...@perl.org
<HUGE chungs of stuff cut>

> my Set of Apple $a;
> my Basket of Fruit $b;
>
> and a generic assignment:
>
> $c = $a;
> $c = $b;
>
> Now we can fill in your list (which is somewhat expanded):
>

Assignment OK? Because...
====================== === ===============================

my Basket $c = $a no $c's type: Basket (of Object)
X ^
| |
$a's type: Set of Apple

my Basket of Apple $c = $a ok $c's type: Basket of Apple
^ ^
| |
$a's type: Basket of Apple


Now, just to be sure I didn't miss a step:

That second entry is wrong, sin't it? it should be OK? no b/c:

C's Type : Basket of Apple
X ^
| |
A's Type : Set of Apple

yes?

(I'm trying to make sure I didn't miss a majikal mystery conversion step
that seems contradictory but somehow exists anyway :o)

--attriel


Dan Sugalski

unread,
Jan 9, 2003, 12:25:04 PM1/9/03
to Peter Haworth, John Williams, Dave Whipp, perl6-l...@perl.org
At 2:08 PM +0000 1/9/03, Peter Haworth wrote:
>On Wed, 8 Jan 2003 15:39:52 -0500, Dan Sugalski wrote:
>> At 7:29 PM -0700 1/7/03, John Williams wrote:
>> >Perhaps you could explain how the $0 object will work in your mind.
>> >A5 assert that $0 is a object, and it behaves as an array and a hash,
>> >depending on how you subscript it. Typeglobs are gone, and we're all
>> >hoping the TIE interface is gone too, so how will this effect be
>> >accomplished?
>>
>> All variables in parrot are implemented as PMCs, and all PMCs may be
>> accessed with a string, integer, or PMC subscript or set of
>> subscripts. For PMCs that don't do subscripting this will be a fatal
>> error, for those that do it'll do whatever the PMC is supposed to do.
>> (In the case of $0, do the lookup)
>
>That's phrased like it's the type of the subscript value which determines
>whether it's a hash-like or array-like access. Shouldn't it be the type of
>brackets which do that?

[snip]

>Maybe it is the right way round, and I've read your remarks the wrong way.
>Or maybe it is the value type which determines the type of access at the PMC
>level, and it's up to the compiler to force the type based on the brackets.

Got it in two, more or less. I'm waffling on whether a type flag in
the key structure is necessary--I can see it going both ways.

David Storrs

unread,
Jan 9, 2003, 4:55:57 PM1/9/03
to perl6-l...@perl.org
On Wed, Jan 08, 2003 at 05:59:14PM +0800, Damian Conway wrote:

> > 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.
>
> Weeeeeell...*I'd* say that @array should act like an Array (that is, you should
> only be able to call the methods specified by the Array class), except that
> any method calls should be polymorphically resolved to invoke the
> equivalent SpecialArray methods.
>
> But maybe that's just saying the same thing. Is there a linguist in the house?


Will an English major do?

If SpecialArray extends the interface of Array, then these two
statements are not the same; the first statement gives you all of
SpecialArray's functionality while the second statement gives you only
a subset.

--Dks

Piers Cawley

unread,
Jan 13, 2003, 1:35:46 PM1/13/03
to Dan Sugalski, perl6-l...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

> At 1:10 PM +0000 1/6/03, Piers Cawley wrote:
>>Dan Sugalski <d...@sidhe.org> writes:
>>> An object is a data type, as much as an array or hash is a data type,
>>> but that doesn't make an array an object. [insert obligatory "all men
>>> are Socratese" quote here)
>>
>>I really hope you're wrong here Dan. At least in that particular
>>case. Being able to inherit from Array or Hash or whatever as a
>>neater way of implementing, say, Tie semantics would be remarkably useful...
>

> Well, you'll certainly be able to use delegation to get in the way if
> nothing else.

Go on, how would delegation help in the case where you want to be
subclass Array so as to be able to do:

my TiedArraySubclass @foo;

Dan Sugalski

unread,
Jan 13, 2003, 1:54:06 PM1/13/03
to Piers Cawley, perl6-l...@perl.org

Then (assuming that Larry either approves of or doesn't notice my
Evil Plans) @foo is a variable of type TiedArraySubclass, which had
best have a vtable capable of dealing with keyed access. How it does
this, by completely reimplementing an array form, or acting as a
layer on top of the base array implementation that it redispatches to
is up to whoever implements TiedArraySubclass. Presumably, from the
name, there wouldn't actually be a real array under the hood, but
there certainly could be.

0 new messages