Re: how typish are roles
On Wednesday 25 October 2006 03:04, Trey Harris wrote: I'll let @Larry speak for @Larry, but at one point I was told that when CArray or CHash appear in signatures, those are roles, not classes; if you examined a particular Array or Hash, the class would be some implementation of the Array or Hash role, perhaps something like CPugsSparseArray or CParrotOpaqueHash or so on. So I'd tend to agree that roles are the heavyweights in the type department. Yes. When you specify a type to constrain some operation, you specify that the target entity must perform that role. Unless you're actually composing or inheriting from something, you shouldn't care whether its type derives from a role, a class, a type set, or a type parameter. Yes. I think the question (which you didn't directly raise, but I've heard from others) of whether role or class will have primacy is kind of as pointless as asking whether subroutines or code blocks have primacy: you can't use the former without the latter; the former is a useful abstraction for the latter, especially when code gets larger or is meant for sharing; and while each have places where they're more appropriate, either can be used in place of the other given a bit of syntactic twiddling. Well... maybe. I believe strongly that you can build a really good system with roles as the fundamental abstraction and where classes are a specialization, but doing the other way around is much more difficult and less cohesive. I can read S12 as saying that classes always do an eponymous role, and so role is what typing is really based on. Yes. In other words, I agree that it's fuzzy, but I personally read the fuziness as intentional, so as to allow implementations flexibility and prevent bad dependencies on particular inner workings of the type system. That fuzziness is classic $Larry. Some of the rest of @Larry can be more *mumble*matic. -- c
Re: how typish are roles
In a message dated Sat, 28 Oct 2006, chromatic writes: When you specify a type to constrain some operation, you specify that the target entity must perform that role. That statement is very concise and direct. If the fuzziness I observed about the identity of the basic building block of type was unintentional, this statement should be added to S06. I think the question (which you didn't directly raise, but I've heard from others) of whether role or class will have primacy is kind of as pointless as asking whether subroutines or code blocks have primacy: you can't use the former without the latter; the former is a useful abstraction for the latter, especially when code gets larger or is meant for sharing; and while each have places where they're more appropriate, either can be used in place of the other given a bit of syntactic twiddling. Well... maybe. I believe strongly that you can build a really good system with roles as the fundamental abstraction and where classes are a specialization, but doing the other way around is much more difficult and less cohesive. But I wasn't suggesting that, any more than I was suggesting that code blocks based on anonymous subroutines would be as cohesive as subroutines based on code blocks. I was just saying that both roles and classes could be equally first-class participants in the type system by my reading of S06 and S12: I don't see any necessity, short a statement like yours I quoted above, for classes to be coerced into a role before they can act as a type. Trey
where constraints as roles (was Re: how typish are roles)
In a message dated Sat, 28 Oct 2006, Trey Harris writes: In a message dated Sat, 28 Oct 2006, chromatic writes: When you specify a type to constrain some operation, you specify that the target entity must perform that role. That statement is very concise and direct. If the fuzziness I observed about the identity of the basic building block of type was unintentional, this statement should be added to S06. Incidentally, this would mean that a Cwhere clause or junctive type defines an anonymous role, and a type parameter defines a lexical role, doesn't it? Seems like a useful characteristic of these constructs to make explicit, perhaps in LS12/Roles. I find this a little unintuitive given the way these typing particles are used, though... If I were insane in a different way than I actually am, I might think I could use this every constraint is a role behavior to write: sub pairs_up_to (Int $x where { $^x % 2 == 0 } ) { (1..^$x:by(2)) = (2..$x:by(2)) } pairs_up_to(4)};# 1 = 2, 3 = 4 try { pairs_up_to(3) } err say $!; # No compatible subroutine found my $even_three = 3 but where { $_ % 2 == 0 }; # Huh? try { pairs_up_to($even_three) } err say $!;# What? Not a useful example, I admit--which is why I had assumed Cwhere constraints were not roles, because I can't think of a useful example of treating them as roles. But I suppose if you're determined to shoot yourself in the foot like that, you'll find some way (like overloading C% so it always returns 0). You could probably even make Perl be able to call the sub in the second Ctry, perhaps by making the anonymous roles generated by Cwhere first match by AST equivalence before testing their value against the constraint or something. Not that I think Perl should be able to do that... I'm just saying I *might* think it would, given how roles usually work (and if I could come up with a less contrived case, I might actually expect it to). But *why* wouldn't it work? One of two reasons I think: 1. The first Cwhere clause in the sub signature defines a different anonymous role from the second Cwhere clause after Cbut, even though they're defined identically. In that case, $even_three would have no practical difference from any other 3, because it merely mixes in a role that never gets used. 2. The assignment would throw a mistyped value exception, just like my Num $foo = 'hi, mom' does. (Except it doesn't. Should it? I don't see a test that addresses this in the suite, nor something in the Synopses to say that that assignment should fail.) In either case, Cwhere clauses create roles that values might do without even realizing they're doing them, and which mutable objects might do and then not do, willy-nilly, even in the course of the scope in which they were typed to do it... which I think is new unless I just haven't been paying attention. sub saturate (Color $c where { $^c.saturation 100 } ) { $c.saturation = 100; # ??? correct_gama($c); } Did that mutation throw an exception, by changing $c's type to one it can't have in this sub? If no, did we just lose gradual typing (assuming correct_gamma cares)? Can we detect that, or do the roles created by Cwhere not participate in gradual typing? If Cwhere constraints weren't roles, this would make sense to me again. It's duck-typing, but a very different type of duck typing than, say Ruby has... it isn't a duck because it walks and quacks, but because when you examine it with your particular duckish litmus test (your Cwhere clause), the litmus test turns the duckish color (Bool::True) you're looking for. A trifling issue, I guess, as you can just ignore how Cwhere works so long as it does work. But when I see a statement like every X is really syntactic sugar for a Y, I want to poke at all the X's to see how they behave deeply as Y's. Trey
Re: where constraints as roles (was Re: how typish are roles)
My initial inclination is to say that where clauses in a signature are only there for pattern matching, and do not modify the official type of the parameter within the function body. However, on a subset the where clause is there precisely to contribute to the typing, so if you want the extra constraints to apply to all uses of the parameter variable within the body, you'd need to declare a subset type that enforces it. On the other hand, I can imagine that an alternative would be to say that a where clause will always subsetize the official type; that would imply that we'd need to add a when clause for mere pattern matching. Something to be said for making such a distinction, if it can be taught. Fuzzily yours, Larry
Re: how typish are roles
On Thu, Oct 26, 2006 at 03:17:27PM +0200, TSa wrote: : HaloO, : : I wrote: : 2) We have AB and the A B juxtaposition to mean $_ ~~ A $_ ~~ B :which is an intersection (sub)type of A and B. : : Is the AB form a legal alternative for the juxtaposition? Not in a signature. It's ambiguous with A B where B is declaring a routine type that returns A. Might be made to work in parens someday. But I'm still somewhat set against the notion of using logical ops to do set theory. (Even if you put parens around them.) Larry
Re: where constraints as roles (was Re: how typish are roles)
Trey Harris wrote: Trey Harris writes: chromatic writes: When you specify a type to constrain some operation, you specify that the target entity must perform that role. That statement is very concise and direct. If the fuzziness I observed about the identity of the basic building block of type was unintentional, this statement should be added to S06. S02 already has q[A variable's type is a constraint indicating what sorts of values the variable may contain. More precisely, it's a promise that the object or objects contained in the variable are capable of responding to the methods of the indicated role.] Incidentally, this would mean that a Cwhere clause or junctive type defines an anonymous role, and a type parameter defines a lexical role, doesn't it? Seems like a useful characteristic of these constructs to make explicit, perhaps in LS12/Roles. IMHO, this gets it backward. You shouldn't turn Cwhere clauses and junctive types into roles; you should turn roles and junctive types into Cwhere constraints: Foo $x is, in effect, shorthand for something like $x where { .does(Foo) }, while Foo | Bar Baz $x becomes something like $x where { .does(Foo) || .does(Bar) .does(Baz) }. At its core, a type is nothing more than a constraint on the objects that a given variable is allowed to handle; this would put Cwhere clauses at the center of the type system, with roles coming in a very close second due to the implicit use of .does() in the compact syntax. IMHO, @Larry got overly precise in the above S02 quote: s[More precisely] = Usually. -- Jonathan Dataweaver Lang
Re: how typish are roles
Larry Wall wrote: But I'm still somewhat set against the notion of using logical ops to do set theory. (Even if you put parens around them.) Understandably so. Perhaps (u) and (n) would be better ASCII equivalents for the union and intersection operators... -- Jonathan Dataweaver Lang
[svn:parrot-pdd] r15037 - trunk/docs/pdds/clip
Author: jonathan Date: Sat Oct 28 09:59:25 2006 New Revision: 15037 Modified: trunk/docs/pdds/clip/pdd17_basic_types.pod Log: Add two new reference PMCs to the Basic Types PDD. Modified: trunk/docs/pdds/clip/pdd17_basic_types.pod == --- trunk/docs/pdds/clip/pdd17_basic_types.pod (original) +++ trunk/docs/pdds/clip/pdd17_basic_types.pod Sat Oct 28 09:59:25 2006 @@ -115,6 +115,30 @@ The PMC that represents a reference to another PMC. Delegates all functions to the referred-to PMC. +=item AggregateElementRef + +This PMC represents a reference to an element contained in an aggregate PMC +type, such as an array or hash. It is initialized with the key being +referenced and the aggregate PMC containing that key. + +Note that assigning to the reference PMC will be equivalent to a keyed set on +the referenced aggregate PMC - that is, it modifies the element rather than +doing a v-table call on the element itself. It is important to be aware of +this when assigning a PMC through this reference; it is not the same behaviour +as the Ref PMC. + +=item WeakRegisterRef + +This PMC represents a weak reference to a register. Should the reference live +beyond the context containing the register that it references, any attempt to +use the reference will throw an exception. + +A weak register reference can only be created by the Cregister_ref opcode. +Any assignment to the register will behave like a set instruction. That is, +when assigning a PMC using a WeakRegisterRef PMC, the register will be updated +to reference that PMC rather than calling the assign v-table call on the PMC +in that register. This is not the same behaviour as the Ref PMC. + =item Random A singleton PMC that generates a random number. {{ NOTE: Why do we have
Anyone relying on objects stringifying to class names?
Hi, At the moment, if you have some ParrotObject instance, say foo, and do something like: $S0 = foo Then $S0 will contain the name of the class. This is BAD because it means you can't overload what a class stringifies too! In fact, there is a comment in the code saying that: /* =item CSTRING *name() Shortcut for .class().name() XXX - this is bad and should go =cut */ So, I want to get rid of this and allow this v-table method to just dispatch to a user implementation or a fallback. But before I do that, I wanted to check if anyone is relying on the behavior? I'd really rather not break working code without giving folks a chance to fix it, but this behavior needs to die. I'm amazed, nobody has killed it already. I propose this is removed in a week, please respond if you'd have an issue with that or think that's too short. Thanks, Jonathan
Re: Anyone relying on objects stringifying to class names?
On Sat, Oct 28, 2006 at 06:50:05PM +0100, Jonathan Worthington wrote: So, I want to get rid of this and allow this v-table method to just dispatch to a user implementation or a fallback. But before I do that, I wanted to check if anyone is relying on the behavior? I'd really rather not break working code without giving folks a chance to fix it, but this behavior needs to die. I'm amazed, nobody has killed it already. I propose this is removed in a week, please respond if you'd have an issue with that or think that's too short. I think it's too long. :-) Does anything fail if you eliminate it (e.g., via make tests)? If no, then I think it's okay to eliminate, and we'll see if anyone carps about it. But that's just my $0.02. Pm
Re: where constraints as roles (was Re: how typish are roles)
On Saturday 28 October 2006 09:15, Larry Wall wrote: My initial inclination is to say that where clauses in a signature are only there for pattern matching, and do not modify the official type of the parameter within the function body. However, on a subset the where clause is there precisely to contribute to the typing, so if you want the extra constraints to apply to all uses of the parameter variable within the body, you'd need to declare a subset type that enforces it. Right; it's awfully difficult to have nominal typing in a room full of blank Hello my name is tags. On the other hand, I can imagine that an alternative would be to say that a where clause will always subsetize the official type; that would imply that we'd need to add a when clause for mere pattern matching. Something to be said for making such a distinction, if it can be taught. -- c
Re: [perl #40443] Separate vtable functions from methods (using :vtable)
Hi, As of r15039, :vtable and :vtable(...) are now both implemented. See example code at the end of this email. As of now, please use this new syntax. I have left in support for the old __-prefix lookup as plenty of old code is using it; please note that if you have a :vtable(xxx) and a __xxx then the first will be called, not the second. I'll leave it to Chip and/or Allison to decide how long the deprecation cycle is for this. Implementation wise, at the moment I'm just storing these entries in \0VTABLE\0 sub-namespace within the class namespace, however I'm not sure I like this (feels like we got rid of one bit of namespace pollution by adding another, albeit a less noticeable one). I don't see another way to attach the VTABLE namespace to the main one, however. But that's an implementation detail - even if we change that any :vtable-using code will go on working fine. Tests and some extra error checking code to come. Jonathan .sub main :main $P0 = newclass [ Test ] $P1 = new [ Test ] $I1 = $P1[11] print $I1 print \n $S1 = $P1[11] print $S1 print \n .end .namespace [ Test ] .sub get_integer_keyed_int :method :vtable .param int key .return(42) .end .sub monkey :method :vtable(get_string_keyed_int) .param int key .return(monkey) .end
[perl #40608] key_append segfault
# New Ticket Created by Jonathan Worthington # Please include the string: [perl #40608] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=40608 The following program segfaults Parrot: .sub main $P0 = new .Key push $P0, test push $P0, test print not reached .end Which sucks. :-(
Re: [perl #40443] Separate vtable functions from methods (using :vtable)
Jonathan Worthington wrote: Tests and some extra error checking code to come. Also now done. If you write one of: .sub not_a_vtable_method :method :vtable .sub badger :method :vtable(not_a_vtable_method) It's a compiler error. I'll leave this ticket open a few more days for comments, then if there are none close it up. Thanks, Jonathan
[perl #40608] key_append segfault
From: Jonathan Worthington (via RT) [EMAIL PROTECTED] Date: Sat, 28 Oct 2006 13:32:25 -0700 The following program segfaults Parrot: .sub main $P0 = new .Key push $P0, test push $P0, test print not reached .end Which sucks. :-( I don't see a segfault in r15040 on x86 GNU/Linux, but it seems to be using push_string(). Same error on r15009. What are you running? -- Bob [EMAIL PROTECTED] cat jw.pir .sub main :main $P0 = new .Key push $P0, test push $P0, test print not reached .end [EMAIL PROTECTED] ./parrot jw.pir push_string() not implemented in class 'Key' current instr.: 'main' pc 3 (jw.pir:4) [EMAIL PROTECTED]
[perl #40608] key_append segfault
On Sat Oct 28 15:30:49 2006, rgrjr wrote: I don't see a segfault in r15040 on x86 GNU/Linux, but it seems to be using push_string(). Same error on r15009. What are you running? Windows. And sorry, I stuffed up the example. It shoulda been: .sub main $P0 = new .Key $P1 = new .String $P1 = test push $P0, $P1 $P2 = new .String $P2 = test push $P0, $P2 print not reached .end That is, you can only push another key onto a key. I discovered this by accident when implementing :vtable, and filed a ticket to make sure it wasn't forgotten. Turns out it was easy to deal with, so as of r15043 the issue is resolved. Sorry for the noise on-list. Jonathan
RFC: Actions without barriers
Almost two weeks ago, I had what I thought was a clever idea for eliminating the continuation barrier from action invocation: Simply call the action using the original continuation instead of creating a new RetContinuation. The original continuation, I reasoned, should be re-entrant after having the dynamic environment partially restored. Unfortunately, it's not that easy. The trick is that you need to pass values from the original context, not the one that is exiting. And exception handling is, well, exceptional: The values come from C code, and not any context. So I had to add a 'payload' slot to struct Parrot_cont in order to remember the exception; I had been hoping to avoid extra state. Furthermore, there is no way for the vtable method of a superclass to abandon the rest of the subclass method, so I used some flag-setting kludgery to hack around that [1]. And it doesn't even quite work; in r15040, I get the following additional test failures: Failed Test Stat Wstat Total Fail Failed List of Failed - t/compilers/imcc/syn/pcc.t 1 256211 4.76% 8 * t/library/mime_base64.t1 256 552 1104 200.00% 1-552 t/op/gc.t 1 256221 4.55% 13 t/pmc/eval.t 1 256211 4.76% 19 * t/pmc/resizablestringarray.t 1 256 173 326 188.44% 11-173 (The ones marked with * also have some failures in vanilla r15040.) So what I want to know is: Do you think this approach is worth pursuing? I would certainly make it work before committing it, and would also want to make the flag-setting hack prettier (if I couldn't eliminate it altogether). There's also some proxy stuff I think I can get rid of. So it wouldn't be quite so ugly. I just want to know if you think it is worth the trouble. Or, I could sit tight and wait for a better way to return values from C, since that is what the handler-calling code needs to do, before or after PDD23 . . . -- Bob Rogers http://rgrjr.dyndns.org/ [1] I also merged Error_Handler:invoke into Continuation:invoke; it actually reduces the code volume, but flattens the abstraction, which doesn't feel quite right. But the point of the existing Error_Handler:invoke is to return values from C, which ought to be handled generally anyway. And I assume EH can go away after PDD23, replaced with a general Continuation. In fact, it may even be possible to get rid of it now. Index: src/pmc/retcontinuation.pmc === --- src/pmc/retcontinuation.pmc (revision 15040) +++ src/pmc/retcontinuation.pmc (working copy) @@ -88,6 +88,11 @@ struct PackFile_ByteCode * const seg = cc-seg; next = SUPER(next); +if (PObj_flag_TEST(private1, SELF)) { +PObj_flag_CLEAR(private1, SELF); +return next; +} + Parrot_free_context(INTERP, from_ctx, 1); #ifdef NDEBUG /* the continuation is dead - delete and destroy it */ Index: src/pmc/continuation.pmc === --- src/pmc/continuation.pmc(revision 15040) +++ src/pmc/continuation.pmc(working copy) @@ -25,7 +25,60 @@ #include parrot/oplib/ops.h #include assert.h +void * +Parrot_invoke_with_continuation_args(Parrot_Interp interpreter, + PMC *sub, PMC *continuation, + const char* sig, ...) +{ +opcode_t *dest; +parrot_context_t *old_ctx = CONTEXT(interpreter-ctx); +parrot_context_t *orig_from_ctx = PMC_cont(continuation)-from_ctx; +/* Mark ourself so that RetContinuation:invoke (if continuation is a + RetContinuation) doesn't immediately destroy the returning context; + we will need it to complete arg passing. */ +PObj_flag_SET(private1, continuation); + +if (continuation-vtable-base_type == enum_class_Exception_Handler) { +/* create a new continuation, since Exception_Handler can't be recycled + this way. */ +PMC *eh = continuation; +continuation = new_ret_continuation_pmc(interpreter, NULL); +PMC_cont(continuation)-payload = eh; +} + +interpreter-current_cont = continuation; +interpreter-current_object = NULL; +dest = VTABLE_invoke(interpreter, sub, NULL); +if (!dest) +internal_exception(1, Subroutine returned a NULL address); +/* restore the original from_ctx (Sub:invoke bashes it). */ +PMC_cont(continuation)-from_ctx = orig_from_ctx; + +/* process args, if any. */ +if (sig *sig) { +va_list args; + +va_start(args, sig); +dest = parrot_pass_args_fromc(interpreter, sig, dest, old_ctx, args); +
Re: Embedded perl5 modules
Steffen: Sorry, Didnt see all correspondence immediately, and hence responded twice. But here is an effort using Gtk2. It works. Can anyone explain why the lines with .can, whilst the other syntaxes dont work? file Gtk2Helper.pm package Gtk2Helper; use Gtk2; sub new_Window { return Gtk2::Window-new(@_); }; sub new_Button { return Gtk2::Button-new(@_); }; 1; end file file Gtk2_test.p6 use perl5:Gtk2; use perl5:Gtk2Helper; Gtk2.init; #This does not work #my $window = Gtk2Helper.new_Window('toplevel'); #This does not work #my $window = Gtk2Helper::new_Window('toplevel'); # The following works my nw := Gtk2Helper.can('new_Window'); my $window = nw('toplevel'); my nb := Gtk2Helper.can('new_Button'); my $button = nb('Quit this dull mortal world'); $button.signal_connect('clicked', sub { Gtk2.main_quit }); $window.add($button); $window.show_all; Gtk2.main; Richard Steffen Schwigon wrote: Richard Hainsworth [EMAIL PROTECTED] writes: Tried use perl5:Wx::SimpleApp; but the compiler complained it could not find SimpleApp.pm Did you see my other suggestion with an intermediate WxHelper (http://www.nntp.perl.org/group/perl.perl6.users/546)? It also doesn't really work but at least it gets you a step further. Try it and maybe you have the next idea as you maybe know Wx better than I do. Steffen
Re: Anyone relying on objects stringifying to class names?
Patrick R. Michaud wrote: I propose this is removed in a week, please respond if you'd have an issue with that or think that's too short. I think it's too long. :-) Does anything fail if you eliminate it (e.g., via make tests)? If no, then I think it's okay to eliminate, and we'll see if anyone carps about it. But that's just my $0.02. A week's notice seems fair. Then if all the tests pass, nuke it! :) Allison
Re: RFC: Actions without barriers
Bob Rogers wrote: Almost two weeks ago, I had what I thought was a clever idea for eliminating the continuation barrier from action invocation: Simply call the action using the original continuation instead of creating a new RetContinuation. The original continuation, I reasoned, should be re-entrant after having the dynamic environment partially restored. Unfortunately, it's not that easy. The trick is that you need to pass values from the original context, not the one that is exiting. And exception handling is, well, exceptional: The values come from C code, and not any context. So I had to add a 'payload' slot to struct Parrot_cont in order to remember the exception; I had been hoping to avoid extra state. Furthermore, there is no way for the vtable method of a superclass to abandon the rest of the subclass method, so I used some flag-setting kludgery to hack around that [1]. I can see why the solution was tempting, and I'm glad you tried it out. I can also see why you paused to ask if it was worth continuing. Your instincts are right, this solution gradually pushes further and further from where we want to be. Out of the possible hacks we could do, I'd rather go for the hack of providing a way to create a new RetContinuation from within the C code (even if it's a special kind of return continuation with the same interface, but a different set of internal actions to satisfy the interface). [1] I also merged Error_Handler:invoke into Continuation:invoke; it actually reduces the code volume, but flattens the abstraction, which doesn't feel quite right. But the point of the existing Error_Handler:invoke is to return values from C, which ought to be handled generally anyway. And I assume EH can go away after PDD23, replaced with a general Continuation. In fact, it may even be possible to get rid of it now. Can you make this a separate patch, so we can review it independently? I'm not sure we want to do it, but it's worth considering, on the Distinction vs. Reuse design scale. Allison