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