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

Variable/value split prelims

5 views
Skip to first unread message

Dan Sugalski

unread,
Oct 7, 2002, 1:37:23 AM10/7/02
to perl6-i...@perl.org
We've been kind of sloppy with variables and values so far--not too
surprising as perl 5 was, and many languages (like C) don't make much
of a distinction, and the distinction doesn't much matter even where
it does exist.

We can't do that any more, unfortunately. That's something of a pity,
as it makes things easier, which should've been a clue that we don't
get to do it that way. :)

A "thing" has three parts, a name (which is optional), a container,
and the contents of the container.

The name lives in a symbol table or scratchpad somewhere, and has a
pointer to the container. That's *all* it has, and is otherwise of no
particular use.

The container part is the variable. It holds the value, and is what
mediates assignment. You must go through the variable when storing the
value, and you must go through the variable when fetching the
value. Unfortunately this also means, in the general case, when doing
any access at all of the value in the variable. Luckily in the normal
case we can skip this indirection. Variables also have properties.

The thing in the container is the value. It also has a type, a vtable
that mediates activities involving the value, and properties. Which
are separate from the variable properties. (Which, again, are
separate from attributes)

What does this mean for us?

Well, first it means we need to conceptually split "variables" into
three parts, rather than two as we have been.

It also means that we need to (or at least really should) split
vtables up into parts, so we can pull them upwards as
appropriate. That way we can promote vtable pieces where appropriate,
when the value and variable are of the same type, to cut out dispatch
overhead. And in those cases where we can't do that, we can do the
normal two-level access. (Though hopefully we can avoid it for most
anything besides objects and aggregates)
--
Dan

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

Leopold Toetsch

unread,
Oct 18, 2002, 4:49:42 AM10/18/02
to Dan Sugalski, perl6-i...@perl.org
In perl.perl6.internals, you wrote:

> A "thing" has three parts, a name (which is optional), a container,
> and the contents of the container.

[ ... ]

> Well, first it means we need to conceptually split "variables" into
> three parts, rather than two as we have been.

Do you have a more verbose description of variable/value separation?

> It also means that we need to (or at least really should) split
> vtables up into parts, so we can pull them upwards as
> appropriate. That way we can promote vtable pieces where appropriate,
> when the value and variable are of the same type, to cut out dispatch
> overhead.

something like:

struct {
can;
has;
isa;
union {
scalar_vtable;
aggregate_vtable;
object_vtable;
};
VTABLE;

"Plain" variables would call either the scalar or the aggregate variant
of the vtable of there type.

Overloaded variables would have a private copy of this vtable. The
overloaded vtable entry points to a stub function, invoking the actual
code.

Objects have their classes vtable, using find_method to locate the PMC
which can then be invoked to do the action.

> ... And in those cases where we can't do that, we can do the


> normal two-level access. (Though hopefully we can avoid it for most
> anything besides objects and aggregates)

verbose please

leo

Dan Sugalski

unread,
Oct 18, 2002, 2:09:43 PM10/18/02
to l...@toetsch.at, perl6-i...@perl.org
At 10:49 AM +0200 10/18/02, Leopold Toetsch wrote:
>In perl.perl6.internals, you wrote:
>
>> A "thing" has three parts, a name (which is optional), a container,
>> and the contents of the container.
>
>[ ... ]
>
>> Well, first it means we need to conceptually split "variables" into
>> three parts, rather than two as we have been.
>
>Do you have a more verbose description of variable/value separation?

Sure. Aggregates are a good one. For example, let's assume you have
an array that can only hold real objects. The objects are the values,
while the array itself is the variable. You *must* go through the
variable's vtable to find a value, while when you manipulate the data
you need to use the vtable in the value.

Tied data's another one. If you tie a scalar, the variable is tied
not the value in the variable. But whenever you access the data in
the variable the variable needs to be involved in the fetch or store,
while the value is what's involved with any actual manipulation.

> > It also means that we need to (or at least really should) split
>> vtables up into parts, so we can pull them upwards as
>> appropriate. That way we can promote vtable pieces where appropriate,
>> when the value and variable are of the same type, to cut out dispatch
>> overhead.
>
>something like:
>
>struct {
> can;
> has;
> isa;
> union {
> scalar_vtable;
> aggregate_vtable;
> object_vtable;
> };
>VTABLE;

Rather than a union, there'd be a set of pointers to various vtable pieces.

> > ... And in those cases where we can't do that, we can do the
>> normal two-level access. (Though hopefully we can avoid it for most
>> anything besides objects and aggregates)
>
>verbose please

Well, with the design as it is, we theoretically need to go through
the variable's vtable every time we need to act on the value in the
variable--we have to do a fetch then dispatch through the fetched
value's vtable to act on it.

What I'd like to be able to do is, for variables that are effectively
passive and don't actually have to get involved, to skip that extra
level of indirection and promote the value's vtable functions into
the variable's vtable.

Leopold Toetsch

unread,
Oct 19, 2002, 10:57:56 AM10/19/02
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski wrote:

> At 10:49 AM +0200 10/18/02, Leopold Toetsch wrote:
>
>> In perl.perl6.internals, you wrote:

>> Do you have a more verbose description of variable/value separation?

> Sure. Aggregates are a good one. For example, let's assume you have an
> array that can only hold real objects. The objects are the values, while
> the array itself is the variable. You *must* go through the variable's
> vtable to find a value, while when you manipulate the data you need to
> use the vtable in the value.


Actually, the new array code works already similar to this scheme.
Actually - and WRT mulit_keyed ops - I would separate the variable
access and the value access at the ops level:

Citing my "[RFC] 2. Proposal for _keyed" ops:


The 3 operand keyed add @a[$i] = @b[3] + %h{"k"}:

add_p_ki_p_kic_p_kc

(which we don't have)

would be 4 ops

key_p_p_ki [3]
key_p_p_kic
key_p_p_kc
add_p_p_p

The key_ ops get the variables out of the aggregate (by setting up
pointers to the actual PMCs), while the add is manipulating the values.
In above example, the variable fetch/store have it's own opcodes...


> Tied data's another one. If you tie a scalar, the variable is tied not
> the value in the variable.


.... while with tieing, we need the variable fetch/store in the vtable.


>> struct {
>> can;
>> has;
>> isa;
>> union {
>> scalar_vtable;
>> aggregate_vtable;
>> object_vtable;
>> };
>> VTABLE;
>
>
> Rather than a union, there'd be a set of pointers to various vtable pieces.


But a scalar (PerlInt) doesn't have all the _keyed methods. An aggregate
doesn't need all the arithmetic or binary vtable entries. So IMHO the
union would be a way to have smaller vtable pieces.

When e.g. a variable is tied, it's vtable would be replaced by a vtable,
which does first fetch the variable, calls the tie-FETCH code, updates
the variable and returns the value.


> What I'd like to be able to do is, for variables that are effectively
> passive and don't actually have to get involved, to skip that extra
> level of indirection and promote the value's vtable functions into the
> variable's vtable.


So we would have e.g.:

- Plain scalar:
vtable->var.get_integer => return cache.int_val
->val.get_integer => return cache.int_val

- Tied scalar:
vtable->var.get_integer => call tie magic (updating the value) =>
->val.get_integer => return cache.int_val

leo

Dan Sugalski

unread,
Oct 23, 2002, 3:54:55 PM10/23/02
to Leopold Toetsch, perl6-i...@perl.org
At 4:57 PM +0200 10/19/02, Leopold Toetsch wrote:
>
>
>>>struct {
>>> can;
>>> has;
>>> isa;
>>> union {
>>> scalar_vtable;
>>> aggregate_vtable;
>>> object_vtable;
>>> };
>>>VTABLE;
>>
>>
>>Rather than a union, there'd be a set of pointers to various vtable pieces.
>
>
>But a scalar (PerlInt) doesn't have all the _keyed methods. An
>aggregate doesn't need all the arithmetic or binary vtable entries.
>So IMHO the union would be a way to have smaller vtable pieces.

Well... the problem is with references. Larry's declared that a
reference must act identically to its referent if used in the right
context. We could force an explicit deref, but I'd rather not.
Treating the reference as if it were the array or hash itself makes
things fit better conceptually, at least for me.

>>What I'd like to be able to do is, for variables that are
>>effectively passive and don't actually have to get involved, to
>>skip that extra level of indirection and promote the value's vtable
>>functions into the variable's vtable.
>
>
>So we would have e.g.:
>
>- Plain scalar:
> vtable->var.get_integer => return cache.int_val
> ->val.get_integer => return cache.int_val

Yep.

>- Tied scalar:
> vtable->var.get_integer => call tie magic (updating the value) =>
> ->val.get_integer => return cache.int_val

Close. (Or the same if I'm misreading) Like:

-tied
vtable->var.get_integer => call tie magic to get value PMC
->tie_magic_returned_pmc.get_integer => reurn cache.int_val

(Assuming in both cases that the int value is cached and doesn't need
to be string converted or anything)

Leopold Toetsch

unread,
Oct 24, 2002, 3:36:39 AM10/24/02
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski wrote:

> At 4:57 PM +0200 10/19/02, Leopold Toetsch wrote:


[ Vtable union ]


> Well... the problem is with references. Larry's declared that a
> reference must act identically to its referent if used in the right
> context. We could force an explicit deref, but I'd rather not. Treating
> the reference as if it were the array or hash itself makes things fit
> better conceptually, at least for me.


So the questions is, how does a reference look like - from a PMC POV?
A PMC with an aggregate VTABLE and ->data pointing to the referents data?

Or a PMC with a pointer to the aggregate in the ->data?

>> So we would have e.g.:
>>
>> - Plain scalar:
>> vtable->var.get_integer => return cache.int_val
>> ->val.get_integer => return cache.int_val
>
>
> Yep.
>
>> - Tied scalar:
>> vtable->var.get_integer => call tie magic (updating the value) =>
>> ->val.get_integer => return cache.int_val
>
>
> Close. (Or the same if I'm misreading) Like:
>
> -tied
> vtable->var.get_integer => call tie magic to get value PMC
> ->tie_magic_returned_pmc.get_integer => reurn cache.int_val
>
> (Assuming in both cases that the int value is cached and doesn't need to
> be string converted or anything)

Your descriptions seems to include another PMC in tie_magic, while mine
just passes the value PMC to tie_magic. tie_magic updates the value,
then the normal scalar behaviour jumps in.

leo

0 new messages