Re: [Python-Dev] Parrot -- should life imitate satire?

Hi.
I imagine you already know: especially when compiling to native code, it is all a matter of optimizing for the common case, and be prepared to be quiet slow otherwise, especially when dealing with dynamic changes, both in Perl and Python there is no clear distiction from normal ops and dynamic changes to methods... but in any case they are rare compared to the rest. Threading adds complexity to the problem. For the rest is just speed vs. memory, customization is a clear example for that. regards, Samuele Pedroni.

At 04:32 PM 8/2/2001 +0200, Samuele Pedroni wrote:
Well, it sort of looks like: name--->variable--->value The name is a symbol table entry that points to the variable. The variable is a data structure that has the vtable info, some pointer data, some flags, and general whatnots. (The docs refer to this as a PMC, or Parrot Magic Cookie, FWIW. Which isn't much) The value is the actual contents. We also have to track properties on both a variable and a value basis. For example: declare c, b declare a is const = 0 but true b = a c = \a dereference(c) = 1 In this case, the variable represented by a has the property 'const', and a value of 0 which has the property 'true'. The assignment to b copies the value, and the properties on the value (true in this case), but not the properties on the variable, so b isn't const. c is a reference to the variable a represents, so the attempt to assign to the dereference of c will fail, since the variable c points to has the const property. We can't depend on the properties to be attached to the *name* a, since (in my crude attempt to use python-style blocking) the name a has gone out of scope by the time we dereference c, and so would any properties attached to the name as such. I think the variable here would correspond to a Python object, but I'll need to go digging into Python semantics more to be sure. Currently there's not a lot planned around the actual symbol table entry, since it's not required for variable existence, and there's not much I can think of to attach to it anyway. (References mean we can't use it for much, really) My bet, and this is just an off-hand thing, is that the parser would spit out bytecode tying the symbol table entry and the PMC structure more closely than it might for other languages. At least do a lot more symbolic fetch/store ops, if need be, which we might not.
I don't think so, but I'm betting we're talking terminologically cross-wise. Assume, for example, the following pseudoish code: declare kitchen isa Thermostat kitchen = 20 In this case the kitchen variable is active, and assigning to it changes the temperature the thermostat in the kitchen is set to. The magic properties aren't attached to the name per se, at least in perl--it's just a handy way to get the PMC that underlies the thing. I can get an indirect handle on the data that the name 'kitchen' refers to and update it that way, or if I have that handle the 'kitchen' name can go completely out of scope and the only way to refer to the object representing (and allowing control over) my kitchen temperature is via the handle I've got on what's now an anonymous object. (Or, if I'm feeling really wacky, have two or more names that look like separate things but actually all point to the same PMC structure) I think it's the potential existence of references (or pointers, or whatever you want to call them) that necessitate the three-level split. It sounds like the things I'm calling 'name' and 'variable' are much more tightly bound in Python. There are several reasons to call a PMC assignment operator, rather than just unconditionally slam a new PMC into the name slot: 1) In the kitchen example above, assigning 20 to kitchen doesn't suddenly make kitchen an integer variable--it needs to stay a Thermostat, and just do something because we assigned to it. (And I understand this might not be the way Python would do things, in which case Python variable vtables might just have an "overwrite myself with the incoming info" function, rather than allow it to be overridden) 2) Since we can't really assign properties like constant-ness to a name (in which case we could get a reference to a variable and bypass the properties on the name by referring to it by reference) that needs to be enforced in other ways. In this case with a custom assignment vtable function which pitches a fit if you try to alter the variable. 3) Some other thing or other I apparently can't think of. It's a really good reason, though.
Self I've not dug into. Despite all the "I haven't see that" that keeps popping up in my conversation, I *have* done a lot of research. (The pile of digested books at one point outweighed my kids. They've grown, but the new research pile's about to grow too...)
Ah, aggressive inlining of a sort. I think. Yep, on the list of things to do with the optimizer. (Not on the first version, probably, but certainly later)
Yup. I am profoundly tempted, and I think it will go in, to have a "stable code" switch that can be given to the optimizer which guarantees that, once the compilation phase is done and we finally get to run for real, code will not change. And then apply all the advanced optimization techniques at that point.
Threading adds complexity to the problem.
Nah, not too badly. A little synchronization issue, but that's reasonably trivial.
For the rest is just speed vs. memory, customization is a clear example for that.
Sure. The one nice thing that both perl and python have going for them is the ultimate presence of all the source (or a high-enough level representation of it to feed to the optimizer) at run time. We can tell with more surety what side-effects various methods and functions in external code libraries will have, and we can get more aggressive (maybe) because of it. Unlike, say, C, where passing a pointer to a routine outside what the compiler can see will hobble the optimizer a whole lot in many cases... Dan --------------------------------------"it's like this"------------------- Dan Sugalski even samurai dan@sidhe.org have teddy bears and even teddy bears get drunk

At 04:32 PM 8/2/2001 +0200, Samuele Pedroni wrote:
Well, it sort of looks like: name--->variable--->value The name is a symbol table entry that points to the variable. The variable is a data structure that has the vtable info, some pointer data, some flags, and general whatnots. (The docs refer to this as a PMC, or Parrot Magic Cookie, FWIW. Which isn't much) The value is the actual contents. We also have to track properties on both a variable and a value basis. For example: declare c, b declare a is const = 0 but true b = a c = \a dereference(c) = 1 In this case, the variable represented by a has the property 'const', and a value of 0 which has the property 'true'. The assignment to b copies the value, and the properties on the value (true in this case), but not the properties on the variable, so b isn't const. c is a reference to the variable a represents, so the attempt to assign to the dereference of c will fail, since the variable c points to has the const property. We can't depend on the properties to be attached to the *name* a, since (in my crude attempt to use python-style blocking) the name a has gone out of scope by the time we dereference c, and so would any properties attached to the name as such. I think the variable here would correspond to a Python object, but I'll need to go digging into Python semantics more to be sure. Currently there's not a lot planned around the actual symbol table entry, since it's not required for variable existence, and there's not much I can think of to attach to it anyway. (References mean we can't use it for much, really) My bet, and this is just an off-hand thing, is that the parser would spit out bytecode tying the symbol table entry and the PMC structure more closely than it might for other languages. At least do a lot more symbolic fetch/store ops, if need be, which we might not.
I don't think so, but I'm betting we're talking terminologically cross-wise. Assume, for example, the following pseudoish code: declare kitchen isa Thermostat kitchen = 20 In this case the kitchen variable is active, and assigning to it changes the temperature the thermostat in the kitchen is set to. The magic properties aren't attached to the name per se, at least in perl--it's just a handy way to get the PMC that underlies the thing. I can get an indirect handle on the data that the name 'kitchen' refers to and update it that way, or if I have that handle the 'kitchen' name can go completely out of scope and the only way to refer to the object representing (and allowing control over) my kitchen temperature is via the handle I've got on what's now an anonymous object. (Or, if I'm feeling really wacky, have two or more names that look like separate things but actually all point to the same PMC structure) I think it's the potential existence of references (or pointers, or whatever you want to call them) that necessitate the three-level split. It sounds like the things I'm calling 'name' and 'variable' are much more tightly bound in Python. There are several reasons to call a PMC assignment operator, rather than just unconditionally slam a new PMC into the name slot: 1) In the kitchen example above, assigning 20 to kitchen doesn't suddenly make kitchen an integer variable--it needs to stay a Thermostat, and just do something because we assigned to it. (And I understand this might not be the way Python would do things, in which case Python variable vtables might just have an "overwrite myself with the incoming info" function, rather than allow it to be overridden) 2) Since we can't really assign properties like constant-ness to a name (in which case we could get a reference to a variable and bypass the properties on the name by referring to it by reference) that needs to be enforced in other ways. In this case with a custom assignment vtable function which pitches a fit if you try to alter the variable. 3) Some other thing or other I apparently can't think of. It's a really good reason, though.
Self I've not dug into. Despite all the "I haven't see that" that keeps popping up in my conversation, I *have* done a lot of research. (The pile of digested books at one point outweighed my kids. They've grown, but the new research pile's about to grow too...)
Ah, aggressive inlining of a sort. I think. Yep, on the list of things to do with the optimizer. (Not on the first version, probably, but certainly later)
Yup. I am profoundly tempted, and I think it will go in, to have a "stable code" switch that can be given to the optimizer which guarantees that, once the compilation phase is done and we finally get to run for real, code will not change. And then apply all the advanced optimization techniques at that point.
Threading adds complexity to the problem.
Nah, not too badly. A little synchronization issue, but that's reasonably trivial.
For the rest is just speed vs. memory, customization is a clear example for that.
Sure. The one nice thing that both perl and python have going for them is the ultimate presence of all the source (or a high-enough level representation of it to feed to the optimizer) at run time. We can tell with more surety what side-effects various methods and functions in external code libraries will have, and we can get more aggressive (maybe) because of it. Unlike, say, C, where passing a pointer to a routine outside what the compiler can see will hobble the optimizer a whole lot in many cases... Dan --------------------------------------"it's like this"------------------- Dan Sugalski even samurai dan@sidhe.org have teddy bears and even teddy bears get drunk
participants (2)
-
Dan Sugalski
-
Samuele Pedroni