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

Namespaces, part 1 (new bits)

32 views
Skip to first unread message

Dan Sugalski

unread,
Sep 24, 2004, 2:04:52 PM9/24/04
to perl6-i...@perl.org
Okay, so we've got two points of dispute:

1) Jeff doesn't think the sigil should be part of the variable name
2) Both Jeff and Jonathan have pointed out that languages we care
about *do* have a combined function/varname store. (Though class
names/namespaces seem to be separate)

For point #1, I think we're just going to have to live with the
ugliness. It's either that or globs and, well, if we go with globs
there are a number of people lined up to have words with me, and I
think I'd like to avoid that. So names are names, perl 6 gets to
prepend the sigils as Larry wants, and we have to do all sorts of
mildly interesting hackery for perl 5, but we can deal with that.

This is *not* an ideal solution, but it is a reasonably workable one,
and I can deal with that.

For point #2, I need to do a bit more research. I'm fine with mashing
functions and variables into a single big mass -- the only reason I
was splitting them out was that I was thinking they needed to be, but
that thinking may well have been wrong. (Which is fine, and not the
first time :) Better to catch that now instead of later.
--
Dan

--------------------------------------it's like this-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Chip Salzenberg

unread,
Sep 24, 2004, 3:57:13 PM9/24/04
to Dan Sugalski, perl6-i...@perl.org
According to Dan Sugalski:
> I'm fine with mashing functions and variables into a single big mass...

Me too (FWIW). And I think it'll work.

PS: I've got the Glob Stick where I can reach it.
--
Chip Salzenberg - a.k.a. - <ch...@pobox.com>
"I don't really think it is a question of bright people and dumb
people, but rather people who can see the game they're playing and
those who can't." -- Joe Cosby

Matt Fowles

unread,
Sep 24, 2004, 4:33:31 PM9/24/04
to Chip Salzenberg, Dan Sugalski, perl6-i...@perl.org
All~

I personally thing that the suggestion of providing a base namespace
PMC and letting each language create their own if they want overrides
is a really nice idea. I think the base one should have the maximum
number of distinct subspaces with special functions to access them
(i.e. function, variable, method, ...) and then if a target language
doesn't want them all it can simply have all of them look in the same
place, check type, and return it.

Matt

--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-???

Chip Salzenberg

unread,
Sep 24, 2004, 4:47:36 PM9/24/04
to Matt Fowles, Dan Sugalski, perl6-i...@perl.org
According to Matt Fowles:

> I personally thing that the suggestion of providing a base namespace
> PMC and letting each language create their own if they want overrides
> is a really nice idea.

I can't speak to that. However:

> I think the base one should have the maximum number of distinct

> subspaces with special functions to access them...

No, no, a hundred times no. There is no "maximum" number. (You may,
perhaps, be underestimating the perversity of language designers.)
The current plan of an (almost) unified namespace for all code and
data, where it's up to the language implementor to design a name
mangling scheme, has the advantage of being known to work.

Jonathan Polley

unread,
Sep 24, 2004, 7:51:28 PM9/24/04
to perl6-i...@perl.org
On Fri, 24 Sep 2004 14:04:52 -0400, Dan Sugalski wrote:

> ...


> (Though class names/namespaces seem to be separate)

> ...

I think Guido might have made things a bit harder to separate out than you
anticipate, unless I misread you. It appears that modules and classes are
also imported into the same namespace as everything else in python.

To expand (but to make the output more compact), my earlier program:

#!/usr/bin/env python
import os as a
print a # <module 'os' from '/usr/lib/python2.3/os.pyc'>
class a:
pass
print a # __main__.a
def a():
pass
print a # <function a at 0x401e0b54>
a = 7
print a # 7


Also, if you are in the interactive interpreter and use dir() to explore
around, you can see that it's all just thrown in together.

--
Jonathan

Dan Sugalski

unread,
Sep 24, 2004, 9:04:52 PM9/24/04
to Jonathan Polley, perl6-i...@perl.org
At 7:51 PM -0400 9/24/04, Jonathan Polley wrote:
>On Fri, 24 Sep 2004 14:04:52 -0400, Dan Sugalski wrote:
>
>> ...
>> (Though class names/namespaces seem to be separate)
>> ...
>
>I think Guido might have made things a bit harder to separate out than you
>anticipate, unless I misread you. It appears that modules and classes are
>also imported into the same namespace as everything else in python.

Yeah, I had that pointed out in private mail. At this point I'm a
half-step away from going fully unified. One thing though:

>To expand (but to make the output more compact), my earlier program:
>
>#!/usr/bin/env python
>import os as a
>print a # <module 'os' from '/usr/lib/python2.3/os.pyc'>
>class a:
> pass
>print a # __main__.a
>def a():
> pass
>print a # <function a at 0x401e0b54>
>a = 7
>print a # 7

What happens if you then do something like "import foo" and the foo
module has a "class a:" definition in it?

Jonathan Polley

unread,
Sep 25, 2004, 12:53:25 AM9/25/04
to perl6-i...@perl.org
On Fri, 24 Sep 2004 21:04:52 -0400, Dan Sugalski wrote:

> At 7:51 PM -0400 9/24/04, Jonathan Polley wrote:
>>On Fri, 24 Sep 2004 14:04:52 -0400, Dan Sugalski wrote:
>>
>>> ...
>>> (Though class names/namespaces seem to be separate)
>>> ...
>>
>>I think Guido might have made things a bit harder to separate out than you
>>anticipate, unless I misread you. It appears that modules and classes are
>>also imported into the same namespace as everything else in python.
>
> Yeah, I had that pointed out in private mail. At this point I'm a
> half-step away from going fully unified. One thing though:
>

> What happens if you then do something like "import foo" and the foo
> module has a "class a:" definition in it?

I'm not exactly sure how I became the python expert. I've only been
using it since July. Glad to be of service, though.

-- foo.py:
class a:
member = 0

-- interactive python session:
>>> import foo
>>> dir()
['__builtins__', '__doc__', '__name__', 'foo']
>>> dir(foo)
['__builtins__', '__doc__', '__file__', '__name__', 'a']
>>> dir(foo.a)
['__doc__', '__module__', 'member']
>>> type(foo)
<type 'module'>
>>> type(foo.a)
<type 'classobj'>
>>> type(foo.a.member)
<type 'int'>

So the class acts pretty much the same as a module as far as namespaces
go, at least to my untrained eye.

I also think you can do some funnybusiness with having a class have a
magic function that gets called when people try to access foo.blah so that
you can have transparent method call behavior, but I do not know how that
works. (That's kind of like what tied hashes are, right? I've never done
that sort of thing in perl, either.)

By the way, this isn't the list for it, but it would be cool if perl6 had
an interactive mode as good as python's. It's one of the few places I
think python has a compelling lead.

--
Jonathan

Sean O'Rourke

unread,
Sep 25, 2004, 1:03:58 PM9/25/04
to perl6-i...@perl.org, jona...@ghostlords.com
At Sat, 25 Sep 2004 00:53:25 -0400,

> By the way, this isn't the list for it, but it would be cool if perl6 had
> an interactive mode as good as python's. It's one of the few places I
> think python has a compelling lead.

I'm sort of partial to:

perl -MTerm::ReadLine -le '$t = new Term::ReadLine; print eval while $_ = $t->readline("> ");'

Other than having to retrain yourself not to use "my" (because you
don't get lexicals across promps), it's not that bad. Or, if you're
an Emacs user and don't mind a few rough edges:

http://search.cpan.org/~seano/sepia-0.57/

/s

TOGoS

unread,
Sep 25, 2004, 11:14:40 PM9/25/04
to perl6-i...@perl.org
> > I think Guido might have made things a
> > bit harder to separate out than you
> > anticipate, unless I misread you. It
> > appears that modules and classes are
> > also imported into the same namespace
> > as everything else in python.
>
> Yeah, I had that pointed out in private
> mail. At this point I'm a half-step away
> from going fully unified.

Doooo it.... doooo it....

> One thing though:
> > To expand (but to make the output more
> > compact), my earlier program:
> >
> > #!/usr/bin/env python
> > import os as a
> > print a # <module 'os' from

> > # '/usr/lib/python2.3/os.pyc'>


> > class a:
> > pass
> > print a # __main__.a
> > def a():
> > pass
> > print a # <function a at 0x401e0b54>
> > a = 7
> > print a # 7
>

> What happens if you then do something
> like "import foo" and the foo
> module has a "class a:" definition in it?

Well I would assume it would say
<class 'a' from 'a.pyc'>
(or however python inspects classes)

Anyway, *not* unifying would make things tricky for
languages that want unification. Going the other way,
however, is fairly simple. Unify away :)



__________________________________
Do you Yahoo!?
Yahoo! Mail - You care about security. So do we.
http://promotions.yahoo.com/new_mail

Jeff Clites

unread,
Sep 26, 2004, 11:10:47 PM9/26/04
to Dan Sugalski, Perl6 Internals List
On Sep 24, 2004, at 9:53 PM, Jonathan Polley wrote:

> On Fri, 24 Sep 2004 21:04:52 -0400, Dan Sugalski wrote:
>
>> At 7:51 PM -0400 9/24/04, Jonathan Polley wrote:
>>>
>>> I think Guido might have made things a bit harder to separate out
>>> than you
>>> anticipate, unless I misread you. It appears that modules and
>>> classes are
>>> also imported into the same namespace as everything else in python.
>>
>> Yeah, I had that pointed out in private mail. At this point I'm a
>> half-step away from going fully unified. One thing though:
>>
>> What happens if you then do something like "import foo" and the foo
>> module has a "class a:" definition in it?
>
> I'm not exactly sure how I became the python expert. I've only been
> using it since July. Glad to be of service, though.

...


> So the class acts pretty much the same as a module as far as namespaces
> go, at least to my untrained eye.

In thinking about this more, I think we're o.k. w.r.t Python and Perl.

Since Python has reference semantics for just about everything, I think
that what that means is that "everything" in Python can go into the
"variables" section of the namespace, and from a Perl perspective
everything Python puts in there is going to look like a reference.

For instance, consider (from interactive Python sessions):

>>> import os as a
>>> print a

<module 'os' from
'/System/Library/Frameworks/Python.framework/Versions/2.3/lib/
python2.3/os.pyc'>

...separate session...
>>> import os
>>> print os
<module 'os' from
'/System/Library/Frameworks/Python.framework/Versions/2.3/lib/
python2.3/os.pyc'>
>>> a = os
>>> print a
<module 'os' from
'/System/Library/Frameworks/Python.framework/Versions/2.3/lib/
python2.3/os.pyc'>

What that's showing is that, in Python, "import os as a" and "a = os"
do the same thing as far as "a" is concerned, namely leave the variable
"a" holding (a reference to) the os module. (A difference is that the
former leaves "os" undefined, as a variable, but that's beside the
point.)

The analogous Perl would be something like:

use os;
$a = getReferenceToNamespace("os"); # don't know of a special perl
syntax for this

So in summary, I think it's appropriate to treat all Python "stuff" as
what we're calling "variables", in terms of namespace segmenting.

This also points out an interesting quirk: If we have "$b" in Perl, the
most we can get at in Python will be "\$b"--that is, since Python's
variables always hold references, Perl variables will have to come
across as references, because I don't think that you can magically give
some Python variables value semantics (ie, assignments in Python copy
references, not the actual objects).

This has another funny consequence: Perl arrays will come across as
references to arrays, and strings as references to strings, but since
Perl has a single data type to hold strings/numbers/references, that
means that (probably) numbers will come across as references to numbers
(though they might not have had to), and references will come across as
references-to-references. That is, presumably Python code like, 'c =
findGlobal("$b")' will leave "c" holding a reference to $b, independent
of whether $b holds a scalar or a reference.

But this still leaves me thinking that our namespace API should allow
for differently-segmented namespaces (ie, let some namespaces have more
slots than others). For instance, as a suggestion:

# assume P0 already holds a namespace object/PMC
lookup P1, P0, "foo", .VARIABLE # or "$foo", if we must
lookup P2, P0, "foo", .SUB
lookup P3, P0, "foo", .NAMESPACE
# now P1 holds $foo, P2 holds &foo, P3 hold namespace "foo" -- or
something along those lines

This allows a language to come along a have:

lookup P4, P0, "foo", .WIDGETS

if the namespace in P0 has a widgets section (possibly, it's a subclass
of the default namespace PMC).

Of course, there could be optimized ops for the "common" cases:

lookupvariable P1, P0, "foo" # equivalent to the first case above

and we can wait to decide if we need a .ARRAY and a .HASH for
Perl(5/6), or if they all go in .VARIABLE with their sigils, because
either way, the infrastructure is the same.

And I still don't think this has anything to do with typeglobs.

JEff

Leopold Toetsch

unread,
Sep 29, 2004, 5:53:19 AM9/29/04
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> wrote:
> Okay, so we've got two points of dispute:

> 1) Jeff doesn't think the sigil should be part of the variable name

Which isn't practicable. We can't strip off the sigil for perl5. It's
part of the variable name, $foo and @foo are different items.

If you want to use a perl5 module from Python which has both $foo and
@foo exported, we can just pitch a fit. Everything else can be handled
by the import module.

And: we can't attach hints to the namespace lookup because you just
don't know, if Python wants the scalar "foo" or the array "foo". There
is exactly one "foo" object that Python can use, that's it.

Python allows only bare names in the import statement:

from a import foo [ as a_foo ]

but not:

from a import "@foo" [ as a_foo ]

> 2) Both Jeff and Jonathan have pointed out that languages we care
> about *do* have a combined function/varname store. (Though class
> names/namespaces seem to be separate)

No. Python just has names. Assigning something to a name binds that
thingy to that name. At bytecode level there is almost no indication
that you are working with classes except for the C<BUILD_CLASS> opcode
(not shown below).
E.g.:

class A(object):
def foo(self):
pass

a = A()
a.foo()
a = 7

The object instantiation is this:

5 22 LOAD_NAME 1 (A)
25 CALL_FUNCTION 0
28 STORE_NAME 2 (a)

That's the "method" call:

6 31 LOAD_NAME 2 (a)
34 LOAD_ATTR 3 (foo)
37 CALL_FUNCTION 0

And that's destroying the object by placing the object int("7")
into the name slot "a":

7 41 LOAD_CONST 2 (7)
44 STORE_NAME 2 (a)

The tricky part of Python "objects" is now to create real Parrot objects
out of it, which might be impossible for the general case. But for
normal cases the method call translates to a real Parrot method call,
with a method "foo" in namespace "A". Such methods would be usable from
Perl6 or other languages that use Parrot's object model.

Internally CPython passes the object to the method implicitely as Perl5
does - as the first argument of the function.

The only thing we can do is separate namespaces from names in it, so
that the namespace "A" doesn't collide with the class "A" from the
example above. But that's already Parrot internal, *if* the method
"foo" is translated to:

.namespace ["A"]
.sub foo method
...
.end

Python per se doesn't have such a concept. It's more a matter of the HLL
compiler that translates Python or Perl5 then anything else.

leo

Uri Guttman

unread,
Sep 29, 2004, 10:20:19 AM9/29/04
to l...@toetsch.at, Dan Sugalski, perl6-i...@perl.org
>>>>> "LT" == Leopold Toetsch <l...@toetsch.at> writes:

LT> If you want to use a perl5 module from Python which has both $foo and
LT> @foo exported, we can just pitch a fit. Everything else can be handled
LT> by the import module.

LT> And: we can't attach hints to the namespace lookup because you just
LT> don't know, if Python wants the scalar "foo" or the array "foo". There
LT> is exactly one "foo" object that Python can use, that's it.

LT> Python allows only bare names in the import statement:

LT> from a import foo [ as a_foo ]

LT> but not:

LT> from a import "@foo" [ as a_foo ]

you could use a priority ordering if two foo items are
exported. something like code, scalar, array, hash, etc. not many cpan
modules currently (AFAIK) export 2 things with the same basename. and
since python is oo they would hopefully expect no imports at all (except
for maybe constants which isn't pure oo then).

or you can still pitch a fit.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Jeff Clites

unread,
Sep 29, 2004, 8:58:20 PM9/29/04
to l...@toetsch.at, Dan Sugalski, perl6-i...@perl.org
On Sep 29, 2004, at 2:53 AM, Leopold Toetsch wrote:

> Dan Sugalski <d...@sidhe.org> wrote:
>> Okay, so we've got two points of dispute:
>
>> 1) Jeff doesn't think the sigil should be part of the variable name
>
> Which isn't practicable. We can't strip off the sigil for perl5. It's
> part of the variable name, $foo and @foo are different items.

Those statements don't follow from one another. :)

First off, Perl5 doesn't describe itself that way. The Camel states,
"Note that we can use the same name for $days, @days, and %days without
Perl getting confused." I'm asserting that it works perfectly well (and
seems to have been the original intent) to say that Perl allows for a
scalar, a hash, and an array all named "foo", and the grammar always
makes it clear which one you mean (mostly, via sigils).

So it's true that $foo and @foo are different items, but that can be
stated as, "the scalar 'foo' and the array 'foo' are different items,
with the same names". (Just like there can be both a person named
"April" and a month named "April" in English.)

Here are some further demonstrations that the seeming intent of Perl5
is not to treat the sigil as actually part of the name, but as a
feature of the grammar which indicates the syntactic category of the
name:

$hello and ${hello} are the same thing, but $hel{lo} is not -- the
name can separate from the sigil
$array[1] refers to @array, not $array -- the sigil changes depending
on context, even for a given item

Secondly, Perl just clouds the issue, since it _could_ work either way.
For other languages, you have distinct syntactic categories, but
without the name decoration. For example, in Common Lisp, this:

(foo foo)

means, "call the function foo, and pass the variable foo as an
argument". So if the function "foo" doubles numbers, and the variable
"foo" is set to 11, then the above evaluates to 22.

The reason I'm taking this as important, despite Common Lisp's not
being a "target" language for Parrot, is that it's pointing out that
namespaces across languages have the concept of dealing with multiple
syntactic categories, though the number of such categories varies
between languages. Ruby and Python are simple--they have unified
namespaces, or so it seems--and Perl has a syntax which allows us to
pretend that it has a unified namespace, although I think that's
stretching the truth. (And, I think there's still an issue with
namespace names and sub names, since they don't have sigils in the
grammar--at least not as normally written.) But other languages aren't
so simple, and if we oversimplify our treatment of namespaces, then we
end up with something less elegant and less flexible that we could
have.

> If you want to use a perl5 module from Python which has both $foo and
> @foo exported, we can just pitch a fit.

We should be able to handle accessing either, if Python provides a
syntax for doing so.

> And: we can't attach hints to the namespace lookup because you just
> don't know, if Python wants the scalar "foo" or the array "foo". There
> is exactly one "foo" object that Python can use, that's it.

That's not accurate, and it's not a hint, it's a demand--the programmer
should know exactly which one he wants (which is especially true if you
are trying to think of the sigil as part of the name). Possible
syntaxes within Python:

a = lookupPerlScalar("foo");
b = lookupPerlSub("foo");
c = lookupPerlArray("foo");

or its:

a = lookupFromPerl("scalar", "foo");

or it's:

a = lookupInParrotNamespace("Perl", "scalar", "foo");

Since Python deals in references only, assignment syntax could work
just fine for this, but if someone wanted a more aliasing-like syntax,
it could work like what Chip suggested in another thread:

> parrot_alias(a, 'b', # dest: Python is unified, no need
> for a category here
> a, 'b', 'scalar') # src: Perl is not unified, so
> source category is required
>
> parrot_alias(a, 'c',
> a, 'c', 'array') # here's a different category, to
> get '@c'
>
> or some such. Yes it's ugly. But if we can't fix a ditch, the least
> we can do is put a big friendly warning sign on it.


I've lost hope for transparent aliasing, but it would work partially so
say, "imports from Perl to Python can automatically alias scalars to
Python variables of the same name, but arrays and hashes you have to
pull in manually, and alias to an explicitly-specified name on the
Python side".

It will never "just work" for all things, since this is a valid
identifier in Common Lisp: *foo-foo*

So to exploit the full power of Parrot, languages will need to have
syntaxes/functionality/API to access "foreign" namespaces, but things
could be made transparent for at least a subset of variables. (And as
an example, not _all_ identifiers in Common Lisp are so exotic.)

> Python allows only bare names in the import statement:
>
> from a import foo [ as a_foo ]
>
> but not:
>
> from a import "@foo" [ as a_foo ]

This seems to make things worse for treating the sigil as part of the
name, no? But anyway, I'd expect languages to need new syntaxes (or use
other introspection API) in order to fully access the namespaces "born"
in other languages.

>> 2) Both Jeff and Jonathan have pointed out that languages we care
>> about *do* have a combined function/varname store. (Though class
>> names/namespaces seem to be separate)
>
> No. Python just has names. Assigning something to a name binds that
> thingy to that name.

I think that's what Dan means--there aren't separate syntactic
categories (in contrast to other languages, such as Perl).

> The tricky part of Python "objects" is now to create real Parrot
> objects
> out of it, which might be impossible for the general case. But for
> normal cases the method call translates to a real Parrot method call,
> with a method "foo" in namespace "A". Such methods would be usable from
> Perl6 or other languages that use Parrot's object model.

I think we have issues going from Perl to Python as well, in other
cases. Things such as arrays/hashes/strings should come across as
references--so I'd say that in Python you access \@foo rather than @foo
directly, because assignment in Python doesn't copy. For strings this
works too (Python sees a reference to the Perl string). But for a Perl
scalar holding a reference, it would seem natural for this to present
to Python as that reference directly--not as as reference to that
reference. But it's not clear what's best to do here.

JEff

Leopold Toetsch

unread,
Sep 30, 2004, 4:00:20 AM9/30/04
to Jeff Clites, perl6-i...@perl.org
Jeff Clites <jcl...@mac.com> wrote:

> First off, Perl5 doesn't describe itself that way. The Camel states,
> "Note that we can use the same name for $days, @days, and %days without
> Perl getting confused."

While that's fine for Perl it doesn't help, if you want to access one
distinct "days" from Python:

import days from Perl.foo # which one?

> So it's true that $foo and @foo are different items, but that can be
> stated as, "the scalar 'foo' and the array 'foo' are different items,
> with the same names".

That does only work, if the context provides enough information, which
one of the "foo"s should be used. That information isn't present always.

> without the name decoration. For example, in Common Lisp, this:

> (foo foo)

> means, "call the function foo, and pass the variable foo as an
> argument".

Ok, then a hyptothetical CL translator has to take care of this. The
"foo" variable is probably kind of a lexical, the function "foo" is
accessible. If both "foo"s are global, the same problem as above exists.

>> If you want to use a perl5 module from Python which has both $foo and
>> @foo exported, we can just pitch a fit.

> We should be able to handle accessing either, if Python provides a
> syntax for doing so.

"If" ... which isn't the case.

>> And: we can't attach hints to the namespace lookup because you just
>> don't know, if Python wants the scalar "foo" or the array "foo". There
>> is exactly one "foo" object that Python can use, that's it.

> That's not accurate, and it's not a hint, it's a demand--the programmer
> should know exactly which one he wants

The programmer might know it, but Python has no means to express the
difference.

> a = lookupPerlScalar("foo");

There isn't a possibility for the Python translator to generate that
kind of code in the general case. Did you read the bytecode snippet?
It's just:

LOAD_NAME "foo"

nothing else.

> I think we have issues going from Perl to Python as well, in other
> cases. Things such as arrays/hashes/strings should come across as
> references--so I'd say that in Python you access \@foo rather than @foo
> directly, because assignment in Python doesn't copy.

I don't think so. Python's assignment is pure name binding. In Python
you access that thing that is in name slot "foo". That has nothing to do
with references, which Python doesn't have anyway.

If you have in Python

foo = bar

then that's in bytecode:

LOAD_NAME "bar"
STORE_NAME "foo"

Now both these name slots have the same item. But modifying e.g. "bar"
doesn't effect "foo", it's not a reference that is common to these name
slots.

The real troubles arise from different issues. Given a PerlString "s"
handled over to Python. Now Python code looks like this:

s += "x"

or

print s % (2,3)

If "s" were a Python string, the first would concatenate, the second is
a sprintf-like interpolation. So what is the result, when "s" is a
PerlString?

> JEff

leo

Jeff Clites

unread,
Oct 3, 2004, 11:56:11 PM10/3/04
to l...@toetsch.at, perl6-i...@perl.org
More detailed responses are below, but some general comments first:

I think that no matter what the approach, there's an unavoidable
mismatch between Perl and Python when it comes to variable naming, it's
going to be a bit awkward to access Perl variables from within Python.
I don't see any way around that. Either of the obvious approaches will
have issues to deal with; these approaches are:

1) Treat Perl variables as having the sigil as part of the name.
-or-
2) Treat Perl variables as not including the sigil in the name, but
have multiple categories.

For Python, the problem with (1) is that no Perl variables will have
legal names from Python's point of view. With (2), the variable names
are okay for Python, but Python doesn't have the concept of multiple
categories of variables.

But, that's not as bad as it sounds, and I'll spell out how either of
those could work. But with either approach, the integration won't be
seamless--using a Perl-originating module (namespace) in Python will
involve more work on the Python side than is required when using a
Python-originating module (in Python). Here's how either approach could
work. Consider the following Perl(5) package as an example:

# Perl5
package Gizmo;
$foo = 1;
@foo = ('a');
%foo = ('b' => 'c');
sub foo { return 1; }


Approach 1) Sigil is part of the name.

import Perl.Gizmo

x = Perl.Gizmo.foo # error--not defined
x = Perl.Gizmo.__dict__['$foo'] # x now holds the value of Perl's $foo
Perl.Gizmo.__dict__['$foo'] = 'hello' # Perl's $foo now holds a
Python string
# similarly for hashes, arrays, etc.; subs would probably need a
sigil, maybe '&'

That would actually work. It's awkward, but it reflects the fact that
Python's symbol tables (like Perl's) can deal with entries which you
couldn't create with the "normal" Python syntax.

Approach 2) Sigil is not part of the name. Use categories.

import Perl.Gizmo

x = Perl.Gizmo.scalars.foo # x now holds the value of Perl's $foo
Perl.Gizmo.scalars.foo = 'hello' # Perl's $foo now holds a Python
string
x = Perl.Gizmo.arrays.foo # x now holds the value of Perl's @foo

Either approach would work from a Python perspective. The syntax of the
second, to my eyes, is a bit less awkward. (Note that even with
approach 2, you'd need to resort to the explicit
Perl.Gizmo.scalars.__dict__[""] style to access variables with
non-ASCII names, but at least you wouldn't have to do that for *all*
variables.)

Both approaches require some special Pythonish behavior of the
Perl-originated namespace. Parrot's namespace-tie-ing mechanism could
probably be leveraged to provide this behavior and avoid putting the
burden on the Perl side (i.e., the extra work should be on the import
side, since it's reaping the benefit of the language crossing). What
I'm thinking here is that when Python tries to import a Parrot module,
it actually gets a namespace object which is a wrapper (or adaptor)
around the actual Perl namespace. (So in the example above, the
Perl.Gizmo that Python gets is actually a special namespace which
mediates interaction with the "real" Perl Gizmo namespace.) Here's what
the adaptor would need to do in each case:

Case 1) The adaptor would need to expose a __dict__ attribute to
provide a hash-like interface to the contents of the namespace. This is
necessary because the real Perl namespace won't have the necessary
__dict__ variable in place. This would be simple to
implement--namespaces are already hash-like.

Case 2) The adaptor would satisfy a request for Perl.Gizmo.scalars.foo
by asking the real Gizmo namespace for the entry "foo" in the "scalars"
category. This would also be simple to implement if we have
category-structured namespaces.

Either approach requires that the import mechanism have an awareness of
the language of the imported namespace (i.e., Perl modules need to be
wrapped but Python modules don't, for import from Python code), but
that's supplied by the "Perl." prefix anyway.

Going from Python to Perl is easy--all Python variables look like
Perl-scalars-holding-references, though we might want to special-case
strings and numbers. See below for further notes on this.

Further comments, some of which will be redundant with the above:

On Sep 30, 2004, at 1:00 AM, Leopold Toetsch wrote:

> Jeff Clites <jcl...@mac.com> wrote:
>
>> First off, Perl5 doesn't describe itself that way. The Camel states,
>> "Note that we can use the same name for $days, @days, and %days
>> without
>> Perl getting confused."
>
> While that's fine for Perl it doesn't help, if you want to access one
> distinct "days" from Python:
>
> import days from Perl.foo # which one?
>
>> So it's true that $foo and @foo are different items, but that can be
>> stated as, "the scalar 'foo' and the array 'foo' are different items,
>> with the same names".
>
> That does only work, if the context provides enough information, which
> one of the "foo"s should be used. That information isn't present
> always.

What I mean is, if someone is importing a variable from a Perl module,
they must have read some documentation about that Perl module, to
figure out that they want to do that--that's how they know the name at
all ("days" v. "automobiles"), and so that same documentation would
tell them whether they need to import a scalar, or an array, or a hash
(or a sub). So the programmer must know--there's no need to infer from
context on the Python side. I've provided, above, some syntax options
for this.

>> without the name decoration. For example, in Common Lisp, this:
>
>> (foo foo)
>
>> means, "call the function foo, and pass the variable foo as an
>> argument".
>
> Ok, then a hyptothetical CL translator has to take care of this. The
> "foo" variable is probably kind of a lexical, the function "foo" is
> accessible. If both "foo"s are global, the same problem as above
> exists.

But a CL compiler has no problem itself--it knows by context what is
meant ("the thing on the far left means a function"), so it can emit to
appropriate instructions--one to lookup the function "foo", one to
lookup the variable "foo", and one to call the former with the latter
as an argument. This should be approximately the same as calling
"foo($foo)" in perl5. Different languages just use different mechanisms
to make their grammars unambiguous.

>>> And: we can't attach hints to the namespace lookup because you just
>>> don't know, if Python wants the scalar "foo" or the array "foo".
>>> There
>>> is exactly one "foo" object that Python can use, that's it.
>
>> That's not accurate, and it's not a hint, it's a demand--the
>> programmer
>> should know exactly which one he wants
>
> The programmer might know it, but Python has no means to express the
> difference.
>
>> a = lookupPerlScalar("foo");
>
> There isn't a possibility for the Python translator to generate that
> kind of code in the general case.

Oh no--I didn't mean for a Python compiler to emit that. That wasn't
meant to be pseudo-PIR. I meant that as a Python function, and that as
the code a Python programmer would type. (It was bad Python
pseudo-code.) The right syntax for this (on the Python side) is as
given above, using __dict__. (And Python has other options, such as its
getattr() built-in function.)

>> I think we have issues going from Perl to Python as well, in other
>> cases. Things such as arrays/hashes/strings should come across as
>> references--so I'd say that in Python you access \@foo rather than
>> @foo
>> directly, because assignment in Python doesn't copy.
>
> I don't think so. Python's assignment is pure name binding. In Python
> you access that thing that is in name slot "foo". That has nothing to
> do
> with references, which Python doesn't have anyway.
>
> If you have in Python
>
> foo = bar
>
> then that's in bytecode:
>
> LOAD_NAME "bar"
> STORE_NAME "foo"
>
> Now both these name slots have the same item. But modifying e.g. "bar"
> doesn't effect "foo", it's not a reference that is common to these name
> slots.

I think we mean the same thing here. Basically, Python variables act
like they hold C pointers. Your example above could be described as
loading the reference held by "bar", and storing it to "foo". Python is
like Java in this regard--there's not an explicit syntax for creating
references, but all variables already act as though they contain
references. (Well in the Java case, object-ish variables, that is.) And
the "Learning Python" book also describes it this way: "Python
assignment stores references to objects in names or data structure
slots. It always creates *references* to objects, instead of copying
objects. Because of that, Python variables are much more like pointers
than data storage areas as in C." (emphasis theirs).

Here's a demo of how Perl and Python differ in this regard:

For instance, consider this, from an interactive session:

>>> a = ['foo', 'bar']
>>> b = a
>>> a
['foo', 'bar']
>>> b
['foo', 'bar']
>>> del a[0]
>>> b
['bar']

That's because the "a = b" doesn't copy the array--you can think of it
as copying a reference (a and b both hold references to the same
underlying array). Note that modifying the object stored in a, modifies
that stored in b (it's the same object). This is just like
Java--clearest to say that all variables hold references, so that
assignment copies the reference (not the underlying object).

But this Perl code is different:

@a = ('foo', 'bar');
@b = @a;

pop @a;

Now @a has one item, and @b still has two--assignment did a copy,
because Perl variables act as though they hold the underlying data
structure directly.

Contrast this:

@array = ('foo', 'bar');
$a = \@array;
$b = $a;

pop @$a;

Both $a and $b hold references to @array, which now contains only one
item.

Now, if Python had a way to access Perl's "@a" as "a" and Perl's "@b"
as "b", then by Python's semantics, you'd expect "b = a" not to do a
copy, but by Perl's semantics, it would. But if all you can access on
the Python side is really "\@a", then "b = a" in Python would act in a
way consistent with both languages. That is, using my category syntax,
consider this code:

import Perl.Example

x = Perl.Example.arrays.a
Perl.Example.arrays.a = Perl.Example.arrays.b
del Perl.Example.arrays.a[0]

What should this do? On the one hand, you might expect this to be
equivalent to Perl's "@a = @b", so that "a" is now a copy of "b" (i.e.,
"a" should act as though it were emptied out, and then filled with the
elements contained in "b"), and thus subsequent modifications to the
object in "b", shouldn't affect the object in "a". But assignment in
Python doesn't work this way, so by Python's semantics, both "a" and
"b" should now refer to the same underlying object. There's a
clash--Python's variables want to hold references, not actual objects.
The only time there isn't a clash (it seems), is in the case of Perl
scalars which happen to hold references. For all the other cases, it's
problematic.

One way to reconcile this, as I was getting at in my previous message,
is to say that Perl.Example.arrays.a isn't actually holding "@a", but
rather a reference to it, such as "\@a". The namespace adaptor we
already need could probably make this happen. But there's a problem
with this, too: You'd probably want to treat scalars homogeneously, so
that you'd get "\$foo", etc. on the Python side. This does what you'd
want for strings (Python hold a string reference), but if $foo holds a
Perl reference, then on the Python side this will look like a
reference-to-a-reference, and Python doesn't (I think) have a syntax
for handling this. (And, I suspect we'd have further problems if we
tried to tread Perl scalars differently depending on whether they held
a reference or a string/number, etc.)

> The real troubles arise from different issues. Given a PerlString "s"
> handled over to Python. Now Python code looks like this:
>
> s += "x"
>
> or
>
> print s % (2,3)
>
> If "s" were a Python string, the first would concatenate, the second is
> a sprintf-like interpolation. So what is the result, when "s" is a
> PerlString?

Yes, that's a problem, for a couple of reasons. First, the compiler
needs to emit the same code whether "s" is a number or a string, since
you can't tell at compile-time, which seems to mean that PerlScalar's
would need to have Python-specific vtable entries (e.g., for a
Python-plus, at least), which is gross, or else blow up, which is not
very useful. The second problem is that Perl scalars are by design
ambiguous between strings and numbers, so that "a += b" in Python is
ambiguous. (Should it do numeric addition or string concatenation?) It
would be easy enough to create utility functions to let you create a
"real" Python number or string from a PerlScalar, but again that's
awkward.

JEff

Paul Seamons

unread,
Oct 4, 2004, 11:15:16 AM10/4/04
to perl6-i...@perl.org
I'll delurk here for a moment,

I am of the opinion that there is not that much of a need to allow for
simultaneous access to similarly named Perl data types in python. I am not
aware of any CPA modules that export two or more of the same name but for
different data types - such as $foo, @foo, %foo, and &foo. While it appears
necessary, on the surface, to allow for access to all of these types at once
I think the need for such access is being overstated. Though it isn't my
place to dictate style, exporting multiple types of the same name seems
ambiguous and should be avoided - even if the module is only to be used in a
straight Perl context.

I like that in the syntax Leo has used, there is no reference to what Perl
type you are using. This seems to be the most natural way to merge the
languages together. I don't know that bridges need to be built around gaps
were languages do not perfectly merge together. If I export or place two
data types with the same name in a "publicly" viewable namespace, I am fine
that only one of them will be viewable in Python and will probably be chosen
based upon type (so long as the decision about which is viewable is
consistent).

If the ability to reference all four data types at once is not easy to do from
within Python as Leo has repeatedly stated, then it should probably be left
alone. In this case being able to do something merely for the sake of being
able to do it, doesn't seem to offer enough justification for the creation of
new syntax in either language.

Paul Seamons

Michal

unread,
Oct 7, 2004, 8:52:20 PM10/7/04
to Jeff Clites, perl6-i...@perl.org
On Sun, 3 Oct 2004, Jeff Clites wrote:

> I think that no matter what the approach, there's an unavoidable
> mismatch between Perl and Python when it comes to variable naming, it's
> going to be a bit awkward to access Perl variables from within Python.

...


> 1) Treat Perl variables as having the sigil as part of the name.

..


> For Python, the problem with (1) is that no Perl variables will have
> legal names from Python's point of view. With (2), the variable names
> are okay for Python, but Python doesn't have the concept of multiple
> categories of variables.

Hey Jeff,

I think this would be just fine.
Languages like ruby and scheme allow
identifiers that aren't valid names
in perl OR python:

rubyThing.sort!
(is-this-true? (> scheme-var 1))

And heaven forbid you want to talk about
perl's other variables: $! , $> $@ , etc...

I've always kind of pictured something
like this:

>>> import parrot
>>> parrot.load("perl","AI::Fuzzy")
>>> f = parrot["perl::AI::Fuzzy::Label"]
>>> f.addlabel("...")


- Michal
http://withoutane.com/

0 new messages