relations as roles (was: using the newer collection types)
First of all, Sam Vilain, thank you for your responses. Giving these issues more thought, I'm am now leaning towards the idea that the best way to provide relational algebra in Perl 6 is that the relation-land Tuple and Relation each be a Role which various other classes can provide to their users. For one thing, this lets people use more types of data collections in the forms where they currently sit, rather than requiring them to first convert the data into separate Tuple or Relation objects, in order to apply relational algebra to them. And I suppose that's "the Perl way". Having things just work the way people intuit that they ought to, given conceptually similar examples. Moreover, some implementations of the Tuple and Relation roles can go beyond the basics and provide features often associated with those roles but that aren't part of the core algebra (such as various kinds of type based or whole-set constraints, or various tied means of persistence), while other implementations of those roles don't have to. Moreover, one key distinction that some implementations can have from others is to whether they are mutable. Some implementations could be mutable and others not. All of the generic relational algebra operators are not mutators, so they will work equally well with immutable or mutable implementations. That said, for this to work properly in all cases, Perl 6 will need to provide a way (and it probably does) for a routine to examine the signature of an anonymous routine passed in as an argument, and make sure that its parameters are all read-only; some generic relational operators, such as restrict() and extend(), would take routines as arguments, like grep() and map() do, and we don't want them to try mutating their arguments. As an aside, you'll recall that I said any other type could be implemented over relations, such as sets or arrays etc. However, every attribute ("column") of a relation has a name, but things like sets or arrays conceptually don't need them and so having sets or arrays or hashes etc implement the Relation role could be difficult, one might think. But I say there is no problem here. We can simply reuse the names of "methods" we already have on those types. For example, a Hash object seen through a Relation role would have 2 attributes named "keys" and "values". With sets, its just "members" or "values" or whatever. Though I suppose the names may need more creativity with a shaped hash or array, where each dimension should be referrable to by a distinct name (a dimension index number if necessary), unless we cop out and make "keys" for a shaped hash or array to be of type Seq, where the one value encompasses all dimensions; such an approach is perfectly valid for a Relation role, but it may or may not be less useful in practice. Getting back to the main topic, if we want to implement the Tuple or Relation role in a way that each attribute ("column") of such is specifically typed (because that tends to be the most common or useful practice), it probably would work best to employ a class factory (implementing said roles) where each distinct heading of a Tuple or Relation corresponds to a distinct actual class definition, where the relation-land attributes correspond 1:1 with actual class attributes, and all the features for addressing, manipulating, and defining said attributes with types can be reused. In this situation, nearly every generic relational algebra operator would necessarily be a factory for new classes; and there needs to be a way to examine existing classes in enough detail to know what attributes they have and/or clone parts of them into new ones (as I assume Perl's various .meta provide). This approach is probably the most powerful of all as an implementation. This email is by no means exhaustive, but feedback is appreciated. And keep in mind that the most important thing I'm suggesting here is both that Tuple and Relation are roles, and that as many built-ins as reasonable "do" (appropriately restricted versions of) them; if people have disagreements, its mainly with that sub-suggestion that I want to know about them. Thank you. -- Darren Duncan
tags
I made the Makefile's handling of ctags a lot smarter, so that the tag refers to the .pmc file, instead of the .c file, for example. And I put the tags file in Subversion. xoxo, Andy On May 5, 2006, at 9:40 PM, [EMAIL PROTECTED] wrote: Author: petdance Date: Fri May 5 19:40:55 2006 New Revision: 12527 Modified: trunk/src/exceptions.c Log: internal consting Modified: trunk/src/exceptions.c == --- trunk/src/exceptions.c (original) +++ trunk/src/exceptions.c Fri May 5 19:40:55 2006 @@ -158,7 +158,7 @@ * this is called during normal stack_pop of the control * stack - run the action subroutine with an INTVAL arg of 0 */ -PMC *sub = UVal_pmc(e->entry); +PMC * const sub = UVal_pmc(e->entry); Parrot_runops_fromc_args(interpreter, sub, "vI", 0); } @@ -183,9 +183,8 @@ void Parrot_pop_mark(Interp * interpreter, INTVAL mark) { -Stack_Entry_t *e; do { -e = stack_entry(interpreter, CONTEXT(interpreter->ctx)- >control_stack, 0); +Stack_Entry_t * const e = stack_entry(interpreter, CONTEXT (interpreter->ctx)->control_stack, 0); if (!e) internal_exception(1, "mark not found"); (void)stack_pop(interpreter, &CONTEXT(interpreter->ctx)- >control_stack, @@ -221,7 +220,7 @@ message = VTABLE_get_string_keyed_int(interpreter, exception, 0); do { PMC *cleanup_sub = NULL; -Stack_Entry_t *e = stack_entry(interpreter, +Stack_Entry_t * const e = stack_entry(interpreter, CONTEXT(interpreter->ctx)->control_stack, 0); if (!e) @@ -274,7 +273,7 @@ fprintf(stderr, "%c", '\n'); } else { -INTVAL severity = +const INTVAL severity = VTABLE_get_integer_keyed_int(interpreter, exception, 2); if (severity == EXCEPT_exit) { print_location = 0; @@ -326,11 +325,11 @@ pop_exception(Interp * interpreter) { Stack_entry_type type; -PMC *handler; struct Parrot_cont * cc; -handler = stack_peek(interpreter, -CONTEXT(interpreter->ctx)->control_stack, &type); +PMC * const handler = +stack_peek(interpreter, CONTEXT(interpreter->ctx)- >control_stack, &type); + if (type != STACK_ENTRY_PMC || handler->vtable->base_type != enum_class_Exception_Handler) { real_exception(interpreter, NULL, E_RuntimeError, @@ -362,7 +361,7 @@ PMC* new_c_exception_handler(Interp * interpreter, Parrot_exception *jb) { -PMC *handler = pmc_new(interpreter, enum_class_Exception_Handler); +PMC * const handler = pmc_new(interpreter, enum_class_Exception_Handler); /* * this flag denotes a C exception handler */ @@ -402,10 +401,9 @@ void * throw_exception(Interp * interpreter, PMC *exception, void *dest) { -PMC *handler; void *address; -handler = find_exception_handler(interpreter, exception); +PMC * const handler = find_exception_handler(interpreter, exception); if (!handler) return NULL; /* put the handler aka continuation ctx in the interpreter */ @@ -460,11 +458,11 @@ void rethrow_c_exception(Interp * interpreter) { -PMC *exception, *handler; -Parrot_exception *the_exception = interpreter->exceptions; +Parrot_exception * const the_exception = interpreter->exceptions; + +PMC * const exception = NULL; /* TODO */ +PMC * const handler = find_exception_handler(interpreter, exception); -exception = NULL; /* TODO */ -handler = find_exception_handler(interpreter, exception); /* XXX we should only peek for the next handler */ push_exception(interpreter, handler); /* @@ -482,7 +480,7 @@ /* =item C +dest2offset(Interp * interpreter, const opcode_t *dest)> Translate an absolute bytecode location to an offset used for resuming after an exception had occurred. @@ -492,7 +490,7 @@ */ static size_t -dest2offset(Interp * interpreter, opcode_t *dest) +dest2offset(Interp * interpreter, const opcode_t *dest) { size_t offset; /* translate an absolute location in byte_code to an offset @@ -503,7 +501,7 @@ case PARROT_SWITCH_JIT_CORE: case PARROT_CGP_CORE: case PARROT_CGP_JIT_CORE: -offset = (void **)dest - interpreter->code- >prederef.code; +offset = (void ** const)dest - interpreter->code- >prederef.code; default: offset = dest - interpreter->code->base.data; } @@ -526,7 +524,7 @@ { PMC *exception; /* exception object */ opcode_t *dest; /* absolute address of handler */ -Parrot_exception *the_exception = interpreter->exceptions; +Parrot_exception * const the_exception = interpreter->exceptions; /* * if the exception number is in the range of our known exceptions @@ -570,9 +568,9 @@ size_t handle_exception(Interp * interpreter) { -
[svn:perl6-synopsis] r9119 - doc/trunk/design/syn
Author: larry Date: Fri May 5 15:02:52 2006 New Revision: 9119 Modified: doc/trunk/design/syn/S04.pod Log: Clarified that parens are required on C-style loop. Modified: doc/trunk/design/syn/S04.pod == --- doc/trunk/design/syn/S04.pod(original) +++ doc/trunk/design/syn/S04.podFri May 5 15:02:52 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 19 Aug 2004 - Last Modified: 30 Apr 2006 + Last Modified: 5 May 2006 Number: 4 - Version: 19 + Version: 20 This document summarizes Apocalypse 4, which covers the block and statement syntax of Perl. @@ -206,7 +206,8 @@ ... } -As seen in the previous section, the 3-part loop spec may be entirely +As in C, the parentheses are required if you supply the 3-part spec; however, +as shown in the previous section, the 3-part loop spec may be entirely omitted to write an infinite loop. If you omit the 3-part loop spec you may add a C or C statement modifier at the end to make it a "repeat at least once" loop. Unlike C in Perl 5,
Re: using the newer collection types
At 8:01 PM +1200 5/5/06, Sam Vilain wrote: Also, I don't agree with the notion of a "header" of each relation. It has a type for each tuple item, sure, but "header" just sounds like the sort of thing you want in a ResultSet, not a Relation. Sam. A relation's heading is essentially the definition of the relation's structure, and is not redundant if the relation has no tuples in it, which is valid. A comment I back-logged on #perl6 yesterday suggested that what I was proposing with relations is sort of a retread of what classes are, where each is defined in terms of zero or more named and typed attributes. I just want to weigh in that I see that as partly true (the same could also be said that it retreads what C structs are), and therefore perhaps some language constructs related to class definitions could be reused with relation definitions. Perhaps "Relation" in Perl 6 would best be a role and/or meta-class with factory methods that produce other classes with common interface elements, such as all the relational algebra methods, and/or objects each of which has its own class. Under this system, each time you perform an operation like a join, you are potentially making a new class, because its attributes are likely different than its predecessors. Frankly, with Perl 6 being what it is, there are probably numerous ways to implement what I'm looking for, and I don't exactly know what would be best. For now I'll just follow the simple path with a single Relation class in Pugs' ext/Relation/ directory for demonstration purposes and evaluate changes later. -- Darren Duncan
[svn:parrot-pdd] r12523 - trunk/docs/pdds/clip
Author: petdance Date: Fri May 5 14:47:39 2006 New Revision: 12523 Modified: trunk/docs/pdds/clip/pdd02_vtables.pod Log: teeny tweak of passive voice Modified: trunk/docs/pdds/clip/pdd02_vtables.pod == --- trunk/docs/pdds/clip/pdd02_vtables.pod (original) +++ trunk/docs/pdds/clip/pdd02_vtables.pod Fri May 5 14:47:39 2006 @@ -1,4 +1,4 @@ -# Copyright: 2001-2004 The Perl Foundation. All Rights Reserved. +# Copyright: 2001-2006 The Perl Foundation. All Rights Reserved. # $Id$ =head1 NAME @@ -24,7 +24,7 @@ various object functions. This does mean, though, that you need to either know what functions are available and what they do, or have some method of finding out. It's faster if you know which vtable entry does what, so that's the method -parrot's using. +parrot uses. The actual vtable structure contains pointers to functions that implement the methods for that particular vtable. All pointers must point to valid functions
[svn:perl6-synopsis] r9120 - doc/trunk/design/syn
Author: larry Date: Fri May 5 15:27:43 2006 New Revision: 9120 Modified: doc/trunk/design/syn/S09.pod doc/trunk/design/syn/S11.pod Log: Typos from Dr.Ruud and Marcus Laire. Modified: doc/trunk/design/syn/S09.pod == --- doc/trunk/design/syn/S09.pod(original) +++ doc/trunk/design/syn/S09.podFri May 5 15:27:43 2006 @@ -182,7 +182,7 @@ which is equivalent to -@array.postcircumfix:<[ ]>( <== @x[0] <== @x[1] <== @x[2]...); +@array.postcircumfix:<[ ]>( <== @x[0] <== @x[1] <== @x[2]..*); Alternately, use a multislice array, indicated by a double C<@@> sigil: @@ -195,7 +195,7 @@ my @@x; @@x <== %hash.keys.grep: {/^X/}; @@x <== =<>; -@@x <== 1...; +@@x <== 1..*; @@x <== gather { loop { take rand 100 } }; %hash{@@x} @@ -207,7 +207,7 @@ my @x; @x <== %hash.keys.grep: {/^X/}; @x <== =<>; -@x <== 1...; +@x <== 1..*; @x <== gather { loop { take rand 100 } }; %hash{@@x} # multidimensional @@ -308,7 +308,7 @@ just like scalars -- the main caveat is that you have to use binding rather than assignment to set one without copying: -@b := @a[0...:by(2)] +@b := @a[0..(*):by(2)] With PDLs in particular, this might alias each of the individual elements rather than the array as a whole. So modifications to @b @@ -340,7 +340,7 @@ semicolon-separated list of slice specifiers, also known as a multislice. A three-dimensional slice might look like this: -@x[0..10; 1,0; 1...:by(2)] +@x[0..10; 1,0; 1..(*):by(2)] It is up to the implementation of C<@x> to decide how aggressively or lazily this subscript is evaluated, and whether the slice entails @@ -412,9 +412,9 @@ @nums[$min..$max:by(3)] @nums[$min..$max] -@nums[$min...:by(3)] -@nums[1...:by(2)] # the odds -@nums[0...:by(2)] # the evens +@nums[$min..(*):by(3)] +@nums[1..(*):by(2)]# the odds +@nums[0..(*):by(2)]# the evens That's all just the standard Perl 6 notation for ranges. Additional syntactic relief is always available as long as it's predeclared @@ -440,15 +440,7 @@ 0 .. Inf :by(2) -That why we have postfix C<...> to mean C<..Inf>. But then if you -leave out the first argument: - -...:by(2) - -you've written the yada-yada-yada operator, which is actually a term -that will not produce an infinite range for you. Don't do that. - -Maybe you should just find some nice Unicode characters for your operators... +That's why we have postfix C<..*> to mean C<..Inf>. =head1 PDL signatures @@ -700,7 +692,7 @@ C<.keys>, C<.values>, or C<.kv>, it calls C<%hash.iterator()> to start one. In scalar context, C<.iterator> returns an iterator object. In list context, it returns a lazy list fed by the iterator. It must -be possible for a hash to be in more than one iterator at at time, +be possible for a hash to be in more than one iterator at a time, as long as the iterator state is stored in a lazy list. However, there is only one implicit iterator (the C iterator) that works in scalar context to return the next pair. [Or maybe not.] Modified: doc/trunk/design/syn/S11.pod == --- doc/trunk/design/syn/S11.pod(original) +++ doc/trunk/design/syn/S11.podFri May 5 15:27:43 2006 @@ -342,4 +342,4 @@ It's not necessary to force Perl 6 if the interpreter or command specified already implies it, such as use of a "C<#!/usr/bin/perl6>" shebang line. Nor is it necessary to force Perl 6 in any file that -beings with the "class" or "module" keywords. +begins with the "class" or "module" keywords.
S11 - s/beings/begins/
S11, near the end: s/beings/begins/ :) -- Affijn, Ruud "Gewoon is een tijger."
[perl #39088] [TODO] Add conditional GCC attributes to functions
# New Ticket Created by Andy Lester # Please include the string: [perl #39088] # in the subject line of all future correspondence about this issue. # https://rt.perl.org/rt3/Ticket/Display.html?id=39088 > GCC has a number of attributes that we can slap on functions. For example, GCC's analysis of flow control will be greatly improved when we put __attribute(noreturn)__ on real_exception(), to tell GCC that it can't return, like exit(). I've done a ton of this for perl5, and can bring it on over. -- Andy Lester => [EMAIL PROTECTED] => www.petdance.com => AIM:petdance
S09: Single typo & postfix ...
There is a typo in S09 (patch included) Also, S09 uses postfix ... to mean ..Inf but S03 uses ..* for this, so one of these should likely be changed unless both are OK. -- Markus Laire patch-S09 Description: Binary data
[perl #39085] [TODO] pmc - make pmc2c.pl extract function declarations
# New Ticket Created by Andy Lester # Please include the string: [perl #39085] # in the subject line of all future correspondence about this issue. # https://rt.perl.org/rt3/Ticket/Display.html?id=39085 > Each .pmc file has redundant function headings. For example, in src/ pmc/integer.c /* =item C Create a new Integer with arguments passed according to pdd03. =cut */ PMC* instantiate(PMC* sig) { PMC* const ret = new_pmc_header(INTERP, 0); opcode_t *arg_op; INTVAL init = 0; There's no reason pmc2c.pl can't create the =item line from the declaration of the function itself. This removes double-maintenance for the programmer, and the chance of getting the two out of sync. -- Andy Lester => [EMAIL PROTECTED] => www.petdance.com => AIM:petdance
Re: [S05] /ee
Juerd schreef: > Dr.Ruud: >> S05: >>> s/pattern/{ eval doit() }/ >> >> s/eval/try/ ? > > No, string eval stays eval. Only block eval is renamed to try. Understood, but I was thinking about variants like { eval '' ~ doit() } { eval $\&doit } and then wasn't sure anymore whether "eval doit()" is a string eval or not. $ perl5 -le 'sub x{print""; ""}; print(":". eval( "x()" ) .":")' :: $ perl5 -le 'sub x{print""; ""}; print(":". eval {x()} .":")' :: $ perl5 -le 'sub x{print""; ""}; print(":". eval( {x()} ) .":")' :: $ perl5 -le 'sub x{print""; ""}; print(":". eval( x() ) .":")' :: -- Groet, Ruud
Re: [S05] /ee
Dr.Ruud skribis 2006-05-05 15:25 (+0200): > > s/pattern/{ eval doit() }/ > s/eval/try/ ? No, string eval stays eval. Only block eval is renamed to try. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
[S05] /ee
Instead of /ee say: s/pattern/{ eval doit() }/ s/eval/try/ ? -- Affijn, Ruud "Gewoon is een tijger."
[ANNOUNCE] Test::Group 0.02
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Dear perl-qa members, I am pleased to announce the first public release of Test::Group, a handy module for grouping batches of tests together. I use it to store the whole test suite of my modules in an __END__ block, à la perlmodlib, while keeping the test suite manageable. No doubt you will find other uses! The tarball should hit a nearby CPAN mirror shortly. With regards, Dom - - The uploaded file Test-Group-0.02.tar.gz has entered CPAN as file: $CPAN/authors/id/D/DO/DOMQ/Test-Group-0.02.tar.gz size: 24868 bytes md5: fc960e3e74dc9c795bdb4722ed66a168 - From the README: DESCRIPTION This is Test::Group version 0.02, a companion module to Test::Builder. It allows to lump tests and fixture into groups that make sense together. For example: use Test::More tests => 1; use Test::Group; test "hammering the server" => sub { ok(I_can_connect); for(1..1000) { ok(I_can_make_a_request); } }; produces 1..1 ok 1 - hammering the server Diagnostics of failed subtests are shown, but successful subtests are muted. This makes the test output very legible even to the naked eye. Test::Group has no dependencies besides what is provided in stock Perl 5.8.8. It also works under Perl 5.6.1 and 5.8.x (with dependencies). Test::Group has been in use in my shop under a different name for years, and has provided significant productivity improvements over plain Test::More in test-driven development. Note that you may want to investigate another CPAN module, Test::Class by Adrian Howard, which is older and offers a similar feature. But being a full-fledged test framework it is also a little bit more cumbersome to use if all you want to do is to group tests. - -- Dominique QUATRAVAUX Ingénieur senior 01 44 42 00 08 IDEALX -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.1 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFEW0r4MJAKAU3mjcsRAor2AKCrTQr95RFYf3jqgDbhr06NdK5a5gCgoMYS Bgyqo+uydbw2CoCKdB4NaFI= =R2oO -END PGP SIGNATURE-
Re: using the newer collection types
Darren Duncan wrote: >>>Is there a reference for the meaning of these methods? >>> >>> >>There are many written references to these methods; just type >>"relational algebra" into Google. >> >> > >I will add that the first hit on such a search, the Wikipedia page on >relational algebra ( http://en.wikipedia.org/wiki/Relational_algebra >), is a perfectly good primer on what relational algebra is and what >its importance is. > > Thanks for the pointer. >While this may not actually change anything, I should point out that >every collection type can also be expressed in terms of a Relation >definition and/or they can all be implemented over a Relation (whose >members are actually always unique). For example: > >1. A Set of Any is a Relation with one Any attribute. >2. A Bag of N Any attributes is a Relation of N+1 attributes, where >the extra attribute is an Int (constrained >= 1) that counts >occurrances of the distinct other attributes. >3. A Mapping can be a Relation of 2 Any attributes. >4. A Hash is a Relation of 2 attributes, Str (key) and Any (value), >where the key has a unique constraint. >5. A Seq is a Relation of 2 attributes, typed Int (>= 0) and Any, >where the first shows their ordinal position and the second is the >actual value; the first has a unique constraint. >6. An Array is the same, assuming it is a sparse; if it is not >sparse, there is an additional constraint that the greatest Int value >is the same / one less than the count of Relation members. > > I don't know if anyone will care, but you can't emulate the raw "Collection" type with this fixed Relation type. That is, a collection of tuples, each of which may be of differing length and type. This is what leads me to think that Collection is the more generic role. I'm not saying Relations are not useful, perhaps they are more useful than Collections in the practical case, but they are a sub-type. Also, I don't agree with the notion of a "header" of each relation. It has a type for each tuple item, sure, but "header" just sounds like the sort of thing you want in a ResultSet, not a Relation. Sam.
[perl #37089] [TODO] PGE - Test Glob
> [coke - Tue Sep 06 07:41:09 2005]: > > Tests need to be written for PGE's glob. > > Can this ticket be closed? We now have glob tests in t/compilers/pge/pge_globs.t (and more can be added there, of course). Pm