Re: Recent news about PGE
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
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]
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
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
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
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!
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
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
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?
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
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
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
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
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
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
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;
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;
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
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;
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;
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;
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
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
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
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
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
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?
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?
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.
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
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.
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.
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
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.
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
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
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)
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
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
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.
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;
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(?)
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(?)
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.
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(?)
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.
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(?)
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;
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' = ???)
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.
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.
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
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.
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
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
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(?)
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
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
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
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
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
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
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
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
(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
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
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!)
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!
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)
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
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.
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 *{}
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
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)
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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
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
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