----
presentation_topic: Apocalypse Now
presentation_title: Perl 6 is Here Today
presentation_place: http://autrijus.org/apoc/start.html
presentation_date: June 27th, 2005
----
{image: http://perlcabal.org/~autrijus/today.jpg}

Apocalypse Now

Autrijus Tang

/pugscode.org/

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

    A ship then new they built for him
    of mithril and of elven glass.

                    -- Perl 5.0, perl.c

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

    A ship then new they built for him
    Of mithril and of elven-glass
    With shining prow; no shaven oar
    Nor sail she bore on silver mast;
    The Silmaril as lantern light
    And banner bright with living flame
    To gleam thereon by Elbereth
    Herself was set, who thither came...

                    -- Pugs 6.2.6, Main.hs

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

    Sie bauten ihm ein neues Schiff
    Aus Mithril und aus Elbenglas
    Mit stolzem Bug, doch ruderlos,
    Mit Silbermast, doch ohne Tuch,
    Und Elbereth kam selbst herab:
    Sie schuf dem Schiff den Silmaril
    Zum Banner, ein lebendiges Licht,
    Ein heller Schein, der nie verblaßt.

                    -- Pugs 6.2.7, Main.hs

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

    眾人為彼造新舟
    鑄以祕銀精靈璃
    船首閃耀何需槳
    銀桅未有風帆繫
 
    無雙寶鑽作燈炬
    旗幟輝煌展生焰
    映照燃星雅碧綠
    神祇乘梭下九天...

                    -- Pugs 6.2.8, Main.hs
----

    use v6;

    for $*Larry {
        our Ship $pugs .= new(:of<mithril elven-glass>);
        given $pugs {
            $.prow does Shine;
            Silver $.mast but none(Oar::Shaven, Sail);
            Light  $.lantern := $*Silmaril;
            Bright $.banner  := Flame.bless:{};
            when $*Elbereth.gleam {
                .sail(...);
            }
        }
    }
                          -- examples/poetry/pugs_main.p6

----
== Perl 6 is Here Today!

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

* Anyone here heard of /Perl 6/?
+** ...I'll focus on the /is Here Today/ part, then. :-)

----
== But First...

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

* Perl 5 is Here Today!
+* The transition from Perl 4 succeeded!
+** ...although it took four years
** 5.000a1 (1993) ~ 5.004 (1997)
+** ...or six years for Win32 people
** 5.005_03 (1999)
+* It was really an amazing new language!

----
== Perl 5: References

{image: http://perlcabal.org/~autrijus/images/ref.png}

    $code->($arg);
    $hash->{3};
    $obj->method($arg);

+    { hash => 1 }
    [ 'array' ]
+    \eval{'scalar'}

----
== Perl 5: Closures

{image: http://perlcabal.org/~autrijus/images/closure.gif}

    my $var;

    $code = sub { ...$var... };

    for my $i (1..10) { ... };

----
== Perl 5: Modules

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

    use strict;
    no warnings;

+    $Package::name = 1;

+    bless($reference => 'Package');
    tie($container => 'Package');

----
== But even more importantly...

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

* CPAN is Here Today (and Here to Stay)!
+** "CPAN is my programming language of choice; the rest is just syntax."

+* 8000+ modules, 2500+ authors
** Automatic download, test and install
** Smoke testing, issue tracking, cross-reference, ratings...

+* CPAN is the greatest thing ever happened to Perl
+** ...However, heavy taxation from Perl 5 really hurts

----
== Language Tax on CPAN Users

* Sigils and references don't match:

    $s          @a      %h      
+    $$s         $a[0]   $h{'!'} 
+    $s->method  ☹       ☹

+* Forced redundancy:

    sub render {
        my $self = shift;
        my %opts = @_;
        foreach my $item ($self->filter(@{$self->{_items}})) {
            print "* @{[$item->draw($@opts{qw( x y z )})]}...\n";
        }
    }

+* In Higher-Order Perl, 50%+ is book keeping

----
== Fast forward to Perl 6...

* Sigils and references work just fine:

    $s          @a          %h      
+    $$s         @a[0]       %h{'!'} 
+    $s.method   @a.method   %h.method

+* Clean and simple semantics:

    method render (+$x, +$y, +$z) {
        for ./filter(@.items) {
            say .draw($x, $y, $z).as('* %s...');
        }
    }

----
== Implementation Tax on CPAN Authors

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

* XS is difficult to write and maintain
+* Backward compatibility leaves little wiggle room
+* Hence, the Jenga architecture of /re(ab)use/
+* Incompatible dialects: Source filter and `eval ""`
+* Arbitary limitations on regex, operators, grammar, etc.
+* OO and functional code are unfairly handicapped in Golf ;-)

----
== Fast forward to Perl 6...

* Faster: Soft, incrementally typed with whole-program optimizations
+* Friendlier: Call Perl5/C/Tcl/Python libraries directly
+* Easier: Common usage patterns dramatically shortened
+* Stronger: Support for OO, Functional, Data-driven styles
+* Leaner: Sane semantics, not endless (documented) workarounds
+* Nicer: Not tied to incomplete unmaintainable XS subsystems
+* DWIMmier: User-defined operators, syntax, grammars....

----
== Without further ado...

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

* We present: `cpan-upload.p6`!

    use perl5:Net::FTP;
    use perl5:HTTP::Status;
    use perl5:AppConfig::Std;
    use perl5:File::Basename;
    use perl5:LWP::UserAgent;
    use perl5:HTTP::Request::Common;

----
== Assimilating CPAN

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

* The first batch of Perl 5 programs looked like that:

    #!/usr/bin/perl
    require 'open3.pl';
    require 'bigint.pl';
    require 'my_library.pl';

+* I have 100+ CPAN modules
** I don't want to throw them away!
+* Why can't we write our first Perl 6 programs like this?

    #!/usr/bin/pugs
    use perl5:DBI;
    use perl5:WWW::Mechanize;

+* This works in the Pugs interpreter by linking in libperl.
+** What about the other way around -- Perl 6 in Perl 5?

----
== Assimilated by CPAN

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

* `pugs.pm` pragma let you embed Perl 6 code in Perl 5:

    #!/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:

    http://pugscode.org/
    http://search.cpan.org/dist/Perl6-Pugs/
    http://linide.sf.net/pugs-livecd-latest.iso
    http://svn.openfoundry.org/pugs/

+* Command line:

    % pugs -e "'Hello, world!'.say"
    Hello, world!

    % pugs examples/japh/ipw-japh.p6
    Just another Perl6 hacker...

+* Interactive mode:

    % pugs
    pugs> { $_ ?? $_ * &?BLOCK( $_ - 1 ) :: 1 }.(10)
    3628800

----
== Pugs the Project

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

    There hammer on the anvil smote,
    There chisel clove, and graver wrote;
    There forged was blade, and bound was hilt;
    The delver mined, the mason built...

                    -- Pugs, Prim.hs

----
== History

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

* Started at Feb 1st; almost 5 months old now
+** Exercise of "Types and Programming Languages"
** (I just wanted to understand junctions and MMD)
+** Learned Haskell because Perl 5 closures leak horribly
+* Not a Perl Foundation project
+** Just a prototype, not the production Perl 6 compiler
+** Optimized for fun, not deliverables
+* Minimizing deadlocks
** Optionally link against Perl 5, Parrot, Haskell
+* Keep Perl 6 retargetable

----
== What we have done

{image: http://linide.sourceforge.net/pugs-svngraph-6.2.7.png}

* Primitive interpreter: Feb 6
+* `Test.pm` runs correctly: Feb 23
+* PCRE regex support: Mar 19
+* `mandel.p6` compiled to Parrot: Mar 24
+* Container types: Apr 10
+* `BEGIN` blocks and `use`: Apr 26
+* PGE-based rule support: May 2
+* Basic objects and classes: May 12
+* mod_pugs: May 17
+* Use Perl 5 modules: May 25

---- 
== What we have done this month

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

* Safe mode and evalbot: Jun 2
+* Source filtering macros: Jun 11
+* `Test.pm` compiled to Parrot: Jun 18
+* `Test.pm` runs on Parrot: Jun 23
+* `Hello, world!` from Perl 5 to PIL to Parrot: Jun 24
+* Perl 6 AST as Perl 6 objects: Jun 25
+* PIR nodes as Parrot objects: Jun 26

----
== Who have done it

{image: http://perlcabal.org/~autrijus/images/commit.png}

* Lambdacamels
** 100+ committers
** 5000+ revisions
+* My primary function is Pugs's journaling filesystem
** http://use.perl.org/~autrijus/journal/
** I'm responsible for less than 40% of commits now

----
== Obligatory timeline

{image: http://pugscode.org/perl6-timeline.png}

* 6.0: Initial release
* 6.2: Basic IO, variable and control flow elements
* 6.28: Classes and traits
* 6.283: Rules, Grammars
* 6.2831: Role composition
* 6.28318: Macros
* 6.283185: Port Pugs to Perl 6, if needed

----
== "Never do live demo"

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

* Math:    mandel
* Network: http-server
* JAPH:    ipw-japh
* Obfu:    snowing
* Games:   hangman
* Prelude.pm!

----
== Catalyst on Pugs...

{image: http://perlcabal.org/~autrijus/images/catalyst.png}

* sri started working on it this month

    <sri> Perl 6 is damn sexy
    <sri> Perl 5 is a horrible hack
    <autrijus> It's a damn sexy hack, though
    <sri> True, but still a hack

+* Two days later, lathos started to port Maypole to Pugs

    <lathos> I'm actually *really* enjoying
             porting Maypole to Perl 6.
    <lathos> SO much cleaner.

+* Lots of dependencies were ported during the course:
** `Text::Glob`, `File::Find`, `FindBin.pm`, etc...
+* More yet to come
** e.g., first templating module `WTemplate.pm` arrived yesterday!

----
== Joining the development
{image: http://perlcabal.org/~autrijus/images/ship.jpg}

    The mountain throne once more is freed!
    O! Wandering folk, the summons heed!
    Come haste! Come haste! Across the waste!
    The king of friend and kin has need...

                    -- Pugs, Run.hs

----
== Expectation management

{image: http://perlcabal.org/~autrijus/images/wish.png}

* State of Carrot: Pugs covers 80% of Perl 6 semantics...
** ...that's unfortunately not the case
* We have 7000 unit tests; at least 15000 more expected
** To the 0th approxmiation, we are less than 30% there
* I'm not part of the Cabal
** I will not promise anything
** If you want something, write a test and hack on it
** ...the commit bit is always waiting for you!

----
== Test first

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

* To report a bug, always write a test
+** `Test.pm` is really simple to use
+** The smoke graph lists TODOs and regressions:

    http://feather.perl6.nl/~autrijus/smoke.html

+* It's a coding monkey's paradise!

----
== Anarchisitic Community

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

* Wiki-style development
+* Thoroughly test driven
+** JFDI, based on the Synopses
+** Unspecified features go to `t/unspecced/`
+* To become a Pugs committer, you just need to:
+** Commit stuff ;)
+** Keep an eye on `#perl6` and `perl6-compiler`
+* `READTHEM` is a good read

----
== Libraries

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

* Foreign:
** CPAN modules
** Parrot modules
** Haskell modules
+* Native:

Algorithm-TokenBucket HTML-Entities Perl-MetaModel URI Benchmark
HTTP-Server-Simple Perldoc WTemplate CGI Kwid-Event-Parser Pod-Event-Parser
fp Config-Tiny Locale-KeyedText Set lib Date Module-Pluggable-Fast Test
libwww-perl File-Find Net-IRC Test-Builder File-Spec POE Text-Glob FindBin
Perl-Compiler Tree

----
== From 6.0.* to 6.2.*

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

* Basic IO and control flow elements
+* Mutable variables
+* Assignment and aliasing
+* Compiling and embedding interface

----
== OO core: 6.28.*

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

* Classes and Objects
+* Inheritance
+* Subtyping
+* Introspection # /TODO/
+* Roles # /TODO/

----
== Rules core: 6.283.*

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

* Match/substitution with rules
+* Named and nested captures
+* Closures in rules # /TODO/
+* Grammar classes # /TODO/

----
== Approximating /2π/

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

* 6.2831
** Role composition
** Fully specified runtime semantics
+* 6.28318
** Macros!
+* 6.283185
** Port Pugs to Perl 6
** Finish bootstrapping

----
== Pugs the Language Implementation

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

    No words were laid on stream or stone
    When Durin woke and walked alone.
    He named the nameless hills and dells;
    He drank from yet untasted wells...

                    -- Pugs, Lexer.hs

----
== A whirlwind tour of Perl 6

{image: http://onestepback.org/articles/usingruby/images/p6_cover.gif}

* Mostly taken from Allison's /Perl 6 Update/ slides
+** ...without features that Pugs does not yet support
+** ...or parts under heavy (re)design 
+* Perl 6's syntax is still changing rapidly
** Half of "Perl 6 and Parrot Essentials" is probably outdated
+** ...but how do we know which half?
+* Read the Bible!
+** http://search.cpan.org/dist/Perl6-Bible/
+** Quick references: pugs/docs/quickref/

----
== Simplicity

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

* Huffman coding makes easy things easy:

    say "Hello, World!" if $x == any(1..3);
    sub unfinished { ... }
    class Dog is Animal { has $.tail }

+* Easier to tell different constructs apart:

    eval "..." / try { ... }
    for @a { ... } / loop (;;) { ... }
    sub a { ... } / method b { ... }

----
== Sigils

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

* Consistent use of sigils:

    $scalar, @array, %hash
    @array[3]       # _not_ $array[3]
    %hash{'key'}    # also as %hash<key>

+* Hence hashes and arrays take methods too!

    %hash.keys
    @array.sort

----
== Dot

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

* Compress three keystrokes to one:

    $obj.method()
    $a_ref.[1]      # also as $ref[1]
    $h_ref.<key>    # $h_ref<key>, $h_ref{'key'}
    $c_ref.()       # $c_ref()

+* There's more than one way to call it:

    say("Hello, World!");   # this works
    "Hello, World!".say;    # this too

----
== Methods

* Much more meaningful:

    @array.elems    # _not_ scalar(@array)
    $string.chars   # _not_ length($string)
    $string.bytes   # _not_ bytes::length($string)
    &function.arity # ... try doing this in Perl 5. ;)

* Easier to remember, too

----
== Named operators

* Lots of named variables:

    sub clean ($text, $method) { ... }          # by address
    sub by_value ($text is copy) { ... }        # by value
    sub some_opt ($req, ?$opt = $req) { ... }   # optional
    sub modify ($text is rw) { ... }            # writable
    sub typed (Int $num, Str $txt) { ... }      # typed

+* Available as Perl6::Subs in a CPAN near you!

+* The old way still works:

    sub sum {
        my $sum;
        $sum += $_ for @_;
        return $sum;
    }

----
== Higher-order functions

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

* Currying with &code.assuming:

    sub times ($x, $y) { $x * $y }
    $sixtimes = &times.assuming(:y(6));
    $sixtimes(9); # 54

+* Implicit parameters:

    sub distance { sqrt( $^a ** 2 + $^b ** 2 ) }
    @array.sort:{ $^y <=> $^x };

----
== Multi Method Dispatch

* Type-based dispatch:

    multi sub add (Int $a, Int $b) { ... }
    multi sub add (Num $a, Num $b) { ... }
    multi sub add (Str $a, Str $b) { ... }

+* Operators are all multisubs by default:

    multi sub infix:«<» (Set $one, Set $two) returns Bool {
        $one.proper_subset($two);
    }

----
== Operators

{image: http://www.bwht.org/images/telephone_operator.gif}

* New operators:

    say =<README.txt>;  # iterator interface
    ...; !!!; ???;      # yada yada yada

+* Unicode operators

    sub prefix:<Σ>  (@x) { sum(@x) }
    sub postfix:<!> ($n) { ($n < 2) ?? 1 :: $n * ($n-1)! }
    say( Σ 1..5! );             # 7260
    (1, 2) ¥ ('a', 'b');        # (1, 'a', 2, 'b')

+* Chained operators 

    if $x > $y > $z { ... }
    if -r -w 'file' { ... }

----
== Strings

* Tilde replaces dot for string concatenation:

    $line = "Blue" ~ $moon;

+* But you won't miss the dot, because interpolation now works great:

    "Hello, $person";
    "You can call &subs() and $obj.methods() too!";
    "The attribute is %obj.keys.sort.reverse().";
    "Two plus Two is just { 2 + 2 }.";

+* Easy access to sprintf() with .as

    $string.as('Hello, %10s');

----
== Logic operators

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

* Short circulting:

    $var  = 9 || 3; # 9

+* Boolean, numeric and bitwise logic:

    $bool = 9 ?| 3; # bool::true
    $true = 9 +| 3; # 11
    $bits = 9 ~| 3; # ";"

+* Skewed || means "defined or"

    $arg //= 3;
    $fh = open('file') err die $!;

----
== Hyper operators

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

* Hyperised binary operators:

    (1,1,2,3,5) »+« (1,2,3,5,8);  # (2,3,5,8,13)

+* Hyperised unary operators:

    -« (1,2,3); # (-1, -2, -3)

+* Autopromoted dimensions

    ('a'..'c') »x« 3;   # ('aaa', 'bbb', 'ccc')

----
== Reduction operators

    [+]                    # sum(...)
    [*]                    # product
    [*] 1..$x              # factorial
    [~]                    # join('', ...)
    [<]                    # monotony
    [==]                   # equality
    [//]                   # first defined element
    [||]                   # first true element
    [=>]                   # linked list construction

----
== Junctions

* Useful for common shorthands

    $options = '--help' | '-d' | '-e';
    if all($x, $y, $z) eq $options { ... }

+* The equivalent Perl 5 code:

    if (($x eq "--help" || $x eq "-d" || $x eq "-e") and
        ($y eq "--help" || $y eq "-d" || $y eq "-e") and
        ($z eq "--help" || $z eq "-d" || $z eq "-e")) { ... }

+* Test for prime numbers

    sub is_prime (Int $n) { $n % all(2 .. sqrt($n)+1) }
    sub has_twin (Int $n) { is_prime($n & ($n + (2 | -2))) }

----
== Aliasing

* There are no globs anymore

    &alias := &sub;
    $alias := $scalar;
    @alias := @array;

+* Aliasing a single container

    $alias := @array[2]{'many'}{'keys'};

+* Aliasing at BEGIN time:

    my $PI ::= 355/113;

----
== Smart Match

* `=~` is now spelled as `~~`:

    $value  ~~ /blue/;
    $value  ~~ s/x/y/;
    $value  ~~ rx:P5/blue/;

* But works for other cases too:

    $string ~~ any(<a b c d>);
    $obj    ~~ Class;

----
== Switch Statements

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

* `given`/`when` uses the same way to match things:

    given $string {
        when all(/foo/, /bar/)  { ... }
        when .is_very_long      { ... }
        default                 { ... }
    }

+* You can use `given` by itself:

    given $very.complex.object {
        .method1;
        .method2;
    }

----
== Loops

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

* `foreach` is now spelled `for`

    for @people -> $person {
        say "Hello, $person";
    }

+* `for` can loop over multiple variables

    for %ages.kv -> $name, $age {
        say "$name is now $age";
    }
    for zip(@a,@b) -> $a, $b {
        say "Are you $a or $b?";
    }

----
== Exceptions

{image: http://perlcabal.org/~autrijus/images/error.png}

* `$!` supercedes `$@`, `$?`, `$^E`

    system('rm -rf /') err die $!;

+* `eval {}` is now `try {}`

    try {
        may_throw_exception();
    }

----
== Classes

* Declarations

    class Tree { method nodes () { ... } }

+* Inheritance

    class Leaf is Tree {
        has $.val;
        method nodes () { .val }
    }

+* Initialisation

    method BUILD ($.x, ?$.y = $.x)

----
== Attributes

* `has $.val` provides accessors automatically

    my $x = Leaf.new(:val<Hello>);
    say $x.val;     # "Hello"

+* Typed attributes:

    class Branch is Tree {
        has Tree $.left;
        has Tree $.right;
        method nodes () { (nodes .left, nodes .right) }
    }

----
== Rules

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

* The same `m//`, `s///`, `//` syntax as Perl 5

    if $text ~~ /blue/ {...}
    $name ~~ s/Dan/Chip/;
    m:perl5/(\()?[^()]+(?(1)\))/;

+* Postfix modifiers moved to front ot string

    s:g/a/b/
    m:P5<ism>/^yes.../

+* Space and comments are ignored by default (just like Perl 5's //x):

    m{ Larry    # perl
     | Matz     # ruby
     | Guido    # python
     };

----
== New Rules Syntax

* qr// is now rx//

    $myrule = rx/[yn]/

+* Anonymous and named rules

    $myrule = rule {\w\s+\w}
    rule myrule {\w\s+\w}

+* Rules may contain other rules

    rule name { Larry | Matz | Guido }
    rule project { perl | ruby | python }
    rule description :w { <name> does this <project> }

----
== Grammar

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

* Grammars are classes that contains rules
** Patrick hacked them together 3 days ago

+* Provides namespace for rules:

    grammar URI { 
        rule reserved   { <[;/?:@&=+$,\[\]]>               };
        rule mark       { <[-_.!~*'()]>                    };
        rule unreserved { <[A-Za-z0-9]+<mark>>             };
        rule scheme     { <[a-zA-Z]><[a-zA-Z0-9.+-]>*      };
        rule uri        { <+<reserved>+<unreserved>+["%"]> };
    }

+* Perl 6 itself will eventually be a grammar too!

    grammar Perl6 { 
        rule statement { ... }
        rule identifier { ... }
    }

----
== Principles

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

* Simple...
+** ...but capable
+* Hybrid...
+** ...but distinct
+* Useful now...
+** ...and relevant in the future
+* Make Perl more Perlish

----
== Pugs the Compiler

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

    And words unheard were spoken then
    Of folk and Men and Elven-kin,
    Beyond the world were visions showed
    Forbid to those that dwell therein...

                    -- Pugs, Compile.hs

----
== How the Pugs interpreter works today

* Take Perl 6 source code
+* Turn it into a parse tree
+* Run BEGIN blocks and store in an environment
+* Evaluate nodes from the parse tree

----
== Problem with that approach

* Cannot emit compile errors
** `2 = 2` survives to runtime
+* No support for warnings and strictness
+* Only allow peep-hole optimization
+* Dispatch speed 100x slower than Perl 5

----
== First-generation compilers

* Take parse tree, generate some other code

+* Good for making stand-alone binaries:

    % pugscc examples/hanoi.p6
    % pugscc --haskell -e "'Hello, world!'.say"
    % pugscc --parrot examples/mandel.p6

+* Compile and run in a single step:

    % pugs -Bparrot examples/mandel.p6

----
== Problem with that approach

* Parse tree has ~100 different node types
+** Many special forms
+** Can't be desugared with only local knowledge
+* Parrot has ~1000 valid opcode forms
+** Hand-written mapping makes optimisation hard
+** Backends cannot be consistent
+* We need an intermediate representation form

----
== PIL Tree: Core of Perl 6

{image: http://feather.perl6.nl/~autrijus/viz.png}

* Simple, high-level representation of Perl 6
** 16 node types currently
** /Diet Perl 6/: No syntax sugar left
+* Remains stable under syntax changes
** Most new language constructs are just rewrite rules
** Other languages may be translatable to PIL too
+* Remains stable under runtime changes
** It only takes two lines in codegen to implement tail calls
+* We need a program to translate from parse tree to PIL

----
== Non-self-hosting approach

{image: http://feather.perl6.nl/~autrijus/viz.png}

* The production release of Perl 6...
+** May be Parrot specific
+** Does not need to be self hosting
+** Preferably written in PIR or other Parrot languages
+** Other communities will dislike a compiler written in Perl6
+** Perl6/Parrot != C#/.Net
+* It's a valid line of thought
+** Patrick will explain it in the afternoon
+** Pugs, however, will take another route

----
== Self hosting approach

{image: http://feather.perl6.nl/~autrijus/viz.png}

* I'd like to keep Pugs decoupled from Parrot
+** By writing the Perl 6 compiler in Perl 6
+** Running Perl 6 on perl5vm is very useful
+** Generating native C and Javascript is cool too
+* Make Perl 6 as portable as Python
** CPython, Jython, IronPython, Psyco, Stackless...
+* But especially PyPy:
+** Reimplementation of Pythong written in Pythong itself
+** Flexible, easy to experiment with
+** Currently targets C, LLVM, and Python

----
== Benefits of self-hosting

{image: http://feather.perl6.nl/~autrijus/viz.png}

* Well-defined semantics
+* Less chance of /misfeatures/
** `my $x if 0`
** Keep the language portable and optimizable
+* Eliminate the low-level black box
** To understand Perl, just learn Perl
+* Prove that Perl 6 can handle complex tasks (i.e. a compiler)
** Perl 5 was especially weak in this area

----
== Targetting Parrot

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

* Parrot has a sound design...
+** Although it can segfault an infinite loop in constant time
+** Mostly due to lack of exercise
+* High entry barrier
+** Missing TODO tests
+** Misleading documentations
+* It can use your help!
+** Chip/Dan will talk about this in the afternoon

----
== PIR Tree: Core of Parrot

* Captures Parrot's semantics
+** Similar to PIL, but lower level
+** Now available as a set of Parrot objects
+* Almost direct mapping to Parrot bytecode
+** Infinite registers
+** No nested expressions
+* Workarounds are maintained in a single place

----
== Parrot: Open issues

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

* Using Perl 5 modules
* Lexical pads
* Object space
* Ahead-of-time compilation

----
== Targetting Perl 5

* Anywhere in your code, write:

    use pugs;
    # Perl 6 code follows
    use perl5:Class::DBI;
    ...

+* No `Inline.pm` involved
** Compiled to Perl 5 and inject back on the fly
** Mixing P6/P5 code seamlessly
+* No dependencies on anything but perl5
** The compiler is just another pure-perl5 module
** Generated by compiling itself from Perl 6
+* Not yet realized; pending some pieces

----
== Code generator

* Written in Perl 6
** `ext/Perl-Compiler` in Pugs source tree
** Started by Luke Palmer
+* Takes a set of PIL node objects
** Generates Perl 5 code via string concatenation
+* Yuval Kogman started working on improved quasiquoting
** `use perl5:PPI;`

----
== Perl 6 object space

+* The only user-visible part
** `lib/Perl6-MetaModel/` in Pugs source tree currently
** Started by Stevan Little
+** Everything else can be run at author's side
+** Hence, the only part that needs to start from Perl 5
+* Currently handles roles, classes, methods
+** It can load the PIL node objects
+** Multimethods not there yet 

----
== Semantic analyzer

* Takes parse tree, produce PIL tree
** `src/Pugs/Compile` in Pugs source tree
** Currently, 150 lines of Haskell code
+* Some parts still missing
+** First-class types and signatures
+** Purely lexical Pad structures
+* Effectively a formal spec of Perl 6 syntax
+** Needs to be ported to Perl 6

----
== The Parser

* Currently, 1000+ lines of Haskell code
+* Special syntax carries heavy sugar
+** BEGIN blocks can't be statically parsed 
+** Must take care of user-defined lexical tokens
+* Eventually translated to Perl 6 rules
+** For rebindable grammars
+** Basic support available in PGE last week
+** Still much more needed to be done
+* If we are to bootstrap on Perl 5...
** PGE needs to be ported to Perl 6 also

----
== Drawbacks

* Performance will not be great
+** Double indirection: `tied` on every variable
+** Tail call and GC will be slow as usual
+** Full continuation support unlikely
+* But that's okay, we have Parrot
+** Instant gratification first
+** Encourage more people to work on Parrot

----
== Other possible runtimes

* GHC (prototype evaluator)
* SpiderMonkey
* Mono
* YARV
* LLVM
* C--

----
== Bonus slides

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

* Experimental features
+** Unspecified
+** Runtime-specific
+* Pending implementation in Parrot
+** Extremely difficult to do in Perl 5
+** Prototypes in Haskell first

----
== Software Transaction Memory

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

* Classical race condition:

    my $a is shared = 1;
    async { my $b = $a; $a = $b + 1 };
    async { my $c = $a; $a = $c + 1 };
    say $a;     # 2? 3?

+* It's either deadlocks, or huge `select()` loops

+* Now solved with automatic rollback:

    atomically { my $b = $a; $a = $b + 1 }
    atomically { my $c = $a; $a = $c + 1 }

+* Implemented in Java, C#, Fortress, GHC...
+* Pugs has switched to STM storage
** No noticeable performance penalty
+** Would be really nice for Perl 6 to have it

----
== Serialised Continuations

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

* What if `dump()` works reliably...
+** Anywhere in your program
+** On part of the stack
+** And produces really small images?
+* No need for web sessions anymore
+** Just save the application state in forms and cookies
+** Multi-step control flow becomes trivial
+* Omniscient debugging
+** Go back and forth in time
+** Not only observe, but modify the program in real-time
+* Many more applications: clustering, mobile code, etc...

----
== Thank you!

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

* Any questions?

