Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PIR methods and local variables occupy the same 'namespace'

0 views
Skip to first unread message

Allison Randal

unread,
Dec 1, 2005, 6:42:16 PM12/1/05
to Internals List
I realize this is a side effect of the fact that method names are
actually strings, but it's an unfortunate result.

If I have a little bit of code that calls a method without quotes
around the name of the method, it calls the method (prints out
"Boojum"), exactly as expected:

.sub main :main
newclass $P1, 'Thingy'
$P2 = new 'Thingy'
$P2.snark()
end
.end

.namespace [ "Thingy" ]

.sub snark method
print "Boojum\n"
.end

But, if I were to foolishly have a local PMC variable of the same
name as the method in the same compilation unit as the method call,
then it tries to invoke the local variable:

.sub main :main
newclass $P1, 'Thingy'
$P2 = new 'Thingy'
.local pmc snark
snark = new PerlArray
$P2.snark()
end
.end

And I get the error:

invoke() not implemented in class 'PerlArray'

If the local variable happens to be a string, it treats the string as
the name of the method and calls that. So if the string happens to be
"snark" it calls the snark method and prints out "Boojum", otherwise
it fails (because Thingy doesn't have any other methods, so any other
method name is not found).

.sub main :main
newclass $P1, 'Thingy'
$P2 = new 'Thingy'
.local string snark
snark = "snark"
$P2.snark()
end
.end

There's an easy way to ensure the clash between method names and
local variables never happens: always wrap the method name in quotes.
This will never try to invoke the local snark variable, because it
knows the method name is a literal string.

.sub main :main
newclass $P1, 'Thingy'
$P2 = new 'Thingy'
.local pmc snark
snark = new PerlArray
$P2."snark"()
end
.end

So, my question is, should we prevent the obj.method() syntax from
ever being interpreted as object."method"()? It's nice convenient
syntax, but makes for some pretty nasty collisions. Or, maybe there's
another solution, like requiring some explicit way of marking when
obj.method() is doing anything other than obj."method"(). (That at
least has the advantage of making the common case the default.)

And, yeah, I just spent some time debugging a bit of code that read
something like:

.local pmc children
children = node.children()

Allison

Roger Browne

unread,
Dec 2, 2005, 4:42:53 AM12/2/05
to Internals List
Allison Randal wrote:
> There's an easy way to ensure the clash between method names and
> local variables never happens: always wrap the method name in quotes.

There's a sort-of-related problem with parameter names and local
variable names, but wrapping them in quotes isn't an available
workaround.

For example: it should be possible for a HLL compiler to emit something
like the following:

.sub main :main
foo("bar")
.end
.sub foo
.param string "pmc"
print "pmc"
print "\n"
.end

when compiling code like this (HLL pseudocode):

main() {
foo("bar")
}
foo(pmc) {
print_line(pmc)
}

Perhaps there should be one universal rule: any identifier that comes
from a HLL must always be quoted. But I guess we can't use doublequotes
(or singlequotes), because then PIR can't tell whether the
right-hand-side of

a = "b"

is a string constant or a .param named b.

Perhaps a prefix of "@" would work. That's what dotNET uses to make
identifier names interoperable between HLLs (to avoid clashes with
keywords).

Regards,
Roger Browne

Leopold Toetsch

unread,
Dec 2, 2005, 6:56:09 AM12/2/05
to Allison Randal, Internals List

On Dec 2, 2005, at 0:42, Allison Randal wrote:

> I realize this is a side effect of the fact that method names are
> actually strings, but it's an unfortunate result.

> .sub main :main


> newclass $P1, 'Thingy'
> $P2 = new 'Thingy'
> $P2.snark()
> end
> .end
>
> .namespace [ "Thingy" ]
>
> .sub snark method
> print "Boojum\n"
> .end
>
> But, if I were to foolishly have a local PMC variable of the same name
> as the method in the same compilation unit as the method call, then it
> tries to invoke the local variable:

Yep. Which might sometimes be, what you want to do:

.sub main
.local pmc snark, o
$P0 = newclass 'Thingy'
snark = find_global 'Thingy', 'snark'
o = new .String
o = o.snark()
print o


.end
.namespace ['Thingy']
.sub snark :method

.return("ok\n")
.end


> There's an easy way to ensure the clash between method names and local
> variables never happens: always wrap the method name in quotes. This
> will never try to invoke the local snark variable, because it knows
> the method name is a literal string.

Yup.

> So, my question is, should we prevent the obj.method() syntax from
> ever being interpreted as object."method"()? It's nice convenient
> syntax, but makes for some pretty nasty collisions. Or, maybe there's
> another solution, like requiring some explicit way of marking when
> obj.method() is doing anything other than obj."method"(). (That at
> least has the advantage of making the common case the default.)

Maybe obj.$method(), where the token '.$' means the method is a
variable?

> Allison

leo

0 new messages