[svn:perl6-synopsis] r14317 - doc/trunk/design/syn

0 views
Skip to first unread message

la...@cvs.perl.org

unread,
Mar 7, 2007, 11:38:17 PM3/7/07
to perl6-l...@perl.org
Author: larry
Date: Wed Mar 7 20:38:15 2007
New Revision: 14317

Modified:
doc/trunk/design/syn/S02.pod
doc/trunk/design/syn/S11.pod

Log:
Module longnames now specified in terms of ident plus adverbials.


Modified: doc/trunk/design/syn/S02.pod
==============================================================================
--- doc/trunk/design/syn/S02.pod (original)
+++ doc/trunk/design/syn/S02.pod Wed Mar 7 20:38:15 2007
@@ -2531,6 +2531,21 @@
END
}

+=item *
+
+A version literal are written with a 'v' followed by the version
+number in dotted form. This always constructs a C<Version> object, not
+a string. Only integers are allowed; for anything fancier you must
+coerce a string to a C<Version>:
+
+ v1.2.3 # okay
+ v1.2.3beta # illegal
+ Version('1.2.3beta') # okay
+
+Note though that most places that take a version number in Perl accept
+it as a named argument, in which case saying C<< :ver<1.2.3beta> >> is fine.
+See S11 for more on using versioned modules.
+
=back

=head1 Context

Modified: doc/trunk/design/syn/S11.pod
==============================================================================
--- doc/trunk/design/syn/S11.pod (original)
+++ doc/trunk/design/syn/S11.pod Wed Mar 7 20:38:15 2007
@@ -202,46 +202,72 @@
where to keep them, such that multiple versions by different authors
can coexist, all of them available to any installed version of Perl.

-The syntax of a versioned module or class declaration has three parts
-separated by hyphens. The three parts are the short name of the
-class/module, its version number, and a URI identifying the author
-(or authorizing authority). For example:
-
- class Dog-1.2.1-cpan:JRANDOM;
- class Dog-1.2.1-http://www.some.com/~jrandom;
- class Dog-1.2.1-mailto:jra...@some.com;
-
-Such a declaration automatically aliases the full name
-of the class (or module) to the short name. So for the rest of the
-lexical scope, C<Dog> refers to the longer name.
+The syntax of a versioned module or class declaration has multiple
+parts in which the non-identifier parts are specified in adverbial pair
+notation without intervening spaces. Internally these are stored in
+a canonical string form which you should ignore. You may write the
+various parts in any order, except that the bare identifer must come
+first. The required parts for library insertion are the short name of
+the class/module, its version number, and a URI identifying the author
+(or authorizing authority, so we call it "auth" to be intentionally ambiguous).
+For example:
+
+ class Dog:ver<1.2.1>:auth<cpan:JRANDOM>;
+ class Dog:ver<1.2.1>:auth<http://www.some.com/~jrandom>;
+ class Dog:ver<1.2.1>:auth<mailto:jra...@some.com>;
+
+Since these are somewhat unweildy to look at, we allow a shorthand in
+which a bare subscripty adverb interprets its elements according to their
+form:
+
+ class Dog:<1.2.1 cpan:JRANDOM>
+
+These declarations automatically alias the full name of the class
+(or module) to the short name. So for the rest of the lexical scope,
+C<Dog> refers to the longer name. The real library name can be
+specified separately as another adverb, in which case the identifier
+indicates only the alias within the current lexical scope:
+
+ class Pooch:name<Dog>:ver<1.2.1>:auth<cpan:JRANDOM>
+
+or
+
+ class Pooch:<Dog 1.2.1 cpan:JRANDOM>
+
+for short.
+
+Here the real name of the module starts C<Dog>, but we refer to it
+as C<Pooch> for the rest of this file. Aliasing is handy if you need to
+interface to more than one module named C<Dog>

If there are extra classes or modules or packages declared within
the same file, they implicitly have a long name including the file's
version and author, but you needn't declare them again.

-Since these long names are the actual names of the classes, when you say:
+Since these long names are the actual names of the classes as far as
+the library system is concerned, when you say:

use Dog;

you're really wildcarding the unspecified bits:

- use Dog-(Any)-(Any);
+ use Dog:ver(Any):auth(Any);

And when you say:

- use Dog-1.2.1;
+ use Dog:<1.2.1>;

you're really asking for:

- use Dog-1.2.1-(Any);
+ use Dog:ver<1.2.1>:auth(Any);

Saying C<1.2.1> specifies an I<exact> match on the version number,
not a minimum match. To match more than one version, put a range
operator in parens:

- use Dog-(1.2.1..1.2.3);
- use Dog-(1.2.1..^1.3);
- use Dog-(1.2.1..*);
+ use Dog:ver(1.2.1..1.2.3);
+ use Dog:ver(1.2.1..^1.3);
+ use Dog:ver(1.2.1..*);

Subversions are wildcarded, so C<1.2> really means C<1.2.*>. If you
say:
@@ -250,45 +276,45 @@

which is short for:

- use Perl-6;
+ use Perl:ver<6>;

-you're asking for any version of Perl 6. You need to say:
+you're asking for any version of Perl 6. You need to say something like

- use Perl-6.0;
- use Perl-6.0.0;
- use Perl-6.2.7.1;
+ use Perl:<6.0>;
+ use Perl:<6.0.0>;
+ use Perl:<6.2.7.1>;

if you want to lock in a particular set of semantics at some greater
degree of specificity. And if some large company ever forks Perl, you can say
+something like:

- use Perl-6-cpan:TPF
+ use Perl:auth<cpan:TPF>

to guarantee that you get the unembraced Perl. C<:-)>

-Perl is the default module name, so this means the same thing:
-
- use v6-cpan:TPF;
-
+To allow a version specification that works with both Perl 5 and 6, we
+use variants of the "v6" pseudomodule. This form specifically allows
+use of a subsequent hyphenated identifier.
Before the full specification of Perl 6.0.0 is released, you can use C<alpha>
-as the author slot to denote a program using syntax that is still subject
+to denote a program using syntax that is still subject
to change:

use v6-alpha;

+Later on
+
+ use v6-std;
+
+will indicate standard version 6 of Perl.
+
The C<use v6-alpha> line also serves as the Perl 5 incantation to switch to
Perl 6 parsing. In Perl 5 this actually ends up calling the v6.pm module with a
C<-alpha> argument, for insane-but-useful reasons.

For wildcards any valid smartmatch selector works:

- use Dog-(1.2.1 | 1.3.4)-(/:i jrandom/);
- use Dog-(Any)-(/^cpan\:/)
-
-Parens are optional on a closure smartmatcher. The preceding may
-also be written:
-
- use Dog-{$^ver ~~ 1.2.1 | 1.3.4}-{$^auth ~~ /:i jrandom/};
- use Dog-{$^ver ~~ Any}-{$^auth ~~ /^cpan\:/}
+ use Dog:ver(1.2.1 | 1.3.4):auth(/:i jrandom/);
+ use Dog:ver(Any):auth({ .substr(0,5) eq 'cpan:'})

In any event, however you select the module, its full name is
automatically aliased to the short name for the rest of your lexical
@@ -298,23 +324,25 @@

and it knows (even if you don't) that you mean

- my Dog-1.3.4-cpan:JRANDOM $spot .= new("woof");
+ my Dog:<1.3.4 cpan:JRANDOM> $spot .= new("woof");

-The C<use> statement actually allows a language on the front of a module name,
-so that you can use modules from other languages. The language is separated
-by a colon. For instance:
+The C<use> statement allows an external language to be specified in
+addition to (or instead of) an authority, so that you can use modules
+from other languages. The C<from> adverb also parses any additional
+parts as short-form arguments. For instance:

- use perl5:Acme::Bleach-1.12-DCONWAY;
- use ruby:Rails <PR_MACHINE>;
+ use Whiteness:from<perl5>:name<Acme::Bleach>ver<1.12>:auth<cpan:DCONWAY>;
+ use Whiteness:from<perl5 Acme::Bleach 1.12 cpan:DCONWAY>; # same thing

=head1 Forcing Perl 6

To get Perl 6 parsing rather than the default Perl 5 parsing,
we said you could force Perl 6 mode in your main program with:

- use Perl-6;
+ use v6-alpha;

-Actually, you can just start your main program with any of:
+Actually, if you're running a parser that is aware of Perl 6, you
+can just start your main program with any of:

use v6;
module;
@@ -322,10 +350,12 @@

Those all specify the latest Perl 6 semantics, and are equivalent to

- use Perl-(v6..*)-(Any);
+ use Perl:ver(v6..*):auth(Any);

-To lock the semantics to 6.0.0, say:
+To lock the semantics to 6.0.0, say one of:

+ use Perl:ver<6.0.0>;
+ use :<6.0.0>;
use v6.0.0;

In any of those cases, strictures and warnings are the default
@@ -341,17 +371,17 @@
a bare literal in a void context I<ought> to have produced a warning.
(Invoking perl with C<-e6> has the same effect.)

-In the other direction, to inline Perl 5 code inside a Perl 6 program, put
+In the other direction, to inline Perl 5 code inside a Perl 6 program, put
C<use v5> at the beginning of a lexical block. Such blocks can nest arbitrarily
deeply to switch between Perl versions:

- use v6-alpha;
+ use v6-std;
# ...some Perl 6 code...
{
use v5;
# ...some Perl 5 code...
{
- use v6-alpha;
+ use v6-std;
# ...more Perl 6 code...
}
}

Smylers

unread,
Mar 8, 2007, 4:05:32 AM3/8/07
to perl6-l...@perl.org
la...@cvs.perl.org writes:

> Saying C<1.2.1> specifies an I<exact> match on the version number,
> not a minimum match. To match more than one version, put a range
> operator in parens:
>

> + use Dog:ver(1.2.1..*);

That[*0] strikes me as a common trap for the unwary. In Perl 5 if you
rely on a feature (or bugfix) from a particular version of a module you
can specify that version and the code will continue to work with future
versions -- which is a reasonably pragmatic approach, effectively saying
"until proven otherwise I'll presume that any future releases of this
module won't break this functionality".

So I fear that people will do the same thing in Perl 6. Which,
initially, will appear to work. But then, some months later, somebody
upgrades the installed version of a module (or the program gets deployed
on another computer, which happens to have a more recent version
installed), and suddenly the program will break.

In summary, I feel uneasy about the combination of:

* In many (most?) cases the breakage will be arbitrary, in that the
module would've worked fine had it been allowed to run rather than
being stopped by the version-checker.

* It's a change from what was good practice in Perl 5.

* The bug _cannot_ hurt straight away, only at some point in the future
(and often by actions of somebody who isn't the programmer).

Any of those separately is liveable with, but together it's a bit much!

[*0] And I recognize from the lack of leading "+" symbols on the text
it isn't a recent change; my apologies for not spotting it earlier.

Smylers

Andreas J. Koenig

unread,
Mar 8, 2007, 1:21:19 AM3/8/07
to la...@cvs.develooper.com, perl6-l...@perl.org
$spot:<Inconsistent>:(parens)

>>>>> On Wed, 7 Mar 2007 20:38:17 -0800 (PST), la...@cvs.develooper.com said:

> + class Dog:ver<1.2.1>:auth<cpan:JRANDOM>;
> + class Dog:ver<1.2.1>:auth<http://www.some.com/~jrandom>;
> + class Dog:ver<1.2.1>:auth<mailto:jra...@some.com>;

> + class Dog:<1.2.1 cpan:JRANDOM>

> + class Pooch:name<Dog>:ver<1.2.1>:auth<cpan:JRANDOM>


> + class Pooch:<Dog 1.2.1 cpan:JRANDOM>

So far you're using angle brackets

> - use Dog-(Any)-(Any);
> + use Dog:ver(Any):auth(Any);

From here you start mixing angle brackets and parens.



> - use Dog-1.2.1;
> + use Dog:<1.2.1>;

> - use Dog-1.2.1-(Any);
> + use Dog:ver<1.2.1>:auth(Any);

Even in one line.



> - use Dog-(1.2.1..1.2.3);
> - use Dog-(1.2.1..^1.3);
> - use Dog-(1.2.1..*);
> + use Dog:ver(1.2.1..1.2.3);
> + use Dog:ver(1.2.1..^1.3);
> + use Dog:ver(1.2.1..*);

> + use Dog:ver(1.2.1 | 1.3.4):auth(/:i jrandom/);
> + use Dog:ver(Any):auth({ .substr(0,5) eq 'cpan:'})

> - use Perl-(v6..*)-(Any);
> + use Perl:ver(v6..*):auth(Any);

Seems accidentally to me.

--
andreas

Smylers

unread,
Mar 8, 2007, 5:14:14 AM3/8/07
to perl6-l...@perl.org
Andreas J. Koenig writes:

> $spot:<Inconsistent>:(parens)
>
> >>>>> On Wed, 7 Mar 2007 20:38:17 -0800 (PST), la...@cvs.develooper.com said:
>
> > + class Dog:ver<1.2.1>:auth<cpan:JRANDOM>;
> > + class Dog:ver<1.2.1>:auth<http://www.some.com/~jrandom>;
> > + class Dog:ver<1.2.1>:auth<mailto:jra...@some.com>;
> > + class Dog:<1.2.1 cpan:JRANDOM>
>
> > + class Pooch:name<Dog>:ver<1.2.1>:auth<cpan:JRANDOM>
> > + class Pooch:<Dog 1.2.1 cpan:JRANDOM>
>
> So far you're using angle brackets

That's a string.

> > + use Dog:ver(Any):auth(Any);
>
> From here you start mixing angle brackets and parens.

That is not literally the author called "Any" releasing the version
"Any", but saying that Any values are permitted.

> > + use Dog:<1.2.1>;

Literal version number.

> > + use Dog:ver<1.2.1>:auth(Any);
>
> Even in one line.

Literal version number, but any author.

> > + use Dog:ver(1.2.1..1.2.3);
> > + use Dog:ver(1.2.1..^1.3);
> > + use Dog:ver(1.2.1..*);
>
> > + use Dog:ver(1.2.1 | 1.3.4):auth(/:i jrandom/);
> > + use Dog:ver(Any):auth({ .substr(0,5) eq 'cpan:'})
>

> > + use Perl:ver(v6..*):auth(Any);
>
> Seems accidentally to me.

Those are all ranges or code that specifies which values are permitted,
rather than literal values.

Smylers

Andreas J. Koenig

unread,
Mar 8, 2007, 6:00:00 AM3/8/07
to Andreas J. Koenig, la...@cvs.develooper.com, perl6-l...@perl.org
>>>>> On Thu, 08 Mar 2007 07:21:19 +0100, andreas.koe...@franz.ak.mind.de (Andreas J. Koenig) said:

> $spot:<Inconsistent>:(parens)

Please accept my apologies for my ignorant posting. Clearly the parens
indicate ranges. Sorry for the noise.

Going back into lurker-mode,
--
andreas

Larry Wall

unread,
Mar 8, 2007, 12:26:31 PM3/8/07
to perl6-l...@perl.org
On Thu, Mar 08, 2007 at 09:05:32AM +0000, Smylers wrote:
: So I fear that people will do the same thing in Perl 6. Which,

: initially, will appear to work. But then, some months later, somebody
: upgrades the installed version of a module (or the program gets deployed
: on another computer, which happens to have a more recent version
: installed), and suddenly the program will break.

Nope, check your assumptions, you've got a big one that just ain't so.
Perl 6 is specced to keep all the old versions of modules around in
the library (unless the new version claims to emulate the old version).
So an upgrade doesn't generally break fixed dependencies.

: In summary, I feel uneasy about the combination of:


:
: * In many (most?) cases the breakage will be arbitrary, in that the
: module would've worked fine had it been allowed to run rather than
: being stopped by the version-checker.

It is allowed to run anyway, and it runs with a known good version.
If there's arbitrary breakage, it's because dependencies depend on a
different version that is incompatible with your version because of
some exclusive resource. Modules that manage an exclusive resource
(such as a database handle) need to learn to deal with that, either
by emulating older versions, or finding some way to share the resource
between different versions.

: * It's a change from what was good practice in Perl 5.

s/good/common/;

First of all, Perl 6 is not aimed at exactly the same problem space
as Perl 5. Hopefully the new Perl problem space is a superset of the
old one...except perhaps for using formats to print reports on your
line printer. :-)

Second, what is "good" practice in Perl 5 is often just a workaround
for one or another of the design flaws; these underlying design flaws
are the real reason Perl 5 has been becoming stagnant over the last
decade or so. This has been happening since long before Perl 6 was
thought of. Those who believe the stagnation of Perl 5 is caused by
Perl 6 should go back and reread the 361 RFCs, and then recognize that
it's very difficult to fix Perl 5 in a piecemeal fashion without simply
make it a bigger mess than it already is. We're trying very hard to
make different mistakes this time, and I believe we're succeeding. :-)

: * The bug _cannot_ hurt straight away, only at some point in the future


: (and often by actions of somebody who isn't the programmer).

Only if the module writers are stupid about preserving the semantics
of exclusive resources. If there are no exclusive resources it
doesn't matter if two different versions of the same module are
loaded--neglecting memory considerations, which I believe is well worth
neglecting for the benefit. And the benefit of this approach is that
it's much more scalable to programming in the large when various of
your dependencies can depend on different versions of the same module
without forcing upgrades on modules that don't need it.

On top of which, you can get the old semantics if you want, but we
just rehuffmanized it so it's not the default unless you leave off
the version requirement entirely. We also provide good intermediate
huffmanizations that allow you to follow a maintenence track without
automatically leaping to the next bleadtrack, using 6.2.* notation.
How do you do that in Perl 5?

Larry

David Green

unread,
Mar 8, 2007, 2:47:19 PM3/8/07
to perl6-l...@perl.org
On 3/8/07, Smylers wrote:
>In Perl 5 if you rely on a feature (or bugfix) from a particular
>version of a module you can specify that version and the code will
>continue to work with future versions -- which is a reasonably
>pragmatic approach, effectively saying "until proven otherwise I'll
>presume that any future releases of this module won't break this
>functionality".

I think that looking at versions from the perspective of the person
using the module is the wrong way around: as you point out, when I
write a program, I have no way of knowing whether future versions of
some module will continue to work (I just assume they do and hope for
the best) -- however, the author of the module should know! So it
should be the *modules* that specify compatible version ranges, not
my program.

And if you are using my program, I likely have no knowledge or
control of what versions of what modules you might be running.
Instead, I ought to specify what version of the module I wrote my
code against (that's one thing I can know for sure); future versions
of the module should then themselves specify which previous versions
they are compatible with.

module Foo:<2.3.4 cpan:JSMITH>
does versions(0.8.0..1.2.2, 1.2.4..2.3.4);

In this example, Foo has been pretty compatible since v0.8, but it
skips v1.2.3, let's say because that version had a bug so it wasn't
really compatible (even though it probably said it was).

My program would say (coining "used" for the sake of example):

used Foo:<2.0.0>;

to indicate the exact version of the module I used to write my code.
Then it doesn't matter whether that exact version is available as
long as there is some module that advertises itself as doing
Foo:<2.0.0>. (As determined by the modules, or by Perl, or by the
Parrot Library Management System.)

Of course, I would still need to be able to specify details such as
"but don't use Foo:<1.2.3> even though it claims to be compatible,
because really I know it's buggy".

This would also allow for modules that are compatible not only with
other versions of themselves, but also with other modules of a
different name. (If your module provides the Foo interface, why not
just name it Foo -- especially since you can choose an authority to
carve out your own space in the Foo universe? You should, of course,
unless your module also is compatible with module Bar. It can't have
two names, but it can advertise itself as being compatible with two
or more other modules.)


-David

David Green

unread,
Mar 8, 2007, 2:57:00 PM3/8/07
to perl6-l...@perl.org
On 3/8/07, Larry Wall wrote:
>Perl 6 is specced to keep all the old versions of modules around in
>the library (unless the new version claims to emulate the old version).

Oh, good! So how does a module say that it emulates another version?
(Or perhaps another module altogether...) Does "does" work for that?

>So an upgrade doesn't generally break fixed dependencies.

Hm, so if I'm not upgrading, but installing a module for the first
time, presumably I will actually get all its different incarnations
to date.

>It is allowed to run anyway, and it runs with a known good version.

Does "allowed to run anyway" mean because older versions stay
installed (and thus you should be able to get an exact match), or
does it mean you might get some other module altogether, as long as
it claims to be compatible with whatever you asked for?


-David

Larry Wall

unread,
Mar 8, 2007, 3:10:50 PM3/8/07
to perl6-l...@perl.org
On Thu, Mar 08, 2007 at 12:57:00PM -0700, David Green wrote:
: On 3/8/07, Larry Wall wrote:
: >Perl 6 is specced to keep all the old versions of modules around in
: >the library (unless the new version claims to emulate the old version).
:
: Oh, good! So how does a module say that it emulates another version?
: (Or perhaps another module altogether...) Does "does" work for that?

Unspecced, but presumably some kind of modifier or trait that maybe
doesn't count as part of the long name, or rather that causes alternate
long names to be generated.

: >So an upgrade doesn't generally break fixed dependencies.


:
: Hm, so if I'm not upgrading, but installing a module for the first
: time, presumably I will actually get all its different incarnations
: to date.

I could argue that both ways. There seems to be little reason to
install an older version unless someone is likely to request it in
the future--especially when we're trying to cram the library onto
one of those nanobots that are running around in your bloodstream.
On the other hand, the more consistent everyone's library configuration
is, the fewer mysterious skew errors we'll run into when the module
search criteria enter the twilight zone. I'm not so sure you want
your blood nanobots anywhere near the twilight zone though.

: >It is allowed to run anyway, and it runs with a known good version.


:
: Does "allowed to run anyway" mean because older versions stay
: installed (and thus you should be able to get an exact match), or
: does it mean you might get some other module altogether, as long as
: it claims to be compatible with whatever you asked for?

Yes. You've more or less restated the current design, and helpfully
pointed out that the current design neglects to provide a syntax for
declaring emulation. Now we just have to come up with one. :)

Larry

Smylers

unread,
Mar 9, 2007, 4:02:20 AM3/9/07
to perl6-l...@perl.org
Larry Wall writes:

> On Thu, Mar 08, 2007 at 09:05:32AM +0000, Smylers wrote:
>
> : So I fear that people will do the same thing in Perl 6. Which,
> : initially, will appear to work. But then, some months later,
> : somebody upgrades the installed version of a module (or the program
> : gets deployed on another computer, which happens to have a more
> : recent version installed), and suddenly the program will break.
>
> Nope, check your assumptions, you've got a big one that just ain't so.
> Perl 6 is specced to keep all the old versions of modules around in
> the library

Yeah, that's why I added "or the program gets deployed on another
computer, which happens to have a more recent version".

> (unless the new version claims to emulate the old version). So an
> upgrade doesn't generally break fixed dependencies.

Aha! So even if I specify that I want, say, version 1.3, if only
version 1.6 is installed but the module's author claims never to've
broken backwards compatibility then it will run anyway? That's good.

> : * In many (most?) cases the breakage will be arbitrary, in that the
> : module would've worked fine had it been allowed to run rather than
> : being stopped by the version-checker.
>
> It is allowed to run anyway,

Sorry, I don't quite understand that. What does happen if a program
requests a version of a module that

> : * It's a change from what was good practice in Perl 5.
>
> s/good/common/;

I'd say that common practice in Perl 5 is merely to use a module and not
specify a version number at all! Specifying a minimum version number is
an improvement -- obviously not ideal, but it is as much as can be done
straightforwardly with Perl 5. And I think it'very likely people in the
habit of doing this in Perl 5 will, at least initially, specify a single
version number in Perl 6 C<use> lines.

> Those who believe the stagnation of Perl 5 is caused by Perl 6 should

> go back and reread the 361 RFCs ... <Snip>

Sorry if my post came across as some kind of attack on Perl 6 as a whole
-- it certainly wasn't supposed to be!! I'm very much in favour of the
way Perl 6 is going and the many improvements it brings.

(And I'm not sure what stagnation has to do with this thread, but for
what it's worth I think quite the opposite: Perl 6 has been the
inspiration for several good things people are already doing with Perl
5.)

Cheers.

Smylers

Reply all
Reply to author
Forward
0 new messages