Day 139/140: Hackathon day #0/1

autrijus on 2005-06-24T05:26:31

The Hackathon is a huge continuous flow of ideas, chatters, pizzas, keystrokes, etc...

All Pug's uncatchable value cast errors are eliminated by theorbtwo's sweeping AST.Internals change, which uncovered various bad assumptions in the evaluator core -- I spent most of time today chasing them down. So, the planned release has (yet again) delayed. :-)

During my flight to Toronto, I jotted down many questions to ask Larry; I'd glad that Larry resolved most of the show-stopping ambiguities, with help from luqui and other hackathoners.

Yesterday, Test.pm finally works correctly with PIR compilation, so I ran make pirsmoke for the first time, which passed 2.5% of all subtests. As I'm writing this, luqui is close to get eval working on Pugs-generated PIR code -- this should improve our percentage by a significant amount.

stevan brought a new paper that describes a concise, dynamically extensible, polymorphic typed metamodel based on kind/class/objects. He is implementing it in Perl 5 right now; once that works we can port it to Haskell and use it in both the evaluator and the codegen.

lwall is hacking on PPD, the Perl5 optree dumper that defeats optimisations. The Perl 5 to Perl 6 translator may then work by compiling PPD to PIL, and then pretty-print PIL back to Perl 6.

Aside from cooking delicious and inflammable pizza, nothingmuch managed to get a Perl 5 implementation of Forth going, as a prototype of the Harrorth work. We didn't get around to generate PIR from that, though.

ingy showcased his Test::Base superior technology, where you can get specification-based testing done automatically for your projects just by writing two lines of harness. He is porting it to Perl 6 as I write this, which would be very cool indeed.

theorbtwo is tracing out the remaining failing tests, so we can have a reasonable chance of cutting a Pugs release tomorrow. Patrick arrives tomorrow; I hope to get PGE repaired against the trunk parrot, and get closures in Rules working.

There's much, much, much more activity going on than I can describe here -- I covered maybe about 3% of it. Below is a glimpse of a few Perl 6 design glitches we've been ironing out so far -- there more to come...

  • deref is now 0-level; $x = 3; $y = \$x; $y++. # now an exception
  • coercion is now done in mmd level in coerce:<as> calls. sqrt("element") now yields to 0. my Int $x = "foo" as Str casts.
  • is lazy parameters in MMD now causes the argument to be delayed even if other MMD candates mandate them as eager; it enters MMD not with the type of its evaluated result, but with its inferred type at compile time.
  • &prefix:<=> is just .shift in item context; in slurpy context it just turns the iterator into a generator. All arrays are concatenations of generators (which may or may not be preflattened)
  • &slurp() is the eager variant of list context &prefix:<=>; you can, alternately, use the steamroller &prefix:<**>.
  • my() declarations scopes lexically to the rest of the block; using $MY::x or $::("x") in the block before the actual declaration is erroneous.
  • Only Roles take type parameters. Hence, Array and Hash and Scalar are roles; PerlArray/PerlHash/PerlScalar are classes that conforms to them. A variable is bound to containers of the Perl* types by default, depending on its sigil.
  • Any is now really Any (includes Junction); the role hierarchy looks like this:
  •      Any
         /  \
    Item    Junction
    
  • Non-source-filter-ish macros work on the PIL(AST) level, not on parse tree level. The AST should preserve enough information to derive the original parse tree and source code back, for the compiler to use.
  • return inside blocks always throw out exception specific to its containing Routine; if the caller chain does not include that routine, it's just a fatal exception.
  • The while loop assigns the evaluated result into the block, but only if it takes an one mandatory parmaeter:
  • while foo() -> $_ {...}   # binds $_
    while foo() -> ?$_ {...}  # does not bind $_
    
  • The Hash, Int, Str etc are just roles; implementation classes are known as PerlHash, PerlInt etc; they are not generally used by the user.
  • role Hash[?::returns=Any, ?::shape=Str] { ... }
    
  • For pair/named binding to work, the inferencer needs to know it is a pair before putting it in the named binding position.
  • sub foo ($x) { ... }
    sub bar returns Pair () { (x => 3) }
    my $y = (x => 3);
    
    foo({ x => 3 }.()); # This assigns (x=>3) to $x
    foo(bar());         # This assigns 3 to $x
    foo($y);            # This assigns 3 to $x, too
    
    sub foo (?$x, ?$Inf) {}
    my $y = (x => 3); foo($y); # binds $x
    my $z = (+Inf => 3); foo($z); # binds $Inf
    
  • Parametric type is now gone. Bare is merged with Block -- it's all of the Block type now.


Unary splat

roie_m on 2005-06-25T14:24:24

I seem to recall the * operator being required for those parameter-binding semantics. Has the the unary splat been cancelled, or am I mistaken?

Re:Unary splat

autrijus on 2005-06-25T17:25:31

The unary splat * takes an aggregate, or reference to an aggregate, and flatten them out on the invocation list. Unary splat on hash arguments flattens it out as pairs for named bindings; splat on scalars deref it to find an array/hash reference; for code and non-reference-to-aggreate scalars it's a no-op.

Re:Unary splat

roie_m on 2005-06-26T01:28:42

Which is why I don't understand why it's not required in foo($y). It seems to me foo(*$y) should assign 3 to $x, and foo($y) should assign $y to $x no matter what $y is.

Re:Unary splat

autrijus on 2005-06-28T01:27:05

Pair is not an aggregate. I thought the same way you did, too, but Larry ruled that Pair, like Junction, is not Item (which is the default for parameter types). To accept Pair, declare it as such, or Object, or Any.