Re: Private contracts?
I've been mucking about a bit more with this whole interface thing. So if we make method signatures only enforced on subclasses if the parent class or method has the interface property... except private methods, obviously. And if we make pre/post conditions and class invariants always enforced... shouldn't we have private invariants and conditions? Semi-tangential to the point of your message... With pre/post conditions, a subclass is allowed to weaken the preconditions or strengthen the postconditions. The postcondition is not really a problem since one can always add additional checks. However, if the parent's preconditions apply to the child invariably, it would be rather difficult to make your subclass accept a wider variety of input. I'm not proposing a solution, but rather just a problem to keep in mind. Mike Lambert
Re: Private contracts?
Michael G Schwern wrote: How exactly does one weaken a precondition? Say I define a mathematical mod() function in my parent number class. precondition: $a 0, $b 0, $b is int mod( $a, $b ) Then in my subclass, I want to make it work in a wider variety of contexts. I change the definition to: precondition: $b is int, $b != 0 mod( $a, $b ) It now properly supports modulo arithmetic for negative numbers, because the requirements for running the function have been weakened. It is still completely substitutable anywhere that the parent implementation would work, but if code is dealing with my subclass it is allowed to work with the weakened precondition. Since your proposal was based upon the idea of having every parent condition apply to child implementations, the possibility for strengthened postconditions falls out of the proposal nicely. But since preconditions work in the opposite direction, they don't quite gel with that particular proposal. Mike Lambert
Re: exegesis 5 question: matching negative, multi-byte strings
guaranteeing that the subsqls have all text up to, but not including the string union. I suppose I could say: rule nonunion { (.*) :: { fail if ($1 =~ munion$); } } What's wrong with: ? rule getstuffbeforeunion { (.*?) union | (.*) } a union = a b = b Am I missing something here? Mike Lambert
Re: Paren madness (was Re: Regex query)
2. Scalar assignment. my $a;# 1. $a = X; my $a;# 3. ($a) = X; These should all do the same thing, regardless of X. Consider: $a = (1); and ($a) = (1); 5. Assignment to arrays and lists. $a = (1, 2, 3); # Same as Perl 5's $a = [1,2,3]; $a = (1) should then do $a = [1], according to the above. This implies that: ($a) = (1) implies that $a is [1], something I don't particularly agree with. How would you resolve this contradiction you've created? (Or do you think the last example is perfectly fine?) What about: $a = 1,2,3 ($a) = (1,2,3) $a = (1,2,3) ($a) = 1,2,3 Do you still believe those should be identical? They have the same problems mentioned above, and likely other issues as well. Mike Lambert
Re: auto deserialization
Damian Conway wrote: Trey Harris wrote: An alias? Isn't class Date is Really::Long::Package::Name::Ugh; a new class declaration, declaring 'Date' as a subclass of Really::Long::Package::Name::Ugh? Yes. It's not an alias. class Date is Really::Long::Package::Name::Ugh; class DateManipulator; our Date $date2manip; date manip methods here... An external class is thus unable to do: $DateManipulator::date2manip = new Really::Long::Package::Name::Ugh() Is that correct? The above example is somewhat contrived, but I still believe it illustrates a problem which *will* arise in practice. Mike Lambert
The Perl5-Perl6 Convertor
In essence, all Perl 5 functions have a signature of (*@_ is rw). Perhaps the translator can turn some of those into (*@_). What'd really be cool is if it could pick up an initial my ($a, $b, $c) = _; Excuse my ignorance here, but I thought the plan for backwards compatibility with perl5 was to embed the Perl5 engine with Parrot, and create thunking/compatibility interfaces between the two. If we try to create a converter to convert perl5 to perl6 code, by say using a B:: backend or such, it forces us to develop both perl5 *and* perl6 in Parrot, each with their own PMCs and semantics. Not to mention the amount of intelligence and introspective abilities you'll need to program into that convertor to actually be able to do the things that are needed. A simple translator will write code which assumes that 'eval' can be called anywhere, etc. Which might very well lead to performance that's worse than perl5 (especially if we force DOD runs on every block exit to ensure the same liveness guarantees of refcounting.) Does anyone actually know what the plan for perl5 to perl6 conversion is, or are we just assuming all possible avenues now, to be discarded as we approach the implementation phase and realize the scope of the project. :) Thanks, Mike Lambert
Finding closure in the continuous forest
Perhaps we should just explain continuations in terms of time travel. Most people think they understand time travel, even when they don't. A continuation is just a funny label for a point in time, and you have a way of sending messages from the future back to that point in time. Hrm...here's my story. The perl program execution is merely a traveller in a maze-like forest, searching for the answer to his life's work. This forest is nested deep within the valley of a large mountain range surrounding it, preventing passage out of the forest. When he passes through some piece of the forest, he can plop down a teleporter, along with a book describing his exact steps to get there from where he began. (It's a step up from hansel and gretal.) Later, he can make a call, and teleport to any of the places he's put down a teleporter, and continue where the book left off, with all of it's history. The forest corresponds to stack memory: every change to the stack, every function call, and every stack movement corresponds to some movement in that forest. The surrounding mountain range is the globals and package data...data not directly in the forest. But no matter how the traveller moves, the mountains are always visible to him, a reminder of where he is in the global scope of things. However, as a nice side-benefit, taking a closure is then nothing more than leaving a teleporter, but with a book marked 'return to sender' on it. I'm not sure how to describe pointers in the forest to the surrounding mountains, however. Rainbows with a pot of gold at the mountainous end? Telescopes on the ground which can be moved and rotated? Mike Lambert
Re: Methods, and such
This is perfectly possible in Perl5, so I don't see why it wouldn't be possible in Perl6... Create a new package. Add the sub to that package. Set the @INC of that package to your current package. Re-bless yourself into the new package. Granted a nice simple syntax would be nice, but that's what modules are for. You also run into issues of identity. If I add a method to an existing object, is that object still of the same type? Should 'ref' return the same classname, or is it okay if it returns some auto-generated name after it's had instance methods added to it? The latter would occur with the Perl5 solution above, and I would argue that it should stay that way, since it's not exactly the same type. Mike Lambert Luke Palmer wrote: Date: Wed, 15 May 2002 19:51:39 -0600 (MDT) From: Luke Palmer [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Methods, and such It seems something messed up while I tried to send this earlier. If this is essentially a duplicate, ignore it. I've always liked how VB allowed you to do instance methods. They allow for more elegant callbacks, and more structure if callbacks are complicated. Will Perl6 allow this? (Perl5 sortof did, but since the bless way of life is going away...) Perhaps... class foo {...} $x = new foo; #BTW: is there some unified way of creating instances # in perl6? method $x.frob() {...} $x.frob; Luke
Re: Loop controls
It's also unnecessary. The Holy Scoping Rules actually work in your favour in this case. In Perl 6 you can just do this: while my $cond = blah() { ... } and C$cond is defined *outside* the block. Question then. Does the following code compile? while my $i = getNextValue() { } while my $i = getOtherNextValue() { } Does it fail due to scoping $i twice within the same enclosing block, or is it sort of like a Scheme/OCaml interpreter where each definition creates a scoping for all the lines that follow it, and the second 'my $i' merely hides the $i scoped in the 'outer' scope. This happens a lot in C where some compilers scope the initializer in a for loop to the enclosed loop (CodeWarrior), and some scope it in the enclosing block (GCC, MSVC). The latter approach causes people to write: for(int i=0; ... ) { ... } for(i=0; ... ) { ... } Which of course breaks when you remove the first loop. I always found that annoying...and that's what the following was used for, in those compilers: #define for if(0) {} else for Mike Lambert
Re: Loop controls
I can also think of some advantages to having the else within the scope of the loop. while alllines(/etc/passwd) - $_ { ... } else { die /etc/passwd: $_; } But the aliased value, $_, is restricted to the scope of the Cwhile's block, it isn't going to be accessible in the block associated with the Celse (you would be getting some $_ from an outer scope). This is the only major reason not to adopt a 'else' on loops, imo. Two solutions to the problem of accessing 'what' returned false are: 1) don't allow it. 2) Alias the value of the while/loop/if conditional into a special variable. while( blah() ) { .. } else { print $COND; } It's ugly, but it works, and doesn't break the holy scoping rules. And given how little you're going to want to know what kind of false value as returned, I don't think it's that bad. Someone might want to come up with a better variable name, however. Just trying to contribute something new to the discussion that hasn't been mentioned a dozen times already... :) Mike Lambert
Regex and Matched Delimiters
'..' before idiom can be Huffman-encoded somehow? And for example, one can register 'e' as eval, and use the misx characters to turn on/off those symbols for the thing enclosed in braces. The problem with this latter idea is that the proposed system does not support turning off of these pragmas. Perhaps we could make '-' a special character which acts like it did in (?misx-misx: ? One could register 'e'=eval and 'r'=regex-interpolate to handle: {e print hello} and {r $code = calculation($);qr/$code/} (Assuming you want to keep these seperate, and don't want to force 'e' to become {r print hello;qr//} where qr// represents an empty regex that doesn't insert anything into the regex stream. I think I'll stop here, as I think I've said more than enough. Mike Lambert
Re: Hashes, Stringification, Hashing and Strings
Speaking of which, how do we ensure the immutability of keys being put into the hash? I think Perl copied the string, so that: $b = aa; $a{$b} = 1; chop $b; print $a{aa}; still works. If we start storing full thingies into the keys of a hash, we either need to make deep copies of these, or copy enough to ensure the hashing function has all that it needs. Say we do: $b = new Cat(); $a{$b} = 1; $b-somefunctionthatchangesthehashvalue(); $a{$b} doesn't find anything, since $b was hashed under it's old identity. Also, Perl allowed this before: $b = aa; %a{$b} = 1; print $a{aa}; Will it allow this? $b = new Cat(); %a{$b} = 1; print $a{new Cat()}; If it does, how does it determine equality of two objects? What if Cat includes a counter that determines which number it is in some total ordering of cats. Will the above still work? Java had all sorts of problems where they force immutability of an object onto the user of their Collection API. It's a pain in the ass, and the source of stupid bugs, where your object changes it's hash value without being rehashed. How will perl handle this? If it automatically rehashed objects in whatever tables they are stored in (forget the speed hit for now), then we still have the problem of: $a = a; %c{$a} = 1; $b = aa; %c{$b} = 2; chop $b; print %c{a}; #what gets printed? According to perl 5 semantics, this would print 1. But according to the rehashing rule above, this is ambiguous. So that's not an option. I personally liked the stringification of keys. It made things a LOT simpler. :) Finally, one last option is to hash based on some memory address, so that when we store objects in there, we can be assured of no two of them pointing to the same place, or worrying about the hash function changing. Assuming we work around our copying GC some way to get a unique object identity value, we still have the problem of two equivalent strings hashing to different places, or two equivalent arrays hashing to different values. I can make a case for the latter being a good thing, but not the former, as it breaks perl5 semantics. Two options I see are: a) stringify everything, and make life simpler. I never really had a problem with stringified keys... b) strings get hashed like perl5. everything else gets hashed based on some unique object identifier (memory address) that's constant throughout the life of the object. This means that in order for an object to be able to have equality work in hashtables, from two objects constructed at different points in time, they'd need to overload the operator:hash() function to return a string. Or has this matter been thought through already? Thanks, Mike Lambert Aaron Sherman wrote: Date: 16 Apr 2002 12:13:55 -0400 From: Aaron Sherman [EMAIL PROTECTED] To: Perl6 Language List [EMAIL PROTECTED] Subject: Hashes, Stringification, Hashing and Strings In this example: %hash = ($a=$b); $a can be anything. In fact, since Perl6 promises to retain the original value of $a, we're rather encouraged to store complex data there. But, this poses a problem. The key to use for hashing might not ideally be the string representation. For example, if I'm hashing a collection of special file objects, it might be useful in one context to do: method operator:qq () { return read_whole_file(); } But, if I have 100 of these objects, and I try to put them in a hash, life could get ugly fast! More helpful would be to have this builtin: method operator:hash () { return operator:qq(); } and then allow me to override it in my class like so: method operator:hash () { return filename(); } This allows me to specify separate hashing and stringification methods, but retains Perl's original default of combining the two.