Re: requirements gathering on mini transformation language

2006-09-29 Thread Adriano Ferreira

Among the features that cannot be missed in a transformation language
(and sorry if that's too obvious) I mention:
* a data structure pattern language
  (something between patterns used in Prolog and some functional languages
   and XPath)
* and rules that are selected via these patterns (with a certain number of
 default behavior to make useful things easier).

For example, an identity transformation may look like

tr_rule id($obj ~~ Any) { tr_apply($kid) for $kid ($obj.children) }

and it could be changed to an almost identity by inserting
a rule that changed the string "foo" to "bar".

tr_rule quasi_id($obj ~~ Any) { tr_apply($kid) for $kid ($obj.children) }
tr_rule quasi_id($obj ~~ "foo") { "bar" }

More complex patterns should be able to give names to structure parts
which may be used in the body of the rule. Something similar to what
Prolog does.

tr_rule some_trans( $obj ~~ [ $a ~~ Hash, $b ~~ { 'k' => $vk } ] ) {
  [ { 'y' => $vk, $a } ]
}

The rules must know how to walk each kind of structure: array, hash,
object, whatever and build new ones.

My 0.0002 cents.

Adriano Ferreira.

On 9/28/06, Allison Randal <[EMAIL PROTECTED]> wrote:

I need a volunteer write up the requirements for a mini transformation
language to use in the compiler tools. You wouldn't have to write up the
specification for the language, just what features we need. This will
help us plan what it's going to take to get from here to there, and give
us a way to measure when the spec/implementation can be called "done".

It's essentially a matter of spending some time with me and Patrick on
the phone and solidifying the ideas on paper, together with any
perspectives or experience you add to the mix.

Allison



[perl #40428] [PATCH] Return perl script and module file locations in parrot distro

2006-09-29 Thread Paul Cochrane
# New Ticket Created by  "Paul Cochrane" 
# Please include the string:  [perl #40428]
# in the subject line of all future correspondence about this issue. 
# http://rt.perl.org/rt3/Ticket/Display.html?id=40428 >


Hi,

This is a patch to return the names and locations of the perl script
and module files within the parrot distribution.  The patch adds
subroutines to lib/Parrot/Distribution.pm that parallel the behaviour
of similar subroutines which return the locations of the C source and
header files.  This functionality can then be used for testing the
perl coda.  Btw: the solution feels untidy and difficult to maintain
somehow, as I just copied the structure from the C-related
subroutines; any feedback on how to refactor the code into a more
maintainable form would be much appreciated.  That said, it does the
job though ;-)

Regards,

Paul

files affected:

lib/Parrot/Distribution.pm
Index: lib/Parrot/Distribution.pm
===
--- lib/Parrot/Distribution.pm	(revision 14786)
+++ lib/Parrot/Distribution.pm	(working copy)
@@ -214,6 +214,150 @@
 }
 
 
+=item C
+
+Returns the directories which contain perl source files.
+
+(but misses Configure.pl...)
+
+=cut
+
+sub perl_script_file_directories
+{
+my $self = shift;
+
+return
+map $self->directory_with_name($_) =>
+	'compilers/imcc',
+	'editor',
+	'examples/benchmarks', 'examples/mops',
+	'languages',
+	map("languages/$_" => qw<
+		APL/tools 
+		BASIC/compiler BASIC/interpreter
+		WMLScript/build
+		dotnet dotnet/build dotnet/tools
+		lua
+		m4/tools
+		plumhead
+		python
+		regex
+		scheme scheme/Scheme
+		tcl/tools
+		urm
+		>
+	),
+	map("tools/$_" => qw),
+;
+}
+
+=item C
+
+Returns the perl script with the specified name.
+
+=cut
+
+sub perl_script_file_with_name
+{
+my $self = shift;
+my $name = shift || return;
+
+$name .= '.pl' unless $name =~ /\.pl$/o;
+
+foreach my $dir ($self->perl_script_file_directories)
+{
+return $dir->file_with_name($name)
+if $dir->file_exists_with_name($name);
+}
+
+print 'WARNING: ' . __FILE__ . ':' . __LINE__ . ' File not found:' . $name ."\n";
+
+return;
+}
+
+
+=item C
+
+Returns the directories which contain perl module files.
+
+=cut
+
+sub perl_module_file_directories
+{
+my $self = shift;
+
+return
+map $self->directory_with_name($_) =>
+	map("config/$_" => qw),
+	'ext/Parrot-Embed/lib/Parrot',
+	map("languages/$_" => qw<
+		APL/t 
+		BASIC/compiler
+		HQ9plus/lib/Parrot/Test
+		WMLScript/build/SRM WMLScript/t/Parrot/Test
+		bc/lib/Parrot/Test bc/lib/Parrot/Test/Bc
+		dotnet/build/SRM dotnet/t
+		jako/lib/Jako
+		jako/lib/Jako/Construct
+		lua/Lua lua/t/Parrot/Test
+		m4/lib/Parrot/Test m4/lib/Parrot/Test/M4
+		parrot_compiler/lib/Parrot/Test
+		perl6/t/01-sanity
+		plumhead/lib/Parrot/Test plumhead/lib/Parrot/Test/Plumhead
+		pugs/t
+		regex/lib
+		scheme scheme/Scheme
+		tcl/lib/Parrot/Test
+		urm/lib/URM
+		>
+	),
+	map("languages/jako/lib/Jako/Construct/$_" => qw<
+		Block Block/Conditional Block/Loop Declaration
+		Expression Expression/Value Statement Type
+		>
+	),
+	map("languages/regex/lib/$_" => qw<
+		Parrot/Test Regex Regex/CodeGen Regex/Ops Regex/Parse
+		>
+	),
+	map("lib/$_" => qw<
+		Class Digest/Perl File Parrot Parse Pod Pod/Simple Test Text
+		>
+	),
+	map("lib/Parrot/$_" => qw<
+		Config Configure Configure/Step Docs Docs/Section IO
+		OpLib OpTrans PIR Pmc2c Test
+		>
+	),
+;
+}
+
+=item C
+
+Returns the perl module file with the specified name.
+
+=cut
+
+sub perl_module_file_with_name
+{
+my $self = shift;
+my $name = shift || return;
+
+$name .= '.pm' unless $name =~ /\.pm$/o;
+
+foreach my $dir ($self->perl_module_file_directories)
+{
+return $dir->file_with_name($name)
+if $dir->file_exists_with_name($name);
+}
+
+print 'WARNING: ' . __FILE__ . ':' . __LINE__ . ' File not found:' . $name ."\n";
+
+return;
+}
+
 =item C
 
 Returns the documentation directory.


[perl #40429] [PATCH] test for perl code coda

2006-09-29 Thread Paul Cochrane
# New Ticket Created by  "Paul Cochrane" 
# Please include the string:  [perl #40429]
# in the subject line of all future correspondence about this issue. 
# http://rt.perl.org/rt3/Ticket/Display.html?id=40429 >


Hi,

This patch adds a test for the perl code coda in a similar manner to
the C code coda test.

Regards,

Paul

files affected:

perl_code_coda.t
Index: t/codingstd/perl_code_coda.t
===
--- t/codingstd/perl_code_coda.t	(revision 0)
+++ t/codingstd/perl_code_coda.t	(revision 0)
@@ -0,0 +1,108 @@
+#! perl
+# Copyright (C) 2006, The Perl Foundation.
+# $Id$
+
+use strict;
+use warnings;
+
+use lib qw( . lib ../lib ../../lib );
+use Test::More tests => 2;
+use Parrot::Distribution;
+
+
+=head1 NAME
+
+t/codingstd/perl_code_coda.t - checks for editor hint coda in perl source
+
+=head1 SYNOPSIS
+
+# test all files
+% prove t/codingstd/perl_code_coda.t
+
+# test specific files
+% perl t/codingstd/perl_code_coda.t src/foo.pl include/parrot/bar.pm
+
+=head1 DESCRIPTION
+
+Checks that all perl source files have the proper editor hints coda,
+as specified in PDD07.
+
+=head1 SEE ALSO
+
+L
+
+=cut
+
+
+my $coda = <<'CODA';
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+CODA
+
+my $DIST = Parrot::Distribution->new;
+my @files = @ARGV ? @ARGV : perl_files();
+my @no_coda;
+my @extra_coda;
+
+foreach my $file ( @files ) {
+my $buf;
+my $path;
+
+## get the full path of the file
+# if we have command line arguments, the file is the full path
+if (@ARGV) {
+$path = $file;
+}
+# otherwise, use the relevant Parrot:: path method
+else {
+$path = $file->path;
+}
+
+# slurp in the file
+open(my $fh, '<', $path)
+or die "Cannot open '$path' for reading: $!\n";
+{
+local $/;
+$buf = <$fh>;
+}
+
+# append to the no_coda array if the code doesn't match
+push @no_coda => "$path\n"
+unless $buf =~ m{\Q$coda\E\n*\z};
+
+# append to the extra_coda array if coda-like text appears more than once
+my $vim_many   =()= $buf =~ m{^ \s* \*? \s* vim: \s* $}gmx;
+my $emacs_many =()= $buf =~ m{^ \s* \*? \s* Local variables: \s* $}gmx;
+push @extra_coda => "$path\n"
+if $vim_many > 1 || $emacs_many > 1;
+}
+
+ok(!scalar(@no_coda), 'Perl code coda present')
+or diag("Perl code coda missing in "
+. scalar @no_coda . " files:[EMAIL PROTECTED]");
+
+ok(!scalar(@extra_coda), 'Perl code coda appears only once')
+or diag("Perl code coda repeating in "
+. scalar @extra_coda . " files:[EMAIL PROTECTED]");
+
+exit;
+
+
+sub perl_files {
+return (
+map($_->files_of_type('Perl script'), $DIST->perl_script_file_directories),
+map($_->files_of_type('Perl module'), $DIST->perl_module_file_directories),
+);
+}
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Mark J. Reed

On 9/29/06, Jonathan Lang <[EMAIL PROTECTED]> wrote:

And here I thought you were a responsible, law-abiding citizen... :P


And so it begins.

I daresay there will be no shortage of jokes among P6ers about "does Hash" ...

--
Mark J. Reed <[EMAIL PROTECTED]>


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Jonathan Lang

Larry Wall wrote:

but only if self.HOW does Hash.


And here I thought you were a responsible, law-abiding citizen... :P

--
Jonathan "Dataweaver" Lang


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Larry Wall
On Fri, Sep 29, 2006 at 01:24:12PM -0700, Larry Wall wrote:
: method postfix:<::> () { return %.HOW.packagehash }

Urque.

Actually, that'd have to be %($.HOW.packagehash) or $.HOW.packagehash.{},
since what I wrote there would mean %(self.HOW).packagehash instead, which
might work accidentally, but only if self.HOW does Hash.

Larry


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Larry Wall
On Fri, Sep 29, 2006 at 02:05:06PM -0400, Mark J. Reed wrote:
: On 9/29/06, Jonathan Lang <[EMAIL PROTECTED]> wrote:
: >Terminology issue: IIRC (and please correct me if I'm wrong), Perl 6
: >uses 'module' to refer to 'a perl 5-or-earlier module', and uses
: >'package' to refer to the perl 6-or-later equivalent.
: 
: 
: Other way around.  "package" is Perl 5, because that's the P5 keyword,
: and seeing a "package" declaration is an indicator to Perl6 that the
: file it's processing is written in P5.  In P6, there are both
: "module"s and "class"es, but no "package"s other than those inherited
: from P5 code..

That is ever so slightly overstated.  We still have packages as a
native notion in P6.  The "'package' indicates P5" thing is just if
the first thing in the file is a package declaration, but elsewhere
in Perl 6 you're allowed to say:

package Foo { our $bar = 3 }

and such.  Our bare unvarnished namespaces are still called "packages",
but in terms of roles, Module does Package just as Class does Module
(and by implication, Package).  Same for roles and subsets and enums.
Basically, all types do Package whenever they need an associated
namespace.  And most of the Package role is simply:

method postfix:<::> () { return %.HOW.packagehash }

or some such, so "$type.::" returns the symbol table hash associated
with the type, if any.  It's mostly just a convention that the Foo
prototype and the Foo:: package are considered interchangable for
most purposes.

Larry


[perl #40430] [PATCH] rename and update C code coda test

2006-09-29 Thread Paul Cochrane
# New Ticket Created by  "Paul Cochrane" 
# Please include the string:  [perl #40430]
# in the subject line of all future correspondence about this issue. 
# http://rt.perl.org/rt3/Ticket/Display.html?id=40430 >


Hi,

This patch renames the C code coda test and removes the Perl-specific
code from the test (this code is now in the Perl code coda test).

Regards,

Paul

files affected:

t/codingstd/code_coda.t
t/codingstd/c_code_coda.t
Index: t/codingstd/code_coda.t
===
--- t/codingstd/code_coda.t	(revision 14786)
+++ t/codingstd/code_coda.t	(working copy)
@@ -1,114 +0,0 @@
-#! perl
-# Copyright (C) 2006, The Perl Foundation.
-# $Id$
-
-use strict;
-use warnings;
-
-use lib qw( . lib ../lib ../../lib );
-use Test::More tests => 2;
-use Parrot::Distribution;
-
-
-=head1 NAME
-
-t/codingstd/code_coda.t - checks for editor hint coda in source
-
-=head1 SYNOPSIS
-
-# test all files
-% prove t/codingstd/code_coda.t
-
-# test specific files
-% perl t/codingstd/code_coda.t src/foo.c include/parrot/bar.h
-
-=head1 DESCRIPTION
-
-Checks that all source files have the proper editor hints coda,
-as specified in PDD07.
-
-=head1 SEE ALSO
-
-L
-
-=cut
-
-
-my $coda = <<'CODA';
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
-CODA
-
-my $DIST = Parrot::Distribution->new;
-my @files = @ARGV ? @ARGV : source_files();
-my @no_coda;
-my @extra_coda;
-
-foreach my $file ( @files ) {
-my $buf;
-my $path;
-
-## get the full path of the file
-# if we have command line arguments, the file is the full path
-if (@ARGV) {
-$path = $file;
-}
-# otherwise, use the relevant Parrot:: path method
-else {
-$path = $file->path;
-}
-
-# slurp in the file
-open(my $fh, '<', $path)
-or die "Cannot open '$path' for reading: $!\n";
-{
-local $/;
-$buf = <$fh>;
-}
-
-# append to the no_coda array if the code doesn't match
-push @no_coda => "$path\n"
-unless $buf =~ m{\Q$coda\E\n*\z};
-
-# append to the extra_coda array if coda-like text appears more than once
-my $vim_many   =()= $buf =~ m{^ \s* \*? \s* vim: \s* $}gmx;
-my $emacs_many =()= $buf =~ m{^ \s* \*? \s* Local variables: \s* $}gmx;
-push @extra_coda => "$path\n"
-if $vim_many > 1 || $emacs_many > 1;
-}
-
-ok(!scalar(@no_coda), 'C code coda present')
-or diag("C code coda missing in "
-. scalar @no_coda . " files:[EMAIL PROTECTED]");
-
-ok(!scalar(@extra_coda), 'C code coda appears only once')
-or diag("C code coda repeating in "
-. scalar @extra_coda . " files:[EMAIL PROTECTED]");
-
-exit;
-
-
-sub source_files {
-return (
-map($_->files_of_type('C code'),   $DIST->c_source_file_directories),
-map($_->files_of_type('C header'), $DIST->c_header_file_directories),
-);
-}
-
-sub perl_files {
-return (
-map($_->files_of_type('Perl code'), $DIST->perl_file_directories),
-);
-}
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:
-
Index: t/codingstd/c_code_coda.t
===
--- t/codingstd/c_code_coda.t	(revision 0)
+++ t/codingstd/c_code_coda.t	(revision 0)
@@ -0,0 +1,108 @@
+#! perl
+# Copyright (C) 2006, The Perl Foundation.
+# $Id$
+
+use strict;
+use warnings;
+
+use lib qw( . lib ../lib ../../lib );
+use Test::More tests => 2;
+use Parrot::Distribution;
+
+
+=head1 NAME
+
+t/codingstd/code_coda.t - checks for editor hint coda in source
+
+=head1 SYNOPSIS
+
+# test all files
+% prove t/codingstd/code_coda.t
+
+# test specific files
+% perl t/codingstd/code_coda.t src/foo.c include/parrot/bar.h
+
+=head1 DESCRIPTION
+
+Checks that all source files have the proper editor hints coda,
+as specified in PDD07.
+
+=head1 SEE ALSO
+
+L
+
+=cut
+
+
+my $coda = <<'CODA';
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
+CODA
+
+my $DIST = Parrot::Distribution->new;
+my @files = @ARGV ? @ARGV : source_files();
+my @no_coda;
+my @extra_coda;
+
+foreach my $file ( @files ) {
+my $buf;
+my $path;
+
+## get the full path of the file
+# if we have command line arguments, the file is the full path
+if (@ARGV) {
+$path = $file;
+}
+# otherwise, use the relevant Parrot:: path method
+else {
+$path = $file->path;
+}
+
+# slurp in the file
+open(my $fh, '<', $path)
+or die "Cannot open '$path' for reading: $!\n";
+{
+local $/;
+$buf = <$fh>;
+}
+
+# append to the no_coda array if the code doesn't match
+push @no_coda => "$path\n"
+unless $buf =~ m{\Q$coda\E\n*\z};
+
+# append to the extra_coda array if coda-like text appears more than once
+my $vim_many   =()= $buf =~ m{^ \s

Re: [svn:parrot-pdd] r14784 - trunk/docs/pdds/clip

2006-09-29 Thread Ben Morrow

Quoth [EMAIL PROTECTED]:
>  ++++
>  | Offset | Length | Description|
>  ++++
>  | 0  | 8  | 0xFE 0x50 0x42 0x43 0x0D 0x0A 0x1A 0x0A|
>  ||| Parrot "Magic String" to identify a PBC file. In C,|
>  ||| this is the string C<\376PBC\r\n\032\n> (ASCII) or |
>  ||| C<\xfe\x50\x42\x43\x0d\x0a\x1a\x0a>.   |
>  ++++

This is probably too late for a change like this, in which case ignore
me, but I don't suppose there's any chance that pbc files could allow an
optional #! line, so that they can be used as executables directly?
Parrot would need an option analogous to gcc's -x, of course, to specify
to type of a file explicitly rather than inferring it from the
extension; but IMHO that also would be a good thing in itself.

Ben

-- 
You poor take courage, you rich take care:
The Earth was made a common treasury for everyone to share
All things in common, all people one. [EMAIL PROTECTED]
'We come in peace'---the order came to cut them down.


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Jonathan Lang

Mark J. Reed wrote:

Jonathan Lang wrote:
> Terminology issue: IIRC (and please correct me if I'm wrong), Perl 6
> uses 'module' to refer to 'a perl 5-or-earlier module', and uses
> 'package' to refer to the perl 6-or-later equivalent.

Other way around.  "package" is Perl 5, because that's the P5 keyword,
and seeing a "package" declaration is an indicator to Perl6 that the
file it's processing is written in P5.  In P6, there are both
"module"s and "class"es, but no "package"s other than those inherited
from P5 code..


Right.  Thank you; I'm not sure how I got those flipped.

--
Jonathan "Dataweaver" Lang


Re: How to pass a ref from a language with no refs

2006-09-29 Thread A. Pagaltzis
* Mark Stosberg <[EMAIL PROTECTED]> [2006-09-29 14:18]:
> my $p5_dumper =
>   eval('sub {use Data::Dumper; print Dumper(@_); }', :lang);
> 
> my @a = ;
> $p5_dumper.(@a);  # received as array
> $p5_dumper.([EMAIL PROTECTED]); # received as arrayref
> $p5_dumper.(VAR @a);  # received as arrayref
> 
> my %h = ( a => 1 );
> $p5_dumper.(@%h); # received as hashref
> $p5_dumper.([,] %h);  # received as hashref
> $p5_dumper.(|%h); # received as hashref
> $p5_dumper.(%h);  # received as hashref
> $p5_dumper.(\%h); # received as hashref
> $p5_dumper.(VAR %h);  # received as hashref

I think you want

  $p5_dumper.(%h.kv);

Regards,
-- 
Aristotle Pagaltzis // 


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Mark J. Reed

On 9/29/06, Jonathan Lang <[EMAIL PROTECTED]> wrote:

Terminology issue: IIRC (and please correct me if I'm wrong), Perl 6
uses 'module' to refer to 'a perl 5-or-earlier module', and uses
'package' to refer to the perl 6-or-later equivalent.



Other way around.  "package" is Perl 5, because that's the P5 keyword,
and seeing a "package" declaration is an indicator to Perl6 that the
file it's processing is written in P5.  In P6, there are both
"module"s and "class"es, but no "package"s other than those inherited
from P5 code..

--
Mark J. Reed <[EMAIL PROTECTED]>


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Larry Wall
On Fri, Sep 29, 2006 at 12:35:43AM -0700, Trey Harris wrote:
: If you define a BUILD in a role, will it be called when an object of a 
: class that does the role is instantiated, as part of the .new BUILD walk?

Yes.  That is mentioned in A12, even if S12 didn't make it explicit.
At least S12:531 implies that roles have BUILD submethods, and the previous
paragraph indicates that BUILDALL calls all appropriate BUILD methods.
What A12 makes clear that S12 doesn't is that if you write your own BUILD
submethod in your class, it doesn't need to worry about the roles'
BUILDs.  Those are called automatically anyway.

Larry


Re: Bytecode PDD

2006-09-29 Thread Leopold Toetsch
Am Freitag, 29. September 2006 01:39 schrieb Jonathan Worthington:
> Hi,
>
> I've checked in the proposed bytecode PDD and also most of the changes
> that I discussed with Allison earlier today. Feedback on it would be
> greatly appreciated.

Great work, thanks.

> A couple of open questions on this are:
>
> 1) Is keeping the Parrot version number around sensible and if so, is
> having it as the version of Parrot that wrote the packfile useful?  I
> guess it's helpful if we need workarounds for bugs in previous versions
> of Parrot in later versions to know this. Other thoughts?

I think it's useful.

> 2) How should we handle changes to the core Parrot library (mostly PMCs,
> but also consider anything we promise is available)? Should this bump
> the packfile version number too? Or do we want some other mechanism to
> handle this?

This is still a can of worms. Not so much changes to PMC type numberings per 
se (which should invalidate PBCs) but the dynamic nature of these resources.

I'll try to dump my thoughts.

A PBC refers - via its contents - to several possibly dynamically extendable 
resources. A probably incomplete list is:

1) PMCs   [*1]
2) charsets
3) encodings
4) HLLs 
5) opcodes

(see also src/pmc/parrotinterpreter.pmc:547 ff)  [*2]

Whenever such items are refered to by a numeric index and that index is part 
of the PBC, we have a possible problem.

Let's look at opcodes. These are present in the PBC as index (the opcode 
number). We got a packfile with some dynamic opcode inside:

  opcodes
  [ 10, 20, 30, 1300, 1301, 0 ]

Let's say, opcode #1300 and #1301 are from some dynamic opcode lib. Now this 
PF gets loaded into an interpreter, which already has dynamic opcode 
librar{y,ies} loaded. In the best case, it was the same opcode library and 
the opcode numbers just happen to match. But that's pure luck.

The same argument holds for all other above resources.

BTW encodings seem to be missing in the pdd - and we can't do:
   "Character set, copied from the string structure." 
because this is a pointer. We need an index into the available 
charsets/encodings.

So what I think, we have to do, is:

- store a metatable of such resources, this is basically for:
  2-4) a list of names / library PMCs, which describes how to load 
   the resource
   (or NULL, if this resource is a core resource)
  1,5) same + range of indices

- when now a PBC is loaded, we'd have to merge this information with already 
in-memory structures of the interpreter. We can at least detect, if there's a 
collision. Still better would of course be to relocate the index and use this 
mapping during unpacking. Unfortunately we can't do the relocation of opcodes 
for mmap-ed bytecde in memory.

[*1] theoretically PMCs shouldn't be a problem, as these are usually looked up 
dynamically, but it depends of course on the usage of dynamic oplibs :-(

  .loadlib "mypmc"
  ...
  new P0, .MyPMC   # new_p_ic  .MyPMC is refered to by index  
  new P0, 'MyPMC'  # referenced by name

For the index case, we'd again have the described problem.
(The .Type syntax is always fine for core PMCs, which don't change for the 
validity range of the packfile).

[*2] This resides currently in the interpreter PMC, but should be moved into 
the future PackFile PMC.

> Again, comments and/or suggestions on anything else in the proposal are
> very welcome! :-)

I've some thoughts re PF PMCs too - later.

> Thanks,
>
> Jonathan

leo


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Miroslav Silovic

Aaron Sherman wrote:


In the RFC, I was trying to develop a method by which a module could
assert a stricture (consider this part of "use strict" in Perl 6 if you
will) that would constrain the CALLER of that module (as well as the
module itself, of course) to a particular signature template for a
multi. This allows us to centrally document a multi that might be
defined in many places, and have that documentation actively constrain
the multi to match. In this way, the user doesn't have to figure out
that max is a method on Array in order to find its documentation, and a
module that uses Array gets



Um, so if I get this right, you want to restrict the users of the module 
from *EVER* extending that particular part of the module's functionality?


I would be strongly opposed to the existence of this feature. Firstly, 
what you propose is not DBC. Design by contract is about requiring 
minimal functionality from the parties in the contract, not about 
banning them from going above the requirements. Secondly, what happens 
when you use two modules with two different prototypes for the same 
multi? Without this declaration, and assuming the modules don't try to 
dispatch on the same argument lists, everything just works. But with 
this stricture, you simply aren't allowed to do this, and I don't see 
any justification for it. Frankly, sometimes things -will- be named the 
same and yes, sometimes you need to use grep to find the docs. Not sure 
why this is a problem, though.


   Miro




Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Jonathan Lang

Terminology issue: IIRC (and please correct me if I'm wrong), Perl 6
uses 'module' to refer to 'a perl 5-or-earlier module', and uses
'package' to refer to the perl 6-or-later equivalent.

Aaron Sherman wrote:

Details:

Larry has said that programming by contract is one of the many paradigms
that he'd like Perl 6 to handle. To that end, I'd like to suggest a way
to assert that "there will be multi subs defined that match the
following signature criteria" in order to better manage and document the
assumptions of the language now that methods can export themselves as
multi wrappers. Let me explain why.


OK.  My understanding of "programming by contract" as a paradigm is
that one programmer figures out what tools he's going to need for the
application that he's working on, and then farms out the actual
creation of those tools to another programmer.

Second, when you mention 'signature criteria', what immediately comes
to mind is the notion of the signature, which applies restrictions on
the various parts of an argument list:

   :(@array, *%adverbs)

This applies two restrictions: there can be only one positional
parameter, and it must do the things that a list can do.  Change the
comma to a colon, and you have a signature that says that there must
be a list-like invocant, and that there can be no positional
parameters.

The only aspect of the signature that is not concerned with argument
types is the part that determines how many of a particular kind of
parameter (invocant, positional, or named) you are required or
permitted to have: even the @-sigil in the first positional parameter
(or the invocant, in the method-based signature) is specifying type
information, as it's placing the requirement that that parameter needs
to behave like a list.

In effect, I could see thinking of a signature as being a regex-like
entity, but specialized for matching against parameter lists (i.e.,
capture objects) instead of strings.


In the continuing evolution of the API documents and S29, we are moving
away from documentation like:

our Scalar multi max(Array @list) {...}
our Scalar multi method Array::max(Array @array:) {...}

toward exported methods:

our Scalar multi method Array::max(Array @array:)
is export {...}

"is export" forces this to be exported as a function that operates on
its invocant, wrapping the method call. OK, that's fine, but Array isn't
the only place that will happen, and the various exported max functions
should probably have some unifying interface declared.


This would seem to be a case for changing the above to something along
the lines of:

   our Scalar multi submethod max(@array:)
   is export {...}

This removes all references to Array from the signature, and leaves it
up to the @-sigil to identify that the invocant is supposed to be some
sort of list-like entity.  The change above from 'method' to
'submethod' is predicated on the idea that methods have to be defined
within a class or role, much like attributes have to be; if this is
incorrect, then it could be left as 'method'.


I'm thinking of
something like:

our proto max(@array, *%adverbs) {...}


The Synposes already define a 'proto' keyword for use with routines;
it's listed right alongside 'multi'.  Were you intending to refer to
this existing keyword, or did you have something else in mind?


This suggests that any "max" subroutine defined as multi in--or exported
to--this scope that does not conform to this prototype is invalid. Perl
will throw an error at compile-time if it sees this subsequently:


In short, you want to define a signature that every routine with the
given name must conform to, whether that routine is a sub or submethod
defined in the package directly, or if it is a method defined in a
class or role that is in turn defined in the package.

While 'role Foo { our method max(@array:) { ... } }' specifies that
whatever composes the role in question must include a method called
max that takes a list-like object as an invocant, you want to be able
to say that any method, sub, submethod, or other routine defined in a
given package that is called 'max' must match the signature ':(@array,
*%adverbs)'.  This would seem to bear some resemblance to Perl 6's
notion of 'subtypes', which add matching criteria to objects, and
throw exceptions whenever you try to assign a value to the object that
doesn't meet the criteria.


The goal, here, is to allow us to centrally assert that "Perl provides
this subroutine" without defining its types or behavior just yet.


Here's the thing: the above doesn't seem to require that any such
subroutine be defined.  That is, the coder could forego defining _any_
'max' routines when he implements your documentation, and the first
indication you'd have of this oversight would be when your application
complains that the function doesn't exist.  That is, you're not saying
'this module provides this subroutine'; you're saying 'if this 

Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Trey Harris

In a message dated Fri, 29 Sep 2006, Aaron Sherman writes:
First the high-level point: I'm dropping the RFC, because, as TimToady 
pointed out on IRC, we're not quite far enough down the line to see the 
breadth or certainty of the need yet.


Yes, but I don't think the conversation should stop.  These are important 
semantics of the object model and we should be at least roughly on the 
same page so that when someone gets the tuits to work on it, it's clear 
what the direction is.


That said, this is a different point, above and I think it's an easy one to 
take on.


role A { method x() {...} }
class B { does A; }

does generate an error per "If a role merely declares methods without 
defining them, it degenerates to an interface:" from S12.


However, that's not to say that a class can't be abstract, just that a class 
that does an interface (a role with nothing but abstract methods) must 
implement the role's interface.


So why would it generate an error?  Why wouldn't it merely result in B 
being abstract too, assuming that contra my prior mail, classes can be 
abstract?  Do you have to be explicit about it and say


  role A  { method x() { ... } }
  class B { does A; method x() { ... } }

?  That seems un-Perlishly verbose to me; we had DRY before Ruby ever did.

Nothing is said of what happens when you compose a role that has both 
defined and undefined methods, but IMHO, that's at most a warning if 
they remain undefined after composition, since you might want to use 
that class as a trait at runtime where target objects will define that 
method.


As I said on IRC, I don't read the part of S12 you quote as being the 
definition of interface; I merely read it as being an analogy to the 
concept of interface found in other languages.  I'd find it absurd if 
merely changing


  role Existential { method is { ... }; method isnt { ... } }

to

  role Existential { method is { ... }; method isn't { ! .is } }

resulted in the role changing its instantiability.


Certainly this:

class A { method x() {...} }

is very explicit, and should be allowed, given that it is a promise that 
"sometime before x is called, it will be defined." It's a runtime error if 
that promise is not kept.


Did you mean to have "class B" and "does A" there, as in my un-Perlish 
example above?  If so, then see my response above.  If not... I'm a little 
surprised.  Since roles and classes share the package namespace, I 
wouldn't expect you to be able to declare a class with the same name as a 
preexisting role, even if you implemented all the role's interfaces within 
that class


One more point for the hypothetical future object-model 
designer/implementer with the even more hypothetical tuits, so that it 
doesn't get lost: note that in a DBC context, { ... } is insufficient for 
an abstract routine.  PRE and POST blocks would ordinarily be included as 
well.  A routine missing a PRE or POST would be considered to have:


   method is {
 PRE  { True }
 POST { True }
 ...
   }

which under DBC rules would be the same as having no POST at all... but 
would unfortunately cause any future PREs to be ignored!


(Under design-by-contract rules, POSTs are and-ed from least-derived to 
most-derived, but PREs are or-ed.  In fact, in Eiffel, PRE is called 
"require" and POST is called "ensure", but only in base classes; in 
derived classes, you must type "require else" and "ensure then" to make 
explicit that your assertions are being or-ed or and-ed with assertions 
elsewhere in code.)


Trey


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Trey Harris

In a message dated Thu, 28 Sep 2006, Jonathan Lang writes:

while roles can be abstract, classes and packages should not be.


Really?  I think I need to let that sink in and percolate a bit.

I'm rather fond of creating abstract superclasses to factor out common 
object-management code.  I have many classes in Perl 5 with code like 
this:


   sub new {
 my $proto = shift;
 my $class = ref($proto) || $proto;
 if ($class eq __PACKAGE__) {
croak "Attempt to instantiate abstract class $class";
 }
 # Proceed with common object instantiation
   }

and then the concrete subclasses either don't define &new at all or do 
their own subclass-specific initializations and call NEXT to get the 
common initializations.  I've been thinking that a role is not the proper 
place for this sort of code, as it is tightly coupled to implementation, 
and my understanding of the gestalt of roles is that they should be 
loosely coupled to their users' implementations.


But if only a role can be abstract, I guess I'd have to use a role (or 
fall back to the Perl 5-ism above and check my .HOW and throw a runtime 
exception).


If you define a BUILD in a role, will it be called when an object of a 
class that does the role is instantiated, as part of the .new BUILD walk?


Trey


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Aaron Sherman

Jonathan Lang wrote:

I hope not.  My understanding is that '{ ... }' is supposed to
represent the notion of abstract routines: if you compose a role that
has such routines into a class or package, I'd expect the package to
complain bitterly if any such routines are left with yada-yadas as
their codeblocks, on the basis that while roles can be abstract,
classes and packages should not be.


First the high-level point: I'm dropping the RFC, because, as TimToady 
pointed out on IRC, we're not quite far enough down the line to see the 
breadth or certainty of the need yet.


That said, this is a different point, above and I think it's an easy one 
to take on.


role A { method x() {...} }
class B { does A; }

does generate an error per "If a role merely declares methods without 
defining them, it degenerates to an interface:" from S12.


However, that's not to say that a class can't be abstract, just that a 
class that does an interface (a role with nothing but abstract methods) 
must implement the role's interface.


Nothing is said of what happens when you compose a role that has both 
defined and undefined methods, but IMHO, that's at most a warning if 
they remain undefined after composition, since you might want to use 
that class as a trait at runtime where target objects will define that 
method.


Certainly this:

class A { method x() {...} }

is very explicit, and should be allowed, given that it is a promise that 
"sometime before x is called, it will be defined." It's a runtime error 
if that promise is not kept.