Piers Cawley wrote: > > Benjamin Goldberg <[EMAIL PROTECTED]> writes: [snip] >>> Reading or writing from the hash does a lookup in the backing database >>> and reads or writes from it. A handy thing, with the variable getting >>> in the way of reads or writes to itself. However, you can do this with >>> plain scalar variables. >>> >>> For example, if you had code: >>> >>> int Foo; >>> Dog Bar = new(); >>> Foo = Bar; >>> >>> you wouldn't want there to be a Dog in Foo--you've declared it an >>> integer, so it can only hold an integer. The assignment can't do a >>> plain pointer copy the way it would in the case where both sides can >>> hold objects. >> >> Indeed ... the compiler needs to detect that a conversion is necessary. >> >> Fortunatly, since we've told the compiler the types of the variables, >> it can do that. > > How about this then: > > sub wibble($arg is rw) { > $arg = Dog.new; > } > > my int $foo; > my Cat $bar; > > wibble(rand < 0.5 ?? $foo :: $bar); > > The compiler does not and cannot know the type of thing passed > into wibble until runtime,
It knows that it's one(Cat, int). (OT for this thread, but I think perl6 ought to have a "oneof" alias for the "one" superposition). > so assignment must be handled by the target thing. Yes, this is a > pathological case, but it is a case that must be handled. But the target pmc doesn't know what kind of variable it's in! Consider: At what point should the following code die? sub wibble($arg is rw) { $arg = Dog.new; } sub wobble(Mammal $arg is rw) { my Mammal $m = $arg; wibble($m); wibble($arg); } my Mammal $foo; my Cat $bar; wobble( int(rand(2)) ?? $foo :: $bar ); Should wibble($m) always work without dieing? What about wibble($arg)? Does wibble($m) cause $m to contain a new pmc (does the assignment inside of wibble have set semantics to the containing variable), or does it cause the existing pmc to be changed (does the assignment inside wibble have assign semantics to the passed in pmc)? > >> As an alternate example, try this: > >> > >> TempMeter kitchentemp = new('kitchenroom'); > >> TempMeter bedroomtemp = new('bedroom'); > >> bedroomtemp = kitchentemp; > >> > >> Where in this case kitchentemp *is* an object, but one of type > >> TempMeter, and bound to an object that represents the temperature in > >> your kitchen, while bedroomtemp is a TempMeter object that represents > >> the temperature in your bedroom. (Code I'd not recommend using in CGI > >> programs....) The assignment does *not* bind the bedroomtemp name to > >> the object for the kitchen temp, rather it sets the bedroom > >> temperature to be the same as that in the kitchen. Even being an > >> object, the object's methods still intercept read and write requests > >> and instead of assignment being rebinding, it's instead a get or set > >> call on the object. > > > > Again, we've told the compiler the types, so it can do that. > > > >> The part that affects us is that we can't tell at compiletime whether > >> assignment is rebinding or is a get/set, because we could have code > >> like: > >> > >> kitchentemp = new('kitchenroom'); > >> bedroomtemp = new('bedroom'); > >> bedroomtemp = kitchentemp; > >> > >> which is typeless, > > > > Actually, we *could* try to infer the types of the variables, based > > on our knowledge of the types of the values assigned to them. I'll > > ignore that, and pretend that we don't know the return type of new() > > at compile time. > > There's no pretending required. In the vast majority of cases you > don't *know* the types returned by new. After all, something could > have altered the behaviour of Class::new after the code in question > is compiled but before it gets run. It's a good thing we (will) have a Notification system, then, eh? We can "know" the return type of new() at compile time, and if it changes, and be notified and respond accordingly. If the new return type of new() is sufficiently compatible with the old type, no changes need to be made to the sub which is calling new(). If the new type is sufficiently different, then the calling sub needs to be recompiled (not from scratch, but from the point just before the type inferencing engine got at it). This might be expensive, but how often do the return types of functions change? Also, recompilation doesn't need to happen right away -- we could set a flag, and defer until necessary. (Actually, it would be pretty cool if by default, perl only compiled subs into ASTs, and didn't produce parrot bytecode until the sub first gets called. This way, we can get the metainfo of a sub right away, as soon as it's been seen, which is useful for code analysis and inter-subroutine optomization, but we don't have to do the extra work if it doesn't ever get called... which is good for big modules/libraries). > >> and yet should still respect the fact that the > >> objects bound to the name intercept assignment (basically overloading > >> it) rather than having the compiler or runtime doing the rebinding > >> for you. > >> > >> Since, of course, we're dealing with basically typeless languages we > >> have to do all the checking at runtime (lucky us) which is why the > >> PMCs have generic get and set methods so they can decide whether > >> we're doing rebinding or something more funky. (Whether this affects > >> languages where = is an explicit binding rather than assignment is up > >> in the air, but neither python nor ruby is truly that way, though > >> they're close. But we can fake it so that things do what they ought > >> when they ought) > > > > I forget, should "bedroomtemp = kitchentemp" be using set_pmc, or > > clone? > > set_pmc -- $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "[EMAIL PROTECTED] ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}