Some Questions about Perl 6 Modules

Getting back into Perl 6 after being away from it for a while, I realized I’m still not comfortable with how Perl 6 handles packages in general. I’m quite a bit more familiar with C++’s namespaces and stone-age way of handling these things, for the record, so I may be expecting unreasonable things from Perl 6. (It doesn’t help that there’s little documentation on this stuff.)

So I’m making this post to collect all my concerns in one place. I’ll be updating this post as I get answers.

Q#1: How do I split a package across multiple files?

In other words: C++’s handling of namespaces. I want to be able to define a particular package’s contents across a number of files. As an example:

package Foo {
    class Bar { ... }
}
package Foo {
    class Baz { ... }
}

Q#2: How do the different names relate?

As an example, let’s say I have a file that can be used by the name A::B (for simplicity, at A/B.pm6). Here are its contents:

unit module C::D;

class E { ... }

Now I use the module in another script file. Which of the say statements are correct?

use A::B;

say A::B::C::D::E; # 1
say C::D::E;       # 2
say E;             # 3

For bonus points, what happens when the module name in the module file is also A::B? What happens if someone puts names the class C::D::E (thereby replicating the unit name)?

I suppose the question here can also be phrased as “Which of these various names matters where? And when do they need to be combined, and how?”

Q#3: What does a unit declaration mean?

In other words, what’s the difference between

unit module Foo;

class Bar { ... }

and

module Foo {
    class Bar { ... }
}

? What differences are between these two, if any? Would a file with multiple braced module declarations act like multiple unit‘d files? Does this choice affect Q#2?

Q#4: What does leaving out a package name mean?

That is, if I leave out the unit module or package foo { } in a package, how does that affect the symbols declared in the file? Are they in global scope?

Q#5: Where is exporting useful?

Is the is export construct only useful inside modules? How about all packages in general? Does it work inside “package-less” module files (see Q#4)?

Q#6: Does it matter how I declare a “nested” name?

Or, put another way, what’s the difference between

package Foo {
    class Bar { ... }
}

and

class Foo::Bar { ... }

, assuming Foo as a name doesn’t yet exist in either case?

Q#7: What are packages and modules anyway?

What’s the difference between a package and a module, exactly? And are there any other package-like constructs I should know about?

Q#FINAL: How to packages for C++ devs?

Ultimately, my confusion and bewilderment stems from being quite OK with how you handle these kinds of things in C++. And Perl 6’s methods feel to me, at least at the moment, to be way more freeform and liberal, and thus more confusing.

To help out with describing my wants, here’s what I want to do (and what C++ does) in Perl 6:

  1. I want to define at least one namespace filled with all the classes, enums, and so on for my project.
  2. This namespace qualifies its constituent identifiers so people using my project won’t run into name conflicts just by importing it.
  3. This namespace should not depend on the filesystem layout, since I prefer to organize files and their contents by what makes sense from an editing perspective. I don’t like enforced organization for braindead packaging systems (looking at you, Java).
  4. People wanting to use various elements of my project can do so with use statements whose names aren’t inextricably linked to the code imported. In C++, this is where #include <foo/bar.hpp> doesn’t mean all the imported symbols are under a foo/bar.hpp:: namespace.
  5. When people import my project, they get qualified names by default, in other words requiring extra work to unqualify them (e.g. using namespace std; in C++).

In short: I want a C++ style way of developing modules and other such projects, since that’s what I’m familiar with :P .

But even if Perl 6 can’t be (easily) made to work this way, I still want to know how it actually does work. Because it’s not at all easy to tell with the present state of documentation. I hope that as my questions get answers, this can be part of the improvement to documentation.

Advertisements

2 thoughts on “Some Questions about Perl 6 Modules

  1. In C/C++ when you are done compiling and linking, you end up with one file, so it knows exactly how to find all of the parts of the module. In Perl 5&6 when you do a use A::B it only tells the runtime to load the file at A/B.pm, it is up to the contents of the file at that location to tell the runtime which modules it implements. (This can cause a problem on case insensitive filesystems if you use the wrong case) Now since Perl 6 does have a more featureful module system some of this can change.

    In Perl 5 you could have the file at A/B.pm with two lines which has two use lines one for A::B::part1 and one for A::B::part2, both of which say they are package A::B, and both would get mixed into the same namespace.

    To do this in Perl 6, the second file would have to augment the module/class that the first one created, because it would have been finalized already. I’m sure there is a way to use the MOP to create the combined module/class by hand, or to create a module that would handle that for you.

    Actually thinking about it some more, it would be better if ::part1 and ::part2 were roles that A::B composed into it. This would require some careful consideration about how to cleanly separate it into parts.

    In the case of modules, ::part1 and ::part2 would just export all of their subroutines, and A::B would get their subroutines that way.

    The “unit” declarator was added for single pass parsing.

    In Perl 5 there was only packages, which were modules or classes depending on how you wrote the subroutines inside of it. ( Some packages try to do both at the same time with limited success ) Perl 6 formalizes this distinction. ( basically don’t use package unless you are doing something weird )

    While you can have files which contain namespaces that don’t match, it is definitely frowned upon. Unless the file has several related modules/classes. Even then there is usually a module with the same name, even if it is practically empty.

    I will say that there are ways to get most of what you want. Some of it goes very much goes against the grain. ( most of it should be fine if you do it right )

    The using namespace std; (if it does what I think it does) could be as simple as use std :all; ( requires more work inside of std but it is possible )

    Basically everything about namespaces in Perl 6 is inspired by the way everyone was doing those same things in Perl 5. ( and similarly the way to do things in C++ was inspired by the way people were doing similar things in C )

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s