Re: Recent news about PGE

2005-11-06 Thread Autrijus Tang
On 11/4/05, Patrick R. Michaud [EMAIL PROTECTED] wrote:
 As a quick example, one can now use the p6rule subrule
 to parse a perl 6 rule expression, and the Match object
 that is returned contains the parse tree.  Other examples
 and demonstrations or parsing are in the examples/pge/
 directory.

pmichaud++ for getting this done. :-)

I have just committed (in Parrot and Pugs) the support for the
newstyle match tree for PGE::Hs, so this works now:

  pugs ('1' ~~ /p6rule/)p6rule
  Match.new(
ok = bool::true,
from = 0,
to = 1,
str = 1,
sub_pos = (),
sub_named =
  { expr =
  Match.new(
ok = bool::true,
from = 0,
to = 1,
str = 1,
sub_pos = (),
sub_named = {type = term:, value = 1}
  )
  }
  )

I noticed that zero-length input is now rejected by p6rules; I tried
to fix it, but could not determine where the fix should go.  A trace is
listed below:

  compilers/pge$ echo 'rule ' | parrot demo.pir
  Missing term at offset 0
  current instr.: 'PGE::OPTable :: parse' pc 1483
(compilers/pge/PGE/Exp.pir:134)

As a workaround, I special-cased m:// and m:P5// in Pugs, which may
be useful anyway, as split(//, $string) is quite common.

Cheers again for getting the OPTable nailed!

Thanks,
/Autrijus/


Re: Recent news about PGE

2005-11-06 Thread Autrijus Tang
On 11/6/05, Patrick R. Michaud [EMAIL PROTECTED] wrote:
 First, for null input, PGE (and p6rules) will likely parse this
 by returning a Match object indicating false, and attempting
 to compile that object will probably return a null subroutine.

Yes, that sounds sane.

 The other case is when there's an operator requiring a term
 and such a term isn't found -- i.e., an invalid expression such
 as  $a + 5 *.  I can either have pge return the portion that
 successfully matches (i.e., the $a + 5 part), return a false
 Match object, or throw an exception.  At the moment I'm in
 favor of returning the portion that successfully matches, similar
 to what a rec-descent parser would do.

This too, as you can trivially concat the OPTable parser with an
explicit end-of-string marker.

  As a workaround, I special-cased m:// and m:P5// in Pugs, which may
  be useful anyway, as split(//, $string) is quite common.

 If I read S05 correctly, that now has to be  split(/?null/, $string).

Indeed.  It's fortunate that there is a split('', $string) form. ;-)

Empty rules are now an error in Pugs.  Thanks for the correction!

/Autrijus/


Re: Avoid the Yen Sign [Was: Re: new sigil]

2005-10-23 Thread Autrijus Tang
Dan Kogai wrote:
 To make the matter worse, there are not just one yen sign in  Unicode.
 Take a look at this.

 ¥ U+00A5 YEN SIGN
 ¥ U+FFE5 FULLWIDTH YEN SIGN

 Tough they look and groks the same to human, computers handle them
 differently.  This happened when Unicode Consortium decided to make  BMP
 round-trippable against legacy encodings.  They were distinct in  JIS
 standards, so happened Unicode.

In addition to your handy table, the  and  french quotes, which are used
quite heavily in Perl 6 for both bracketing and hyper operators, also have
full width equivalents:

300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;Y;OPENING DOUBLE ANGLE BRACKET
300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;Y;CLOSING DOUBLE ANGLE BRACKET

Half width: «»
Full width: 《》

There is no way to type out the half-width yen and double angle brackets under
MSWin32, under either the traditional or simplified code pages; only full width
variants are available.

One way to approach it is to make Perl 6 accept both full- and
half-width variants.

Another way would be to use ASCII fallbacks exclusively in real programs, and
reserve unicode variants for pretty-printing, the same way that PLT Scheme and
Haskell recognizes λ in literatures, but actually write lambda and
\ respectively
in everyday coding.

TIMTOWTDI. :)

Thanks,
/Autrijus/


Re: new sigil

2005-10-22 Thread Autrijus Tang
Juerd wrote:
 I do not see why $ and @ couldn't be both a sigil and an infix
 operator, and the same goes for whatever ASCII equivalent ¢ gets.
 
 ^ and | are available for sigil use. (All the closing brackets are too,
 but that would be very confusing because we tend to visually parse those
 in pairs.)
 
 Using the an infix operator's symbol as a sigil is not weird, not wrong,
 not confusing and mostly: not a new idea.

Indeed.  Somehow I think this makes some sense:

sub Bool eqv (|T $x, |T $y) { ... }

Thanks,
/Autrijus/


Re: Accessing parrot functions/PMCs with Pugs

2005-10-22 Thread Autrijus Tang
Christian Renz wrote:
 I recently got my feet wet with Pugs. So far, it's been fun
 :-).

Cool!

 However, I couldn't find any information on how to access
 functions defined in parrot, or even how to use classes defined as
 PMCs in parrot. Is this possible already?

If Pugs is linked with Parrot (env PUGS_EMBED=parrot perl Makefile.PL),
this should work (may require blead parrot as 0.3.0 has a nasty bug in
its C embedding interface):

eval(print 1, :langpir)

as well as this syntax:

require_parrot 'foo.pir';

We don't currently have a way to bind Parrot symbols as Pugs symbols.
Feel free to write up tests in t/ -- maybe t/embed/ -- on how you think
it should behave.  Alternately, come to irc.freenode.net #perl6 and
chat a bit on how you plan to use it; posting p6c is fine too.

Thanks,
/Autrijus/

PS. I just sent you a committer bit; welcome aboard, and remember  to check in
your name to AUTHORS under the subversion repo http://svn.openfoundry.org/pugs/
:-)



Re: Complex types

2005-10-12 Thread Autrijus Tang

Larry Wall wrote:

On Thu, Oct 13, 2005 at 09:43:15AM +1300, Sam Vilain wrote:
: Hi all,
: 
: Is it intentional that S09 lists unboxed complex types, but equivalent

: Boxed types are missing from the Types section in S06?

Nope.


As it's a trivial omission, I went ahead and changed S06.pod (r6201).

Thanks,
/Autrijus/


[RELEASE] Pugs 6.2.10 released!

2005-10-09 Thread Autrijus Tang
I am delighted to announce Pugs 6.2.10, released during a slashdotting 
on geoffb's Optimizing for Fun column:


http://developers.slashdot.org/article.pl?sid=05/10/09/1831219

The release tarball will be available from CPAN shortly:

http://pugscode.org/dist/Perl6-Pugs-6.2.10.tar.gz
SIZE = 2394516
SHA1 = 3d8669fdccc3616c99cdde68659759b8b5782859

With two months of development, this release features more tightly 
integrated JavaScript and Perl5 code generator backends, a library 
interface to the Pugs system via support for the Haskell Cabal 
frameworks, as well as many new tests.


After the release, the push toward 6.28.0 will begin in earnest, with 
the newly specified container model and object model integrated back to 
the main runtime, fleshing out support for the remaining OO features.


Again, thanks to all the lambdacamels for building this new ship with me. :)

Enjoy!
/Autrijus/

= Changes for 6.2.10 (r7520) - Oct 10, 2005

== Feature Changes

=== Shared components

* Support for the Haskell Cabal framework, exposing Pugs as a library to 
other Haskell users, paving the way for use in IDEs, as well as future 
Inline::Pugs and Inline::GHC modules

* Adopted the code convention of expanding literal tab chars to spaces
* JavaScript backend can be invoked with `pugs -B JS`
* Perl 5 backend can be invoked with `pugs -B Perl5`
* Pugs will now compile version ranges in 'use/require' statements
* 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 {...}`)
* Support for `$CALLER::` and `$OUTER::`
* Support for `lazy {...}` blocks for delayed evaluation
* Support for `temp` and `let` declarations
* Support for array and hash autovivification
* Support for array and hash slices
* Support for evaluating expressions in the PIL2JS shell (`:e exp`)
* Support for junctions
* Support for loading JSAN modules by using `use jsan:Module.Name`
* Support for lvalue subroutines (`foo() = ...`)
* Support for slurpy hashes in subroutine signatures
* Support for the `Proxy` class (not yet user-visible)
* Support for the `eqv` operator
* Using `for` with only one element to loop over works now
* `int()` works correctly on special values like `Inf` or `NaN` now
* `substr()` returns a r/w proxy: `substr($str, $pos, $len) = $replacement)`

=== Perl 5 backend

* Passes 33% of the main test suite (including TODO failures)
* Integrated with the Perl 5 edition of MetaModel 2.0
* Compiles and runs Perl 6 version of `Test.pm`
* Infinite lazy lists, Pairs, References, and intrinsic classes
* Multi Sub, Class, Match, exceptions, types and subtypes
* Scalar, Hash and Array containers, with tieing, binding and read-onlyness
* Support for an extensive list of operators
* Supports eval() with Perl 5 and Perl 6 code
* `%ENV` is shared with Perl 5; [EMAIL PROTECTED] is separate from [EMAIL 
PROTECTED]::INC`

== Bug Fixes

=== Shared components

* Fixed `foo {1}.blah` being misparsed as `foo({1}).blah`
* Fixed a hashref infinite loop
* Fixed infinite loop on sub { 1 }.pairs
* Multiple `sub foo` no longer silently means `multi foo`

=== JavaScript backend

* Fixed evaluation order of assignments and bindings
* Fixed `.values` and `.kv` to return aliases

== Bundled Modules

=== New Perl 6 modules

* Perl6-Container-Array, Perl6-Value-List: prototype modules for 
implementing Lazy lists in Perl 6.

* Log-Selective
* Cipher - Cipher API suite for cryptographic ciphers
* FA-DFA

=== Updated modules

* Locale-KeyedText: Synchronized with p5 version 1.6.2
* Test-Builder: new APIs, including test_pass() and test_fail()

=== Experimental modules (in misc/, not installed)
* Blondie, prototype compiler for native code generation and 
type-inferencing with Attribute Grammers

* XML::SAX
* Getopt::Long
* Rosetta-Incubator, a complete set of Rosetta[|::*] and 
SQL::Routine[|::*] modules, restarted development at 2005.09.29


== Test, Examples and Documentations

* Many new tests and test refactoring, we now have 10300+ tests
* Documentation for draft GC API at `docs/notes/GC.pod`
* Data file for curcular prelude exploratory diagram at 

Re: A listop, a block and a dot

2005-10-05 Thread Autrijus Tang

Luke Palmer wrote:

With parentheses:

print((length foo)  4)
print(3  4)

So this was quite a disturbing bug.


This is now also quite a fixed bug. :-)

However:
f:{1}.()

still parses as

(f(:{1})).()

as the adverbial block form takes precedence.  Is that also wrong?

/Autrijus/


Re: FYI: Lambda Calculus on Perl 6

2005-09-05 Thread Autrijus Tang
On Mon, Sep 05, 2005 at 12:35:36PM +0900, Dan Kogai wrote:
 And I found that these can be made much, much simpler and more  
 intuitive with Perl 6, even more so than scheme!
 
   our $ZERO = sub($f){ sub($x){ $x }};
   our $SUCC = sub($n){ sub($f){ sub($x){ $f.($n.($f)($x)) }}};
   our $ADD  = sub($m){ sub($n){ sub($f){ sub($x){ $m.($f)($n.($f) 
 ($x)) ;
   our $MULT = sub($m){ sub($n){ sub($f){ $m.($n.($f)) }}};
   our $POW  = sub($m){ sub($n){ $n.($m) }};

Nice!  Also the pointy notation may or may not be clearer:

- $f { - $x { $x } }

Also, you can use the  sigil:

our SUCC := sub(n){ sub(f){ sub(x){ f(n(f)(x)) }}};

which may or may not be clearer... probably not, come to think about it.

 P.S.  I am surprised to find Pugs does not include this kind of  
 sample scripts.

I'm surprised to find dan-san is not a Pugs committer.  I've remedied
this situation by sending you an invitation.  The commit URL is the
same as the anonymous checkout svn URL.

Please commit them into the suitable examples/ subdirectory, probably
algorithms.  Also please add yourself to AUTHORS.  Welcome aboard!

Thanks,
/Autrijus/


pgpxay8rW4Bi3.pgp
Description: PGP signature


Re: Who is @Larry?

2005-08-25 Thread Autrijus Tang
On Thu, Aug 25, 2005 at 09:25:30PM -0400, Matt Fowles wrote:
 I have a simple question.  Who comprises @Larry?  I am fairly sure
 that I know a few people in it, but I am highly doubtful that I know
 all of them.

dev.perl.org has a Who's Who list:

http://dev.perl.org/perl6/people.html

The Architecture team is comprised of:

 larry damian chip leo chromatic allison hugo luke nathan dan 

Thanks,
/Autrijus/


pgpd7ZJW1e0OH.pgp
Description: PGP signature


Re: P6 Picture Bootstrap

2005-08-19 Thread Autrijus Tang
On Fri, Aug 19, 2005 at 09:45:16AM -0700, Kris Bosland wrote:
   Autrijus, I think your pictures look great.

Thanks!  Want a T-shirt from http://cafepress.com/pugscode/ ? :-)

 If it is not too much of a trade secret, I'd like to ask:
 
 1. What program(s) did you use to make the pictures?

Microsoft Visio 2003.

 2. Did you create the icons yourself or get them from somewhere?

They are the free Nuvola icon set. :)

Thanks,
/Autrijus/


pgpawA0Cu3DtG.pgp
Description: PGP signature


Re: Parrot and Neko

2005-08-19 Thread Autrijus Tang
On Fri, Aug 19, 2005 at 07:37:41PM +0200, Nicolas Cannasse wrote:
 I released a few days ago the Neko intermediate language at
 http://nekovm.org . In the FAQ I'm comparing Neko to LLVM / C-- and Parrot.
 According to a mail sent to me by Leopold Toetsch I got some points wrong
 when trying to generalize theses three frameworks in the same category,
 which of course is true since Parrot is more high-level than the two
 others and still I guess more low-level than Neko.

I'm not sure how you mean by Neko being of higher level than Parrot;
for all I can see they offer pretty similiar abstractions, with Parrot
additionally providing an object model (including RTTI for user-defined
types), namespaces, and first-class continuations.

 I would like to know if some people would be interested in studying a way to
 run Perl6 programs on Neko, or which would be the problems in trying to do
 so, since Neko - as Parrot - is intended to provide a common runtime for
 several languages.

Cool. I'd like to direct further perl6-on-neko mails to perl6-compiler
(Cc'ed), if that is okay with you.

The most crucial thing I see from Parrot is the built-in support of full
continuations; most other things Perl 6 needs can be faked one way or
another, but a CPS-transformed runtime on another VM is more difficult
to reason about than a VM that is built around CPS.

Also, while to me PIR is much more primitive and considerably harder to
work with than the Neko language (which at least has nested expressions),
at least the builtin types and functions are enumerated (with
documentations), which makes a code generator much easier to write.

It would be great if some kind of documentation can be generated
automatically, akin to how Parrot generates .pod files from ops/*.op,
about the semantics of various builtin (neko/vm/builtins.c) and library
(neko/lib/) primitives.  Without that information it is not feasible
for us to source-dive constantly to target the runtime.

 I guess that some LambdaCamels here will be interested to know that the Neko
 compiler is written in OCaml and than I'm planing to add the NekoML language
 that would bring a ML type system language running on the Neko runtime, the
 goal being to be able to rewrite the Neko compiler in NekoML.

That would be great.  It would be even better if F-sub can be translated
to NekoML in a type-directd fashion somehow, since that will safe a lot
of time here.  AbsIL-to-NekoML would be useful, too.

Thanks,
/Autrijus/


pgpc4pUjWyEll.pgp
Description: PGP signature


Re: Serializing code

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 12:24:40PM +, Ingo Blechschmidt wrote:
 - closures? 
 A subclass of Code, e.g. Bare. 

pedantic
There is no Bare anymore:
Code - Routine
 - Block
/pedantic

Thanks,
/Autrijus/


pgplvP6gLhemH.pgp
Description: PGP signature


Re: Implementing perl BEGIN blocks

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 04:51:58PM +0200, Leopold Toetsch wrote:
 There was some recent discussion [1] [2] on p6l about BEGIN blocks and 
 constant, which is executed at compile time too.
 
 Parrot has since quite a time the @IMMEDIATE subroutine pragma, which 
 causes execution of subs during compilation.

You mean, during PIR compilation?

 As PMC constants are already represented as frozen images in PBC this 
 would work for nested data strucuters, objects, and their classes too.
 
 Comments welcome,

I think it's interesting, but as BEGIN blocks may affect subsequent
parsing, as well as trigger compilation of other source files, I wonder
how to address this.  Hmm.

Also I wonder about scoping issues:

{
my $a = $a / 2;
BEGIN { $a = 10 };
}
say $a; # this should to print 5

How is @IMMEDIATE going to handle this?

Thanks,
/Autrijus/


pgpcvuMn4K7uB.pgp
Description: PGP signature


Re: Implementing perl BEGIN blocks

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 06:00:43PM +0200, Leopold Toetsch wrote:
 This shouldn't be a problem (at least when the last few globals from 
 imcc are gone), i.e. compilation / running code should be fully re-rentrant.

Oooh, that will be much better.

 BTW can you explain why the above example prints 5?

That was a typo.  Something like this may illustrate the issue better:

my $a;
{ my $b; BEGIN { $a = { say $b++ } } }

Thanks,
/Autrijus/


pgpvPARUfK4wl.pgp
Description: PGP signature


Re: Hoping that Params::Validate is not needed in Perl6

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 10:02:23AM -0700, chromatic wrote:
 On Wed, 2005-08-17 at 23:43 -0500, Dave Rolsky wrote:
 
  But I'd really like to get this stuff done at compile time wherever 
  possible.  If I write this:
  
 validate( credit_card_number: $number );

BTW, the colon is on the left:

:credit_card_number($number)

  it should blow up at compile time, right?
 
 Does that depend on how closed you want Perl 6 to think your world is at
 compile time?

Right, because introducing new multi variant at runtime is a
desired feature.  Which is why I think closed should not be
limited to classes, but should extend to packages as well...

Thanks,
/Autrijus/


pgp8R2G2dVU87.pgp
Description: PGP signature


Re: my $pi is constant = 3;

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 10:09:16AM -0700, Larry Wall wrote:
 In other words, you could desugar
 
 sub foo ($a = 1) {...}
 
 to
 
 sub foo ($a) {
   $a = 1 unless exists $a;
   ...
 }

I like this.  Can we go for it, at least for this week? :)

Thanks,
/Autrijus/


pgpjdvfaczX88.pgp
Description: PGP signature


Re: my $pi is constant = 3;

2005-08-18 Thread Autrijus Tang
On Fri, Aug 19, 2005 at 01:15:23AM +0800, Autrijus Tang wrote:
 On Thu, Aug 18, 2005 at 10:09:16AM -0700, Larry Wall wrote:
  In other words, you could desugar
  
  sub foo ($a = 1) {...}
  
  to
  
  sub foo ($a) {
  $a = 1 unless exists $a;
  ...
  }
 
 I like this.  Can we go for it, at least for this week? :)

Also, preemptively -- I think the corresponding delete $a is insane,
as it would just lift up the constancy problem one level, defeating the
no rebinding restriction.

Thanks,
/Autrijus/


pgpt3vjYU2Z5l.pgp
Description: PGP signature


Re: Serializing code

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 08:22:20PM +0300, Yuval Kogman wrote:
  sub foo { $?DOM.document.write(...) } 
  BEGIN { foo() };   # error, there's no $?DOM object 
 # at compile-time! 
 
 Unless you're compiling in the browser ;-)

Which... is possible, and that's how I plan to support eval().

Thanks,
/Autrijus/


pgpHjLnUAZzaX.pgp
Description: PGP signature


Re: my $pi is constant = 3;

2005-08-18 Thread Autrijus Tang
On Thu, Aug 18, 2005 at 10:26:00AM -0700, Larry Wall wrote:
 Sure.  Though it probably also wants to stay as metadata associated
 with the signature, since part of the reason for putting it in
 the signature in the first place is so that optimizers can install
 constants on the caller end, at least for ordinary sub calls.  Also,
 desugaring a predeclaration would tend to cloak the yadae at the end,
 but maybe that's not a problem unless you use the presence of bare
 yadae in the body to suppress redefinition warnings.

The full desugared form is, I think:

our foo;  # lifted to beginning of package!
...
BEGIN {
foo := a Sub is stub {
($a) := ?Internals::GETARGS();
$a = 1 unless exists $a;
# real body begins here
...
};
}

with the is stub -- not neccessarily exposed to the user level --
filled in by a parser rule, i.e. a predefined macro.

Does this sound sane?

Thanks,
/Autrijus/


pgp4hcyvUJMGm.pgp
Description: PGP signature


Re: my $pi is constant = 3;

2005-08-18 Thread Autrijus Tang
On Fri, Aug 19, 2005 at 01:36:30AM +0800, Autrijus Tang wrote:
 BEGIN {
   foo := a Sub is stub {
   ($a) := ?Internals::GETARGS();
   $a = 1 unless exists $a;
   # real body begins here
   ...
   };
 }

Er, sorry, the ($a) would need a my() scope identifier, as with all
parameters and hoisted mid-block my() declarations.

Also, a Sub should read a sub.

Thanks,
/Autrijus/


pgpTSrDDjSqJr.pgp
Description: PGP signature


Re: my $pi is constant = 3;

2005-08-17 Thread Autrijus Tang
On Wed, Aug 17, 2005 at 08:47:18AM -0700, Larry Wall wrote:
 : That could be made to work by defining constant to mean you can assign
 : to it if it's undefined.  But then it gets a little harder to reason
 : about it if $pi can later become undefined.  I suppose we could
 : disallow undefine($pi) though.

If you can assign it when it contains an undefined value, bad
things happen:

sub f ($x is readonly) { $x = 10 }
my $a; f($a);

Compare this with:

my $x is readonly;
$x = 10;

If it is defined as bound to a immutable value cell, both cases
above would fail, which is imho the easiest to explain.

 You could still reason about it if you can determine what the initial
 value is going to be.  But certainly that's not a guarantee, which
 is one of the reasons we're now calling this write/bind-once behavior
 readonly and moving true constants to a separate declarator:
 
 my $pi is readonly;
 $pi = 3;

The question remains, whether you can bind the readonliness away:

my $pi is readonly; # undef at this point
my $e is rw = 2.7;
$pi := $e;
$pi = 9;

I can argue both sides -- rebindable is easier to implement, but
non-rebindable is perhaps more intuitive.

Thanks,
/Autrijus/


pgppQH8aaeZBP.pgp
Description: PGP signature


Re: Parrot - Java integration

2005-08-17 Thread Autrijus Tang
On Mon, Aug 15, 2005 at 08:07:22PM +0100, Tim Bunce wrote:
 Anyone given any thought to Parrot - Java integration?

I have been looking at IKVM:

http://www.ikvm.net/

It's basically a full Java environment but using CLR instead of
JVM as the underlying runtime.  The JIT conversion from Java
bytecode to CIL is very interesting.  It's already reasonably
mature for serious applications.

Thanks,
/Autrijus/


pgpJne9jAPM8l.pgp
Description: PGP signature


Re: Ambiguity of parsing numbers with underscores/methods

2005-08-17 Thread Autrijus Tang
On Wed, Aug 17, 2005 at 11:37:26AM -0700, Larry Wall wrote:
 On Tue, Aug 16, 2005 at 05:25:40PM -0400, Roger Hale wrote:
 : 1.e5# all of these...
 : 1._e5   #
 : 1._0e5  #
 : 1.e_0_5_# == 1 * 10^5?
 
 The last three are illegal because underline is allowed only between
 digits.

...yet Perl5 accepts them.  So Perl6 is more restrictive?

(Which is good, because that's how Pugs currently implements them)

Thanks,
/Autrijus/


pgpOmp2xwJGou.pgp
Description: PGP signature


Re: Hoping that Params::Validate is not needed in Perl6

2005-08-17 Thread Autrijus Tang
On Wed, Aug 17, 2005 at 11:45:52PM -0500, Dave Rolsky wrote:
 And another question.  How will I make Perl6 not do automatic coercion for 
 me.  If I have this sub:
 
  sub date (Int +$year is required, +$month, +$day)

BTW, Pugs supports the ++ syntax, which iirc is said to be back in favour
during the Oscon design meeting:

sub date (Int ++$year, +$month, +$day)

 and someone does this:
 
  date('this year', 12, 1);
 
 I'd prefer for this to fail, rather than giving me -12-01!  I vaguely 
 remember a mention of use strict 'types' either on this list or hanging 
 out with some pugs folks at YAPC.

You will probably get:

1. a compile time warning of unsafe coercion, possibly made fatal.
and 
2. a NaN at runtime if you ignore the warning.

Thanks,
/Autrijus/


pgp1xZHMMuAGd.pgp
Description: PGP signature


Type inferencing for Perl5

2005-08-16 Thread Autrijus Tang
On Tue, Aug 16, 2005 at 02:04:41PM +0100, Nicholas Clark wrote:
 On Thu, Aug 11, 2005 at 01:35:14AM +0800, Autrijus Tang wrote:
  On Wed, Aug 10, 2005 at 07:32:01PM +0200, TSa wrote:
   Counting the sigil quadriga as 4, what is the fifth element?
   @ $ % :: 
  In Perl5, :: is replaced by *.
 
 Strictly in Perl 5 there are 7 types
 SCALAR, ARRAY, HASH, CODE, GLOB, FORMAT and IO.
 
 (where IO might actually be 2 types, file handles and directory handles,
 and in turn FORMAT is implemented as a subtype of CODE.

 Also, internally there are 16 variants of SV*, with mostly a 1 to 1 mapping
 for all the types except SCALAR, which sort of absorbs the other 10. Except
 that the null SV type is easily directly morphable into any of the others.

It would be great if we can use a type-directed transform from Perl 5
syntax tree into PIL/Perl6, i.e. annotate each term with the 16
variants, maybe with union/intersection types that represents ambiguous
context, such as:

f(reverse(g()));

Hm, I seem to remember that Gary Jackson (cc'ed) is working on that,
as his Summer of Code project.  Gary, can you share with us how you
plan to approach that, and/or how to get involved to your project?

Thanks,
/Autrijus/


pgpwAje3EkLjb.pgp
Description: PGP signature


Re: Time::Local

2005-08-16 Thread Autrijus Tang
On Tue, Aug 16, 2005 at 08:37:24AM -0700, Larry Wall wrote:
 : But that's in contrast to your saying that the epoch would be December 31, 
 : 1999 at 23:59:29.0 UTC.  Or did I misread your earlier messages?
 
 Yes, you misread it.  I was angling for 00:00:00.0 UTC.  But it scarcely
 matters if UTC keeps screwing around with leap seconds, and civil time
 stays locked to UTC.  I personally think we should add a bunch of leap
 seconds at the beginning of every year divisible by 100, and leave the
 rest of the years alone.

...This seems to be quite consistent with the rumoured US proposal to
abolish leap seconds by adding leap hours every 500 years or so:

http://www.post-gazette.com/pg/05210/545823.stm

Ending leap seconds would make the sun start rising later and later by the
clock -- a few seconds later each decade. To compensate, the U.S. has
proposed adding in a leap hour every 500 to 600 years, which also
accounts for the fact that the Earth's rotation is expected to slow down
even further. That would be no more disruptive than the annual switch to
daylight-saving time, said Ronald Beard of the Naval Research Laboratory,
who chairs the ITU's special committee on leap seconds and favors their
abolishment. It's not like someone's going to be going to school at four
in the afternoon or something, he said.

Thanks,
/Autrijus/


pgp64R6ie0nA5.pgp
Description: PGP signature


Re: Should this be valid in perl 6?

2005-08-16 Thread Autrijus Tang
On Tue, Aug 16, 2005 at 03:03:39PM +0800, Yiyi Hu wrote:
 $handle.close
 close($handle)
 close $handle:
 close $handle
 
 From Synoposis, It's said that the last example( close $handle )
 should be valid.
 But in pugs, It isn't.
 
 class TMP { method tmp { Hello.say}; }; my TMP $t .= new;
 tmp $t;
 
 So, I wonder, If perl 6 will allow tmp $t;

Hm, I think that's a case of a unimplemented special case.

I have just sent you a committer invitation; please write it up as a
test in t/syntax/ and commit the new test.

Thanks!
/Autrijus/


pgpjhLsFOVaHL.pgp
Description: PGP signature


Re: Should this be valid in perl 6?

2005-08-16 Thread Autrijus Tang
On Wed, Aug 17, 2005 at 12:42:31AM +0800, Autrijus Tang wrote:
  class TMP { method tmp { Hello.say}; }; my TMP $t .= new;
  tmp $t;
  
  So, I wonder, If perl 6 will allow tmp $t;
 
 Hm, I think that's a case of a unimplemented special case.
 
 I have just sent you a committer invitation; please write it up as a
 test in t/syntax/ and commit the new test.

Fixed as r6286.  Please still commit the test, and add your
(ideographic?) name to AUTHORS.

Thanks,
/Autrijus/


pgp0HGmSELY11.pgp
Description: PGP signature


Re: Generic classes.

2005-08-16 Thread Autrijus Tang
On Mon, Aug 15, 2005 at 11:07:51AM -0700, Larry Wall wrote:
 Sure, except that you're not really inheriting from a role here.
 You're really inheriting from an anonymous class of the same name.  :-)

Hmm, Anonymous class with the name 'Array of Any' sounds like
an oxymoron.  Also consider:

role Foo {};
my Foo $x .= new;
my Foo $y .= new;
ref($x) eqv ref($y);# bool::true, surely?

If all the anonymous classes are actually the same class underneath, and
have the name that's identical to the role name, then where do their
anonymousness manifest?

Can we simply say Foo is a role can double as a class -- i.e. you
can choose to is it or does it?  Then it follows that Array of Any
is a class, and Array of Int is also a class, etc.

Thanks,
/Autrijus/


pgpzRAtDlfrXR.pgp
Description: PGP signature


Re: Pugs MetaClass Model Picture

2005-08-15 Thread Autrijus Tang
On Mon, Aug 15, 2005 at 02:03:22PM +0400, Konovalov, Vadim wrote:
  # Pugs - Lambda Camels
  http://pugscode.org/images/lambdacamels.png
 
 I wonder do greek symbols have any meaning?

Yes, omega stands for higher-order polymorphism, as in
System F-omega.

The reversed E is the standard there exists symbol in mathematics.

The Y letter stands for the Y combinator, the canonical
device for general recursion.

The lambda, well, stands for lambda. :)

Thanks,
/Autrijus/


pgpHPumlzNVbc.pgp
Description: PGP signature


Re: Generic classes.

2005-08-15 Thread Autrijus Tang
On Mon, Aug 15, 2005 at 08:19:38AM -0700, Larry Wall wrote:
 I think the distinction is still useful to document that there are
 still unbound types.  What we need to emphasize is that a role can be
 used as a class, at which point any unbound types are bound to Any,
 or whatever we're calling it these days.  I'd say Array is a role,
 not a class.  So these all might do different things:
 
 class LoudArray is Array { ... }
 role LoudArray does Array { ... }
 role LoudArray is Array { ... }

So the last line means a role can be used just like a class, and
_inherit_ its behaviour as well?

role Point { has $.x; has $.y; method move_right { $.x++ } };
role MyPoint is Point {
method move_right { ./SUPER::move_right(); $.y++; }
}

Thanks,
/Autrijus/


pgpSJaSHU4JCK.pgp
Description: PGP signature


Re: Generic classes.

2005-08-15 Thread Autrijus Tang
On Mon, Aug 15, 2005 at 10:43:45AM -0700, Larry Wall wrote:
 : So the last line means a role can be used just like a class, and
 : _inherit_ its behaviour as well?
 : 
 : role Point { has $.x; has $.y; method move_right { $.x++ } };
 : role MyPoint is Point {
 : method move_right { ./SUPER::move_right(); $.y++; }
 : }
 
 It means that when MyPoint is finally nailed down into a class, that
 class will inherit from Point.  The role itself doesn't inherit.

Aye.  But if a Role can be inherited _from_, then this should
work too, right?

role Point {
has $.x; has $.y;
method move_right { $.x++ }
};
role OurPoint is Point {
method move_right { ./SUPER::move_right; $.y++ }
}
role MyPoint is MyPoint {
method move_right { ./SUPER::move_right; $.x++ }
}

my MyPoint $point .= new( :x(0) :y(0) );
$point.move_right;
say $point.x; # 2
say $point.y; # 1

Thanks,
/Autrijus/


pgpOkxZOMIspG.pgp
Description: PGP signature


Re: Pugs MetaClass Model Picture

2005-08-14 Thread Autrijus Tang
On Sat, Aug 13, 2005 at 04:07:28AM +0800, Autrijus Tang wrote:
 On Sat, Aug 13, 2005 at 01:08:38AM +0800, Autrijus Tang wrote:
  As promised on #perl6, today I produced a drawing showing how the
  Perl 6 metamodel would work in Pugs.  It aims to cover the common
  elements between Perl5, JavaScript and Haskell editions:
  
  http://pugscode.org/images/metamodel.png
  
 
 Stevan made a GIF animation showing the bootstrapping sequence:
 
 http://no.perlcabal.org/~stevan/metamodel.gif

Simon Cozens posted some questions on my journal entry; he mentioned
on IRC that we should probably bring it back to p6c.  Previous
discussion is here:

http://use.perl.org/~autrijus/journal/26259

In other news, I made two more picture today, this time not related
to Pugs internals:

# Perl 6 - Imaginary Timeline
http://pugscode.org/images/timeline.png

# Pugs - Lambda Camels
http://pugscode.org/images/lambdacamels.png

Thanks,
/Autrius/


pgpVZ5TYDJiFl.pgp
Description: PGP signature


Generic classes.

2005-08-14 Thread Autrijus Tang
S06 made many explicit uses of generics as classes, which I find
difficult to reconcile with the only roles takes type parameter
ruling.  For example:

my Hash of Array of Recipe %book;
my Hash[returns=Array[returns=Recipe]] %book;

And later:

class LoudArray is Array { ... }

Clearly, here Hash and Array are used as instantiable, generic classes,
instead of mere roles.  Does this need to change, or can we lift the
ban on type-parameterized classes?

Thanks,
/Autrijus/


pgp13rCkji3S3.pgp
Description: PGP signature


Pugs MetaClass Model Picture

2005-08-12 Thread Autrijus Tang
As promised on #perl6, today I produced a drawing showing how the
Perl 6 metamodel would work in Pugs.  It aims to cover the common
elements between Perl5, JavaScript and Haskell editions:

http://pugscode.org/images/metamodel.png

I plan to draw another picture showing the time-indexd bootstrapping
process; feedback are welcome.  Good ideas found on that design is due
to Stevan Little; all flaws are likely to be my fault. :)

The gnostic metasyntactic names coincide with names used in the
new PIL runcore:

http://svn.openfoundry.org/pugs/src/PIL/MetaModel.hs
http://use.perl.org/~autrijus/journal/26097

You may wish to first consult a more accessible, much reduced version,
written in Perl5:

http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/docs/MiniMetaModel.pl

Other documents under the same directory are helpful, too.

Thanks,
/Autrijus/


pgpYQ8iBfDRQq.pgp
Description: PGP signature


Re: Pugs MetaClass Model Picture

2005-08-12 Thread Autrijus Tang
On Sat, Aug 13, 2005 at 01:08:38AM +0800, Autrijus Tang wrote:
 As promised on #perl6, today I produced a drawing showing how the
 Perl 6 metamodel would work in Pugs.  It aims to cover the common
 elements between Perl5, JavaScript and Haskell editions:
 
 http://pugscode.org/images/metamodel.png
 

Thanks for #perl6 and #parrot's feedback, I have uploaded several
new revisions under the same URL.

Stevan made a GIF animation showing the bootstrapping sequence:

http://no.perlcabal.org/~stevan/metamodel.gif

Thanks,
/Autrijus/


pgpTbWeZcKIsV.pgp
Description: PGP signature


Re: Typed type variables (my Foo ::x)

2005-08-11 Thread Autrijus Tang
On Thu, Aug 11, 2005 at 08:02:00PM +1000, Stuart Cook wrote:
 What's the current meaning of type annotations on type-variables?
 
 For example, if I say...
 
 my Foo ::x;
 
 ...which of these does it mean?
 
 a) ::x (=) ::Foo (i.e. any type assigned to x must be covariant wrt. Foo)
 b) ::x is an object of type Foo, where Foo.does(Class)
 c) Something else?

My current reading is a) -- but only if ::x stays implicitly
is constant.  So your assigned above should read bound.

 Also, can I do crazy stuff like this?
 
 my $a = ::Foo;
 my ::$a $obj;  # analogous to @$x, where $x is an arrayref

Note that $a at compile time is unbound, so that automatically fails.
Now had you written this:

my $a ::= ::Foo;
my ::$a $obj;

Then I can see it working.

Thanks,
/Autrijus/


pgpbCgwOgxfmQ.pgp
Description: PGP signature


Re: Classes as special undefs

2005-08-11 Thread Autrijus Tang
On Thu, Aug 11, 2005 at 08:53:47PM +1000, Stuart Cook wrote:
 On 11/08/05, Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] wrote:
  One that you missed was that this syntax:
  
 my Dog $spot .=new();
  
  Falls out of it quite naturally.
 
 Actually I tried to mention that indirectly, but I'm glad you
 explicitly mentioned it.

What about this?

my $spot = Dog;
defined($spot); # false!?
$spot .= new;   # instantiated?

Thanks,
/Autrijus/


pgpCO7fYWwTAk.pgp
Description: PGP signature


Re: Classes as special undefs

2005-08-11 Thread Autrijus Tang
On Thu, Aug 11, 2005 at 04:47:49PM +0200, TSa wrote:
 OK, let's play some manual type inferencing ;)

Note that $spot here is intended to be dynamic typed, i.e. not subject
to inference.  :-)

 my $spot = Dog;
 
 $spot.does(Item of Dog), that means what ever the name Dog represents
 was stored or bound to $spot.

Right, except $spot can later hold other non-Dog values as well, as it
is dynamically typed by default...

 defined($spot);  # false!?
 
 true! Even for my $spot = ::Dog because when my is evaluated the
 name ::Dog has be be bound, AUTOLOADED or by whatever means become
 available.

I agree, with exactly the same logic.  However, Larry somehow thought
that defined(Dog) is false, which should lead defined($spot) is false
as well.  I still can't quite grasp this idea. :)

Thanks,
/Autrijus/


pgpXA2s4zXWR8.pgp
Description: PGP signature


Re: Proposal: is defined trait, is typed trait, traits pragma.

2005-08-11 Thread Autrijus Tang
On Thu, Aug 11, 2005 at 09:22:27AM -0700, Larry Wall wrote:
 On Thu, Aug 11, 2005 at 10:47:35AM +0800, Autrijus Tang wrote:
 : Adding inference (is typed) to the mix massively sweetens the first
 : option, which would be a good thing.
 
 Only if the programmer can be taught to understand the inferences...

Aye.  That is a very good argument for is typed to be off by default,
which I fully concur. :)

 Probably the first, actually, given the .= shortcut.  It takes *me*
 a lot of thought to reproduce in my head what the inferencer is doing
 there, and you can't really understand code unless you can play the
 same mindgames the computer is playing.  When the computer gets too
 smart, it forces anyone of less-than-genius caliber into cargo-cult
 programming.  That's what I don't like about type inferencing systems.

Indeed, but I expect Perl6 programmers start rapid-prodotyping in the
dynamic variant of Perl6, so the inferencing does not kick in anyway.

However, once a programmer starts using type annotations, rapidly the
compiler will (rightfully) complain about unsafe coercing.  That would
force the programmer into another kind of cargo-cult programming,
rampant in the Java world, namely manually key-in type declarations
everywhere.

Also, it is common in inference-based language environment to tell you
the inferred type for expressions, in a way that can be copy-and-pasted
back to the program, instead of having to type them out by hand.

Something like this:

pugs sub fact ($x) is typed { [*] 1..$x }
pugs :t fact
sub fact (Int $x -- Int)

 And there's something to be said for locating type information near
 the my declaration for documentation purposes even if it's entirely
 redundant.

That is true.

 Actually, this is a case where a declared return variable would reduce
 my cognitive load since I don't have to scan for a return statement
 to see that $skip is in fact the return value:
 
 use traits 'typed'; 
 method skip (-- Test::Builder::Test::Skip $skip) {
   $skip .= new;
   my $status = $skip.status;
   $status.do_something; $skip.do_something; # ...
 }
 
 Arguably that's just locating the type near the my again, though the
 my is implicit in the signature in this case.

Yes, I think that form would rock.  Also, I think leaving off the
Test::Builder::Test::Base::Status from the $status declaration does
not harm its documentation value -- indeed, that's the DWIM form Perl
programmers are used to.

Thanks,
/Autrijus/


pgpqACMdllQpn.pgp
Description: PGP signature


Re: my $pi is constant = 3;

2005-08-11 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 12:41:17PM -0700, Larry Wall wrote:
 : If yes, what does it desugar to?
 : 
 : my $pi is constant := 3;
 : my $pi is constant ::= 3;
 
 In this case it desugars to
 
 my $pi is constant = 3;
 
 :-)

However, I wonder if the intention was to replace the Perl 5 form of:

use constant PI = 3;

Which is a binding that happens at compile time.  It'd be somewhat
strange if this dies with undef -- or even 'Str':

my Str $x is constant = 'foo';
BEGIN { die $x };

Or do you think that people should really write ::= for constants?

Thanks,
/Autrijus/


pgpQWObbpwRkC.pgp
Description: PGP signature


Re: Perl 6 Meta Object Protocols and $object.meta.isa(?)

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 10:47:47AM +0200, Juerd wrote:
 Larry Wall skribis 2005-08-09 16:19 (-0700):
  So either something in the context tells us what Foo means, or
  it will be taken as a list operator that hasn't been declared yet.
 
 Is there, by the way, a pragma to force predeclaration of subs, to gain
 compile time typo checking?

Actually, use optimize :packageclosed effectively does that.

But it's an toplevel optimization, which is not applicable to
module authors.  So I'd very much welcome a lexical pragma that
forces static binding of subroutine calls.

Preferably we can use the same pragma can handle methods as well.
Something like:

use strict 'calls';

Thanks,
/Autrijus/


pgpyTVlepkjSX.pgp
Description: PGP signature


Re: Perl 6 Meta Object Protocols and $object.meta.isa(?)

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 06:03:18AM -0600, Luke Palmer wrote:
 On 8/10/05, Autrijus Tang [EMAIL PROTECTED] wrote:
  But it's an toplevel optimization, which is not applicable to
  module authors.  So I'd very much welcome a lexical pragma that
  forces static binding of subroutine calls.
 
 Yeah, but the whole point of not allowing that is so that you can
 override modules when you need to.

No.  A lexical static binding pragma controls the function I _call_;
the outlawed is final / is closed is to control the functions
I _define_.

Also, runtime rebinding of the actual function I call is always
possible, provided that it's rebound to something of compatible type.

Thanks,
/Autrijus/


pgpbuxt4ikQth.pgp
Description: PGP signature


Proposal: is defined trait, is typed trait, traits pragma.

2005-08-10 Thread Autrijus Tang
So I'm starting to write the inferencer.  Immediately I encounter the
problem that every type can potentially contain undef:

my IO $x = open('/etc/passwd');
$x = undef;
$x.close;

This raises the runtime error:

*** Can't call method close on an undefined value.

The undef literal can defeat the type checker freely:

my Int @x := undef;
say @x.end; # boom, undefined list generator, per S04

I understand $Larry had rejected RFC192 Undef Values ne Value, on the
ground that undef can now carry more interesting information.
However, sometime it is better if we can have a clear boundary so
the dreaded NullPointerException can be raised as early as possible.

The Nice programming langugage (http://nice.sourceforge.net/) has a nice
way to solve this.  Transliterating to Perl 6:

my IO $x = ...;  # never undef
$x.method;   # always succeeds

my ?IO $x = ...; # possibly undef
if defined $x {  # needed -- direct $x.method will not typecheck
$x.method
} else { # handle the undef case
...
}

This is certainly too static for Perl6.  However, it would be nice to
be at least able to declare a variable so that all undef reaching it
will instantly explode.  So I propose the is defined trait:

# must be assigned before use
# if open() returns undef, die right there.

my IO $x is defined = open('/etc/passwd');

$x = undef; # this fails at compile time

For the compiler, $x is compiled to the real IO type, while the
ordinary my IO $x is compiled to Either Error IO type.

Furthermore, it would be nice to tell the inferencer to infer the type
of a certain variable, instead of having to either write them out by
hand, or accepting their fate as Any.  I'd like to see is typed:

{
my $x is typed; # Infer $x's type (Str) for me
$x = Hello;
print $x;
}

Finally, it would get tedious to write them out by hand.  So a lexical
traits pragma may help:

{
# Entering the realm of referential transparency...
use traits  defined typed constant ;
my $x;  # automagically receives the three traits

{
# Falls back to the dynamic world...
no traits  typed constant ;
my $y;
}
}

Does this sound sane?

Thanks,
/Autrijus/


pgpdLhv58UdWZ.pgp
Description: PGP signature


Re: Perl 6 Meta Object Protocols and $object.meta.isa(?)

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 10:12:45AM -0700, Larry Wall wrote:
 We can get away with this in Perl 6 because bindings to positionals
 happen lazily.  So all we have to check for syntactically is that we
 don't have a subsequent declaration that changes the syntax from list
 to unary (or none-ary).

Just to be sure, this form from Perl5:

sub foo ($$) { ... }

is then no longer available to the parser?

Thanks,
/Autrijus/


pgp2iqlH3DwBf.pgp
Description: PGP signature


Re: Proposal: is defined trait, is typed trait, traits pragma.

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 10:25:05AM -0700, Larry Wall wrote:
 I'll have to think about the rest of your proposal, but I was suddenly
 struck with the thought that our platonic Class objects are really
 forms of undef:
 
 say defined IO; # prints 0

Hmm, bool::false stringifies to '0'?

Also, isn't IO an instance of Class, and hence defined?

My current understanding is that the typechecker considers IO to be of
Class type, not of IO type; the fact that IO.does(IO) is true is purely
an illusion created by special dispatch for .does.

Am I way off base? :)

Thanks,
/Autrijus/


pgpyl9MZNA633.pgp
Description: PGP signature


Re: Perl 6 Meta Object Protocols and $object.meta.isa(?)

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 07:32:01PM +0200, TSa wrote:
 you wrote:
 Perl 6 in its unannotated form is also (mostly) a typeless languages,
 with only the five builtin types, much like Perl 5 is.
 
 Counting the sigil quadriga as 4, what is the fifth element?

 @ $ % :: 

In Perl5, :: is replaced by *.

Thanks,
/Autrijus/


pgp6SpOJPVp7y.pgp
Description: PGP signature


my $pi is constant = 3;

2005-08-10 Thread Autrijus Tang
According to S06:

my $pi is constant = 3;

Is this a special form?  If yes, what does it desugar to?

my $pi is constant := 3;
my $pi is constant ::= 3;

If not a special form, should this work? 

my $pi is constant;
$pi = 3;

If yes, should this pass compilation?

my $pi is constant;
$pi = 3 if (0|1).pick;
$pi = 4;

If not, should this work?

my ($x is constant, $y is constant) = (1, 2);

Thanks,
/Autrijus/


pgp28FOFadzCA.pgp
Description: PGP signature


Re: $obj.meta.add_method('foo' = ???)

2005-08-10 Thread Autrijus Tang
On Tue, Aug 09, 2005 at 06:32:52PM -0400, Stevan Little wrote:
 Now I realize that in perl 6 you can re-open classes and add methods to 
 them. However this is not convenient for programmatic class generation. 

Because of string eval, you mean?  Well, some quasiquoting should
fix that, but let's suppose Template Perl6 doesn't exist...  :-)

 And I would really prefer the old Perl 5 way of mucking with the symbol 
 table not be the Perl 6 way of doing this. The ideal approach IMO is to 
 be able to do what the p5 MetaModel prototype does, and be able to add 
 methods to the metaclass instance directly (which then exposes them to 
 the class and instances of the class).
 
 So, how should this look in Perl 6? I currently have a two 
 thoughts/suggestions/directions.
 
 1) Anonymous methods/submethods
 $obj.meta.add_method('foo' = method (Foo $self: $bar) { ... });# 
 adding an instance method

I think it was ruled a while ago that anonymous methods should exist, so
this form is certainly more preferred. 

Thanks,
/Autrijus/


pgp7v3u6BrLTG.pgp
Description: PGP signature


Re: Proposal: is defined trait, is typed trait, traits pragma.

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 11:24:05AM -0700, Larry Wall wrote:
 : My current understanding is that the typechecker considers IO to be of
 : Class type, not of IO type; the fact that IO.does(IO) is true is purely
 : an illusion created by special dispatch for .does.
 
 Well, that's what I thought last week.  :-)
 
 But these days I'm wondering if the whole point of a class is to proxy
 for its missing members, and everything else is deferred to the metaclass.

Hm.  How is this different from prototype-based OO, as in JavaScript?
I'd like to see some code examples that shows the difference of the
week-before view and the current view...

Thanks,
/Autrijus/


pgp4adObBlDCg.pgp
Description: PGP signature


Re: Proposal: is defined trait, is typed trait, traits pragma.

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 09:29:38PM +0200, TSa wrote:
 Finally, it would get tedious to write them out by hand.  So a lexical
 traits pragma may help:
 
 {
  # Entering the realm of referential transparency...
  use traits  defined typed constant ;
  my $x;  # automagically receives the three traits
 
  {
  # Falls back to the dynamic world...
  no traits  typed constant ;
  my $y;
  }
 }
 
 Does this sound sane?
 
 To me it sounds more superfluous. What distinguishes
 'referential transparency' from 'the dynamic world'?

I think that's because you live in the static realm already. :)

my $x is typed;
$x = 123;
$x = length($x);

Would be a type error.  If it's in the dynamic world (as in Perl5),
that's just fine.  Does that difference make sense to you?

Thanks,
/Autrijus/


pgpW2Ryj2YhWi.pgp
Description: PGP signature


Re: Perl 6 Summary for 2005-08-02 through 2005-08-10

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 11:47:54PM -0400, Matt Fowles wrote:
   Perl 6 Compilers
Pugs Argument Processing
 Vadim Konovalov submitted a patch to pugs affecting @*ARGS processing.
 Maybe it got applied, maybe not, Warnock applies.
 http://xrl.us/g3op

In Pugs land, Warnock often translates to Vadim got a committer bit
and then Vadim committed the patch but did not reply to himself, as is
the case here. :)

Thanks,
/Autrijus/


pgpMWxdicudjP.pgp
Description: PGP signature


Re: Proposal: is defined trait, is typed trait, traits pragma.

2005-08-10 Thread Autrijus Tang
On Wed, Aug 10, 2005 at 10:31:40PM +0200, TSa wrote:
 my $x is typed;
 $x = 123;
 $x = length($x);
 
 Would be a type error.  If it's in the dynamic world (as in Perl5),
 that's just fine.  Does that difference make sense to you?
 
 The question remains, when exactly does $x acquire its constraint
 and how long does it persist? For my vars it's easy to say: from
 first assignment of none(Undef).does(Item) to end of scope.
 Which in the above code gives: the first assignment puts a Str
 into $x and if length returns an Int the second assignment fails.

Hm, in a language with type inference, the process is more like
inventing an anonymous type variable (let's call it ::X for now) for $x,
and noting the three constraints:

Str.does(::X)   # store from 123
::X.does(Str)   # fetch into length()
Int.does(::X)   # store from length()

No monotype satisfies the constraints, so unification fails and an
exception is raised.

 This is what I understand. But how usefull is this feature?
 I mean the programmer who reads 'my Int $x' knows that everything
 that is true for an Int is true wherever $x is subsequently used.
 A 'my $x is typed' pretty much means: read on and find out what
 type $x aquires.

Yes, but without this, you have to write down the full type every time
you declare a variable in order to get any typechecking at all.  In many
cases the compiler already knows it for you.

Really this is about path of least resistance.  Without inference,
we are asking the user to choose between:

1) Verbose annotation and type safety
2) Convenience (no annotation) and unsafe behaviour

Adding inference (is typed) to the mix massively sweetens the first
option, which would be a good thing.

 Do you have a non-trivial application for this in mind?

Yes.  But I can only show trivial examples:

use traits typed;
my $test = Test::Builder.new();

Now, without inferencing (the first line above), $Test would have to be
dynamically typed (no typechecks possible), essentially forcing the user
who wants typechecks to write out by hand:

my Test::Builder $test = Test::Builder.new();

This is silly.  Or, take another trivial (but common) example:

method skip (-- Test::Builder::Test::Skip) {
my Test::Builder::Test::Skip $skip = Test::Builder::Test::Skip.new;
my Test::Builder::Test::Base::Status $status = $skip.status;
$status.do_something; $skip.do_something; # ...
return $skip;
}

With inferencing:

use traits 'typed'; 
method skip (-- Test::Builder::Test::Skip) {
my $skip  .= new;
my $status = $skip.status;
$status.do_something; $skip.do_something; # ...
return $skip;
}

Which language do you want to write in? :-)

 It reminds me a bit to the 'bind a variable once in the constraint
 store' of the constraint programming paradigma.

No, I didn't have that in mind; I think it's just local type inferences.

 But there it serves as guiding the control flow. What is the purpose
 in a typed, imperative language as Perl6?

The purpose is that we don't have to be strong typists to enjoy Strong
Typing.  To make Perl6 easier to type, and easier to Type.

Thanks
,/Autrijus/


pgpzsj2n8Npoa.pgp
Description: PGP signature


Re: [DOCS] Updated intro.pod

2005-08-09 Thread Autrijus Tang
On Mon, Aug 08, 2005 at 12:03:25AM +0100, Jonathan Worthington wrote:
 So, I re-wrote it.  It now talks about PIR, and has examples in PIR.  It 
 mentions how PIR differs from PASM.  Subroutines now get a look in to the 
 introduction, and it mentions in passing that Parrot is capable of doing OO 
 stuff, threads and GC.  I've attached it for review and, if nobody yelps in 
 horror, I'll commit it in a couple of days.  Suggestions for improvements 
 are welcome, though as it's an intro it probably doesn't want to get too 
 much longer.

I did some spellchecking, PODification, and also some pedantic
wordsmithing (as attached).  Hope it helps.

Thanks,
/Autrijus/
# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
# $Id: intro.pod 8818 2005-08-05 13:21:09Z leo $

=head1 NAME

docs/intro.pod - The Parrot Primer

=head1 Welcome to Parrot

This document provides a gentle introduction to the Parrot virtual machine for 
anyone
considering writing code for Parrot by hand, writing a compiler that targets 
Parrot,
getting involved with Parrot development or simply wondering what on earth 
Parrot is.

=head1 What is Parrot?

=head2 Virtual Machines

Parrot is a virtual machine. To understand what a virtual machine is, consider 
what
happens when you write a program in a language such as Perl, the run it with the
applicable interpreter (in the case of Perl, the perl executable). First, the 
program
you have written in a high level language is turned into simple instructions,
for example Ifetch the value of the variable named x, Iadd 2 to this value,
Istore this value in the variable named y, etc. A single line of code in a
high level language may be converted into tens of these simple instructions.
This stage is called Icompilation.

The second stage involves executing these simple instructions. Some languages 
(for
example, C) are often compiled to instructions that are understood by the
CPU and as such can be executed by the hardware. Other languages, such as Perl,
Python and Java, are usually compiled to CPU-independent instructions.  A
Ivirtual machine (sometimes known as an Iinterpreter) is required to
execute those instructions.

While the central role of a virtual machine is to efficiently execute 
instructions,
it also performs a number of other functions. One of these is to abstract away 
the
details of the hardware and operating system that a program is running on. Once 
a
program has been compiled to run on a virtual machine, it will run on any 
platform
that the VM has been implemented on. VMs may also provide security by allowing 
more
fine-grained limitations to be placed on a program, memory management 
functionality
and support for high level language features (such as objects, data structures,
types, subroutines, etc).

=head2 Design goals

Parrot is designed with the needs of dynamically typed languages (such as Perl 
and
Python) in mind, and should be able to run programs written in these languages 
more
efficiently than VMs developed with static languages in mind (JVM, .NET). 
Parrot is
also designed to provide interoperability between languages that compile to it. 
In
theory, you will be able to write a class in Perl, subclass it in Python and 
then
instantiate and use that subclass in a Tcl program.

Historically, Parrot started out as the runtime for Perl 6. Unlike Perl 5, the 
Perl 6
compiler and runtime (VM) are to be much more clearly separated. The name 
IParrot
was chosen after the 2001 April Fool's Joke which had Perl and Python 
collaborating
on the next version of their languages. The name reflects the intention to build
a VM to run not just Perl 6, but also many other languages.


=head1 Parrot concepts and jargon

=head2 Instruction formats

Parrot can currently accept instructions to execute in four forms. PIR (Parrot
Intermediate Representation) is designed to be written by people and generated 
by
compilers. It hides away some low-level details, such as the way parameters are
passed to functions. PASM (Parrot Assembly) is a level below PIR - it is still 
human
readable/writable and can be generated by a compiler, but the author has to 
take care
of details such as calling conventions and register spilling. PAST (Parrot 
Abstract
Syntax Tree) enables Parrot to accept an abstract syntax tree style input - 
useful
for those writing compilers.

All of the above forms of input are automatically converted inside Parrot to PBC
(Parrot Bytecode). This is much like machine code, but understood by the Parrot
interpreter. It is not intended to be human-readable or human-writable, but 
unlike
the other forms execution can start immediately, without the need for an 
assembly
phase. Parrot bytecode is platform independent.

=head2 The instruction set

The Parrot instruction set includes arithmetic and logical operators, compare 
and
branch/jump (for implementing loops, if...then constructs, etc), finding and 
storing
global and lexical variables, working with classes and objects, 

Re: Container model - pictures and questions

2005-08-09 Thread Autrijus Tang
On Tue, Aug 09, 2005 at 02:06:58PM +0200, TSa wrote:
 The first one is about the compilation cycle:
 
 http://pugscode.org/images/simple-compilation.png
 
 Question: where is the namespace in the picture?
 I would expect it to be build in parallel to the
 syntax tree between parser and compiler. From there
 it might be serialized like PIL itself? Or as part
 of it? Only the Target Code Emitters might strip
 it if the target doesn't need or support it.

Packages, aka namespaces, are mutable pointers from names to pads.

They are emitted as part of PIL structure.

Also, thanks for the earlier suggestion about modeling container types
as parametric types; it's indeed a valid suggestion and
I'll try to use that idea in my current prototype.  Will write more
when I get the automatic insertion of coercion statements working.

Thanks,
/Autrijus/


pgpv9miJWduUa.pgp
Description: PGP signature


Re: Perl 6 Meta Object Protocols and $object.meta.isa(?)

2005-08-09 Thread Autrijus Tang
On Tue, Aug 09, 2005 at 06:36:28PM +0200, TSa wrote:
 But Smalltalk is a typeless language that dispatches along the lines
 of the (meta)class/(meta)object links. I propose to call this kind
 of thing slot dispatch and reserve single and multi method dispatch for
 the type based approach. Don't get me wrong, I consider them all as
 equally usefull tools that belong into a state of the art programming
 language. The only question is which gets the nicest syntax. And I
 guess the meta model by its nature of beeing 'behind the illusion
 of simplicity' has to take the burden of beeing somewhat uglier or
 more verbose or some such.

Perl 6 in its unannotated form is also (mostly) a typeless languages,
with only the five builtin types, much like Perl 5 is.

I suspect that the unannotated form will be the form most program
begins, which is why they are (naturally) shorter than annotated forms.

As you add more types and turn on optimization settings, the
inferencer/typechecker kicks in, and you get more static bindings;
however, the metamodel still exist at runtime, and it is with it that
most runtime reflection is performed.

 Yes, but those are not going to be handled in the meta-model, because 
 the meta-model is all about classes. You can however, build a classless 
 system on top of the metamodel, using classes of course.
 
 Could it be the case that choosing the same terms 'class' and 'object'
 on the meta level as on the user level is a *bad* idea? At least it
 will be a source of confusion.

I think the meta- prefix is what caused much of the initial conclusion.
When I first heard metatheory, I also thought it was some kind of
ontological mystery.  Turns out that meta in this context coincides
with guts, as in perlguts -- i.e., something that happens at the
internals level.

So, think of them more like Internal Objects and Internal Classes,
or Object Guts and Class Guts...

 Ahhh, the circularity of it all :)
 What is the benefit of the circularity?

The benefit is that the implementor won't need to implement a countless
set of turtles all the way down. :)

 Once you get used it it, it is really a beautiful thing.
 
 Infinite recursion is a great mental tool, indeed.
 But somewhat difficult to implement without either
 infinite processing time or infinite memory :)

Nah, lazy evaluation is the canonical solution to this!
(Sorry, can't resist it.)

Thanks,
/Autrijus/


pgp7tOGiUdfil.pgp
Description: PGP signature


Re: Hoisting lexical declarations

2005-08-09 Thread Autrijus Tang
On Tue, Aug 09, 2005 at 12:33:48PM -0700, Larry Wall wrote:
 : Alternatively, this could raise a warning and treat the second my()
 : as a no-op.  Personally, I'm in favour of an exception.
 
 I think the exception should certainly be the default, perhaps with
 the other behavior pragmatically available.

Yay for sanity!

 : The only problem I see with it is that $CALLER::x from ADD's position
 : will refer to the inner, not the outer, $x.
 
 A similar problem pops up for eval as well, though arguably it is the
 same problem if the compiler is using the CALLER mechanism to lookup
 variables.

Right, they are the same problem, as eval merely compiled string into a
Code and calls it in-place.

 : However, seeing that the two
 : arguments are in different scopes, I think it is not worth keeping any 
 promise
 : about interaction between $CALLER:: and mid-block declarations anyway.  
 : 
 : Does this sound sane?
 
 We can certainly declare it to be sane.  :-)

Please do then. :)

 Alternately, we could do the fancy thing now and just remember the actual
 limits of the variables' visibility.  But only if it's fun.  :-)

The fancy thing (position-counting) is likely to get out of control
rapidly under macros, so it's probably not much fun.  Erroneousness
sounds much saner.

Thanks,
/Autrijus/


pgpg7x2jW7vAL.pgp
Description: PGP signature


Re: Container model - pictures and questions

2005-08-08 Thread Autrijus Tang
On Sun, Aug 07, 2005 at 10:58:01PM +0100, Tim Bunce wrote:
 What's missing from the description is that there's some form of
 'pointer' from a container to the cell it currently contains.
 (I'm trying to avoid using the term reference.)

I have updated the picture.  It it marked as (v2):

http://pugscode.org/images/container.png

The read-only lookups are now in italic, and rw pointers are marked
as Pointer in the legend.  Also added the tied accessor to the
underlying tied object.

Thanks!
/Autrijus/


pgp5Y3tY7s1Mz.pgp
Description: PGP signature


Re: PXPerl 5.8.7-4 released with Windows binaries of Pugs 6.2.9

2005-08-08 Thread Autrijus Tang
On Mon, Aug 08, 2005 at 08:58:39AM -0400, Robert wrote:
 Just started here and I found PXPerl. What are the benefits of this over the
 ActiveState version?

Supposedly it's built with Intel C compiler, so it's a bit faster;
also you can choose among VC++, GCC and Intel C to compile further
CPAN modules, which is kind of convenient.

Thanks,
/Autrijus/


pgp8PEINMhYYL.pgp
Description: PGP signature


Re: PXPerl 5.8.7-4 released with Windows binaries of Pugs 6.2.9

2005-08-08 Thread Autrijus Tang
On Mon, Aug 08, 2005 at 09:39:41AM -0400, Robert wrote:
 Here is a question out of ignorance then. I currently use ActiveState but
 the ability to use CPAN vs PPM is kind of nice. Since AS only releases stuff
 as binaries, they work. Since I have to compile with PXPerl am I going to
 have problems with nmake on Windows (since most modules lean toward beind
 *nix friendly)?

That I believe is fine, as they should be binary compatible.

Also, you don't have to use PXPerl's Perl5 part to play with Pugs and
Parrot; you can continue to use C:\Perl\bin\ as your first PATH entry.

Thanks,
/Autrijus/


pgpLOyU7NJ3Vd.pgp
Description: PGP signature


Re: Container model - pictures and questions

2005-08-08 Thread Autrijus Tang
On Mon, Aug 08, 2005 at 06:04:51PM +0200, TSa (Thomas Sandla�) wrote:
 Autrijus Tang wrote:
 If I'm mistaken, please let me know, preferably by suggesting
 new arrangements on the diagram. :-)
 
 Without judging your mistakes, here are my comments to the
 container picture.
 
 1) I would move the ::name to the Pad level. The idea is
that ::name is some less specific supertype of the
Fantastique Four ($@%) if more than one of them exists
on the container level.

Please annotate this idea with the code.  You mean:

my $a = 3;
my @a = 1..10;

And somehow ::a is the supertype of the two!?

 2) I don't understand why you need two levels of indirection
firstly the container and then the cell. Not to mention
the third one to the tied thingy.

Because assignment (=), binding (:=) and tie are operating on different
levels, the same way Perl 5 typeglobs and tie works.

 3) Why is the link from the container labeled with :=
but the link between the cell and the value with =?

Because you change container-cell relationship with binding (:=) and
cell-value relationship with assignment (=).

I would consistently dispatch *all* operators including
:=, = and =:=. Preferably at compile/check time. Container
types are then on the same level as any other parametric
type. This naturally explains why your is IType can
be changed like underwear. For the type system it is just
another mutator. Whatever it does to the tied object takes
effect only by changing the type and hence the methods which
are applicable.

Again, please annotate your idea with code.  For scalars, I cannot see
how and assignment are supposed to be dispatched to the same
underlying object.  It seems to me that:

$x := $y

and

$x = $y

are manipulating two different entities, as I have shown in the drawing.

I would also like to know how the perl 5 idea of tie can be explained
with coercing the variable into another parametric type.  It seems to
me that tie() is a runtime operation that associates a cell with an
object, and the concrete object then intercepts access into that cell.

Thanks,
/Autrijus/


pgp0fJxAoF2tz.pgp
Description: PGP signature


Re: Container model - pictures and questions

2005-08-07 Thread Autrijus Tang
On Sun, Aug 07, 2005 at 10:58:01PM +0100, Tim Bunce wrote:
  The Container either has-a mutable cell, or has-a constant cell.
  
  my $mut = 3;
  my $con := 3;
  
  Use := to change the cell inside a container:
 
 How about:
 
   Use := to change the container to have a different cell.

That is correct.  Or replace the cell.

  Each cell has a Id.  Use =:= to check whether two containers have
  cells of the same Id:
  
  $x =:= $y;  # false
  $x =:= $z;  # true
 
 It's hard to imagine two containers both containing the same cell.
 The cell isn't really in two places at the same time.
 
 What's missing from the description is that there's some form of
 'pointer' from a container to the cell it currently contains.
 (I'm trying to avoid using the term reference.)

Yes.  The mutable has-a relationships are maintained with pointers.
I think the legend needs to be updated to reflect this fact.

 The description of the container model might benefit from making that
 pointer more explicit. It would help to clarify the action of the :=
 operator. (And =:= ?)

Right.  =:= is first retrieving the cells by chasing the pointer,
read the cell's id, and then comparing them.

 Please correct me if I'm laboring under too much perl5 baggage or
 confused in other ways.

No, your understanding is entirely sound.  The Container model is
basically a renormalized glob concept to apply also to lexical pads,
but with only one way to dereference the glob (i.e. the container),
instead of seven ways.

Hence, it looks like that it is indeed possible to rebind a variable
declared is constant to something mutable, just as this Perl 5
snippet does:

our ($a, $b);
*a = \3;
$b = 4;
*a = *b;
print $a;   # 4

Compare with Perl 6:

my $a := 3;
my $b = 4;
$a := $b;
print $a;   # 4

Thanks,
/Autrijus/


pgpHBFihaCzfs.pgp
Description: PGP signature


Re: Unable to run perl 6 test under Parrot 0.2.x

2005-08-06 Thread Autrijus Tang
On Sat, Aug 06, 2005 at 01:51:17AM +0400, Andrew Shitov wrote:
  Parrot 0.2.3 Serenity Released!
 
 Possibly I'm growling again but I cannot run any Perl 6 programme with
 new Parrots.
 
 One-liner test.p6 containing 'print perl 6;' is compiled to test.imc and 
 cause an error:

The README in that directory states:

Status
==
This prototype of the perl6 compiler was abandoned in June 2004. Current
work on the compiler may be found in the development of the Pugs
prototype (www.pugscode.org) and in the Parrot grammar engine (PGE) in
the Parrot repository at compilers/pge. You can track the development of
both on the perl6-compiler mailing list (perl6-compiler@perl.org).

Pugs, however, does work:

$ ./pugs -e 'say perl 6'
perl 6
$ ./pugs -B PIR -e 'say perl 6 (via parrot)'
perl 6 (via parrot)
$ perl perl5/PIL2JS/runjs.pl -e 'say perl 6 (via javascript)'
perl 6 (via javascript)

Thanks,
/Autrijus/


pgp7fMD8i1LhW.pgp
Description: PGP signature


Container model - pictures and questions

2005-08-06 Thread Autrijus Tang
(Cc'ing p6l, but this feels like a p6c thread...)

Greetings.  As I'm moving forward with the new PIL runcore,
I'm now trying to document my understanding as visual diagrams.

The first one is about the compilation cycle:

http://pugscode.org/images/simple-compilation.png

The second one is about the container model:

http://pugscode.org/images/container.png

Under this container model, there are two consequences that I'm
not very sure about.  One is that everything is rebindable:

my $a is constant;
my $b = 123;
$a := $b;
$a = 456;   # succeeds

Another is that the is IType form is always untieable:

my $a is SomehowTiedScalar;
untie($a); # succeeds

If I'm mistaken, please let me know, preferably by suggesting
new arrangements on the diagram. :-)

Thanks,
/Autrijus/


pgpGNMrooYm0D.pgp
Description: PGP signature


Re: Container model - pictures and questions

2005-08-06 Thread Autrijus Tang
On Sat, Aug 06, 2005 at 12:43:13PM -0400, Matt Fowles wrote:
 The pictures are pretty and the compilation one makes a great deal of
 sense, but I must admit to being enitrely confused by the container
 one.  I think part of the problem is that I don't have a good footing
 from which to understand it.  Is there somewhere I can look for a
 gentle explanation of the whole container/tied/untied thing?

Hm, I'm afraid there are not much material on this beyond the Synopses,
so I'll try to describe that picture a bit.

First off, all the lines you see are has-a relationships.  To wit:

Pad has-a Scalar Container that you can look up with $name.

my $name;

The Container either has-a mutable cell, or has-a constant cell.

my $mut = 3;
my $con := 3;

Use := to change the cell inside a container:

my $x = 3;
my $y = 4;
my $z = 5;
$x := $y;   # $x and $y now contain the same cell
$x := $z;   # not anymore; $x now shares the cell with $z

Each cell has a Id.  Use =:= to check whether two containers have
cells of the same Id:

$x =:= $y;  # false
$x =:= $z;  # true

Mutable cells has-a mutable scalar value.  Use = to change its value:

$mut = 5;   # works

Constant cells has-a immutable scalar value.  You cannot change it:

$con = 6;   # error

Each cell is declared to be is Tieable or not tiable when it was
allocated; you cannot change tieableness at runtime.

my $nvar;
my $tvar is Tieable;

Tieable cells may be tied or untied.  Use tie to tie a tieable cell:

tie($tvar, SomeClass, some_param = 1);

Non-tieable cells may not be tied.  However, untie always works:

untie($tvar); # works
untie($nvar); # no-op

That's about it. :-) Hopefully my two questions will make more sense
to you now...

Thanks,
/Autrijus/


pgp49c9iDshl5.pgp
Description: PGP signature


Re: The meaning of returns

2005-08-06 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 03:52:41PM +0200, TSa (Thomas Sandla�) wrote:
 And this is a natural extension to guide the inferencer so it won't be
 totally giving up on polymorphic functions such as id.  C) and D) can
 be taken together, resulting to a powerful soft typed language.
 
 This is my preference. The only known issue with parametric typing is
 the proliferation of params as soon as you want to stay away from
 unpecificity.

On #perl6, chip reported that during the design team meeting, the two
forms below are introduced to carry full inferential soft typing
information:

sub negate (Num $x -- Num) { ... }
our Num sub negate (Num $x) { ... }

 However, if we take the view that type annotation are merely storage
 allocation hints and runtime coercers, then A) is probably the way to go.
 
 Please no. Or at least not exclusively. I see your storage allocation
 hints as a data environment needed to implement the type.

The old returns form would become a type annotation for the return
inside it, but does not propagate outwards.  From the outside, that
function can return anything it likes.

sub negate (Num $x) returns Num { ... }

I think -- could be right-associative, so we can write things like:

# Function application combinator
sub infix:$ ( f:(::A -- ::B) -- A $x -- B ) {
return { f($^x) }
}

However, as these are only transcripts from IRC, I can't vouch for
their accuracy before @Larry confirms it.

Thanks,
/Autrijus/


pgpcOxWgPwlV6.pgp
Description: PGP signature


Re: Whitespace (Was: [RELEASE] Pugs 6.2.9 released!)

2005-08-04 Thread Autrijus Tang
On Thu, Aug 04, 2005 at 10:55:12AM +0400, Andrew Shitov wrote:
 why do we have to give up a space when calling functions under Pugs?
 
 A need to type open('file.txt') instead of open ('file.txt') makes
 me perplexing (not perl-flexing ;-) Our recent discussions in 'zip with()'
 gave no answer.

This is so:

print (1+2)*3;

can print 9, instead of 3.

However, all three forms below should still work:

open('file.txt');
open ('file.txt');
open 'file.txt';

Thanks,
/Autrijus/


pgpOUEocut2jd.pgp
Description: PGP signature


[RELEASE] Pugs 6.2.9 released!

2005-08-03 Thread Autrijus Tang
I am glad to announce Pugs 6.2.9, released during Ingy's OSCON talk:

http://pugscode.org/dist/Perl6-Pugs-6.2.9.tar.gz
SIZE = 1439642
SHA1 = efd32419dcddba596044a42564936888a28b3c69

Following last month's plan, this release features a Perl6/PIL to javascript
code generator, written in Perl 5, currently passing 64% of the test suite.

We also see the beginning of a code generator from PIL to perl5, and a
self-representing Perl 6 object model prototype.  The new PIL design and
runcore is also progressing nicely, which should give a more robust
specification to Perl 6's compile time and runtime semantics.

A live CD is available as usual, courtesy of Ingo Blechschmidt:

http://linide.sf.net/pugs-livecd-6.2.9.iso

Ingy's slides are under the Pugs tree as docs/talks/oscon-apocalypse.spork and
online at http://www.kwiki.org/apocalypse/start.html in HTML.

All in all, it's a lot of fun.  Check out the two movies we made for the
OSCON talk as well:

http://no.perlcabal.org/~autrijus/oscon05-autrijus.mp4
http://no.perlcabal.org/~autrijus/oscon05-stevan.mp4

Change the .mp4 to .swf or .wmv for alternate video formats.

Enjoy!
/Autrijus/

== Changes for 6.2.9 (r6049) - Aug 4, 2005

=== Pugs Internals

* New build system in `inc/PugsBuild`
** Configuration preferences are stored in `config.yml`
** Presists across builds, overridable via `%*ENVPUGS_BUILD_OPTS`
* `$CALLER::_` is now again usable in defaults.
* JavaScript Backend
** Actively progressing in `perl5/PIL2JS`
** Passes 64.00% of the Pugs test suite
* Perl5 Backend
** Begun in `perl5/PIL-Run`
** Primitive interactive shell as `crude_repl.pl`
* Object MetaModel
** Perl 5 prototype is mostly self-hosting 
** New C3-based method dispatch algorithm
** JavaScript version partially completed
** Java version begun (in very early stages)
* Pugs Intermediate Language
** New runcore design begun in `src/PIL`
** QuickCheck-based specification tests added
* Precompilation for arbitrary modules (not enabled by default)

=== Bundled Modules

* New Perl 6 modules:
** `MIME::Base64`
** `Recurrence`
** `Span`
* Additions to `libwww-perl`:
** `HTTP::Cookies`
** `HTTP::Query`
** `HTTP::Request::CGI`
** `HTTP::Status`
** `URI::Escape`
* Additions to `DateTime`:
** `DateTime::Set`

=== Test, Examples and Documentations

* Many new tests and test refactoring, we now have 8100+ tests
* A number of additions to `examples/cookbook`
* Beginning of Rule-based grammars for Perl6 in `modules/Grammars`
* SVG generation examples in `examples/graphics`
* `STATUS` document added to the top level to keep track of current progress
* `docs/notes/plan` expanded and added macro-related issues
* `examples/algorithms/Newton.pm` implements the newton method with currying
* `examples/network/evalbot.p6` gets safe print primitive
* `examples/network/seenbot.p6` gets pretty duration printing
* `examples/network/svnbot.p6` supports branch information
* `examples/ppt/cat.p6` added to Perl Power Tools
* iblech's LUGA talk as `Anatomie_eines_Compilers_am_Beispiel_von_Pugs.latex`
* ingy's OSCON talk as `oscon-apocalypse.spork`

=== Bug Fixes

* Fix pair binding for functions expecting pairs as arguments
* Global destruction is now guaranteed upon program exit
* Parameter's defaults are now evaluated in its original lexical scope
* Parser for hash subscripting was globbing whitespaces after it
* Primitive listops now handles Pairs as regular arguments
* Various `+$foos` in sub signatures changed to `?$foo` in `Test.pm`
* `%hx` was misparsed as `%h{'x'}`
* `-Inf` now stringifies as `-Inf`, not `-Infinity`
* `.end` and `.elems` no longer work as scalar methods
* `/a/ ~~ a` now works the same way as `a ~~ /a/`


pgpbq1Emgmfmm.pgp
Description: PGP signature


Re: sub foo ($x) returns ref($x)

2005-08-01 Thread Autrijus Tang
On Mon, Aug 01, 2005 at 03:16:50PM +0200, TSa (Thomas Sandla�) wrote:
sub equitype ( ::a $x, a $y) { ... }

That's not a bad idea at all.  I rather like it.  I'd just still like an
explicit type-unifying parens around ::a, just so people won't say

sub foo (::Int $x) { ... }

and accidentally rebind Int.

 which is the same behaviour as for the value of $x which can be used
 immediately for subsequent parameter bindings. Hmm, how do coderefs behave
 in that respect?
 
sub codeparam ( foo, ?$val = foo ) {...}
 
 Does this invoke a bar argument once for the call codeparam( bar )
 and capture the result in $codeparam::val while the call
 codeparam( bar, 42 ) stores 42 without invoking bar through
 codeparam::foo?

Yes.

 And in which exact environment does a call to bar take place when
 needed to bind $val? Purely ::CALLER? Signature as bound so far?
 ::OUTER of the use'er of the package which contains codeparam? Or the
 ::OUTER of the 'real' package file?

The lexical scope of the sub, with the signature bound so far.

Thanks,
/Autrijus/


pgpO5EjM9ryKW.pgp
Description: PGP signature


Re: Complete type inferencing

2005-08-01 Thread Autrijus Tang
On Tue, Aug 02, 2005 at 12:49:06PM +1000, Brad Bowman wrote:
  1. Asserted
  
  The usual case for Perl 6 functions, due to its default Item
  signature for parameters.  In the example below, I assume that ::* 
  cannot
  be changed freely to do away with ::*IO at runtime.  (If it could, then
  assertions won't be of much use in general.)
  
  sub f (IO $x) { $x.close }
  f(open('/etc/passwd'));
  
  As both f and open may be rebound at runtime, we cannot guarantee that
  this will not go wrong.  However, we can insert an runtime assertion 
  for $x
  in f's scope, so we can avoid doing the same assertion in *IO::close
  again.  If IO is declared as final, then *IO::close can also be 
  resolved
  statically.
 
 Could this be implemented optimistically, with disabled 
 assertions which are enabled at runtime if either f or open 
 are rebound?

Yes, it is conceivable to hoist assertions whereever possible, and
reactivate them if the earlier assertion no longer hold due to rebind. 
I'll prototype it a bit and see if it works.

Thanks,
/Autrijus/


pgpR7u66MSM2S.pgp
Description: PGP signature


Re: Definition of containers.

2005-07-31 Thread Autrijus Tang
On Sun, Jul 31, 2005 at 02:00:13PM +1200, Sam Vilain wrote:
 Tieing a hash would be the same as sub-classing it

Sub-classing a container is exactly what tying is all about.
That, and not losing the original non-tied storage inbetween ties.

 Or is this merely a mechanism for the above?

You can say that, yes. :)

Thanks,
/Autrijus/


pgpKxS4IzzOtO.pgp
Description: PGP signature


Eliminating {} and *{}

2005-07-31 Thread Autrijus Tang
Under my current design of containers (see definition of containers on
p6c), there are only Scalar, Array and Hash containers.  This is in
accordance to them being the only first-class data structures that deals
with mutable data storage.

This is similar to JVM's division between scalar data and collection data;
it's just Perl 6 introduces two collections with differnet interfaces.

With the elimination of the * sigil and the *{} dereferencer, the only
unresolved sigil type is .  Unlike collections, it is really difficult
to tell the difference between $code and {$code}.  Moreover, it makes
little sense to say:

tie(code, TiedCode);

Since it is much easier to just wrap the code in place.

All this led us to think about whether (my foo) can be merely treated
the same as (my Code $foo).  The mutable form will enable convenient
notations such as:

foo = sub { ... };

So instead of having to explain to newcomers that you cannot assign
to a -sigil symbol, it would all just work.  Under this view, {$x}
would be eliminated with *{}.

Another idea is to treat (my foo) the same way (my Code $foo is constant).
That will discourage people into assigning into functions, and enable
the compiler to detect function variables at lvalue position as errors,
but on the whole I don't think it's worth the complexity.

Does this make sense?

Thanks,
/Autrijus/


pgp8rJ03TtMzH.pgp
Description: PGP signature


Hoisting lexical declarations

2005-07-31 Thread Autrijus Tang
Pugs did not support inline variable declarations, largely because the problem
caused by this construct:

{
say values of β will give rise to dom!;
$x = $x + my $x if $x;
#1   #2  #3#4
}

The evaluation order for the four $x is (#4, #2, #3, #1). However, because
$Larry made it very clear that lexical scopes are lexical, (#1, #2) must refer
to the same (outer) $x, and (#3, #4) refers to the inner $x. When implemented
naively, this creates fragmented scopes in the PIL tree.

To simplify code generation, I propose that we float all lexical declarations
in a scope to the top of the scope, in the same place as its formal
parameters.  Of course, we will still reject bogus programs like this:

# No previous $x available here
{ say $x; my $x; }

But that means these now raises the same exception:

sub f ($x) { my $x }
sub f { my $x; my $x }

Alternatively, this could raise a warning and treat the second my()
as a no-op.  Personally, I'm in favour of an exception.

Under this scheme, the compiler will mark variable lookups to the outer
scope explicit.  The sample construct at the beginning of this post will
get compiled to this form, leaving the evaluation order explicit:

CODE(
syms = [$x],
body = [
SAY(values of β will give rise to dom!),
IF(
cond = $x,
body = ASSIGN(
from = ADD(
l = $OUTER::x,
r = $x,
),
into = $OUTER::x
)
);
]
);

The only problem I see with it is that $CALLER::x from ADD's position
will refer to the inner, not the outer, $x. However, seeing that the two
arguments are in different scopes, I think it is not worth keeping any promise
about interaction between $CALLER:: and mid-block declarations anyway.  

Does this sound sane?

Thanks,
/Autrijus/


pgp5Nvjf0RpOJ.pgp
Description: PGP signature


sub foo ($x) returns ref($x)

2005-07-30 Thread Autrijus Tang
Suppose we have a function that takes an argument and returns something
with the same type as that argument.  One previous suggestion is this:

sub identity ((::a) $x) returns ::a { return(...) }

This is fine if both invariants in the the meaning of 'returns' thread
are observed, since the inner return will check that (...).does(::a),
and the outer context will demand ::a.does(ref($x)).

However, this relies on the fact that we unify argument types first,
then use the bounded type variables to handle returns types.  Under that
scheme, It is less clear how to talk about how the types of two arguments
must relate.  For example, assuming argument types are unified in a single
phase, the example below does nothing useful:

sub equitype ((::a) $x, (::a) $y) { ... }

It won't not help even if we replace the implicit does with of:

sub equitype ($x of (::a), $y of (::a)) { ... }

The reason, in Luke Palmer's words:

The trouble with this is that it doesn't provide any type safety.
 In the case of a type conflict, a just degenerates to the Any type.
 (cf. pugs/docs/notes/recursive_polymorphism_and_type)

This fact, coupled with the unappealing (::a) syntax, leads me to look
for a more Perlish representation.  Adopting an idea from Odersky's
Nested Types paper, we can let terms occur at type variant position,
by introducing a ref form for types:

sub equitype ($x, $y of ref($x)) { ... }
sub subtype  ($x, $y does ref($x)) { ... }
sub identity ($x) returns ref($x) { ... }

This reads like Perl, and can be guarded with trivial compile time
and runtime checks.  We can also use type selectors to check
that pick can always return Int from an Array[of = Int]:

sub pick (@x) returns ref(@x).of { ... }

The only problem I can find is that the possible confusion between the
ref() operator and the unboxed basic type ref.  Another thought is to
simply use ::() as a special ref form:

sub pick (@x) returns ::(@x).of { ... }

But that can confuse with the symbolic dereference syntax.  All in all
I'm more happy with ref(), but better suggestions welcome.

Thanks,
/Autrijus/


pgpVukkp3HJdW.pgp
Description: PGP signature


Re: Binding scalars to aggregates

2005-07-30 Thread Autrijus Tang
On Sat, Jul 30, 2005 at 09:40:11AM -0700, Larry Wall wrote:
 Right, so I guess what really happens is ref autogeneration in that
 case, and there's no difference between
 
 $x = @array;
 $x := @array;
 
 Hey, who said anything about consistency?  :-)

Hm, not exactly.  This form:

$x = [EMAIL PROTECTED];

Triggers STORE for a tied $x, and allows for assignments to $x
afterwards.  This form:

$x := [EMAIL PROTECTED];

Destroys $x's current tie, and binds it to a read-only container
(as \ produces rvalues), so future assignments will not work.

I'll post a separate semi-formal analysis of containers to
perl6-compiler.

Thanks,
/Autrijus/


pgpzQezRLYGMl.pgp
Description: PGP signature


Definition of containers.

2005-07-30 Thread Autrijus Tang
I have just checked in the container type part of the new PIL runcore:

http://svn.openfoundry.org/pugs/src/PIL.hs

In the Pugs directory, you can run a sample test with:

*PIL tests
== %ENV =:= %ENV;
True
== %ENV =:= %foo;
False
== untie(%ENV); my %foo := %ENV;
()
== my %foo := %ENV;

Following is a semi-formal treatment for containers, directly transliterated
from the Haskell source.

Containers come in two flavours: Non-tieable and Tieable.  Both are typed,
mutable references.  There is no way in runtime to change the flavour.

data Container s a
= NCon (STRef s (NBox a))
| TCon (STRef s (TBox a))

A Non-tieable container is comprised of an Id and a storage of that type, which
can only be Scalar, Array or Hash.  Again, there is no way to cast a Scalar
container into a Hash container at runtime.

type NBox a = (BoxId, a)

A Tieable container also contains an Id and a storage, but also adds a
tie-table that intercepts various operations for its type.

type TBox a = (BoxId, a, Tieable a)

The type of tie-table must agree with the storage type.  Such a table
may be empty, as denoted by the nullary constructor Untied.  Each of
the three storage types comes with its own tie-table layout.

data Tieable a where
Untied :: Tieable a
TieScalar  :: TiedScalar - Tieable Scalar
TieArray   :: TiedArray  - Tieable Array
TieHash:: TiedHash   - Tieable Hash

Binding only happens between containers of the same type:

bind :: Container s a - Container s a - ST s ()

Additionally, the compiler needs to compile ($x := @y) into ($x := [EMAIL 
PROTECTED]).

To bind a container to another, we first check to see if they are of the
same tieableness.  If so, we simply overwrite the target one's Id,
storage and tie-table (if any):

bind (TCon x) (TCon y) = writeSTRef x = readSTRef y
bind (NCon x) (NCon y) = writeSTRef x = readSTRef y

To bind an non-tieable container to a tieable one, we implicitly remove
any current ties on the target, although it can be retied later:

-- %*ENV := %foo
bind (TCon x) (NCon y) = do
(id, val) - readSTRef y
writeSTRef x (id, val, Untied)

To bind a tieable container to a tied one, we first check if it is
actually tied.  If yes, we throw a runtime exception.  If not, we
proceed as if both were non-tieable.

-- %foo := %*ENV
bind (NCon x) (TCon y) = do
(id, val, tied) - readSTRef y
case tied of
Untied - writeSTRef x (id, val)
_  - fail Cannot bind a tied container to a non-tieable one

We can compare two containers for Id equivalence.  If the container types
differ, this should never return True:

(=:=) :: Container s a - Container s b - ST s Bool
x =:= y = do
x_id - readId x
y_id - readId y
return (x_id == y_id)

Untie an non-tieable container is a no-op:

untie (NCon x) = return ()

For a tieable container, we first invokes the UNTIE handler, then set
its tied slot to Untied:

untie (TCon x) = do
(id, val, tied) - readSTRef x
case tied of
Untied  - return ()
_   - do
tied `invokeTie` UNTIE
writeSTRef x (id, val, Untied)

Thanks,
/Autrijus/


pgpZ4bQLJ5AWC.pgp
Description: PGP signature


Complete type inferencing

2005-07-29 Thread Autrijus Tang
On Fri, Jul 29, 2005 at 04:59:21AM +0800, Autrijus Tang wrote:
 However, my intuition is that a soft-typed system, with clearly defined
 dynamic parts translated to runtime coerce and dependent types, that can
 work exactly as Perl 5 did at first, but provide sensible inferencing
 and compile-time diagnostics as you gradually provide annotations, is
 really the way forward.

Several people replied off-list to point out the SBCL/CMUCL system does
inferencing and static+runtime type tagging for Common Lisp.  After
playing with it a bit, it seems that soft typing does not naturally
describe my initial intuition, as it never rejects any programs.
When types cannot be inferred, it merely inserts runtime assertions.

What I'm designing is a system that can decide on one of five classes of
judgements for each PIL term:

0. Untyped

As in Perl 5, nothing is done for $x or the call to $x.close.
Runtime failures are never detected until the actual call is made.

sub f (Any $x) { $x.close }
f(42);

1. Asserted

The usual case for Perl 6 functions, due to its default Item
signature for parameters.  In the example below, I assume that ::* cannot
be changed freely to do away with ::*IO at runtime.  (If it could, then
assertions won't be of much use in general.)

sub f (IO $x) { $x.close }
f(open('/etc/passwd'));

As both f and open may be rebound at runtime, we cannot guarantee that
this will not go wrong.  However, we can insert an runtime assertion for $x
in f's scope, so we can avoid doing the same assertion in *IO::close
again.  If IO is declared as final, then *IO::close can also be resolved
statically.

2. Well-typed

This term's type is provably sound, and can be optimized at will
without any runtime checks.  An example:

{
my sub f (IO $x) { $x.close }
my sub g () returns IO { open('/etc/passwd') }
f(g());
}

Here the call to f and $x.close doesn't need assertions, as g's return
type took care of it.  Under use optimized, many more terms can be
resolved statically and checked in this manner.

3. Warning

Under certain circumstances, this term's type can be shown to be unsound,
but we cannot prove statically that this will come to pass:

my sub f (IO $x) { $x.close }
my sub identity ($y) returns IO|Str { $y }
f(identity(/etc/passwd));

Here the call to identity masked a potential type incompatibility.
We know that if the IO half of the junctive type is chosen then it
will typecheck; on the other hand, nothing in identity or $y tells
whether it will return IO or Str.  Hence we can raise a warning that
says this call can potentially go wrong had it returned Str.

4. Error

This is a type error:

my sub f (IO $x) { $x.close }
f(/etc/passwd);

Note that this can still be made to work at runtime by introducing
coerce:as from Str to IO, or make Str a subtype of IO.  Therefore
in the absence of optimization hints of closed for Str and final
for IO, the compiler should only raise a severe warning, that says
if you don't do something, this will fail at runtime.

However, if the user had provided the neccessary optimization hints: 

use optimize :classes close finalize ;
my sub f (IO $x) { $x.close }
f(/etc/passwd);

Then there is no way it could have worked, and the compiler should
reject this program.

Interested readers can consult Manfred Widera's similar work for Scheme,
in his Complete Type Inference in Functional Programming paper.

Feedback, preferably on-list, are most welcome. :-)

Thanks,
/Autrijus/


pgpmOuOsKeqPW.pgp
Description: PGP signature


Curious use of .assuming in S06

2005-07-29 Thread Autrijus Tang
In S06's Currying section, there are some strange looking examples:

textfrom := substr.assuming(:str($text) :len(Inf));

textfrom := substr.assuming:str($text):len(Inf);

woof ::= bark:(Dog).assuming :pitchlow;

Why is it allowed to omit comma between adverbial pairs, and even
omit parens around method call arguments?  Is .assuming a special form?

This is S06-specific; neither A06 nor E06 exhibits this syntax.

Thanks,
/Autrijus/


pgp7dyDQHVzbp.pgp
Description: PGP signature


Re: Curious use of .assuming in S06

2005-07-29 Thread Autrijus Tang
On Fri, Jul 29, 2005 at 12:53:03PM -0700, Brent 'Dax' Royal-Gordon wrote:
 Autrijus Tang [EMAIL PROTECTED] wrote:
  In S06's Currying section, there are some strange looking examples:
  
  textfrom := substr.assuming(:str($text) :len(Inf));
  
  textfrom := substr.assuming:str($text):len(Inf);
  
  woof ::= bark:(Dog).assuming :pitchlow;
  
  Why is it allowed to omit comma between adverbial pairs, and even
  omit parens around method call arguments?  Is .assuming a special form?
 
 Isn't this just another form of the syntactic rule that gives us
 @array.grep:{ ... } ?

I thought that only applies to adverbial blocks, not arbitary
adverbial (named) pairs.  Hm, S04 uses this:

leave :from(Loop) :labelLINE == 1,2,3;

So maybe this is as intended?  (If so, tests welcome. :-))

Thanks,
/Autrijus/


pgptQmKblgnJL.pgp
Description: PGP signature


Some thoughts on PIL

2005-07-28 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 06:31:34PM +0200, TSa (Thomas Sandla�) wrote:
 BTW, where can I read about PIL, other then in Parrot/Pugs svn?

(Cc'ing in P6C.)

The current type-indexed design of PIL is going away, because it is
closely tied to the PIR/Parrot model, to the disadvantage of our
Perl5/JavaScript backends.  Also it does not capture any notion of
rank-n types, and relies on the VM for a semantics for container types,
which is prone to trouble.

In the past few weeks I've been reading up on F:, Fw, CoC, vObj, as
well as intersectional and split types for object calculi, in the
hope of revamping PIL -- Pugs's new internal language -- that can
alleviate backend author's pain and improve type-directed translation.

Perl 6's uniqueness is that it relies on runtime-rebindable package
objects for its type system, but at the same time carries the vague
promise of partial static analysis for the part of the closed world via
toplevel `use optimize`.  The semantic of type annotations remains
unresolved; I reflected this in the recent `the meaning of returns`
thread.

It would be far easier if we concede that Perl 6 is essentially untyped,
and all type annotations are merely storage hints, that will still
always require runtime coercion.  This coincide with Parrot's current
idea of never checking subroutine parameter's PMC types (except for
MMD), and always resolve method calls as late as possible, exactly as
Perl 5 did.

Under that view, the only use of type annotation at compile time is
speeding up property/method lookup for typed variables, so they can be
looked up by number instead of names, provided new fields always go
toward the end.  Other than that, they can only serve as runtime
assertions, leading to the curious effect that well-typed programs
can run slower than the unannotated counterpart.

However, my intuition is that a soft-typed system, with clearly defined
dynamic parts translated to runtime coerce and dependent types, that can
work exactly as Perl 5 did at first, but provide sensible inferencing
and compile-time diagnostics as you gradually provide annotations, is
really the way forward.

Under soft typing, Parrot's role would become a fast implementation for
the object space and primitives, but the soundness of large-scale
programs and the standard library will be provided by the compiler, not
the runtime.  This plays well with Pugs's -- not neccessarily Perl 6's --
goal of keeping the language retargettable.

This may not be popular view, as evidented by the relative lack of
research and real-world interest to bridge the gap of static/dynamic
languages, so it would take a while to come up with a suitable formal
treatment.  I'm currently trying to express this idea under the F:
framework for the new PIL, and I'll keep p6c posted as it goes forward,
and cotinue to reflect design issues to p6l.

Thanks,
/Autrijus/


pgpzcvHiHzmiw.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-28 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 09:27:00AM -0700, Larry Wall wrote:
 Or maybe Any really does mean Object and we're just viewing our
 hierarchy too strictly if we make every relationship isa.  That's one
 thing that neither this formulation nor Thomas's are making very
 clear--which type relations are really subclassing, which are role
 composition, and which are subtype constraints.

FWIW, I've been reading up on Scala's formulation of trait/class/delegation
hierarchy, and I feel a bit like flipping through a puzzle book to look
at the hints, if not answers. :-)

http://scala.epfl.ch/docu/files/api/index.html

 And I'm still not entirely sure I believe the not-yet-bound-ness of
 Pairs is all that different from the not-yet-bound-ness of Junctions
 to the extent that a different type level is warranted.

Junctive autothreading are outside bindings -- they can be viewed as a
two-phase exception handling from parameter type mismatches that fires
away more function applications.  Pairs on the other hand are bound
normally; they just have a preferred zone unless overriden by the
parameter signature; this resolution is strictly within the same
one-step binding.  I think there may be more types to come that has its
preferred binding semantic, than outside-the-box devices like Junctions.

 I guess I still think there ought to be a way of marking Pairs on the
 call end as to whether they're intended for named args or not, without
 warping the whole top-level type system to that end.

I can see marking things explicitly for named bindings:

foo(:literalpair);
foo(*%nameds);
foo(*$pair);
foo([EMAIL PROTECTED]);

That will mean that foo($pair) will always be positional.

Thanks,
/Autrijus/


pgpwsP0LMxs4l.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-28 Thread Autrijus Tang
On Fri, Jul 29, 2005 at 05:59:43AM +0800, Autrijus Tang wrote:
 I can see marking things explicitly for named bindings:
 
 foo(:literalpair);
 foo(*%nameds);
 foo(*$pair);
 foo([EMAIL PROTECTED]);

Er, sorry, the last one should be

  foo(*%{ hash @list_of_pairs });

Thanks,
/Autrijus/


pgpq4Tu2ITfnw.pgp
Description: PGP signature


Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Fri, Jul 22, 2005 at 03:40:34PM -0700, Larry Wall wrote:
 I dunno.  I'm inclined to say that it should default to Item|Pair, and
 let people say Any explicitly if they really want to suppress autothreading.
 Otherwise conditionals and switches are going to behave oddly in the
 presence of accidental junctions.

Okay.  However, in that view, I suspect many builtins will be defined on
Item|Pair, for example perl, clone, id, as well as various coercion
builtins.  Considering that builtins are Code objects but not Routines,
maybe they, too, should default to Item|Pair -- except the ones that
operates on junctions, of course.

This leads me to think that maybe users don't really need to write down
the two junctive types, under the hierarchy below:

- Object
- Any
- Item
- ...pretty much everything
- Pair
- Junction
- num, int, str...

Since junctions are still boxed objects, having the Object type to
effectively mean Any|Junction seems natural (everything is an object).

Also, since Any unifies Item and Pair, the rule for implicit types of
argument becomes:

sub ($x) { }# Item $x
- $x { }   # Any $x- i.e. Item|Pair but not Junction
{ $^x } # Any $x- i.e. Item|Pair but not Junction

Does this sound sane?

Thanks,
/Autrijus/


pgpRSxeJCbrO5.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Wed, Jul 27, 2005 at 12:19:10PM -0400, Matt Fowles wrote:
 While we are talking about words... I dislike having Object encompass
 Juction.  I get the feeling that some people will write functions that
 take Objects and not expect Junctions to slip in.  I suppose that
 could be one of those hurdles that developers just have to jump, but
 it doesn't feel like it should be.

Er, but Junctions take methods, the same way Objects do, so if there is
an Object in the type hierarchy, Junction probably belongs to it.

However we can tone down the ordinariness of Object so people will be
less inclined to use it. Boxed?

Thanks,
/Autrijus/


pgpGTiXBMayFQ.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Wed, Jul 27, 2005 at 09:12:00AM -0700, Larry Wall wrote:
 Yes.  The only thing I don't like about it is that any() isn't an Any.

snip

 - Object
   - Mumble
   - Item
   - ...pretty much everything
   - Pair
   - Junction
 - num, int, str...

Hrm.  I thought the original motivation of forcing people to write

Any|Junction

was precisely to discourage people from accidentally write

sub foo (Any $x)

and have $x accept a Junction.  In other words, any() should not be of
type Any.  Hence it still feels natural for me that Any occurs at the
position of Mumble.

Thanks,
/Autrijus/


pgp8GevQWpLzr.pgp
Description: PGP signature


The meaning of returns

2005-07-27 Thread Autrijus Tang
Consider this:

sub id (Any $x) returns Any { return($x) }
sub length (Str $y) returns Int { ... }

length(id(abc));

Under standard static subtyping rules, this call will perform three
different typechecks:

 1) abc.does(Any) # (abc as Str)  === (Any $x) in id
 2) $x.does(Any)# ($x as Any) === (returns Any) in return
 3) Any.does(Str)   # (returns Any)   === (Str $y) in length

The final (returns Int) is unimportant here.

Obviously, typecheck #3 fails, as Any cannot do Str.  Indeed, there is
no type literal in the return position that can satisfy this static
typecheck for id, other than the bottom type which would be a subtype
for every type.  Let's call it All:

sub id (Any $x) returns All { return($x) }

However, had we used that, #2 will fail, as it would now be checking for
$x.does(All), which is guaranteed to fail regardless of whether the
check occurs at runtime (Str.does(All)) or compile time (Any.does(All)).

Hence, it seems to me that there are only four ways out:

  A) Omit the #3 check from compile time; at runtime, use the actual
 type of $x.  The returns type annotation will not propagate
 outward to the caller.
 
At compile time, check for #2: Any.does(Any)
At runtime, check for #2: abc.does(Any)
check for #3: abc.does(Str)

  B) Omit the #2 check from both compile time and runtime; this allows
 us to write the returns All version.
 
At compile time, check for #3: All.does(Str)
At runtime, check for #3: abc.does(Str)

  C) Make the return type observe both #2 and #3 at compile time,
 using junctive types to pass both checks:

sub id ( Any $x ) returns Any|All { return($x) }

  D) Make the return type observe both #2 and #3 at compile time,
 using type variables:

sub id ( (::T) $x ) returns ::T { return($x) }

At this moment, I don't have a strong preference to either; I'm more
curious on whether this topic has been covered before by p6l and @Larry.

Thanks,
/Autrijus/


pgpqpS9rYqWnB.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 03:55:55AM +0800, Autrijus Tang wrote:
 Hrm.  I thought the original motivation of forcing people to write
 
 Any|Junction
 
 was precisely to discourage people from accidentally write
 
 sub foo (Any $x)
 
 and have $x accept a Junction.  In other words, any() should not be of
 type Any.  Hence it still feels natural for me that Any occurs at the
 position of Mumble.

FWIW, if Any is to be ruled to be the top type and includes Junction,
then I support Darren's proposal of Single, and maybe the Object type
can be simply eliminated to Any:

Any - Item - Single
   - Pair
- Junction
- int, num, str

This also means that int num str will fit to Any via autoboxing.

Thanks,
/Autrijus/


pgpuicDNYdQ0U.pgp
Description: PGP signature


Re: The meaning of returns

2005-07-27 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 05:03:05AM +0800, Autrijus Tang wrote:
 Hence, it seems to me that there are only four ways out:

Some annotations copied from discussion in #perl6:

   A) Omit the #3 check from compile time; at runtime, use the actual
  type of $x.  The returns type annotation will not propagate
  outward to the caller.
  
 At compile time, check for #2: Any.does(Any)
 At runtime, check for #2: abc.does(Any)
 check for #3: abc.does(Str)

This is the view that says (returns Foo) amounts to declare a:

my sub return (Foo $x) { *return($x) }

and perform no static checking for return types to match their calling
context.  It's got the dynamic language feel, which means practically
no nontrivial type errors will happen at compile time, because function
calls, regardless of its declared return type, can be used in any type
context.

   B) Omit the #2 check from both compile time and runtime; this allows
  us to write the returns All version.
  
 At compile time, check for #3: All.does(Str)
 At runtime, check for #3: abc.does(Str)

This is quite absurd, and was included only for completeness.

   C) Make the return type observe both #2 and #3 at compile time,
  using junctive types to pass both checks:
 
 sub id ( Any $x ) returns Any|All { return($x) }

This is similar to the approach taken by OO-style local type
inferencers; see the Colored local type inference paper for details.

The idea is that, if one omits the returns declaration from a function
of undecidable type, the inferencer can silently fill in (Any|All) and
make the program compile, effectively defer typechecks to runtime.

On the other hand, if the user does provide a type annotation, then both
#2 and #3 will be observed, and type errors can occur.  It's closer to
the soft typing or incremental typing idea.

   D) Make the return type observe both #2 and #3 at compile time,
  using type variables:
 
 sub id ( (::T) $x ) returns ::T { return($x) }

And this is a natural extension to guide the inferencer so it won't be
totally giving up on polymorphic functions such as id.  C) and D) can
be taken together, resulting to a powerful soft typed language.

However, if we take the view that type annotation are merely storage
allocation hints and runtime coercers, then A) is probably the way to go.

Thanks,
/Autrijus/


pgp6x0gDVDRtP.pgp
Description: PGP signature


Re: The meaning of returns

2005-07-27 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 05:57:28AM +0800, Autrijus Tang wrote:
 On Thu, Jul 28, 2005 at 05:03:05AM +0800, Autrijus Tang wrote:
  Hence, it seems to me that there are only four ways out:
 
 Some annotations copied from discussion in #perl6:

Last time I reply to myself on this thread, hopefully. :-)

B) Omit the #2 check from both compile time and runtime; this allows
   us to write the returns All version.
   
  At compile time, check for #3: All.does(Str)
  At runtime, check for #3: abc.does(Str)
 
 This is quite absurd, and was included only for completeness.

On second thought, this is not as absurd as it seems.  This view is that
sub f () returns Foo means f() can be used in any place that a Foo
literal can occur, which means that it can be used in contexts that
demands a supertype of Foo (like Any), but never a subtype of Foo.

The language defined this way would still be dynamic; disabling #2 means
that the type of $x will not be checked against Foo upon return($x), so
anything at all can be used in that position.  Meaningful type errors
can occur, for example when saying close(length(abc)), where length
would have returns Int and close have a IO parameter.

However, this does require the curious device of returns All as the
default return type, unless we eliminate that using type variables
and/or type inferencing, at which time we can get #2 back for free and
implement full static typechecking anyway.

Thanks,
/Autrius/


pgpeHCJEgKBNk.pgp
Description: PGP signature


Inferring (Foo of Int).does(Foo of Any)

2005-07-27 Thread Autrijus Tang
As Perl 6's aggregate types are generics (Role that takes type
parameters), the problem of type variancy naturally arises.

The basic premise is that:

1.  (Array of Item).does(Array of Int); # false
2.  (Array of Int).does(Array of Item); # also false!

Intuitively, while an (Array of Item) can store anything that an
(Array of Int) can store, it cannot promise to yield a Int as the
latter can.  Conversely, while (Array of Int) can always yield
something that does Item, it cannot promise to store any Item.
Hence neither can be the subtype of the other.

As another example, consider this:

sub f (Foo @x) { ... }
my Bar @y;

One can't expect f(@y) to work, unless both Bar.does(Foo) _and_
Foo.does(Bar).  To see the reason, consider Array's interface:

# invariant generics
role Array[of = ::t] {
method FETCH (Int $idx) returns ::t { ... }
method STORE (Int $idx, ::t $elm) { ... }
}

Note that ::t occurs at both the return position, and at the parameter
position.  This means what when we fetch elements from an array of @foo,
it needs to be used in a context that expects a supertype of Foo.
On the other hand, when we store something into @foo, the expected
context is a subtype of Foo.  For @y to work in both positions, Bar
needs to meet both side of the demands.

I think it makes sense to hold both #1 and #2, instead of favoring
one side or the other.  If so, then the default Array type needs to be
something like (Array of Any|All), and do a coerce:as whenever an
actual fetch happens.

However, this rigid invariancy does not need to apply to all generic
types.  For example, consider this:

# covariant generics
role Input[of = ::t] {
method READ () returns ::t { ... }
}

Clearly, we can have (Input of Int).does(Input of Item), since anything
that can read Int can be used in places that expects Item as inputs.

On the other hand, this:

# contravariant generics
role Output[of = ::t] {
method WRITE (::t) { ... }
}

means that (Output of Item).does(Output of Int), as a output channel for
Items can surely be used anywhere that wishes to writes out Ints.

As a final example:

# nonvariant generics
role Contrived[of = ::t] {
method NOOP () { ... }
}

Not only (Contrived of Int).does(Contrived of Item), the converse is
also true, as the type parameter is not actually used anywhere.

Hence, my proposal is that Perl 6's generics should infer its variancy,
based on the signature of its methods, and derive subtyping relationships
accordingly.

The other alternative is do as Java does, which is assume invariancy by
default, then force users to write variancy annotations, but I think
that is considerably less attractive.  There may be a case for inferring
by default, but overridable by the user; if so there needs to be a
syntax for that.

Thanks,
/Autrijus/


pgpjeWwGoKTaN.pgp
Description: PGP signature


End-of-program global destruction is now guaranteed

2005-07-26 Thread Autrijus Tang
Heya.  This is just a heads-up in response to your r5759:

--
r23564 (orig r5759):  chromatic | 2005-07-23 03:30:54 +0800

Added tests for global destruction: call DESTROYALL() on all active
objects.
(This is the last feature Test::Builder needs to work completely.)
--

It's now solved:

--
r23725 (orig r5815):  autrijus | 2005-07-27 02:06:52 +0800

* Global destruction -- DESTROYALL() on all active objects --
  is now guaranteed upon program exit.

--

I look forward to your perl.com article. :)

Thanks,
/Autrijus/


pgpy11XA0eldc.pgp
Description: PGP signature


Re: [PATCH] Perl 6 FAQ

2005-07-25 Thread Autrijus Tang
On Sat, Jul 23, 2005 at 11:53:01AM -0700, Robert Spier wrote:
 Thanks, applied.

Thanks!  However, the rendered form is still of an old revision:

http://dev.perl.org/perl6/faq.html

Cheers,
/Autrijus/


pgp31aL1GpSEb.pgp
Description: PGP signature


[PATCH] Perl 6 FAQ

2005-07-20 Thread Autrijus Tang
Below is a patch to remove the first QA from:

http://dev.perl.org/perl6/faq.html

Against its source form:

http://svn.perl.org/perl.org/docs/live/dev/perl6/faq.pod

I tried to think of a rewrite to replace the two outdated assertions,
but failed miserably.

Thanks,
/Autrijus/

Index: faq.pod
===
--- faq.pod (revision 688)
+++ faq.pod (working copy)
@@ -4,19 +4,6 @@
 
 =head1 GENERAL QUESTIONS
 
-=head2  When will Perl 6 be released?
-
-The current plan is to have a working 6.0.0 compiler ready in the 3rd
-quarter of 2005, based on a snapshot of the language design taken in
-late 2004.
-
-This goal is, however, predicated on The Perl Foundation receiving
-sufficient contributions to fund the 5 or more developer-years of
-effort required to complete the implementation. Without that
-funding, development will continue, but on a volunteer basis and
-hence more slowly.
-
-
 =head2  Will I be able to convert my Perl 5 programs to Perl 6?
 
 Yes. Larry Wall and others are already working on a Perl 5 to Perl 6


pgpW4t3JdOAve.pgp
Description: PGP signature


Re: Is namespace qualification really required

2005-07-19 Thread Autrijus Tang
On Mon, Jul 18, 2005 at 02:47:06PM -0500, [EMAIL PROTECTED] wrote:
 I did this.  I included two tests, one without multiple packages (which 
 works) and one with them (which fails).  I marked the second test todo.

...and I fixed the bug promptly. :)

 Thanks for the gentle help with this process.

No problem.  Welcome aboard!

Thanks,
/Autrijus/


pgpgumOfceviX.pgp
Description: PGP signature


Re: Is namespace qualification really required

2005-07-19 Thread Autrijus Tang
On Tue, Jul 19, 2005 at 12:53:19PM -0500, [EMAIL PROTECTED] wrote:
 Thanks for working on this, but there is still a problem.
 
 When I run make test, the two tests both pass.  When I run the test as:
 
 perl -Iblib/lib t/subroutines/defaults.t

perl?

 I get errors:
 1..2
 ok 1 - default sub called
 not ok 2 - default sub called in package namespace
 #   Failed test (t/subroutines/defaults.t line 35, column 1-62)
 #Got: undef
 # Looks like you failed 1 tests of 2

Did you perhaps had an order version of pugs in PATH?

 Further, the original example still fails.  This is all quite confusing to 
 me.  When I saw the tests pass during make test, I thought I was set to 
 move on to my real example.  Now I don't know which way is up.

Hm, put your real example to the test file, then?

Thanks,
/Autrijus/


pgpbwLyHC1UcS.pgp
Description: PGP signature


Re: Is namespace qualification really required

2005-07-19 Thread Autrijus Tang
On Tue, Jul 19, 2005 at 01:58:18PM -0500, [EMAIL PROTECTED] wrote:
 Now I want to contribute an example.  It shows off named parameters with 
 default values (including those of code type :-) as well as currying.  It 
 does this by implementing Newton's method for root finding.  Is this 
 appropriate for inclusion in the examples directory?  If so, where should 
 it go in that directory?

examples/algorithms/ most likely.

Thanks,
/Autrijus/


pgp5wYQVaN97n.pgp
Description: PGP signature


Strange interaction between pairs and named binding

2005-07-18 Thread Autrijus Tang
This currently works in Pugs:

for [1..10].pairs - Pair $x { say $x.value }

But this does not:

for [1..10].pairs - $x { say $x.value }

Because the ruling that pairs must not be bound to parameters that are
not explicitly declared to handle them.  Is this a desirable behaviour?

Thanks,
/Autrijus/


pgp1DMNKlnL1K.pgp
Description: PGP signature


Re: Is namespace qualification really required

2005-07-18 Thread Autrijus Tang
On Mon, Jul 18, 2005 at 09:00:50AM -0500, [EMAIL PROTECTED] wrote:
 I made the test.  The problem only occurs when the sub is called from 
 another package, in my case that was a driving script.
 
 I'm not sure how to accept the invitation (or what that even means).  

Oh.  It means you should have received a mail from openfoundry.org
that contains a URL to be registered on http://rt.openfoundry.org/ --
the system that manages Pugs committership.  You can also go to that 
website and register manually, using your mail address; once you
have done so, you'll be listed among Pugs committers, and then
you can commit in your test using the username/password chosen at 
the registration time.

If you are using command-line svn, the sequence should be:

svn co http://svn.openfoundry.org/pugs
cd pugs
# ... create t/subroutines/defaults.t ...
# ... edit AUTHORS to add your name ...
svn add t/subroutines/defaults.t
svn ci

If you are using svk, the sequence is exactly the same, with the
svn replaced with svk.

Thanks,
/Autrijus/


pgpGbpIzgIrmL.pgp
Description: PGP signature


Re: Strange interaction between pairs and named binding

2005-07-18 Thread Autrijus Tang
On Mon, Jul 18, 2005 at 03:48:55PM -0700, Brent 'Dax' Royal-Gordon wrote:
 Autrijus Tang [EMAIL PROTECTED] wrote:
  This currently works in Pugs:
 
  for [1..10].pairs - Pair $x { say $x.value }
 
  But this does not:
 
  for [1..10].pairs - $x { say $x.value }
 
  Because the ruling that pairs must not be bound to parameters that are
  not explicitly declared to handle them.  Is this a desirable behaviour?
 
 How much violence would be done to the language if we declared that
 block (i.e. closure with no sub keyword) parameters defaulted to
 Item|Pair, while sub parameters defaulted to plain Item?  I can't
 imagine named arguments are going to be used very often on blocks,
 which tend to be things like loop bodies...

If the Bare code object (including pointy and non-pointy) default their
parameter types to Any (that is, Item|Pair|Junction), then all of
these would work:

for [1..10].pairs { say(.value) }
for [1..10].pairs { say($^x.value) }
for [1..10].pairs - $x { say($x.value) }
for 1|2, 3|4 { say(.values) }
for 1|2, 3|4 { say($^x.values) }
for 1|2, 3|4 - $x { say($x.values) }

 Right now one of my biggest Perl 6 nits is that the combination of
 subroutines everywhere and the Pair type's special role in subroutine
 dispatch makes Pairs a real pain to work with.  This would help to fix
 the problem without creating a new SuperPair type or something
 similarly silly.

Seconded.

Thanks,
/Autrijus/



pgpxMSflL0GBA.pgp
Description: PGP signature


  1   2   3   4   >