Perl6-Pugs

 view release on metacpan or  search on metacpan

ChangeLog  view on Meta::CPAN

* Multi-dispatching now handles parenthesized expressions as arguments
* Named arguments with no matching parameters is now an error
* New `&c.call($capture)` method to call without a caller frame
  (similar to Perl 5's `goto &sub`, but it returns)
* New `&c.signature` method to get a Signature object from a Code object
* Parse for the `proto` routine modifier: `proto method foo ($x) {...}`
* Precompiled `.pm.yml` files with mismatching AST version will no longer load
* Support for user-defined unary and optional-unary prefix macros
* The main package is now ::Main, not ::main
* `&?CALLER_CONTINUATION` is now fully reentrant
* `&yield` in coroutines works correctly within loop blocks
* `sub ($x = 0 is copy)` no longer allowed; say `sub ($x is copy = 0)` instead
* `sub f ($x is lazy) {...}` no longer evaluates $x more than once
* `sub f (@x?) {...}; f()` now sets `@x` to `[]`, not `[undef]` 

=== Classes and Objects

* Attribute-like method call syntax: `@.method(1)`, `$.method: 2, 3, 4`
* Class attributes: `class C { my $.x is rw }`
* Class name literals are now term macros, not prefix functions
* Compile-time self-mixin no longer allowed: `role A does A`

ChangeLog  view on Meta::CPAN

* Significant backend enhancements; see below
* `$?PUGS_BACKEND` can be used to tell which runtime is in use 
* `exec` emulated (partially) on Win32

=== JavaScript backend

* Passes 91% of the main test suite (including TODO failures)
* Integrated with MetaModel 1.0
* Faster code generation, taking advantage of `-CPerl5` output
* Switched to continuation passing style (CPS) to properly support
  `return()`, `&?CALLER_CONTINUATION`, coroutines, and `sleep()`
* Improved support for binding and autodereferentiation
* Initial support for multi subs
* Initial support for symbolic dereferentiation
* List construction no longer creates new containers
* Miscellaneous performance improvements
* Named-only arguments (`+$x` and `++$x`) can't be passed positionally anymore
* Parts of the Prelude can be written in Perl 5 now to improve performance
* Perl 5-like regular expressions mostly working
* Proper UTF-8 handling
* Support for "monkey-but" (`$foo but {...}`)

ChangeLog  view on Meta::CPAN

* Fix one broken test from the `Set` module


= Changes for 6.2.4 (r3790) - May 24, 2005

== Pugs Internals

* All infix operators now receive reduction forms, such as `[+]`
* All operators now receive hyperised forms, such as `>>+<<` and `~<<`
* Dereferencers: `@{...}` and `@$var`
* Experimental support for `coro { ... }`, `coro name { ... }` and `yield()`
* Experimental support for `lazy {...}`
* External Parrot for Rules is now kept in a single process
* Inheritance: `class Foo is Bar` and `class Foo does Bar`
* Interactive shell commands normalised to always begin with `:`
* MMD handling is now more sophisticated, and `$.chained.attr.methods` works
* Much better error messages, with cascading stack trace
* New `./method` syntax implemented
* Objects numify to a unique value accessible with `$obj.id()`
* Parrot compiler backend now handles namespaces and method calls
* Parsing of hierarchical return types: `sub foo returns Hash of Str`

MANIFEST  view on Meta::CPAN

docs/talks/perl6-apw2005/code/class/class1.pl
docs/talks/perl6-apw2005/code/class/class2.pl
docs/talks/perl6-apw2005/code/class/class3.pl
docs/talks/perl6-apw2005/code/class/class4.pl
docs/talks/perl6-apw2005/code/class/class5.pl
docs/talks/perl6-apw2005/code/class/class6.pl
docs/talks/perl6-apw2005/code/class/code1.pl
docs/talks/perl6-apw2005/code/class/code2.pl
docs/talks/perl6-apw2005/code/class/code3.pl
docs/talks/perl6-apw2005/code/class/code4.pl
docs/talks/perl6-apw2005/code/class/coro1.pl
docs/talks/perl6-apw2005/code/op/aufruf1.pl
docs/talks/perl6-apw2005/code/op/bereichs-ops.pl
docs/talks/perl6-apw2005/code/op/bind1.pl
docs/talks/perl6-apw2005/code/op/euler.pl
docs/talks/perl6-apw2005/code/op/hyper1.pl
docs/talks/perl6-apw2005/code/op/junkt1.pl
docs/talks/perl6-apw2005/code/op/kontext-ops.pl
docs/talks/perl6-apw2005/code/op/logik1.pl
docs/talks/perl6-apw2005/code/op/op-arten.pl
docs/talks/perl6-apw2005/code/op/op-arten2.pl

MANIFEST  view on Meta::CPAN

examples/matrix-p5.pl
examples/matrix.pl
examples/naive_bayesian/apples
examples/naive_bayesian/grapes
examples/naive_bayesian/naive_bayesian-p5.pl
examples/naive_bayesian/naive_bayesian.pl
examples/naive_bayesian/oranges
examples/naive_bayesian/README
examples/naive_bayesian/run.pl
examples/naive_bayesian/test
examples/nested_loops/coroutine.pl
examples/nested_loops/functional.pl
examples/nested_loops/iterative.pl
examples/nested_loops/iterative_2.pl
examples/nested_loops/oo.pl
examples/nested_loops/README
examples/nested_loops/recursive.pl
examples/network/bot_irc.pl
examples/network/evalbot/evalbot-loop
examples/network/evalbot/evalbot.pl
examples/network/evalbot/evalhelper-p5.pl

MANIFEST  view on Meta::CPAN

t/syntax/varnames.t
t/TASKS
t/Test-Less/index.txt
t/types/variables.t
t/unspecced/assignment.t
t/unspecced/async-sleep.t
t/unspecced/async.t
t/unspecced/chop.t
t/unspecced/config.t
t/unspecced/cont.t
t/unspecced/coro.t
t/unspecced/cwd.t
t/unspecced/eval_haskell.t
t/unspecced/eval_yaml.t
t/unspecced/evaluation_order.t
t/unspecced/precompile.t
t/unspecced/sort.t
t/unspecced/sub_application.t
t/unspecced/times.t
t/var/assigning_refs.t
t/var/autoderef.t

SIGNATURE  view on Meta::CPAN

SHA1 7d41f4d842c0639723f4c1411a29d30f7ce3c76f docs/talks/perl6-apw2005/code/class/class1.pl
SHA1 0b0762b7c72c9528c6e5f367fd04f6314f6822c3 docs/talks/perl6-apw2005/code/class/class2.pl
SHA1 d00f549b082478ac8e567c6c8bef4827f10739f5 docs/talks/perl6-apw2005/code/class/class3.pl
SHA1 c5c78572b3e2c6b5348383d671663fd42083dc1e docs/talks/perl6-apw2005/code/class/class4.pl
SHA1 a61d1288b817cea80ecc84d908cbbc665f671a4a docs/talks/perl6-apw2005/code/class/class5.pl
SHA1 a42df2b9fc9ab8541e9dffd9891ebca280ccdc2a docs/talks/perl6-apw2005/code/class/class6.pl
SHA1 c2fd56279ca10f278c6782a6a987c3dbb2b1f9ec docs/talks/perl6-apw2005/code/class/code1.pl
SHA1 ff64cb3c5abe3a7ba38e3660991d0eefe18f3f21 docs/talks/perl6-apw2005/code/class/code2.pl
SHA1 75840d594488e3dbfb7921f2c1d6a44edc085766 docs/talks/perl6-apw2005/code/class/code3.pl
SHA1 ee4cbaebec2c6ceb0c6fb8ccda9a2c518589e806 docs/talks/perl6-apw2005/code/class/code4.pl
SHA1 d1ae32a02808fc85809f37241436c8311b7d9b47 docs/talks/perl6-apw2005/code/class/coro1.pl
SHA1 b5a31607405ceea8b6391d19597875c6ccc8e691 docs/talks/perl6-apw2005/code/op/aufruf1.pl
SHA1 fbb568e0fd18b2d6a7a4b428671b3def3b2f3195 docs/talks/perl6-apw2005/code/op/bereichs-ops.pl
SHA1 a16a7e311c09ed179ea16925a691420cb75c8344 docs/talks/perl6-apw2005/code/op/bind1.pl
SHA1 f91b403f124bb7eb4f9b5482cccb5b654e8e0273 docs/talks/perl6-apw2005/code/op/euler.pl
SHA1 b1ceb48f21a47ab90289b1621e4be1968c6dca75 docs/talks/perl6-apw2005/code/op/hyper1.pl
SHA1 fa00eb76aad7868b93828b28fba3057cf44dab22 docs/talks/perl6-apw2005/code/op/junkt1.pl
SHA1 83f41c437f2db0c35d53641dbbc02e6c6efdb30b docs/talks/perl6-apw2005/code/op/kontext-ops.pl
SHA1 e90f1173121e08ae2a4d384b26d5aa9aaad04419 docs/talks/perl6-apw2005/code/op/logik1.pl
SHA1 bd9b139f58ef649956658fedbe14669ae8571e09 docs/talks/perl6-apw2005/code/op/op-arten.pl
SHA1 6e72a79316bc9ad782162ce8a3acc16642485f7e docs/talks/perl6-apw2005/code/op/op-arten2.pl

SIGNATURE  view on Meta::CPAN

SHA1 67532f34f6c301d51976fe5e32c2c07e8115375c examples/matrix.pl
SHA1 d1be97fcc382901efe009055caeeb1d4369142f4 examples/naive_bayesian/README
SHA1 80b13df35aa22120abd9fd791aeb5b7520b73e3c examples/naive_bayesian/apples
SHA1 a8e3f65fd3a79c7d2864d07ea47e8f07d7c27216 examples/naive_bayesian/grapes
SHA1 e487c70ec0490380675ee4d1229ab2ccd78003a7 examples/naive_bayesian/naive_bayesian-p5.pl
SHA1 96d5c964159229c88842d59bfe84f70907e9af10 examples/naive_bayesian/naive_bayesian.pl
SHA1 f121b20ff781cbfcbf0c6fb4b89d9937bb0e6cdf examples/naive_bayesian/oranges
SHA1 8e3b10b353d26880bd0b8609c60a928bc761a285 examples/naive_bayesian/run.pl
SHA1 2d5d58571a2da63ba3176df2f027c567444f3744 examples/naive_bayesian/test
SHA1 86323f7f39d6e7d326b59c6443ec4b7bd4ba53fd examples/nested_loops/README
SHA1 162489d04b494ed4978167357a7ea78bd78f9612 examples/nested_loops/coroutine.pl
SHA1 942a458b6dd1f83a5c0a87047fd0ffba5f69b01b examples/nested_loops/functional.pl
SHA1 5f00a1cb97718d935b81995cd3d0a8aa27e3d280 examples/nested_loops/iterative.pl
SHA1 0b0df1ceca4ff605e19869315ea6f9941b631bd8 examples/nested_loops/iterative_2.pl
SHA1 ad72bf5ca211e39449f65e6010b7deac5bc37c3c examples/nested_loops/oo.pl
SHA1 0e3265fba2582f2530fc0e9f98e4162926c8bf82 examples/nested_loops/recursive.pl
SHA1 e05324cb43b77577a4f8f966dc877ed04562b928 examples/network/README
SHA1 4359459ce8158a81fa93f8122fab4e9a1d72885e examples/network/bot_irc.pl
SHA1 40131a13438508b45231bffedd726284af7f092a examples/network/evalbot/README.pod
SHA1 08c0461ad56f5dd402a4c4af9680709c2480c733 examples/network/evalbot/evalbot-loop
SHA1 5627f36791502b0e56b770978ac0d21de408a05d examples/network/evalbot/evalbot.pl

SIGNATURE  view on Meta::CPAN

SHA1 24fb96de250ab44d63aef54ec53d6e5846fd2998 t/syntax/symbol_table.t
SHA1 ba6ebb0034e606498523a3705ecf87d9fa3ce6ff t/syntax/unicode.t
SHA1 efc8d7290cc20a917d3aaed79f9f77a403f57855 t/syntax/varnames.t
SHA1 5bb1805cbd19247b060a8b7355a328734f737629 t/types/variables.t
SHA1 f1c40e537c335936ebb05610904ab73ba45550ed t/unspecced/assignment.t
SHA1 89c8f9e4479a2c06e1475b9c47785d68ae34af3a t/unspecced/async-sleep.t
SHA1 ca20506090fbf29096d93be451cc3d3504d70eba t/unspecced/async.t
SHA1 bde32f145a2a624cc382ffe194de1a5b9ea00325 t/unspecced/chop.t
SHA1 8fd43a874977098b91a071f024f9831cd53bb0c2 t/unspecced/config.t
SHA1 ba7de1de852f030db0d194566d50bbf545b1484c t/unspecced/cont.t
SHA1 a8d3f23bfe9f8d514638563acb51ff927d717b00 t/unspecced/coro.t
SHA1 f5ce2b541f76353c1e1fb5040b1a6b6ad848a306 t/unspecced/cwd.t
SHA1 fc955448a5652d15942528b926cacbc6492d269d t/unspecced/eval_haskell.t
SHA1 b1bc6787f4ab8dc5f5849822ad5a60f69c3bdf43 t/unspecced/eval_yaml.t
SHA1 d4594631e7bf1b0252a0f386baaa4b4725304416 t/unspecced/evaluation_order.t
SHA1 3ea1554a617201231ed680c4c7e42884393b23ac t/unspecced/precompile.t
SHA1 71fc9906d5bf72c1fd93c94ab8fc54e179a0606c t/unspecced/sort.t
SHA1 466e64f1ec05b0bee77a61c9e39e7881157a7b80 t/unspecced/sub_application.t
SHA1 350b5a15e833ed381b71b8bbeb83c86eb995a737 t/unspecced/times.t
SHA1 ba4636dfb90aad96d7a79037db63d8b5e83a3180 t/var/assigning_refs.t
SHA1 2aef55b09ac310b2011567ff055db86f910726bb t/var/autoderef.t

docs/03Evaluator.pod  view on Meta::CPAN


When all the auxiliary functions have been defined, we can run the body with
the list passed into the for (munging into C<elms> omitted):

    runBody elms $ munge sub

=head2 VCode application

Now that we've seen a nice example of how a subroutine (which might be
masquerading as a simple block) is used, lets see how C<VCode>, the value
representing closures (subroutines, blocks, coroutines, etc) is called.


Subroutine application can be very simple, in the case of a C<Prim>. At other
times it involves entering a lexical scope, due to block open. Sometimes
parameter binding is involved too.

But have no fear, we will soon see that like most parts of pugs, these
things are actually pretty simple.

=cut

docs/Perl6/Spec/Concurrency.pod  view on Meta::CPAN


Unlike in Perl 5's ithreads where you cannot share anything after the fact,
this allows passing shared objects in an C<ad-hoc> fashion across concurrent
parts of the program.  Under the default (multiplexing) concurrency model, this
is basically a no-op.

=head2 Continuations

=head3 Coroutines

## braindump of coro meeting by Liz and Autri, more to follow

- Coros are _like_ processes

coro dbl { yield $_ * 2; yield $_; return };
my @x = 1..10;
my %y = map &dbl, @x;
# 2 => 2, 6 => 4, 10 => 6, ...

coro perm (@x) {
    @x.splice(rand(@x),1).yield while @x;
}

my &p1 := &perm.start(1..10);
my &p2 := &perm.start(1..20);

p1(); p1();
p2(); p2();

coro foo { yield 42 };

(1..10).pick;

coro foo ($x) {
    yield $x;
    yield $x+2;
    cleanup();
    while (2) {
        while (1) {
            &?SUB.kill; # seppuku
        }
    }
} # implicit falloff return + return() means startover without yielding
  # return() means yielding and restart + no implicit falloff (I LIKE THIS)

&foo.finished; # true on return() and false on midway yield()

foo(4); # and that's all she wrote

coro foo ($x) {
    yield $x;
    # this point with $x bound to 10
    yield $x+1;
    return 5;
    ... # this is never reached, I think we all agree
}

# If you don't want your variables to get rebound, use "is copy":
coro foo ($x is copy) {...}
# which is sugar for
coro foo ($x) {
  {
    my $x := $OUTER::x;
    ...;
    # Further calls of &foo rebound $OUTER::x, not $x.
  }
}

sub foo {
    return undef if rand;
    ...

docs/Perl6/Spec/Concurrency.pod  view on Meta::CPAN

%*ENV(123);

&foo_continued := &foo.start(10);
&foo.start(20);

foo(10);    # returns 10

foo();      # be "insufficient param" error or just return 11?
foo(20);    # returns 21

# continuation coros
multi foo () { ...no rebinding... }
multi foo ($x) { ...rebinding... }

&foo.kill;


my $first_ret = zoro( type => <even> );
&zoro.variant(:type<even>).kill;
&zoro.variant(type => 'even').kill;

zoro( type => <odd> );

zoro( even => 1 );
zoro( odd => 1 );

multi coro zoro ($type where 'even') {}
multi coro zoro ($type where 'odd') {}

multi coro zoro ($even is named) {}
multi coro zoro ($odd is named) {}


# iblech's thoughts:
# Coroutine parameters should never be rebound. Instead, yield(...)s return
# value is an Arglist object containing the new arguments:
coro bar ($a, $b) {
    ...;
    my $new_set_of_args = yield(...);
    my $sum_of_old_a_and_new_a = $a + $new_set_of_args<$a>;
    ...;
}
bar(42, 23);  # $a is 42, $b is 23
bar(17, 19);  # $a still 42, $b still 19,
              # $new_set_of_args is \(a => 17, b => 19)

=head2 Junctive Autothreading and Hyper Operations

docs/summaries/2006/05-31.yaml  view on Meta::CPAN

        message_id: 7b0e52b40605291354k211929aav1e44030e76a80f7a@mail.gmail.com
        posters:
          - email: parrotcode@gmail.com
            name: Klaas-Jan Stol
          - email: liz@dijkmat.nl
            name: Elizabeth Mattijsen
          - email: lt@toetsch.at
            name: Leopold Toetsch
        subject: Coroutine reset functionality?
        summary: |-
          Klaas-Jan Stol proposed functionality to reset a coroutine.  
          Elizabeth Mattijsen and Leopold Toetsch felt it would be useful.
          
          Later, in thread <msgid:447CA3BF.7000106@gmail.com>,
          Klaas-Jan Stol wrote that if a coroutine is called more times than 
          it `.yield()`s, there is a segmentation fault.
          Leopold Toetsch replied that this was indeed closely linked to
          `.reset()`.
      - date_from: 1148999735
        date_to: 1148999735
        hidden: 1
        message_id: 20060530143432.57A7ACBA47@x12.develooper.com
        posters:
          - email: coke@cvs.perl.org
        subject: '[svn:parrot-pdd] r12839 - in trunk/docs: . imcc pdds pdds/clip pmc req'

docs/summaries/2006/05-31.yaml  view on Meta::CPAN

        summary: ~
      - date_from: 1149019087
        date_to: 1149022765
        hidden: 1
        message_id: 447CA3BF.7000106@gmail.com
        posters:
          - email: parrotcode@gmail.com
            name: Klaas-Jan Stol
          - email: lt@toetsch.at
            name: Leopold Toetsch
        subject: coroutine segfaults
        summary: ~
      - date_from: 1149019594
        date_to: 1149019594
        hidden: ~
        message_id: rt-3.0.11-39249-134142.7.66945534394161@perl.org
        posters:
          - email: parrotbug-followup@parrotcode.org
            name: Will Coleda
        rt_ticket: 'perl #39249'
        subject: "[perl #39249] Can't use literal unicode string as a hash key."

docs/summaries/2006/10-07.yaml  view on Meta::CPAN

          - 5.1.0.14.2.20061004084513.0287d900@pop.besancon.parkeon.com
        posters:
          - email: rogers-perl6@rgrjr.dyndns.org
            name: Bob Rogers
          - email: francois.perrad@gadz.org
            name: François PERRAD
        subject: 'Heads up:  Dynamic environment now captured in continuations'
        summary: |-
          Bob Rogers announced that as of r14830, continuations capture the
          dynamic environment in order to restore it properly on invocation.
          He also noted that moving the `control_stack` slot broke coroutines,
          but that he suspected this was due to problems with coroutines.  He
          asked to know if any problems with coroutines developed.  François Perrad
          replied that he'd been unable to implement coroutines in Lua.
          Bob Rogers was not surprised, and discussed some of the problems involved.
      - date_from: 1159837611
        date_to: 1159837611
        hidden: formatting commit
        message_id: 20061003010641.6F584CBA4E@x12.develooper.com
        posters:
          - email: chromatic@cvs.perl.org
            name: chromatic
        subject: '[svn:parrot-pdd] r14831 - in trunk: . docs/pdds/clip'
        summary: ''

docs/summaries/2006/10-14.yaml  view on Meta::CPAN

            name: Bob Rogers
          - email: francois.perrad@gadz.org
            name: François PERRAD
          - email: lt@toetsch.at
            name: Leopold Toetsch
        subject: 'Heads up:  Dynamic environment now captured in continuations'
        summary: |-
          Earlier,
          Bob Rogers announced that as of r14830, continuations capture the
          dynamic environment in order to restore it properly on invocation.
          He also noted that moving the `control_stack` slot broke coroutines,
          but that he suspected this was due to problems with coroutines.  This
          led to a discussion on the problems of coroutines in Lua.
          
          This week, Bob and François Perrad continued the discussion.
          François noted two specific problems with Lua, and posted the error message. 
          Bob suggested a workaround, and noted that he has used this in
          Parrot.  He supplied the Parrot::Coroutine patch. 
          
          Bob also reported that he had moved the `control_stack` slot in r14876.
          He noted that there could still be problems with coroutines, and he is
          considering deprecating `Coroutine.pmc` until it can be redesigned.
          Leopold Toetsch replied that he would like to see some specifications
          first.  Bob explained how it would be used, and Leopold replied that he
          now saw the use for it, but still would like to see a proposal.
      - date_from: 1159908092
        date_to: 1160662024
        hidden: discussion on what's wrong
        message_id: 4522CADF.7020506@ajs.com
        messages:
          - 17698.54984.678960.91503@localhost.localdomain

docs/talks/Apocalypse_Now.spork  view on Meta::CPAN

    #!/usr/bin/perl
    use pugs;   # Here is some Perl 6 code...
    sub postfix:<!> { [*] 1..$_ }
    sub sum_factorial { [+] 0..$_! }

+    no pugs;    # Here is some Perl 5 code...
    print sum_factorial(3); # 21

+* Implemented with Inline::Pugs and source filter
+* Keeps the Pugs process and shuffle `eval` commands around
+** Extremely fragile; only parses `/^(sub|coro)/`
+** We'd like to fix that so it works reliably
+** More on that in the second half of this talk

----
== Getting started

{image: http://perlcabal.org/~autrijus/images/justdoit.jpg}

* Download Pugs:

docs/talks/hw2005.tex  view on Meta::CPAN

into equivalent Perl code.  In that case, it is a simple matter of applying a
source filter, or of \code{eval}ing the translated code in its own namespace.

\item Native call:  Statically compiled languages (such as C, C++ and assembly)
are compiled into dynamically loaded shared libraries.  Inline.pm automatically
generates wrappers to call foreign functions; it also exports Perl's runtime
API so the embedded language can call functions defined in Perl.

\item Runtime harness:  For languages with a rich runtime (e.g. Java and Python),
Inline.pm will run them alongside Perl's own runtime, sharing the execution
context in a coroutine-like fashion.  Types and global bindings are encoded
both ways; the Perl program can invoke a foreign object's methods, and vice
versa.
\end{enumerate}

In addition to these strategies, Perl 6 is also designed to run on a shared
high-level virtual machine, such as the Java VM or .Net CLR.  As part of the
Perl 6 project, the Parrot VM is the reference implementation for a
cross-language runtime to support Perl 6 and other dynamic languages.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 

docs/talks/hw2005.tex  view on Meta::CPAN

        { envLexical :: !Pad
        , envGlobal  :: !(TVar Pad)
        , -- ...more fields...
        }
\end{lstlisting}

As such, sub-terms can override global bindings by writing to the shared
\code{TVar} storage, but new lexical bindings will never leak out.

We implement control flow with the \code{ContT} monad transformer, because it
can directly support Perl 6's continuation and coroutine constructs.  We
represent the dynamic scope with \code{resetT}/\code{shiftT}: calling a
subroutine will push a new prompt via \code{resetT}, so we can simply express
the \code{return} primitive as:

\begin{lstlisting}
    doReturn :: Val -> Eval a
    doReturn = shiftT . const . return
\end{lstlisting}

Finally, we layer a new transformer EvalT on top of \code{ContT}, so we can

docs/talks/hw2005.tex  view on Meta::CPAN

compiled to run on Parrot can continue to take advantage of STM.

% 5.3.
\subsection{Reified Continuations}
\label{sec:ReifiedContinuations}

In the previous subsection, we saw how Pugs uses \code{runEvalIO} and
\code{runEvalSTM} to resume execution from the IO and STM monad.
Unfortunately, although both can restore the evaluation environment,
they invalidate previously captured continuations by starting a new
\code{runContT}, rendering coroutines unusable across an \code{async} boundary:

\begin{lstlisting}
    coro foo () { yield 1; yield 2 }
    async { say foo() }     # fails to resume "foo"
\end{lstlisting}

To solve this problem, we need to represent the continuation context as data
structure.  Here we make use of the \code{CC\_2CPST} monad from Oleg Kiselyov
et al, based on previous work by Dybvig et al~\cite{Dybvig}.

We further use Kiselyov's \code{ZipperD} design to represent the evaluation as
a traversal on the \code{Exp} type, keeping the position as a
\code{[Direction]} type.  This allows us to re-express the reduction logic as a

docs/talks/hw2005.tex  view on Meta::CPAN


Because the new Eval monad will update the cursor at each reduction step, we can
define a pair of serialize/deserialize functions:

\begin{lstlisting}
    data EvalD = MkEvalD Exp Env [Direction]
    reifyEval  :: Eval Val -> EvalD
    runEval    :: EvalD -> Eval Val
\end{lstlisting}

This \emph{suspend to memory} capability is sufficient to make coroutines work across
\code{async\{\}} calls.  In the future, we may also implement a \emph{suspend
to disk} feature, by snapshotting the values of all \code{TVar}s in the
\code{Env} structure into a byte-string image:

\begin{lstlisting}
    showEvalD  :: EvalD -> STM String
    readEvalD  :: String -> STM EvalD
\end{lstlisting}

This has many interesting applications, including web continuations, omniscient

docs/talks/perl6-apw2005/code/alles.kateproject  view on Meta::CPAN

[Dir class]
Dirs=
Files=class1.pl/class2.pl/class3.pl/class4.pl/code1.pl/code2.pl/code3.pl/code4.pl/class5.pl/coro1.pl/class6.pl

[Dir op]
Dirs=
Files=bereichs-ops.pl/euler.pl/kontext-ops.pl/op-arten.pl/op-arten2.pl/op-arten3.pl/typen-konvertierung.pl/wiederholungs-ops.pl/wurf1.pl/zuweisung.pl/aufruf1.pl/bind1.pl/smart1.pl/vergl1.pl/smart2.pl/hyper1.pl/logik1.pl/reduce1.pl/wurf2.pl/wurf3.pl/j...

[Dir syn]
Dirs=
Files=hallo1.pl/hallo2.pl/otto1.pl/otto2.pl/otto3.pl/summe1.pl/summe2.pl/waehrung1.pl/waehrung2.pl/kommentare.pl/summe3.pl/vars1.pl/vars2.pl/vars3.pl/interp1.pl/interp2.pl/interp3.pl/interp4.pl/state1.pl/state2.pl/temp1.pl/temp2.pl/class.pl/let1.pl/f...

[Project Dir]

docs/talks/perl6-apw2005/code/class/coro1.pl  view on Meta::CPAN

#=Coroutinen
use v6;
coro zähler {
	for 1..10 -> $i {
		yield $i;
	}
}

my $i;
while $i = zähler() != 0 {
	say $i;
}

docs/talks/perl6-apw2005/objekte.tex  view on Meta::CPAN

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}
	\frametitle{NEXT/LAST Blöcke}
	\input{code/class/code4.pl.tex}
\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}
	\frametitle{Coroutines}
	\input{code/class/coro1.pl.tex}
\end{frame}


% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Filehandle-Objekte}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{frame}
% 	\frametitle{Filehandle-Objekte}
% 
% 	Ein filehandle ist ein ganz normales Objekt.

examples/nested_loops/coroutine.pl  view on Meta::CPAN

        if $only_when {
            return &?ROUTINE() unless $only_when($next);
        }

        $code($next) if $code;
        return $next;
    }
}

sub NL2 (:@loop!) {
    coro {
        given (@loop.elems) {
            when 0  { yield [] }
            when 1  { for @loop[0] { yield [$^first] } yield undef while 1 }
            default {
                for @loop[0] -> $first {
                    my &rest = NL2(loop => @loop[1..Inf]);
                    my @rest;
                    while @rest = rest() {
                       yield [$first, @rest];
                    }

examples/qotw/009r/words.spel  view on Meta::CPAN

cornet
cornfield
cornflower
Cornish
cornish
cornmeal
cornstarch
cornucopia
Cornwall
corny
corollary
corona
Coronado
coronary
coronate
coroner
coronet
coroutine
Corp
corpora
corporal
corporate
corporeal
corps
corpse
corpsman
corpsmen
corpulent

examples/qotw/009r/words.spel  view on Meta::CPAN

decomposition
decompress
decompression
decontrol
decontrolled
decontrolling
deconvolution
deconvolve
decor
decorate
decorous
decorticate
decorum
decouple
decoy
decrease
decree
decreeing
decrement
decry
decrypt

examples/qotw/009r/words.spel  view on Meta::CPAN

ramp
rampage
rampant
rampart
ramrod
Ramsey
ran
ranch
rancho
rancid
rancorous
Rand
Randall
Randolph
random
randy
rang
range
rangeland
Rangoon
rangy

ext/Parse-Rule/Architecture.pod  view on Meta::CPAN

implementor, because as I convert to the new architecture, I'm having
trouble navigating and understanding what I still need to do.  But it
will probably serve as a useful guide to the hacker/extender.

Here are the goals:

=over

=item * Not to commit to a particular evaluation strategy.  

PGE uses coroutines, and my version uses continuation passing style.  We
don't know which will be better or faster yet.  We'd also like to
eventually support local DFA optimization.  Being noncommital is the
best choice.

=item * Not to commit to particular media.

In Perl 6, rules can match against strings and they can match against
arrays.  That's only two, and we could support each explicitly.  But
what about matching against parameter lists, against trees and data
structures?  Those are possibilities that we would like to give the

ext/Perl6-Container-Array/lib/Perl6/Container/Array.pm  view on Meta::CPAN

* Lazy::CoroList is gone
* Lazy list methods (grep, map, ...) moved from Array::Lazy to 
  Lazy::List. These methods can be accessed from an array
  by doing a 'splat()' first. 
  Array::Lazy::reverse() is still supported.

2005-08-07
* Lazy Range supports 'a'..Inf
* New lazy array methods: splat(), elems(), uniq(), end(), 
  next(), previous(), kv(), keys(), values(), zip()
* Code rewritten to use coroutines instead of states
* New class Lazy::CoroList - takes a coroutine (or two, 
  for shift and pop support) and creates a Lazy List, that
  can be used to create a Lazy Array.
* Removed internal class Lazy::Generator

2005-08-06
* new lazy methods reverse(), grep(), map()
* Array::Lazy supports multi-dimensional Lazy Array
* new class 'Lazy::List'
* lazy List / Array of junctions is tested
* removed 'Iter' class; renamed 'Iter::Range' to 'Lazy::Range'

ext/Perl6-Container-Array/t/array-operations.t  view on Meta::CPAN

  flunk "infinite loop";
# is( $a1.shift, 2, 'seen element was skipped' );

  # end
  $a1 = Perl6::Container::Array.from_list( $a1 );
  is( $a1.end, 9, 'end' );
  is( $a1.pop, 9, 'end is still there' );
}

{
  # coroutine
  
  my coro mylist { yield $_ for 1..2; yield; }
  
  my $iter = Perl6::Value::List.new( cstart => &mylist ); 
  my $a1 = Perl6::Container::Array.from_list( $iter );
  is( $a1.shift, 1, 'lazy array from coroutine' );
  is( $a1.shift, 2, 'coroutine' );
  is( $a1.shift, undef, 'coroutine end' );
  is( $a1.shift, undef, 'coroutine really ended' );
}

{
  # kv
  
  my coro mylist { yield $_ for 4..5; yield; }
  
  my $iter = Perl6::Value::List.new( cstart => &mylist ); 
  my $a1 = Perl6::Container::Array.from_list( $iter );
  $a1 = $a1.to_list.Perl6::Value::List::kv;
  is( $a1.shift, 0, 'kv' );
  is( $a1.shift, 4, 'kv' );

  flunk("erratic behaviour, disable for now");
  flunk("erratic behaviour, disable for now");
# is( $a1.shift, 1, 'kv' );
# is( $a1.shift, 5, 'kv' );
}

{
  # pairs
  
  my coro mylist { yield $_ for 4..5; yield; }
  
  my $iter = Perl6::Value::List.new( cstart => &mylist ); 
  my $a1 = Perl6::Container::Array.from_list( $iter );
  $a1 = $a1.to_list.Perl6::Value::List::pairs;
  my $p = $a1.shift;
  is( ~($p.WHAT),  'Pair',     'pair' );
  is( $p.perl, '(0 => 4)', 'pair' );
}

{
  # zip
  
  my coro mylist1 { yield $_ for 4..5; yield; }
  my $iter1 = Perl6::Value::List.new( cstart => &mylist1 ); 
  my $a1 =    Perl6::Container::Array.from_list( $iter1 );
  
  my coro mylist2 { yield $_ for 1..3; yield; }
  my $iter2 = Perl6::Value::List.new( cstart => &mylist2 ); 
  my $a2 =    Perl6::Container::Array.from_list( $iter2 );
  
  $a1 = $a1.to_list.Perl6::Value::List::zip( $a2 );
  is( try { $a1.shift }, 4, 'zip' );
  is( try { $a1.shift }, 1, 'zip' );
  is( try { $a1.shift }, 5, 'zip' );
  is( try { $a1.shift }, 2, 'zip' );
  is( try { $a1.shift }, undef, 'zip' );
  is( try { $a1.shift }, 3, 'zip' );

ext/Perl6-Value-List/lib/Perl6/Value/List.pm  view on Meta::CPAN

use v6-alpha;

# Perl6::Value::List - implementation of Perl6 'List' class in Perl6

=begin ChangeLog

2005-08-10
* New methods List.flatten(), is_lazy(), from_coro( $sub )
* Factored Perl6::Value::List out of the Array package

=cut

# TODO - sync with Perl5 version:
# * Separate from_num_range() and from_range() constructors. 
#   - from_num_range() is a numeric range. It accepts a 'step' value.
#   - from_range() is a generic range for strings, etc. It accepts a 'celems' closure.
#   Both constructors are just new() wrappers.
# * grep(), map() don't depend on coroutines
# * Removed pair() - this module does not have access to the Pair constructor
#
# TODO - is_contiguous() should test if $step == 1
# TODO - test flatten(), is_lazy(), error messages
# TODO - emit error message if attempting to flatten() an infinite list 
# TODO - does zip() has additional parameters?
# TODO - document unsupported operations: join, reduce, sort - call fail()
# TODO - check grep() syntax
# TODO - provide a better default stringify - see Span.pm
# TODO - fix elems() in from_range(), when start/end are Str - 'a'..'z'
#      - add tests
# TODO - rewrite ops using closures (instead of coro)
# TODO - reuse map() to write ops

# Things that will be solved by the compiler:
# - keys/kv/pairs/values with indexes (S29) --> array slice
# - lists of junctions --> junctions of lists
# - list concatenation --> array concatenation

# ---------

class Perl6::Value::List {

ext/Perl6-Value-List/lib/Perl6/Value/List.pm  view on Meta::CPAN

        );
    }

    method from_single ( $class: *@list is copy ) {
        $class.new( cstart => sub{ @list.shift },
                    cend =>   sub{ @list.pop },
                    celems => sub{ +@list },
                    is_lazy => Bool::False );
    }

    method from_coro ( $class: $start ) {
        my $size = Inf;
        $class.new(
                    cstart =>  sub {
                                my $r = &($start)();
                                $size = 0 unless defined $r;
                                return $r;
                            },
                    cend =>    sub {},
                    celems =>  sub { $size },
                    cis_infinite => sub { $size == Inf },

ext/Perl6-Value-List/lib/Perl6/Value/List.pm  view on Meta::CPAN

                celems =>         $ret.celems,
                cis_infinite =>   $ret.cis_infinite,
                cis_contiguous => $ret.cis_contiguous,
                cstringify =>     $ret.cstringify,
        );
    }

    method grep ( $array: Code $code ) { 
        my $ret = $array; 
        Perl6::Value::List.new(
                cstart => coro {
                        my $x = $ret.shift // yield;
                        yield $x if &$code($x);
                        return;
                },
                cend => coro { 
                        my $x = $ret.pop // yield;
                        yield $x if &$code($x);
                        return;
                },
                # TODO - signal end of data using 'elems()'
        );
    }

    method map ( $array: Code $code ) { 
        my $ret = $array; 
        Perl6::Value::List.new(
                cstart => coro {
                        my @ret;
                        my $x = $ret.shift // yield;
                        &*unshift(@ret: &$code($x)); 
                        yield @ret.shift while @ret;
                        return;
                },
                cend => coro {
                        my @ret; 
                        my $x = $ret.pop // yield;
                        &*push(@ret, &$code($x));
                        yield @ret.pop while @ret;
                        return;
                },
                # TODO - signal end of data using 'elems()'
        )
    }

    method uniq ( $array: ) { 
        my %seen = ();
        my $ret = $array; 
        Perl6::Value::List.new(
                cstart => coro {
                        my $x = $ret.shift // yield;
                        unless %seen{$x} { 
                            %seen{$x} = Bool::True; 
                            yield $x;
                        }                       
                        return;
                },
                cend => coro {
                        my $x = $ret.pop // yield;
                        unless %seen{$x} { 
                            %seen{$x} = Bool::True; 
                            yield $x;
                        }
                        return;
                },
                # TODO - signal end of data using 'elems()'
        )
    }

    method kv ( $array: ) { 
        my $ret = $array; 
        my $count = 0;
        Perl6::Value::List.new(
                cstart => coro {
                        my $x = $ret.shift // yield;
                        yield $count++;
                        yield $x;
                        return;
                },
                celems => sub { $ret.elems + $ret.elems },
        )
    }

    method pairs ( $array: ) { 
        my $ret = $array; 
        my $count = 0;
        Perl6::Value::List.new(
                cstart => coro {
                        my $x = $ret.shift // yield;
                        my $pair = $count => $x;
                        yield $pair;
                        $count++;
                },
                celems => sub { $ret.elems },
        )
    }

    method keys ( $array: ) { 
        my $ret = $array; 
        my $count = 0;
        Perl6::Value::List.new(
                cstart => coro {
                        my $x = $ret.shift // yield;
                        yield $count++; 
                },
                celems => sub { $ret.elems },
        )
    }

    method values ( $array: ) { 
        $array
    }

    method zip ( $array: Array @list ) { 
        # TODO: implement zip parameters
        # TODO: implement count = max( @lists.elems )
        my @lists = ( $array, @list );
        Perl6::Value::List.new(
                cstart => coro {
                        my @x;
                        my $count = 0;
                        # TODO - rewrite this checking 'elems()'
                        # XXX - the list would normally stop after the first 'undef'
                        for @lists -> $xx {
                            &*push(@x, [$xx.shift]);
                        }
                        if defined any(@x) {
                            for @lists -> $xx {
                                yield &*shift(@x);

ext/Perl6-Value-List/lib/Perl6/Value/List.pm  view on Meta::CPAN

=kwid

= NAME

Perl6::Value::List - implementation of Perl6 'List' class in Perl6

= SYNOPSIS

  my $list = Perl6::Value::List.from_range( start => 10, end => 20 );

  my $list = Perl6::Value::List.new( start => coro mylist2 { yield $_ for 1..3; yield; } );

= DESCRIPTION

A lazy list created from coroutines or subs.

= CONSTRUCTORS

- `new( ... )`

= METHODS

- `shift`

- `pop`

ext/Perl6-Value-List/t/array-operations.t  view on Meta::CPAN

  my $mapped = $grepped.map:{ $_ % 6 == 0 ?? ($_, $_) !! () };
  is( $mapped.shift,  6, 'map 0' );
  is( try{ $mapped.shift },  6, 'map 1' );
  is( try{ $mapped.shift }, 12, 'map 0' );
  is( try{ $mapped.shift }, 12, 'map 1' );

  is( try{ $mapped.shift }, undef, 'end' );
}

{
  # coroutine
  
  my coro mylist { yield $_ for 1..2; yield; }
  
  my $a1 = Perl6::Value::List.from_coro( &mylist ); 
  is( $a1.shift, 1, 'lazy array from coroutine' );
  is( $a1.shift, 2, 'coroutine' );
  is( $a1.shift, undef, 'coroutine end' );
  is( $a1.shift, undef, 'coroutine really ended' );
}

{
  # kv
  
  my coro mylist { yield $_ for 4..5; yield; }
  
  my $a1 = Perl6::Value::List.new( cstart => &mylist ); 
  $a1 = $a1.kv;
  is( $a1.shift, 0, 'kv' );
  is( $a1.shift, 4, 'kv' );
  is( $a1.shift, 1, 'kv' );
  is( $a1.shift, 5, 'kv' );
}

{
  # pairs
  
  my coro mylist { yield $_ for 4..5; yield; }
  
  my $a1 = Perl6::Value::List.new( cstart => &mylist ); 
  $a1 = $a1.pairs;
  my $p = $a1.shift;
  is( ~($p.WHAT),  'Pair',     'pair' );
  is( $p.perl, '(0 => 4)', 'pair' );
}

{
  # zip
  
  my $a1 = Perl6::Value::List.from_range( start => 4, end => 5 ); 
  
  my coro mylist2 { yield $_ for 1..3; yield; }
  my $a2 = Perl6::Value::List.new( cstart => &mylist2 ); 
  
  $a1 = $a1.Perl6::Value::List::zip( $a2 );
  is( try {$a1.shift}, 4, 'zip' );
  is( try {$a1.shift}, 1, 'zip' );
  is( try {$a1.shift}, 5, 'zip' );
  is( try {$a1.shift}, 2, 'zip' );
  is( try {$a1.shift}, undef, 'zip' );
  is( try {$a1.shift}, 3, 'zip' );
  is( try {$a1.shift}, undef, 'zip' );

ext/Set-Infinite/lib/Set/Infinite.pm  view on Meta::CPAN

method closest ($self: $x ) {
    my $n = $self.next( $x );
    my $p = $self.current( $x );
    return $n - $x < $x - $p ?? $n !! $p;
}

method iterator ($self: ) returns Set::Infinite::Iterator {
    return ::Set::Infinite::Iterator.new( set => $.set );
}

coro lazy ($self: ) {
    my $iter = $self.iterator();
    loop { 
        my $n = $iter.next;
        return unless defined $n;
        yield $n;
    }
}

} # class Set::Infinite

ext/Span/lib/Span.pm  view on Meta::CPAN


method iterator ($self: ) returns Span::Iterator {
    if ( ! defined( $.span.density ) &&
         ! $.span.isa( 'Span::Code' ) )
    {
        warn "creating an iterator for a continuous Span";
    }
    return ::Span::Iterator.new( span => $.span );
}

coro lazy ($self: ) {
    my $iter = $self.iterator();
    loop { 
        my $n = $iter.next;
        return unless defined $n;
        yield $n;
    }
}

} # class Span

ext/Span/t/span.t  view on Meta::CPAN

    my $i;
    # say $i while $i = $iter.previous;
    is( $i = $iter.previous, 2, 'iterator previous 0' );
    is( $i = $iter.previous, 1, 'iterator previous 1' );
    is( $i = $iter.previous, undef, 'iterator previous 2' );
    }

    {
    my $iter = $span.iterator;
    my $i;
    my $x = coro { 
                loop { 
                    my $n = $iter.next;
                    return unless defined $n;
                    yield $n
                 }
            };
    is( $i = $x(), 1, 'coro 0' );
    is( $i = $x(), 2, 'coro 1' );
    is( $i = $x(), undef, 'coro 2' );
    }

    {
        my $i;
        my $a;
        while $a = $span.lazy {
            is( $a, ++$i, "lazy $i" );
        }
    }

ext/Tree/lib/Tree.pm  view on Meta::CPAN

}

method post_order_traverse ($self: Code $func) returns Void {
    for @!children -> $child is rw {
        $child.traverse($func);
        $func($child);
    }
}

method traverse_iter($self: Str $traversal_order?) returns Code {
    return coro {
        $self.traverse(sub { yield $^node }, $traversal_order);
    };
}

## ----------------------------------------------------------------------------
## utility methods

# NOTE:
# Occasionally one wants to have the 
# depth available for various reasons

ext/Tree/t/basic.t  view on Meta::CPAN

};

is($output, 
' my other tree
 my tree 3
-- tree 1.1
 my tree 4
', '... got the right output (iterator)');
};

flunk "iterator/coroutine test", :todo<feature> if $!;

lib/Inline/Pugs.pm  view on Meta::CPAN

    my $self = shift;
    my $code = $self->{API}{code};
    my $pkg  = $self->{API}{pkg} || 'main';
    my $pid  = $self->{pid} ||= $self->init_pugs;
    $self->eval_pugs($code);

    # now try to figure out what functions are toplevel...
    # XXX - bloody hack for now

    no strict 'refs';
    foreach my $sym ($code =~ /^\s*(?:sub|coro)\s+(\w+)\s+/mg) {
        *{"$pkg\::$sym"} = sub {
            local $Data::Dumper::Terse = 1;
            my @args = map { $self->quote_pugs(Dumper($_)).'.eval' } @_;
            $self->eval_pugs(
                "$sym(".join(',', @args).")"
            );
        }
    }
}

misc/old_pugs_perl5_backend/Perl6-Container/t/array-operations.t  view on Meta::CPAN

  is( $a1->shift, 0, 'not seen element' );
  is( $a1->shift, 2, 'seen element was skipped' );

  # end
  $a1 = Perl6::Container::Array->from_list( $a1 );
  is( $a1->end, 9, 'end' );
  is( $a1->pop, 9, 'end is still there' );
}

{
  # (test originally written to test coroutines)

  my $iter = Perl6::Value::List->from_num_range( start => 1, end => 2, step => 1 );
  my $a1 = Perl6::Container::Array->from_list( $iter );
  is( $a1->shift, 1, 'lazy array from subroutine' );
  is( $a1->shift, 2, 'subroutine' );
  is( $a1->shift, undef, 'subroutine end' );
  is( $a1->shift, undef, 'subroutine really ended' );
}

{

misc/old_pugs_perl5_backend/Perl6-Value/lib/Perl6/Value/List.pm  view on Meta::CPAN

#
# 2005-08-12
# * fixed map()->pop()
#
# 2005-08-11
# * Fixed string comparison to Inf portability (Windows x Linux)
# * Separate from_num_range() and from_range() constructors. 
#   - from_num_range() is a numeric range. It accepts a 'step' value.
#   - from_range() is a generic range for strings, etc. It accepts a 'celems' closure.
#   Both constructors are just new() wrappers.
# * grep(), map() don't depend on coroutines
# * Removed pair() - this module does not have access to the Pair constructor
#
# 2005-08-10
# * Removed method concat_list(), added "TODO" methods

# TODO - finish sum() - not all operations support sum() yet; 
#      - object numification is not supported yet

# TODO - finish support for unshift, push 

misc/old_pugs_perl5_backend/Perl6-Value/lib/Perl6/Value/List.pm  view on Meta::CPAN

        clone =>   sub { $class->from_single( @list ) },
        start =>   sub { $list[0]  },
        end =>     sub { $list[-1] },
        cstart =>  sub { shift  @list },
        cend =>    sub { pop    @list },
        celems =>  sub { scalar @list },
        is_lazy => 0,
     );
}

sub from_coro {
    my $class = shift;
    my $start = shift;
    my $size =  &Inf;
    $class->new(
        clone => sub { 
            warn "from_coro->clone() not implemented";
            $class->from_coro( $start ) 
        },
        cstart =>  sub {
            my $r = $start->();
            # print "coro\n";
            $size = 0 unless defined $r;
            return $r;
        },
        cend =>           sub {},
        celems =>         sub { $size },
        cis_infinite =>   sub { $size == Inf },
        cis_contiguous => sub { 0 },
    );
}

misc/old_pugs_perl5_backend/Perl6-Value/t/list-operations.t  view on Meta::CPAN


  is( $mapped->shift, undef, 'end' );
}

{
  # subroutine
 
  my @a = ( 1, 2 ); 
  sub mylist { shift @a }
  
  my $a1 = Perl6::Value::List->from_coro( \&mylist ); 
  is( $a1->shift, 1, 'lazy array from subroutine' );
  is( $a1->shift, 2, 'subroutine end' );
  # is( $a1->shift, undef, 'subroutine really ended' );
}

{
  # elems
  my $iter = Perl6::Value::List->from_num_range( start => 1, end => 1000000, step => 2 );
  is( $iter->elems, 500000, 'Lazy List elems' );

  # is( $iter->kv->elems, 1000000, 'Lazy List elems doubles after kv()' );
}

{
  # uniq
 
  my @a = ( 1, 2, 2, 3 ); 
  sub mylist0 { shift @a; } # my $x = shift @a;print " --> shifting $x\n";  $x }
  
  my $a1 = Perl6::Value::List->from_coro( \&mylist0 )->uniq; 
  is( $a1->shift, 1, 'uniq' );
  is( $a1->shift, 2, 'uniq' );
  is( $a1->shift, 3, 'uniq' );
  # is( $a1->shift, undef, 'subroutine really ended' );
}

{
  # kv
  
#  my @a = ( 4, 5 ); 

misc/pX/Common/lrep/Tasks  view on Meta::CPAN

  - default parser for macros
  - short operator names infix:<+> === +
- use putter's Match.pm
- bind special variables $0, ...
- see also the 'not implemented' rule list below
- optimize infix:<+> to 'native +' when possible
- mixing boxed/unboxed types (there are several tools available - which one to use?)
- Perl 6 OO - which tools to use? - talk to stevan
- un-source-filter rule return blocks
- un-source-filter macro variable binding
- coroutines

Other interesting things to do (low priority):
- reimplement iterator_engine.pl in 
  - Javascript - I like the 'run in the browser' idea very much
  - Perl 6 - Perl 6 version could be started with a source filter, since the syntax used is very simple
  - Parrot - not so useful - Parrot already has PGE
- test the compiler in Perl 5.5x
- try out Smart::Comments
- move project to a new subdir and give it a name?
- Extract 'Changes' and 'TODO' from README (extract old Changes from svn)



( run in 0.476 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )