Re: One-pass parsing and forward type references

2010-02-01 Thread Moritz Lenz
Carl Mäsak wrote:
 But on another level, the level of types, Perl 6 makes it fairly
 *un*natural that the type CFoo refers to the type CBar, which in
 turn refers to the type CFoo.

True, and that has also been bothering me quite a bit.

The solution is to always write ::Typename instead of Typename
except when it isn't a solution.

First of all in signatures ::T means actually type capture, secondly I
guess that some constructs really want to resolve type names at compile
time -- for example the multi dispatcher needs to know the inheritance
structure of a type in order to its pre-sorting of signatures.

The first problem could be solved by introducing another syntax for type
captures (perhaps  :foo   or so?), of the second I know too little to
really comment on it.

Cheers,
Moritz


Re: One-pass parsing and forward type references

2010-02-01 Thread Carl Mäsak
Moritz (), Carl ():
 But on another level, the level of types, Perl 6 makes it fairly
 *un*natural that the type CFoo refers to the type CBar, which in
 turn refers to the type CFoo.

 True, and that has also been bothering me quite a bit.

 The solution is to always write ::Typename instead of Typename
 except when it isn't a solution.

 First of all in signatures ::T means actually type capture, secondly I
 guess that some constructs really want to resolve type names at compile
 time -- for example the multi dispatcher needs to know the inheritance
 structure of a type in order to its pre-sorting of signatures.

 The first problem could be solved by introducing another syntax for type
 captures (perhaps  :foo   or so?), of the second I know too little to
 really comment on it.

I had half an idea about the second one as I wrote the first mail. It
may or may not be useful, but here goes:

Some keyword, on the level of 'is' and 'does', which allows one to use
a not-yet-defined typename within another type. It wouldn't solve the
core problem -- the one about having to think about circularities --
but it would allow one to create cycles. So this would work:

  class A precedes-but-refers-to B { ... B ... }
  class B { ... A ... }

Just an idea.

// Carl


Re: One-pass parsing and forward type references

2010-02-01 Thread Patrick R. Michaud
On Sun, Jan 31, 2010 at 06:35:14PM +0100, Carl Mäsak wrote:
 I found two ways. Either one uses Caugment (the language construct
 formerly known as Cis also):
 
   class B {}
   class A { sub foo { B::bar } }
   augment class B { sub bar { A::foo } }
 
 ...or one may use the C:: notation to index a type using a string value:
 
   class A { sub foo { ::B::bar() } }
   class B { sub bar { A::foo } }

There's a third way:

class B { ... }# introduce B as a class name without definition
class A { sub foo { B::bar } }

class B { sub bar { A::foo } }

The first line is a literal ... in the body of the class -- it
indicates that we're only declaring the name as being a type,
and that something else will fill in the details later.

Pm


Re: One-pass parsing and forward type references

2010-02-01 Thread Carl Mäsak
Patrick (), Carl ():
 I found two ways. Either one uses Caugment (the language construct
 formerly known as Cis also):

   class B {}
   class A { sub foo { B::bar } }
   augment class B { sub bar { A::foo } }

 ...or one may use the C:: notation to index a type using a string value:

   class A { sub foo { ::B::bar() } }
   class B { sub bar { A::foo } }

 There's a third way:

    class B { ... }    # introduce B as a class name without definition
    class A { sub foo { B::bar } }

    class B { sub bar { A::foo } }

 The first line is a literal ... in the body of the class -- it
 indicates that we're only declaring the name as being a type,
 and that something else will fill in the details later.

That's nice. Seems like a decent way to avoid 'use MONKEY_TYPING'.

Is it allowed to do 'class B { ... }' several times in different files
before finally declaring the real B? If so, then I'd consider it
equivalent to my proposed keyword, and thus there'd be no need for the
latter.

// Carl


Re: One-pass parsing and forward type references

2010-02-01 Thread Jan Ingvoldstad
On Mon, Feb 1, 2010 at 17:46, Patrick R. Michaud pmich...@pobox.com wrote:

 There's a third way:

class B { ... }# introduce B as a class name without definition
 class A { sub foo { B::bar } }

class B { sub bar { A::foo } }

 The first line is a literal ... in the body of the class -- it
 indicates that we're only declaring the name as being a type,
 and that something else will fill in the details later.


It seems to me that this doesn't really solve the problems that will occur
when people start making packages independently of eachother.

Of course it can be solved by submitting patches to the other developer's
code, but it seems inelegant.
-- 
Jan


Announce: Rakudo Perl 6 Development Release #25 (Minneapolis)

2010-02-01 Thread Patrick R. Michaud
[This notice is going out a bit late; the release was indeed
produced on time, but I was delayed in sending out this notice.
With apologies for the delay...  --Pm]

On behalf of the Rakudo development team, I'm pleased to announce the
January 2010 development release of Rakudo Perl #25 Minneapolis.
Rakudo is an implementation of Perl 6 on the Parrot Virtual Machine
(see http://www.parrot.org).  The tarball for the January 2010 release
is available from http://github.com/rakudo/rakudo/downloads .

Rakudo Perl follows a monthly release cycle, with each release 
code named after a Perl Mongers group.  The January 2010 release 
is code named Minneapolis for Minneapolis.pm, hosts of the annual 
Frozen Perl Workshop [1].  In 2009 the Frozen Perl Workshop featured a 
one-day hackathon for Perl 6 and Rakudo development, which ultimately 
informed the design and implementation of the current build system.
(The 2010 Frozen Perl Workshop will be on February 6, 2010, for those
interested in attending.)

Shortly after the October 2009 (#22) release, the Rakudo team began a new
branch of Rakudo development (ng) that refactors the grammar to much more
closely align with STD.pm as well as update some core features that have been
difficult to achieve in the master branch [2, 3].  We had planned for
this release to be created from the new branch, but holiday vacations
and other factors conspired against us.  This is absolutely the final 
release from the old development branch; we expect to make the new branch 
the official master branch shortly after this release.

This release of Rakudo requires Parrot 2.0.0.  One must still
perform make install in the Rakudo directory before the perl6
executable will run anywhere other than the Rakudo build directory.
For the latest information on building and using Rakudo Perl, see the
README file section titled Building and invoking Rakudo.

Some of the specific changes and improvements occuring with this
release include:

* Rakudo is now passing 31,957 spectests, or 85.7% of the available
  test suite.  This is roughly the same level as the December 2009
  release (because most effort has taken place in the ng branch
  as described above).

* Rakudo's calling conventions have been updated to match changes
  in Parrot 2.0.0's calling and context structures.

The Perl 6 language specification is still in flux. Please take note of the
following changes, which might affect your existing programs. In the next
release of Rakudo, the deprecated features will likely be gone.

* The root of the object hierarchy has been changed from 'Object' to 'Mu'.
  The type 'Object' goes away.

* The term 'undef' is gone. You can replace it with other constructs,
  depending on context:
- 'Nil' is undefined in item context, and the empty list in list context
- 'Mu' is the most general undefined value which does not flatten in list
  context
- as a smart matching target, you can replace '$obj ~~ undef'
  by '$obj ~~ *.notdef'

* Builtin classes will derive from 'Cool' (which itself derives from 'Any').
  Most of the builtin methods on these classes will be defined in the
  'Cool' class instead of 'Any'.  See Synopsis 2 for more details.

* Starting with the next release, we will likely switch to using
  .MM instead of -MM (dot instead of hyphen) as release 
  identifiers.  This is intended to simplify building and packaging
  for other distribution systems.

The development team thanks all of our contributors and sponsors for
making Rakudo Perl possible.  If you would like to contribute,
see http://rakudo.org/how-to-help , ask on the perl6-compi...@perl.org
mailing list, or ask on IRC #perl6 on freenode.

The next release of Rakudo (#26) is scheduled for February 18, 2010.
A list of the other planned release dates and codenames for 2010 is
available in the docs/release_guide.pod file.  In general, Rakudo
development releases are scheduled to occur two days after each
Parrot monthly release.  Parrot releases the third Tuesday of each month.

Have fun!

[1] http://www.frozen-perl.org/
[2] http://use.perl.org/~pmichaud/journal/39779
[3] http://use.perl.org/~pmichaud/journal/39874


Re: One-pass parsing and forward type references

2010-02-01 Thread Larry Wall
Please don't assume that rakudo's idiosyncracies and design fossils
are canonical.  STD does better namespace management in some respects,
particularly in accepting the approved predeclaration form:

class Foo {...}

(and rakudo might now accept this too).

You don't want to use augment for this, because augment is only for
*cheating*, and will eventually require a 'use MONKEY_TYPING;' before it.

You are correct that the one-pass parsing is non-negotiable; this is
how humans think, even when dealing with unknown names.  However, human
language has ways of telling the listener whether a new word is a noun
or a verb, and we generally choose not to require articles or verb
markers in Perl 6, so class names (nouns) are officially ambiguous
with function names (verbs).  We could, as has been suggested before,
have an optional noun marker for undeclared classes, but this tends
to insidiously creep into lots of places, when a single predeclaration
would be clearer and more efficient.

The other reason we'll stick with one-pass parsing is that you can
only do multiple pass parsing if you know exactly which language
you're parsing all the time.  This works against extensibility.
Multiple passes introduce linguistic race conditions any time you're
not sure what language you're in; see source filters for a good bad
example of why you don't want to do multi-pass parsing.

Because type names are nouns in Perl 6, we want to parse them like
other nouns, such as variables and constants, not like verbs.
Know whether something is a noun or a verb is very important in
maintaining the two-terms-in-a-row prohibition, which is the
primary way in which Perl 6 expressions are self-clocking.  Break
that clock and your error messages will turn to mush.  Some of
the smartest error messages that STD emits are actually the
two-terms message transmogrified into something more specific
by context.

Therefore, a word that is declared as a sigilless noun must change
the parsing from there on down so that we know to expect an infix
after it, not a term, which a verb functioning as a listop would
expect.

constant Int pi = 3;
pi 'foo';   # syntax error

(Notice how the fact that Int is predeclared also allows us to
correctly parse the constant declaration, since allows us to
distinguish the existing type from the name to be declared.)

Now that we have basic philosophy out of the way, on to other
arguments.  You might take the predeclaration policy as subtle
encouragement to use the late binding provided by method calls,
which don't require predeclaration.  But Perl 6 is not religiosly
OO to the exclusion of FP, so that's a weak argument, and we're not
trying to discourage people from doing cross-module function calls.

You make an analogy between type recursion and functional recursion,
which is true up to a point, but types and other unsigilled names
tend to be rarer than function names, so it makes sense, if we see
an unknown name, to assume (if we choose to assume) that it is a
postdeclared verb rather than a postdeclared noun.  We don't want to
break function recursion in order to support type recursion.  We can't
guess it both ways since we wouldn't know what to expect next.  Perl 5
did lookahead and tried to guess in some cases, but this generally
turned out to be a mistake.  It was difficult to document and only
inspired mistrust in the parser.  Plus it degrades the two-term rule.

But also note that there are several other ways to predeclare
types implicitly.  The 'use', 'require', and 'need' declarations
all introduce a module name that is assumed to be a type name.

We can also deduce that any use of Foo::Bar::baz to mean
there exists a Foo::Bar type.  STD does this already, though
perhaps only as a lexically scope name at the moment.  We might
assume it to (at least potentially) be global.

A 'use' also predeclares any types in its own space and makes the
public ones available as predeclaration.  From the standpoint of a
typical midsized application that are spread across multiple files,
most of the predeclarations should arrive like this, and not require
a yadayada predeclaration.  And in Perl 6 you shouldn't generally
be using types without a 'use' of the definitions of those types,
or you might not import some desirable multi into your lexical scope.

Of course, we have to deal with 'use' cycles.  Perl 5 simply assumes
that it doesn't need to load a module that it knows is already being
loaded, even if that loading is not complete or would result in
something not being defined that ought to be.  We could take the same
agnostic approach and require the user to break use cycles explicitly
with yada.

Or we could detect that exact situation and relax the rules slightly
to do a bit of dwimmery on type names that *start* with the
partially compiled module.  In that case, it might be reasonable,
if we've got a suspended 'use Foo', to assume:

Foo::Bar::baz   # likely a function
Foo::Bar::Baz   # likely 

Re: One-pass parsing and forward type references

2010-02-01 Thread Matthew Wilson
On Mon, Feb 1, 2010 at 9:32 AM, Larry Wall la...@wall.org wrote:
 But I also think that type recursion is likelier to indicate a design
 error than function recursion, so I'm not sure how far down this road
 we want to go.  We could, for instance, create a new type name every

I was going to say I use self-referential and cyclical type definitions in
Sprixel's (stage0) C# source... (because I did at one point), but then I
realized I stopped doing that; it worked, but it was a tad too tricksy to
maintain.

So, point taken.


Re: One-pass parsing and forward type references

2010-02-01 Thread yary
A slight digression on a point of fact-

On Mon, Feb 1, 2010 at 9:32 AM, Larry Wall la...@wall.org wrote:
...
 You are correct that the one-pass parsing is non-negotiable; this is
 how humans think, even when dealing with unknown names.

It's common for people to read a passage twice when encountering
something unfamiliar. That's on the large level. And even on the small
level of reading for the first time, people don't read completely
linearly, skilled readers make regressions back to material already
read about 15 percent of the time. -
http://en.wikipedia.org/wiki/Eye_movement_in_language_reading (and I
read about that elsewhere years ago, wikipedia happens to be the most
convenient reference.)

I'm not arguing against 1-pass parsing for Perl6, just reminding that
humans are complicated. And Larry's quote is how humans think
whereas the research on eye jumps is about how humans read which are
not exactly the same...

-y


Re: One-pass parsing and forward type references

2010-02-01 Thread Larry Wall
On Mon, Feb 01, 2010 at 10:10:11AM -0800, yary wrote:
: A slight digression on a point of fact-
: 
: On Mon, Feb 1, 2010 at 9:32 AM, Larry Wall la...@wall.org wrote:
: ...
:  You are correct that the one-pass parsing is non-negotiable; this is
:  how humans think, even when dealing with unknown names.
: 
: It's common for people to read a passage twice when encountering
: something unfamiliar. That's on the large level. And even on the small
: level of reading for the first time, people don't read completely
: linearly, skilled readers make regressions back to material already
: read about 15 percent of the time. -
: http://en.wikipedia.org/wiki/Eye_movement_in_language_reading (and I
: read about that elsewhere years ago, wikipedia happens to be the most
: convenient reference.)
: 
: I'm not arguing against 1-pass parsing for Perl6, just reminding that
: humans are complicated. And Larry's quote is how humans think
: whereas the research on eye jumps is about how humans read which are
: not exactly the same...

True enough; I was thinking primarily about the parsing of spoken
speech, where one generally doesn't have the option to replay beyond
what you can remember.  And Perl 6 is arguably more textual than aural.

Larry


r29604 - docs/Perl6/Spec

2010-02-01 Thread pugs-commits
Author: lwall
Date: 2010-02-01 21:14:16 +0100 (Mon, 01 Feb 2010)
New Revision: 29604

Modified:
   docs/Perl6/Spec/S02-bits.pod
   docs/Perl6/Spec/S06-routines.pod
Log:
[S02,S06] continue de-confusing flat and eager


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2010-01-31 22:21:10 UTC (rev 29603)
+++ docs/Perl6/Spec/S02-bits.pod2010-02-01 20:14:16 UTC (rev 29604)
@@ -13,8 +13,8 @@
 
 Created: 10 Aug 2004
 
-Last Modified: 30 Jan 2009
-Version: 197
+Last Modified: 1 Feb 2009
+Version: 198
 
 This document summarizes Apocalypse 2, which covers small-scale
 lexical items and typological issues.  (These Synopses also contain
@@ -3993,8 +3993,9 @@
 
 =item *
 
-To force non-lazy list flattening, use the Ceager list operator.
-List assignment is also implicitly eager.
+To force non-lazy list processing, use the Ceager list operator.
+List assignment is also implicitly eager. (Actually, when we say
+eager we usually mean mostly eager as defined in LS07).
 
 eager $filehandle.lines;# read all remaining lines
 
@@ -4008,6 +4009,9 @@
 and calls the iterator as it needs more elements.  (Counting the elements
 in the array will also force eager completion.)
 
+This operator is agnostic towards flattening or slicing.  In merely changes
+the work-ahead policy for the value generator.
+
 =item *
 
 A variant of Ceager is the Chyper list operator, which declares
@@ -4020,6 +4024,9 @@
 as the results come in, such that some keys can be seen even before
 the hyper is done.  Thinking about Map-Reduce algorithms here...)
 
+This operator is agnostic towards flattening or slicing.  It merely changes
+the work-ahead policy for the value generator.
+
 =item *
 
 Signatures on non-multi subs can be checked at compile time, whereas

Modified: docs/Perl6/Spec/S06-routines.pod
===
--- docs/Perl6/Spec/S06-routines.pod2010-01-31 22:21:10 UTC (rev 29603)
+++ docs/Perl6/Spec/S06-routines.pod2010-02-01 20:14:16 UTC (rev 29604)
@@ -16,8 +16,8 @@
 
 Created: 21 Mar 2003
 
-Last Modified: 19 Nov 2009
-Version: 125
+Last Modified: 1 Feb 2010
+Version: 126
 
 This document summarizes Apocalypse 6, which covers subroutines and the
 new type system.
@@ -970,10 +970,11 @@
 
 The C| operator flattens lazily -- the array is flattened only if
 flattening is actually required within the subroutine. To flatten before
-the list is even passed into the subroutine, use the Ceager list
+the list is even passed into the subroutine, use the Cflat list
 operator:
 
-foo(|eager @onetothree);  # array flattened before foo called
+foo(|flat 1,2,3 Z 4,5,6);# zip list flattened before interpolation
+foo |(1,2,3 Z 4,5,6).flat# same thing
 
 
 =head2 Multidimensional argument list binding



r29605 - docs/Perl6/Spec

2010-02-01 Thread pugs-commits
Author: lwall
Date: 2010-02-01 21:33:47 +0100 (Mon, 01 Feb 2010)
New Revision: 29605

Modified:
   docs/Perl6/Spec/S02-bits.pod
   docs/Perl6/Spec/S03-operators.pod
   docs/Perl6/Spec/S04-control.pod
Log:
[S02,S03,S04] more @@ removal; some s/Capture/Parcel/ cleanup


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2010-02-01 20:14:16 UTC (rev 29604)
+++ docs/Perl6/Spec/S02-bits.pod2010-02-01 20:33:47 UTC (rev 29605)
@@ -1600,7 +1600,6 @@
 %   unordered hash (associative array)
code/rule/token/regex
 ::  package/module/class/role/subset/enum/type/grammar
-@@  slice view of @
 
 Within a declaration, the C sigil also declares the visibility of the
 subroutine name without the sigil within the scope of the declaration:
@@ -2124,7 +2123,7 @@
 operators:
 
 print $( foo() )# foo called in item context
-print @@( foo() )   # foo called in slice context
+print %( foo() )   # foo called in hash context
 
 In declarative constructs bare sigils may be used as placeholders for
 anonymous variables:

Modified: docs/Perl6/Spec/S03-operators.pod
===
--- docs/Perl6/Spec/S03-operators.pod   2010-02-01 20:14:16 UTC (rev 29604)
+++ docs/Perl6/Spec/S03-operators.pod   2010-02-01 20:33:47 UTC (rev 29605)
@@ -15,8 +15,8 @@
 
 Created: 8 Mar 2004
 
-Last Modified: 30 Jan 2010
-Version: 188
+Last Modified: 1 Feb 2010
+Version: 189
 
 =head1 Overview
 
@@ -205,7 +205,6 @@
 %z
 $^a
 $?FILE
-@@slice
 func
 div:(Int, Int -- Int)
 
@@ -217,7 +216,6 @@
 @()
 %()
 ()
-@@()
 
 =item *
 
@@ -919,11 +917,10 @@
 @list xx $count
 
 Evaluates the left argument in list context, replicates the resulting
-CCapture value the number of times specified by the right argument and
-returns the result in a context dependent fashion.  If the operator
-is being evaluated in ordinary list context, the operator returns a
-flattened list.  In slice (C@@) context, the operator converts each 
CCapture
-to a separate sublist and returns the list of those sublists.
+CParcel value the number of times specified by the right argument
+and returns the result as a list of CParcels (which will behave
+differently depending on whether it's bound into a flat context or
+a slice context).
 
 If the count is less than 1, returns the empty list, C().
 If the count is C*, returns an infinite list (lazily, since lists
@@ -1703,11 +1700,11 @@
 
 ('a', '1'), ('a', '2'), ('b', '1'), ('b', '2')
 
-This becomes a flat list in C@ context and a list of arrays in C@@ context:
+This becomes a flat list in flat context and a list of arrays in slice context:
 
-say @(a b X 1 2)
+say flat(a b X 1 2)
 'a', '1', 'a', '2', 'b', '1', 'b', '2'
-say @@(a b X 1 2)
+say slice(a b X 1 2)
 ['a', '1'], ['a', '2'], ['b', '1'], ['b', '2']
 
 The operator is list associative, so
@@ -2358,7 +2355,7 @@
 The forms with the double angle append rather than clobber the sink's
 todo list.  The C ==  form always looks ahead for an appropriate
 target to append to, either the final sink in the chain, or the next
-filter stage with an explicit C@(*) or C@@(*) target.  This means
+filter stage with an explicit C@(*) or C@(**) target.  This means
 you can stack multiple feeds onto one filter command:
 
 source1() ==
@@ -4655,7 +4652,7 @@
 turn into subarrays, and each element would then have to be unpacked
 by the signature:
 
-for @@(zip(@names; @codes)) - [$name, $zip] {
+for slice(zip(@names; @codes)) - [$name, $zip] {
 print Name: $name;   Zip code: $zip\n;
 }
 

Modified: docs/Perl6/Spec/S04-control.pod
===
--- docs/Perl6/Spec/S04-control.pod 2010-02-01 20:14:16 UTC (rev 29604)
+++ docs/Perl6/Spec/S04-control.pod 2010-02-01 20:33:47 UTC (rev 29605)
@@ -352,9 +352,9 @@
 iteration.  Iterations that return a null list (such as by calling
 Cnext with no extra return arguments) interpolate no values in the
 resulting list.  (This list is actually a two-dimensional list of
-CCaptures (a slice) with dimensional boundaries at each iteration.
+CParcels (a slice) with dimensional boundaries at each iteration.
 Normal list context ignores these boundaries and flattens the list.
-Slice context turns the captures into subarrays, so an iteration
+Slice context turns the parcels into sublists, so an iteration
 returning a null list does show up as a null subarray when viewed as
 a slice.)
 
@@ -688,16 +688,18 @@
 the statement or block in sink (void) context; its return value is instead
 specified by calling the Ctake list prefix operator one or more times
 within the dynamic scope of the Cgather.  The Ctake function's
-signature is like that of Creturn; it merely captures the CCapture
+signature is like that of Creturn; it merely 

Re: One-pass parsing and forward type references

2010-02-01 Thread Patrick R. Michaud
On Mon, Feb 01, 2010 at 05:55:47PM +0100, Carl Mäsak wrote:
 Is it allowed to do 'class B { ... }' several times in different files
 before finally declaring the real B? If so, then I'd consider it
 equivalent to my proposed keyword, and thus there'd be no need for the
 latter.

Yes.  And declaring the real B doesn't have to be final, nor
does it have to occur at all (as long as none of the features needed
from B are ever needed).

Pm


Re: One-pass parsing and forward type references

2010-02-01 Thread Solomon Foster
On Mon, Feb 1, 2010 at 3:46 PM, Patrick R. Michaud pmich...@pobox.com wrote:
 On Mon, Feb 01, 2010 at 05:55:47PM +0100, Carl Mäsak wrote:
 Is it allowed to do 'class B { ... }' several times in different files
 before finally declaring the real B? If so, then I'd consider it
 equivalent to my proposed keyword, and thus there'd be no need for the
 latter.

 Yes.  And declaring the real B doesn't have to be final, nor
 does it have to occur at all (as long as none of the features needed
 from B are ever needed).

And just to finish it off... are you allowed to do 'class B { ... }'
even after declaring the real B?

-- 
Solomon Foster: colo...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com


Re: One-pass parsing and forward type references

2010-02-01 Thread Patrick R. Michaud
On Mon, Feb 01, 2010 at 05:56:09PM +0100, Jan Ingvoldstad wrote:
 On Mon, Feb 1, 2010 at 17:46, Patrick R. Michaud pmich...@pobox.com wrote:
  There's a third way:
 
 class B { ... }# introduce B as a class name without definition
  class A { sub foo { B::bar } }
 
 class B { sub bar { A::foo } }
 
 It seems to me that this doesn't really solve the problems that will occur
 when people start making packages independently of eachother.
 
 Of course it can be solved by submitting patches to the other developer's
 code, but it seems inelegant.

I see it as not being much different that what already happens now
in most languages I deal with.

Assume the above lines of code are in different files -- one for A
and one for B.  Presumably A has a reason for saying class B { ... }  
instead of the more likely use B; -- i.e., the author of A knows 
that it is using B, and that B is likely to refer back to A.

And in the above example, I'd expect the file containing the definition
of B to likewise have either a use A; or class A { ... }
declaration.

It ultimately comes down to the fact that Perl expects each module
to declare class names before they get used, unless the class
names are part of CORE.

Pm


Re: One-pass parsing and forward type references

2010-02-01 Thread Larry Wall
On Mon, Feb 01, 2010 at 03:55:15PM -0500, Solomon Foster wrote:
: On Mon, Feb 1, 2010 at 3:46 PM, Patrick R. Michaud pmich...@pobox.com wrote:
:  On Mon, Feb 01, 2010 at 05:55:47PM +0100, Carl Mäsak wrote:
:  Is it allowed to do 'class B { ... }' several times in different files
:  before finally declaring the real B? If so, then I'd consider it
:  equivalent to my proposed keyword, and thus there'd be no need for the
:  latter.
: 
:  Yes.  And declaring the real B doesn't have to be final, nor
:  does it have to occur at all (as long as none of the features needed
:  from B are ever needed).
: 
: And just to finish it off... are you allowed to do 'class B { ... }'
: even after declaring the real B?

STD does not currently allow it because you have to install the name
immediately in case of references in the traits, even before the block.
The block is too late to say whoops, didn't mean it really.  Pretty
much the same reason we changed is also to augment.  We want to
look up the name right now and know whether it should exist without
doing lookahead.

Larry


Re: One-pass parsing and forward type references

2010-02-01 Thread Carl Mäsak
Larry ():
 [Long exposition on the philosophy of predeclaration]

 Hope this helps, or I just wasted a lot of time.  :-)

It did help. Thanks.

A comment on one part, though:

 But I also think that type recursion is likelier to indicate a design
 error than function recursion [...]

I do too. A month or so ago I would have considered type recursion to
always indicate a design error. That was before I started trying to
port type cycles in a program making sensible use of them. :)

As far as I can see, the two cases of type recursion in PGE I outlined
do not indicate a design error. I'd be happy to chat with anyone who
has an idea about how they could be simplified away and replaced by
something non-ugly.

Another thing I started thinking about: if Perl 6 professes to be able
to put on the hat -- syntactically and semantically -- of most any
other programming language out there, through the use of a simple 'use
Language::Java' or 'use Language::Ruby' -- how will Perl 6 compensate
for the fact that its parser is one-pass whereas most other languages
do two passes or more? Specifically, will some programs in those other
languages fail to compile under a Perl 6 language module due to the
fact that a type keyword was referred to before it was declared? If
multiple passes introduce linguistic race conditions, what about
outright linguistic infelicities due to the Perl 6 limitation of
one-pass parsing?

// Carl


Re: One-pass parsing and forward type references

2010-02-01 Thread Larry Wall
On Tue, Feb 02, 2010 at 12:23:50AM +0100, Carl Mäsak wrote:
: Another thing I started thinking about: if Perl 6 professes to be able
: to put on the hat -- syntactically and semantically -- of most any
: other programming language out there, through the use of a simple 'use
: Language::Java' or 'use Language::Ruby' -- how will Perl 6 compensate
: for the fact that its parser is one-pass whereas most other languages
: do two passes or more? Specifically, will some programs in those other
: languages fail to compile under a Perl 6 language module due to the
: fact that a type keyword was referred to before it was declared? If
: multiple passes introduce linguistic race conditions, what about
: outright linguistic infelicities due to the Perl 6 limitation of
: one-pass parsing?

The one-pass ideal is only for standard Perl 6 and other languages
that make that commitment.  Once you switch to another language, you
should use whatever kind of recognizer you need for that language.
Since Perl is Turing complete, it can (in theory) emulate any atomaton
in the right column in the table at the end of:

http://en.wikipedia.org/wiki/Unrestricted_grammar

In short, it's simple only from the standpoint of the *user* of the
module.  Module creators, on the other hand, should be acquainted
with the concept of vicarious suffering before they begin.

Larry


Re: One-pass parsing and forward type references

2010-02-01 Thread Jon Lang
Larry Wall wrote:
 But also note that there are several other ways to predeclare
 types implicitly.  The 'use', 'require', and 'need' declarations
 all introduce a module name that is assumed to be a type name.

Just to clarify: it's possible to define a module within a file,
rather than as a file; and in fact the usual means of defining classes
and roles is an example of this, since they are specialized kinds of
modules.  Correct?  So if I' understanding this correctly, you should
be able to say something like:

use Foo;
class Bar { ... has Foo $x ... }
class Foo { ... }

...where the dots are stand-ins for irrelevant code.  In effect, use
tells the compiler that Foo is a noun, so that the parser knows the
proper way to handle it.  It also looks for the definition of Foo; but
will it start screaming bloody murder if it can't find the definition
right away?  Have I failed to correctly tell it where to look for the
definition?  (i.e., do I need to say something like use ::Foo to let
the parser know that the definition is in this file?)

-- 
Jonathan Dataweaver Lang