--- Dan Sugalski <[EMAIL PROTECTED]> wrote:
> >we Ruby folks would like to be able to do:
> >
> >   $P1 = $P2 + $P3
> >
> >Which, of course, doesn't work.
> 
> Well... actually you don't want what you're asking
> for.

Maybe... :/

> Specifically you don't want
> 
>     foo = bar + baz
> 
> to access the foo, bar, or baz named slots in the
> global or lexical 
> variable areas if you can possibly help it. Really,
> you don't--doing 
> so likely needs a hash lookup (for globals) or an
> indirect slot 
> lookup (for lexicals, if you're lucky. If not you
> have a hash lookup) 
> You *definitely* don't want it to translate into:
> 
>     $P0 = fetch_lex "bar"
>     $P1 = fetch_lex "baz"
>     add_new $P2, $P0, $P1
>     store_lex "foo", $P2
> 
> Because that's really inefficient if you've used
> foo, bar, or baz 
> elsewhere in the compilation unit already. It's also
> very wrong if 
> foo is *not* an object, because you don't want
> assignment to 
> unconditionally rebind--the destination variable has
> to control what 
> happens on assignment. Rebinding might be the right
> thing, but, then, 
> it might not be. (If foo, for example, is a
> low-level 32 bit integer 
> you would *not* want it rebinding)

Well, I understand the reason for using mediating
structures for efficiency, but why do I never want
assignment to unconditionally re-bind? In my
experience, that usually *is* what I want.

> The standard, and arguably correct, thing to do here
> is to introduce 
> a mediating structure. It's a pretty common
> thing--you bind the name 
> to the mediating structure essentially permanently,
> and then hand 
> your object off that structure. Doing assignment
> then, rather than 
> rebinding the name to the new object, instead
> rebinds the mediating 
> structure to the new object. This allows the
> compiler to cache what 
> is fetched from the symbol tables--since the binding
> to the mediating 
> structure is permanent you can avoid multiple
> fetches and stores.

So you would normally never use store_global, but only
fetch_global, and then assign to that container? In
that case, it might be useful to have another op that
retrieves that container, or creates it if it doesn't
exist (find_or_create_global).

> The added bonus here is that if the thing you got
> out of the symbol 
> table *isn't* one of these mediating structures
> (because it's a PMC 
> for an int, say, or a matrix) then assignment still
> Does The Right 
> Thing, since the destination controls the
> assignment.

So if you don't want people messing with your object
when assigning to a global, you'd better put it in a
mediating structure before storing it in that global?

> Right now the missing piece for Parrot is that
> mediating 
> structure--ParrotObjects, rather than going directly
> into the symbol 
> tables, really need to be hidden behind
> ParrotReference or 
> ParrotObjectHandle PMCs to provide the appropriate
> level of 
> indirection.
> 
> If we do that it all works out right, which is quite
> nice.

My main issue with this is that you're assuming that
there is *always* a mediating structure involved, and
building this assumption into the PIR syntax by using
the same operator ("=") both for operations that work
on the register directly (new), and for those that go
through the reference object (add). It's fine to have
operations that work through the reference object,
even to *only* have those, but they should look
different than those that work directly on values (as
the int or float version of 'add' do). There should be
one operator for binding, and one for 'assign'ment. So
when I look at this PIR code

   foo = bar + baz

it shouldn't matter if foo, bar, and baz are PMCs or
ints or floats. It'll either have 'set' behavior, or
not compile (assuming "=" represents the binding op,
and not the assignment op. Otherwise, replace "set"
with "assign").


__________________________________
Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway 
http://promotions.yahoo.com/design_giveaway/

Reply via email to