On Tue, May 22, 2007 at 01:41:32PM -0700, Allison Randal wrote:
> Oh, could someone capture that IRC discussion we just had and paste it 
> on the list?

Here it is (long, 247 lines).  

Pm


19:45 <pmichaud> I know I should already know this, but is there a way to make 
a named function that is global to all namespaces?  Does putting something
                 in the root namespace do that for me?
19:45 <pmichaud> and what sort of naming convention should we use to avoid 
naming collisions there?
19:46 <pmichaud> (in particular, I'm looking at a PIR version of the 
assign_keyed operation from my email
19:46 <particle> why not stick it in a library?
19:46 <particle> you don't want to load the lib in each namespace?
19:46 <pmichaud> right
19:47 <particle> well, you could use exporter
19:47 <allison> by "global to all namespaces", do you mean you store it in one 
namespace, but can look it up in any namespace? if so, there isn't any
                such option (it would be a massive pollution)
19:47 <particle> can you stick it in a constant?
19:47 <allison> but, you can store it in the top level namespace, and look it 
up with get_root_global
19:47 <particle> .const pmc myassign = ...
19:48 <pmichaud> I don't necessarily want to look it up in every subroutine 
generated by PAST-pm
19:48 <pmichaud> I mean, I can, but...
19:48 <particle> macros are global
19:48 <pmichaud> I'd like for PAST-pm to be able to simply generate  
'assign_keyed'($P0, key, $P1)     and have it work
19:48 <allison> what are you looking to pass into the subroutine?
19:49 <particle> pmichaud: you could create a dynamic opcode lib
19:49 <pmichaud> allison: did you happen to read my post to parrot-porters 
about assignment?  That's what I'm looking at
19:49 <allison> or, what are $P0 and $P1 in those examples
19:49 <particle> it'd be c, but i think that's your ultimate goal anyway
19:49 <pmichaud> particle: yes, that would probably work
19:49 <allison> I skimmed them this morning, but can look again
19:49 <pmichaud> allison:  ideally I'd like to be able to have it as an opcode
19:49 <particle> assign_keyed aggregate, key, value
19:49 <pmichaud> given an aggregate $P0, a key, and a value to be assigned $P1
19:49 <pmichaud> assign_keyed $P0[key], $P1
19:49 <pmichaud> key could be an int, string, or PMC
19:50 <particle> pmichaud: current pir won't allow that syntax iirc
19:50 <allison> is that an advantage over aggregate[key] = value?
19:50 <particle> yes, = is set
19:50 <pmichaud> yes, because aggregate[key] = value does a bind, not an assign
19:50 <pmichaud> $P0 = aggregate[key]
19:50 <pmichaud> aggregate[key] = $P1
19:50 <particle> aggregate[key] := value
19:51 <allison> so "assign aggregate[key], value"?
19:51 <particle> unfortunately, := is what we have already as =
19:51 <pmichaud> there is no "assign aggregate[key], value"
19:51 <pmichaud> and yes, I'd like that sort of assign, but with a huge caveat
19:51 <allison> but that's what you're looking for?
19:51 <pmichaud> yes, but I also want it to create aggregate[key] if it doesn't 
exist, and to morph aggregate[key] to value's type if it does
19:52 <particle> dwim_assign_keyed
19:52 <particle> is it the op's job to create a nonexistent key, or the 
aggregate's job?
19:53 <allison> seems like something that may vary per-pmc, so you'd want it to 
be handled by vtable entries
19:53 <pmichaud> it should be a vtable on the aggregate, same as set 
aggregate[key], value   does now
19:53 <particle> who's in charge of auto-vivifying?
19:53 <allison> but I'll look over your proposal
19:53 <particle> yeah, i agree it should be the pmc
19:53 <pmichaud> in the meantime, I was looking for a way to implement it even 
if it's not an opcode
19:54 <pmichaud> thus, something "global-ish"  :-)
19:54 <allison> do you need both set_pmc_keyed and assign_pmc_keyed?
19:54 <pmichaud> probably, yes
19:54 <particle> yep
19:54 <pmichaud> one is binding, one is assignment
19:54 <particle> however... parrot *can* punt on this one
19:55 <pmichaud> it can?
19:55 <particle> iiuc you can implement the semantics of assignment with 
binding only or vice-versa
19:55 <pmichaud> particle:  If you can show me how to do that for the example I 
gave in the message, I'm all ears :_)
19:55 <pmichaud> er, eyes
19:55 <particle> however you need a container type
19:55 <pmichaud> right, we don't have a scalar container type
19:55 <allison> the container type is PMC
19:56 <particle> ok, a value type :)
19:56 <allison> which is Integer, String, etc
19:57 <pmichaud> if we had a scalar container type, it could work, yes.  But 
then an aggregate would need to be an array of scalar containers
19:58 <allison> what's the advantage of morphing the PMC to an Undef first and 
then morphing it to a new type?
19:58 <pmichaud> it works :-)
19:58 <allison> you lose the value anyway, so why not just store a new PMC?
19:58 <pmichaud> because of binding
19:58 <pmichaud> I may have other lexicals bound to the old PMC
19:58 <pmichaud> my $b := @a[2]
19:58 <pmichaud> if @a[2] goes to a new PMC, then $b still points to the old one
19:58 <allison> you may have the aggregate member aliased to another name
19:59 <particle> yep
19:59 <pmichaud> so, we have to make sure that the existing PMC at @a[2] 
changes to the new value, as opposed to simply giving @a[2] a new PMC
20:00 <allison> so, it used to be that all PMCs could morph to another type, 
but we dropped that feature
20:00 <particle> pm: we can create a Scalar, ResizableScalarArray, and 
ScalarHash if you wish
20:00 <allison> because it was only needed by perl
20:00 <pmichaud> I don't think it's ever been that all PMCs could morph to 
another type, at least not as long as I've been with Parrot
20:00 <allison> well, the basic types
20:00 <pmichaud> I know that several of the basic types (Int, Scalar, Fl... ) 
yeah
20:00 <pmichaud> but I couldn't, say, morph an array into an Integer
20:00 <particle> tcl has "shimmering" which is morphing
20:00 <allison> (they were called PerlInt, PerlString, etc in those days)
20:01 <pmichaud> well, Int, String, and Float still morph
20:01 <pmichaud> sorry, Integer, String, and Float still morph
20:01 <allison> what you're really looking to is an alias to a structural slot
20:02 <pmichaud> I'm not sure that's what I'm looking for :-)
20:03 <pmichaud> unless we have some way of keeping track of structural slots
20:04 <allison> does Perl 6 specify that if you take an alias to an array 
within an array, and assign an integer to the same position in the array, that
                the alias will still point to the integer?
20:04 <pmichaud> I don't think Perl 6 specifies
20:04 <allison> I can't see anywhere that's useful
20:04 <pmichaud> however, it's not just here that's an issue
20:05 <pmichaud> sub foo($x is rw) { ... }     foo(@a[2]);
20:05 <pmichaud> the caller would need to know to construct an lvalue reference 
to @a[2]
20:06 <pmichaud> yes, we can do this, but it seems nicer if we just supported 
the standard assign semantics that most dynamic languages use directly in
                 parrot
20:06 <pmichaud> I have to leave now to pick up kids from school... be back in 
30 or so
20:07 <allison> I'll be on a plane then, but will look over your message
20:08 <allison> I question the idea that this is "standard assign semantics 
that most dynamic languages use" (or if it is, I haven't fully understood
                your message yet)
20:11 <particle> assign here means bind
20:12 <particle> our vtable function names are unfortunate (set and assign)
20:12 <allison> seems that the core of the behavior is in this code:
20:12 <allison>     assign $P6, $P4                 # $P6 needs to morph
20:12 <allison>                                     #   to whatever type $P4 is
20:13 <particle> yes, then there's all the if key doesn't exist, etc
20:13 <particle> but that's the core
20:14 <allison> well, you can't take an alias to a key that doesn't exist
20:14 <allison> aliases are to values. no value means no alias
20:15 <particle> what about autovivification?
20:15 <particle> i suppose that would have to happen at a higher level
20:16 <particle> as in, opcodes would have to be emitted to check whether or 
not the index exists in the aggregate, and create it if not--then perform
                 the bind
20:16 <allison> if taking an alias kicks off autovivification, then the key 
would always exist any time it was aliased
20:17 <Coke> (shimmering) note that we're not actually shimmering, we're 
morphing. it's just that it's *close* to shimmering. =-)
20:17 <particle> right, i think it's the aggregate's job to determine whether 
or not a keyed lookup will work or not
20:17 <particle> coke: i was pretty sure you were morphing
20:17 <allison> yeah, that's the aggregate's implementation of get_pmc_keyed
20:17 <particle> thanks for the confirmation
20:18 <particle> so assign_keyed would have to call get_pmc_keyed, then
20:18 <particle> or, both ops would need to be emitted
20:18 <Coke> shimmering seems to involve having multiple slots to keep this 
information, and being able to switch back and forth if the value hasn't been
             mucked with without having to recalc.
20:19 <chromatic> Perl 5 does that.
20:19 <particle> coke: that's a caching strategy then, like perl SVs
20:20 <particle> allison: nicholas is right about pmc design size wrt cache size
20:20 <particle> s/design/
20:20 <allison> so the Tcl data types have slots for all standard values?
20:20 <particle> gah, shouldn't have had that beer
20:20 <allison> particle: it was designed as a cache, yes, but it's being used 
as the core data of the PMC
20:21 <Coke> allison: I've been avoiding looking at the tcl source, mostly. =-)
20:21 <particle> i mean, the size of the pmc was designed to fit in processor 
caches
20:21 <allison> particle: which is a problem for role composition, and for 
intelligent inheritance across the low-level to high-level boundary
20:21 <allison> particle: that too
20:22 <particle> that's why the UnionVal is funny... that's the different types 
of things that would fit in that space
20:22 <allison> aye
20:23 <pmichaud> back
20:23 <particle> certain gc implementations (currently in core) rely on 
constant-size pmcs
20:23 <pmichaud> standard assign semantics:  in most languages that I've dealt 
with, if I say $a = $b, then I expect $a to be a duplicate of $b,
                 including its type
20:23 <allison> the PMCs will stay constant sized
20:23 <allison> that's one aspect of Leo's proposal that I've rejected
20:24 <allison> pmichaud: but generally I'd also expect $a to be a copy of $b
20:24 <pmichaud> by "duplicate" I was meaning "copy"
20:25 <allison> not an alias to $b, and not retaining any connection to the 
former value of $a
20:25 <allison> so, if a attached a property to $a, and then called $a = $b, I 
would expect it to lose the property
20:25 <pmichaud> really?  I don't think so
20:25 <pmichaud> my $a is context(rw);
20:25 <pmichaud> $a = $b
20:26 <pmichaud> (okay, that's a trait. hrm.)
20:26 <allison> ah, drat, this is back to the very old argument of how many 
levels of container we need
20:27 <pmichaud> yes, and I spent several weeks last fall struggling with it to 
end up with what we have now
20:27 <pmichaud> I'm only bringing it up now in response to Nicholas Clark's 
question about "how much morphing do we need in Parrot", and the current
                 answer, at least for PAST-pm, is "well, quite a lot, actually"
20:27 <allison> we've tried to keep it as simple as possible, with the PMC 
container and a core struct
20:27 <pmichaud> I just do the morph through a sequence of   morph/assign
20:28 <allison> how much of the behavior could be implemented in the assign 
vtable function for the Perl 6 PMC types?
20:29 <pmichaud> is this assuming I have an assign_keyed op?
20:29 <pmichaud> oh, wait, assuming I don't
20:29 <pmichaud> hmmm
20:29 <allison> yeah, assuming you don't have it
20:29 <particle> we'd need many more perl 6 pmc types
20:29 <pmichaud> if all of the Perl 6 PMC types knew how to morph to any other 
Perl6 PMC type, then I think it would work
20:30 <particle> yeah, totally own type system, starting with Perl6Undef
20:30 <pmichaud> there's still the issue of dealing with non-existent keys, 
however
20:30 <allison> the Perl 6 types could be simple inherits from core types, with 
morphing added
20:30 <pmichaud> that's where the advantage of assign_keyed comes in, in that 
it creates the key at the time of assignment
20:30 <allison> isn't that a question of autovivification on the aggregate 
types for Perl 6?
20:30 <particle> pmichaud: the pmc will handle the _keyed lookup semantics
20:31 <pmichaud> particle:  looking up a key shouldn't always autovivify it
20:31 <particle> right, it depends on the pmc type
20:31 <pmichaud> $a = $b[2]   should not autovivify $b[2]
20:31 <particle> oh, i see. hrmm.
20:31 <allison> that's a get_pmc_keyed
20:31 <particle> ah, yes. we have different vtable functions for that
20:32 <pmichaud> right, but I don't have an equivalent of assign_pmc_keyed that 
autovivifies
20:32 <particle> so it'll be more than one opcode to do that
20:32 <allison> so, set_pmc_keyed clearly always autovivifies
20:33 <pmichaud> yes and now
20:33 <pmichaud> er, yes and no
20:33 <pmichaud> it does create the key, yes, but it could still point to NULL
20:33 <allison> well, it always sets a value
20:33 <allison> (not even autovivify)
20:33 <particle> in perl 5, auto-vivify means an undef value is associated with 
the key
20:33 <pmichaud> and set_pmc_keyed breaks any binding to an existing PMC.  
Sometimes we want that, yes, but sometimes we don't
20:34 <allison> so, perl 6 types, when they autovivify a key must also give it 
an .Perl6Undef value?
20:34 <allison> you can't take an alias to a NULL
20:34 <pmichaud> exactly
20:34 <pmichaud> and yes, we'd autovivify to an undef
20:35 <Coke> ... this sounds like a very similar conversation to the tcl way of 
doing things vs. the core parrot way of doing things from years ago.
20:35 <particle> allison: autoviv will give Perl6Undef value... if key exists, 
it must morph value to Perl6Undef
20:35 <pmichaud> that's what would happen for, say,   my $b := @a[2]
20:35 <particle> ...during assign_keyed
20:35 <pmichaud> during assign_keyed, if key doesn't exist then we clone value 
and bind the key to that value
20:36 <allison> so, what code path could you follow to end up with an alias to 
a keyed element that is still NULL?
20:36 <pmichaud> if key does exist, then we give that key the new value
20:36 <pmichaud> allison: in PIR or in Perl 6?
20:36 <particle> ah, clone value. right
20:36 <pmichaud> (or, instead of clone value we do COW semantics, but it's much 
the same)
20:36 <allison> pmichaud: Perl 6
20:36 <pmichaud> allison: in Perl 6 I don't think we get there, no.
20:37 <pmichaud> allison: in Perl 6 I don't think we end up with a case of 
assigning to a keyed element that is NULL
20:37 <allison> so, if there is a NULL, it's always safe to set_pmc_keyed, 
because there can't be an alias to it
20:37 <pmichaud> right
20:37 <pmichaud> that's what PAST-pm is doing now
20:37 <pmichaud> if a key is NULL, then we clone the value and use set_pmc_keyed
20:37 <pmichaud> if a key is not NULL, then we get a reference to it and do 
morph/assign
20:38 <allison> okay, we're all on the same page, that's goo
20:38 <allison> good
20:38 <allison> (my flight
20:38 <pmichaud> note that this occurs not only for arrays, but can also occur 
for lexicals and package variables
20:38 <allison>  is about to board)
20:38 <pmichaud> okay, allison, thanks
20:40 <allison> I'm still not quite getting the need for assign_pmc_keyed, 
unless it's just to condense the code? If so, then it's a simple complexity
                balance: whether it's better to have the complexity in one 
place than another.
20:40 <Coke> allison: fly safe.
20:40 <allison> thanks, ttyl
20:40 <Coke> it's better to have the complexity hidden from the HLL authors.
20:40 <Coke> chromatic: ping
20:40 <particle> it's better to get parrot out the door
20:40 <allison> agreed, if it is a form of complexity that is always standard 
across all HLLs
20:41 <pmichaud> it's to condense the code
20:41 <pmichaud> we'd be replacing a sequence of 10 or more PIR instructions 
with one
20:41 <pmichaud> and since assignment is a _very_ common operation, it seems 
better to do that
20:41 <allison> I'll email
20:41 -!- allison [EMAIL PROTECTED] has quit [Quit: ChatZilla 0.9.78.1 [Firefox 
2.0.0.3/2007030919]]
20:42 <pmichaud> at any rate, I've already decided that at some point I'm going 
to revise PAST-pm so that it's using the same code for keyed assignment
                 and global variables, instead of separate store_global 
instructions as it does now


Reply via email to