Re: Some Things I'd Like To Do With Pod
On 22/06/07, brian d foy [EMAIL PROTECTED] wrote: ===Per class documentation, not per file documentation Related to the one above, I'd like to have NAME, SYNOPSIS, etc. for each class, not just per file. Well, what I really want is the Smalltalk class and method browsers, but I know I'm not going to get those. I'm sure it's going to be great deal easier to implement such a tool in Perl 6 than it is in Perl 5 though. It's just not going to be in the core. And even if it's not going to be easy, I can think of at least one person who is going to have a bloody good go at implementing it. With apologies if I'm teaching my grandma to suck eggs here.
Re: Selective String Interpolation
Damian Conway [EMAIL PROTECTED] writes: Brad Bowman asked: When building code strings in Perl 5 I usually write the code, then wrap it in double quotes, then \ escape everything light blue under syntax highlighting. I was wondering if there'll a better way in Perl 6. I thought it would be nice to define the variables you wish to interpolate individually, perhaps as extensions to the :s, :a, etc quote adverbs, perhaps using a signature object. There is already a mechanism for this. You simply turn off all variable interpolation, and interpolate any the variables you wish to interpolate via block interpolations. Or, more simply, only turn on block interpolation in a non-interpolating string: my $code = q:c{ package {$package_name}; sub {$sub_name} \{ return {$return_val} \} }; The problem here is that sometimes (especially in code generation) you don't really want to interpolate the stringification of a value, you just want the value itself. I've been struggling with this slightly when I've been writing code generation methods in Ruby. Where, in Scheme or lisp you'd simply use some combination of C`, C, and C,@, in Ruby you end up having to store values somewhere in the binding that will be accessed by your compiled code; which would be fine if (again, as with Lisp macros) you could generate what I tend to think of as an anonymous symbol to bind the value to: my $anon_symbol = gensym my ${$anon_symbol} = $the_complex_value_we_want_to_use_in_generated_code my $code = q:c{ package {$package_name}; sub {$sub_name} \{ return ${$anon_symbol} \} }; And backwhacking braces in generated code is *not* a pretty solution to my eyes. I'd *like* to be able to have a quasiquoting environment along the lines of lisp's backquote (though I'm not sure about the unquoting syntax): my $code = q:`{ package ,$package_name; sub ,$sub_name { ,$the_complex_value_we_want_to_use_in_generated_code } sub ,$another_sub_name { ,[EMAIL PROTECTED](';')} } }; Whatever we go with, we need a quoting mechanism that returns a parse tree rather than a simple string if we want to deal with interpolating complex values (especially if we don't want to have to worry about what, if any, quotes are needed round some of our interpolated values. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Perl 6 OO and bless
John Siracusa [EMAIL PROTECTED] writes: On 1/18/06 11:06 PM, Rob Kinyon wrote: Not to mention that 90% of the hacking done in Class:: and Object:: will handled by the fact that Perl6 has actual OO syntax. (Look Ma, no hands!) You won't need Class::MakeMethods because Perl6 will make your accessors for you. There's more to life than simple get/set accessors. Method-makers will have and a long and glorious life in Perl 6, I assure you :) I refer the interested reader to all the handy dandy method makers (and other tricksy class methods) to be found in the Ruby on Rails framework... -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: relationship between slurpy parameters and named args?
Stuart Cook [EMAIL PROTECTED] writes: On 29/12/05, Austin Frank [EMAIL PROTECTED] wrote: So, is there a conceptual connection between imposing named argument interpretation on pairs in an arg list and slurping up the end of a parameter list? Are there other meanings of prefix:* that relate to one or the other of these two meanings? The missing link is that prefix:* in an argument list also causes things like arrays to be treated as a sequence of separate parameters, rather than as a single array parameter. See Flattening argument lists in S06. (This was the original meaning of prefix:* in arglists; the named-pair behaviour was added later, when pair values ceased to have named behaviour automatically.) Personally, I think that prefix * in an arglist should only flatten array arguments if there is only one array. And if it doesn't, how do I declare parameter that is 'a slurpy list of arrays' or 'the rest of the arguments, without flattening'. If I *really* want aggressive flattening then I can call, say, @slurpy_param.flatten -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Journal moved.
Audrey Tang (autrijus) [EMAIL PROTECTED] writes: [...] I am not sure how much (if any) of this should be cross-posted to P6C... Would the list subscribers be interested in getting them in email form, in addition to the current blog format? It'd certainly make it easier for this summary writer if they appeared in the same inbox as the rest of p6c. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: relational data models and Perl 6
Rob Kinyon [EMAIL PROTECTED] writes: On 12/16/05, Ovid [EMAIL PROTECTED] wrote: Minor nit: we're discussing to the relational algebra and not the relational Calculus (unless the topic changed and I wasn't paying attention. I wouldn't be surprised :) Algebra, in general, is a specific form of calculus. So, we're speaking of the same thing, just in different terms. Umm... I think you have that relationship the wrong way around. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: statement_controlfoo()
Larry Wall [EMAIL PROTECTED] writes: On Tue, Nov 22, 2005 at 10:12:00AM +0100, Michele Dondi wrote: : Oh, I'm not the person you were responding to, and probably the less : entitled one to speak in the name of everyone else here, but I feel like : doing so to say that in all earnestness I'm quite sure no one took any : offense out of your words. Despite the slight harshness, they're above all : witty. Just as usual: and that's the style we all like! $fh = open '', 'quotefile' or fail; $fh.print 'EOQ' I like witty sayings as much as the next guy, but wit can hurt when misdirected. If people want me to be machine for cranking out quote file fodder, I'll do my best. But I also care about my friends. Larry EOQ -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Perl6 perlplexities
Rob Kinyon [EMAIL PROTECTED] writes: First-class blocks make continuations and coros almost neglible to implement from an API perspective. Almost makes me wonder how much trouble it would be to implement this in P5 ... Um... tosh. Seriously. Full continuations need some fairly serious retooling of the call stack if they are to work properly. And one shot continuations are the next best thing to useless. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Perl6 perlplexities
Juerd [EMAIL PROTECTED] writes: Michele Dondi skribis 2005-11-04 14:58 (+0100): Let me explain: we all know that Perl5 has a very simple parameter passing mechanism for subs and an even more rudimentary {prototyping,signature} mechanism that one actually seldom uses. It is unused because it sucks. /blunt With this simple mechanism one can implement or fake quite a lot of parameter passing paradigms. And it is a lot of work to do so. for simple subs in Perl6 I will probably still use @_ You'd be a fool to do so, with the sole exception of list manipulation, which at least in my codebase isn't used quite that much, and almost never listens to the qualification simple sub. Compare: sub dosomething { @_[0] blah @_[1] } sub dosomething ($a, $b) { $a blah $b } sub dosomething { $^a blah $^b } The @_ solution is really the most ugly and hard to type of the three possibilities. err... that or the new pointy subs which are indeed so cool! Cool, but probably not a good idea for named subs, if only for style. our dosomething ::= - $a, $b { $a blah $b } Not really a winner in any perspective. And the return semantics of pointy blocks are different, you have to be careful about doing an explicit return in them because that returns to the caller of the lexical scope in which they were defined (otherwise for ... - ... {...} wouldn't work) -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Perl6 perlplexities
Rob Kinyon [EMAIL PROTECTED] writes: On 11/4/05, Michele Dondi [EMAIL PROTECTED] wrote: I'm still convinced my remark _partly_ applies in the sense that the overall impression is that a vast majority of most common needs is addressed by a *subset* of the current features and trying to stuff all them in has brought in quite a lot of discussions of which I'm not even sure if they've all settled down. I think a good comparison can be made to Ruby. For work, I've been learning Ruby this past week (we're going to try out Rails to see if we like it). As my colleague put it, Ruby has all the P6 features we want and it's usable now. Ruby's OO system is 1000% more complex that Perl5's. Yet, it's still a net win. For one thing, I don't have to write the following anymore (lifted from a CPAN module I am working on): The thing about Ruby (and Perl 6's) OO system is that the complexity is in the right place -- tucked away where most people don't have to worry about it until they want to do something complex. sub children { my $self = shift; if ( caller-isa( __PACKAGE__ ) || $self-isa( scalar(caller) ) ) { return wantarray ? @{$self-{_children}} : $self-{_children}; } else { return @{$self-{_children}}; } } This is in a vain attempt to implement a protected subroutine. In fact, I really want a private writing accessor with a public reading accessor, but have absolutely no way to implement that. Why do I want such a beast? Because I want to GUARANTEE in an absolute kind of way that, unless my user truly intended to do so, he's not going to be able to accidentally screw up my internal state. And when your user does want to, essentially say Nah, you screwed up designing that object protocol, children shouldn't've been protected. it's the work of a moment to write: thing.send(:children, *args) (Oh, and Ruby has first-class block. W00T!) And continuations. But continuations are scary. Good scary, but still scary. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: All tests successful considered harmful
chromatic [EMAIL PROTECTED] writes: On Thu, 2005-10-27 at 10:26 -0700, jerry gay wrote: we're missing some parts of a testing framework. we don't have the ability to write test files in PIR, so we're dependent on a perl install for testing. perl's a great language for writing tests anyway, and right now we're dependent on perl for parrot's configure and build as well. that said, breaking this dependency will make parrot just a bit closer to standing on its own. We have a Test::Builder port in PIR. I will move up my plan to port Parrot::Test to use it. Somewhere I have the beginnings of an xUnit style 'parrotunit' testing framework, but that was written ages ago, so I'd need to start it again, but it wasn't that hard to implement. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Proposal to make class method non-inheritable
Stevan Little [EMAIL PROTECTED] writes: Piers, On Oct 12, 2005, at 5:22 AM, Piers Cawley wrote: We definitely have two instances of A since, B.isa(::A). We also have a fragile implementation of count. :) Sorry, I purposefully made it a kludge as that is usually the way the example is shown in most tutorials about class methods. So, let me see if I have this straight here. You're arguing that, because people are often foolish, we should make it harder to be clever? And you're using a deliberately broken example as grist to your mill? Doesn't sound all that Perlish to me. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Roles and Trust
Ovid [EMAIL PROTECTED] writes: --- Piers Cawley [EMAIL PROTECTED] wrote: How about: my method SCALAR::attributes($self:) { $$self } my method HASH::attributes(%self:) { %self.kv } my method ARRAY::attributes(@self:) { [EMAIL PROTECTED] } method _attributes($attrs) { my @attributes = $attrs.attributes return @attributes[0] if @attributes == 1; ... } Assuming it's legal. Just saw this. Sorry for the late reply. At first that gave me the willies, then I noticed the my on the front. I assume because of the my on there that this would affect those data types only locally? That seems like it would be a nice compromise. Is this legal syntax? After some discussion on #perl6, we thought probably not (unless @Larry rules otherwise). However, my multi attributes( Scalar $scalar: ) { $$scalar } my multi attributes( Hash %hash: ) { %hash.kv } my multi attributes( Array @array: ) { [EMAIL PROTECTED] } definitely is legal (though it does rather suffer from the end-weight problem to my way of thinking). -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Proposal to make class method non-inheritable
Stevan Little [EMAIL PROTECTED] writes: Hello all. I would like to propose that class methods do not get inherited along normal class lines. I think that inheriting class methods will, in many cases, not DWIM. This is largely because your are inheriting behavior, and not state (since class attributes are not inheritable). Let me explain in more detail. Let's start by making a very basic definition of an *object*, ignoring any implementation details or specifics. object == state + behavior This statement assumes that *objects* at their core are a unique state coupled with a collection of behaviors to act upon that particular state. Of course we are ignoring all the other class/meta/ inheritence junk for now. To take away the behavior, and only be left with state would degrade our object to the level of C struct or Pascal-style record-type. To take away the state, and only be left with behavior, would basically leave a module/package or some pseudo-random collection of functions. So at this point, I think it is safe to say that an *object* should have both state and behavior. Now, back down from the theoretical cloud to reality. I would like to show some canonical class-method examples (and in some cases, show how they are broken), then show how they might be better accomplished in Perl 6 without the need for class methods to be inherited. == Instance Counting Class The most common example given for class methods is an instance counter. Here is how one might (naively) look in Perl 6: class A { our $.count; method count (Class $c:) { $.count; } submethod BUILD { $.count++; } } Each time an instance of A is created the counter is incremented. So that ... A.count; # 0 A.new; A.count; # 1 Now this makes sense, until we subclass A. class B is A {} A.count; # still 1 B.new; # calls A::BUILD A.count; # 2 B.count; # 2 Clearly, we only have one instance of A, and one instance of B, so those numbers are wrong. It could be argued that since B is a subtype of A, we do have two A's, but the argument does not work in reverse. But either way, I would argue that the results shown above are misleading, and probably not what the programmer intended. We definitely have two instances of A since, B.isa(::A). We also have a fragile implementation of count. class A { our %.count_of method count (Class $c:) { %.count_of{$c} } method BUILD { $class = ($?SELF.class) @countable_ancestors = $class.ancestors.uniq.grep :{.isa(::A)} for $class, [EMAIL PROTECTED] - $c { %.count_of{$c}++ } } Where we're assuming I've got the syntax of 'for' right, and that 'ancestors' is a class method that returns all of a class's ancestors. This might not work too well in the face of a dynamic inheritance tree, but it should be possible to work around. Something like this might work: Class A { our %.instance_count_of method count (Class $c: ?$with_descendents = undef) { my @interesting_classes = $c; if $with_descendents { push @interesting_classes, *($c.all_subclasses); } [+] %.instance_count_of(@interesting_classes) } method BUILD { %.instance_count_of($?SELF.class) } } Where we're assuming that a class can find all its subclasses -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Roles and Trust
Ovid [EMAIL PROTECTED] writes: Apocalypse 12 has the following to say about roles and trust (http://www.perl.com/pub/a/2004/04/16/a12.html?page=10) It's not clear whether roles should be allowed to grant trust. In the absence of evidence to the contrary, I'm inclined to say not. In Perl 5, I recently found myself in the annoying position of having a method which could accept scalar, array, or hash references. My primary code looked similar to this (simplified for clarity): sub _attributes { my ($self, $attrs) = @_; return $$attrs if UNIVERSAL::isa( $attrs, 'SCALAR' ); my @attributes = UNIVERSAL::isa( $attrs, 'HASH' ) ? %$attrs : @$attrs; return unless @attributes; # more code here } This was a private method, but $attrs is an argument that is passed in by the person using my class. It would be nice if I could just assign an attributes role to the SCALAR, ARRAY, and HASH classes and say that only my class could see the method(s) it provides. Thus, my caller would be blissfully unaware that I am doing this: $attrs-attributes; # even if it's an array reference How about: my method SCALAR::attributes($self:) { $$self } my method HASH::attributes(%self:) { %self.kv } my method ARRAY::attributes(@self:) { [EMAIL PROTECTED] } method _attributes($attrs) { my @attributes = $attrs.attributes return @attributes[0] if @attributes == 1; ... } Assuming it's legal. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Exceptuations
Peter Haworth [EMAIL PROTECTED] writes: On Wed, 5 Oct 2005 19:24:47 +0200, Yuval Kogman wrote: On Wed, Oct 05, 2005 at 16:57:51 +0100, Peter Haworth wrote: On Mon, 26 Sep 2005 20:17:05 +0200, TSa wrote: Piers Cawley wrote: Exactly which exception is continued? The bottommost one. If you want to return to somewhere up its call chain, do: $!.caller(n).continue(42) Whow, how does a higher level exception catcher *in general* know what type it should return and how to construct it? The innocent foo() caller shouldn't bother about a quux() somewhere down the line of command. Much less of its innards. Well said. No! Not well said at all! Sorry, I misread that. I thought I was agreeng with how does a higher level exception catcher know what to change in order to make resuming the continuation useful?, especially in the light of Piers saying that the bottom-most exception should be the one resumed. I'm sorry, we appear to have lost some kind of context, the original example given only had one exception thrown, but it got propagated up through a long call chain. At no point did anything catch the original exception and rethrow. If they had, you're absolutely correct in asserting that by default things should resume from the point of the outermost rethrow. A brave exception catcher (or more likely programmer with a debugger) might want to crack that exception open and examine its inner exceptions, but in general that's not going to be safe. The scary syntax proposed above is, again, the sort of thing that might be useful in a debugger I don't really care about the inner workings of these helper functions, I just want 'open' to return this mocked handle. (actually in that case, being able to do $!.caller(open).continue(MockIO.new), where 'caller open' looks up the call chain for the lowest call to open and returns that continuation would be rather neat) The highest level exception is the only one a caller has any right to deal with, but even then it doesn't really know what will happen if it resumes some random continuation attached to the exception. Oh stop with the 'rights'. And it's not dealing with a 'random' continuation, if it's going to resume it should be damned careful about which exceptions it resumes from; you don't just go around doing CATCH {...; $!.continue(...)}, you do CATCH SomeSpecificKindOfResumableException { ...; $!.continue(...)}. And, in general, you don't do that either, because in the average program you catch the exception at a point where you can simply return a sensible default to your caller. Resumable exceptions come into their own, however, when you're debugging. I can envisage doing: perl6 -debug::on::error some_script And have it run along happily until an exception gets propagated up to the top level, at which point the debugger swings into action and uses the continuation to tunnel back to the point at which the exception was thrown so the programmer can inspect the program state, possibly fix things up, return something sensible and carry on. CATCH { when some_kind_of_error { $!.continue($appropriate_value_for_some_kind_of_error) } } That just gives me the willies, I'm afraid. It doesn't amuse me that much, unless whatever generates $appropriate_value_for_some_kind_of_error is very, very smart indeed. But, as I've said above, that's not really where resumable exceptions shine. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Exceptuations
TSa [EMAIL PROTECTED] writes: BTW, I would call *intentional* exceptions terrorism. So that would be all exceptions then. They all get implemented somewhere, even the ones that get thrown by builtins. CATCH Exception { say Why do you hate freedom? } -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: This week's summary
TSa [EMAIL PROTECTED] writes: HaloO, The Perl 6 Summarizer wrote: Meanwhile, in perl6-language \(...) Oh look, a thread in p6l that's still going more than a fortnight later. How unusual. Is a long running thread considered a bad thing on this list? Nah, it's just hard to summarise. I have grasped so far, that spawning a new thread after some divergence from the original topic is considered nice. Definitely. This particular instance of the form is nominally about the behaviour of \($a, $b) but various subthreads have drifted onto discussions of context in general and meaningful whitespace. So far there has been no discussion of the return value of Pin.head.contents.grep - Angel $a {$a.is_dancing} but I'm sure it's only a matter of time. Please tell me if the particular pinhead is me. I'm actually about to reply to Juerds question about my ranting about code backing the interpolation of data into strings. Or is that considered counter productive hairsplitting? Just a reference to the old philosophical question of how many angels can dance on the head of a pin. That and the fact that I occasionally get curmudgeonly and hit the send button before I have second thoughts. The weird thing is that the syntax I rolled there is soon to be the topic of an original thread, once I've got the thing written up a little more. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: loadlib and libraries with '.' in the name
Joshua Juran [EMAIL PROTECTED] writes: On Sep 23, 2005, at 3:47 AM, Leopold Toetsch wrote: On Sep 23, 2005, at 7:51, Ross McFarland wrote: i was planning on playing around with gtk+ bindings and parrot and went about looking around for the work that had already been done and didn't turn anything up. if anyone knows where i can find it or who i should talk to i would appreciate that info as well. Google for NCI gtk. There is also a weekly summary entry but the xrl.us shortcut seems to have expired. I was wondering about that. I Googled for tinyurl considered harmful and was surprised to find only one message, discussing the phishing risks. I found no mention of the risk of outsourcing a bottleneck to a third party who has zero obligation or direct interest to continue providing the service. From http://metamark.net/about#expire: Do Metamark links expire? The Metamark urls expire after five years or two years after the last usage - whichever comes later. However, if a link is never used, it will expire after two years. This should mean that as long as a link is on a public page, some search engine will visit it and keep it alive. Of course, this is subject to change and is no promise but just my intentions as of this writing. If you want guarantees you can make your own service. To be quite frank, I'm astonished the practice exists here in the first place. In my opinion it goes directly against the spirit of the Web envisioned by Tim Berners-Lee. A better practice would be to post long URL's within angled brackets. And there's no reason you can't do both, either. Which is why the archived summaries at deve.perl.org and perl.com all use the long form URLs. The metamarked URLs only ever appear as a convenience for readers on the mailing list. I am not about to start polluting my mailed summaries with such monstrosities as http://groups.google.com/[EMAIL PROTECTED] any time soon. You're welcome to write your own summaries that do use the full URLs of course. Or, if it bothers you that much, write something to run from cron once a month or so that grabs shortened summary URLs and does a simple GET on them. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Sort of do it once feature request...
Michele Dondi [EMAIL PROTECTED] writes: Every time I've desired a feature for Perl6 it has turned out that either it was already planned to be there or I have been given good resons why it would have been better not be there. And you've done it again. What you ask for is already there. See below. Now in Perl(5) {forum,newsgroup}s you can often see people doing stuff like my @files=grep !/^\.{1,2}/, readdir $dir; Letting aside the fact that in the 99% of times they're plainly reinventing the wheel of glob() a.k.a. File::Glob, there are indeed situations in which one may have stuff like for (@foo) { next if $_ eq 'boo'; # do something useful here } for @foo { next if (($_ ne 'boo')..undef) # do something useful } whereas they know in advance that Cif can succeed at most once (e.g. foo could really be Ckeys %hash). Or another case is this: while () { if (@buffer MAX) { push @buffer, $_; next; } # ... shift @buffer; push @buffer, $_; } while { if 0..MAX { push @buffer, $_; next } end -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Exceptuations
Luke Palmer [EMAIL PROTECTED] writes: On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote: I propose a new model - each exception has a continuation that allows it to be unfatalized. I think we've already talked about something like this. But in the presence of use fatal, it makes a lot more sense. Something comes to mind: use fatal; sub foo() { bar() } sub bar() { baz() } sub baz() { quux() } sub quux() { fail } { say foo(); CATCH { $!.continue(42) } } Exactly which exception is continued? The bottommost one. If you want to return to somewhere up its call chain, do: $!.caller(n).continue(42) Assuming caller returns a continuation (which I still fondly hope it will). I'm assuming you're examples aren't necessarily tail calls of course. Where do we cut off the call chain and replace our own value? This comes up again with open(). Let's say open is implemented with a series of five nested calls, the innermost which knows how to fail and propagate outwards. However, the programmer using open() has no idea of its internals, so it ought to override the return value of open() itself, rather than its utility functions. However, we can't go with outermost, because then you'd only be fixing the lexical call (say foo() above). So it's somewhere in between. Where? Obviously the topmost function should do: sub open(...) { ... CATCH { $!.rethrow } } This assumes that 'rethrow' throws a new exception that delegates to the original exception for lots of its behaviour. If, later, you want to explicitly get at the exception thrown by the helper function, you could do something like: $!.inner -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Exceptuations
TSa [EMAIL PROTECTED] writes: HaloO, Piers Cawley wrote: Exactly which exception is continued? The bottommost one. If you want to return to somewhere up its call chain, do: $!.caller(n).continue(42) Whow, how does a higher level exception catcher *in general* know what type it should return and how to construct it. It asks the continuation? The information should be there. Consider a function definition: sub whatever(...) returns List { throw ResumableException; } Then, assuming that caller returns continuation -- which is a pretty big assumption, but which would be really cool -- $!.caller(1) would be a continuation with an signature of (List $not_a_real_name). If the function can return several types dependent on context, then the continuation's signature would be the appropriate one for the context in which the function was called. Monkeying with this kind of thing in code isn't necessarily a good idea, but it's great for, for instance, having a top level exception catcher that could (potentially) bring up an interactive shell with limited debugging features which would allow you to inspect the running program and work out what went wrong. Ruby on Rails already does something like this, with the added wrinkle that, if it hits a breakpoint when running in the server it hands off the interactive session to a console process rather than having you monkey with it within your browser. A very neat trick and a remarkably powerful debugging technique. The inocent foo() caller shouldn't bother about a quux() somewhere down the line of command. Much less of it innards. Think of receiving a 'shelf picker died of lung cancer' exception when you just ordered a book from your favorite book dealer. Irrespective of the seriousness to the shelf picker, but how would you expect a customer to handle such an exception? I wouldn't, but I would expect that a programmer would find such an exception very useful indeed. -- Piers Cawley [EMAIL PROTECTED] http://www.bofh.org.uk/
Re: Do slurpy parameters auto-flatten arrays?
Luke Palmer [EMAIL PROTECTED] writes: On 7/26/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, are the following assumptions correct? sub foo ([EMAIL PROTECTED]) { @args[0] } say ~foo(a, b, c); # a Yep. my @array = a b c d; say ~foo(@array);# a b c d (or a?) say ~foo(@array, z); # a b c d (or a?) a for both of these. The *@ area behaves just like Perl 5's calling conventions. I could argue for never auto flattening arrays, but then there'd really be no difference between @ and $. say ~foo([EMAIL PROTECTED]); # a say ~foo(*(@array, z));# a Hmm, *(@array, z)... what does that mean? Whatever it means, you're correct in both of these. In the latter, the @array is in a flattening context, so it gets, well, flattened. sub bar ([EMAIL PROTECTED]) { [EMAIL PROTECTED] } say bar(1,2,3); # 3 say bar(@array); # 1 (or 4?) 4 Wha? And I mean that sincerely. That's cockeyed. Surely a [EMAIL PROTECTED] in the signature simply says 'gather up the rest of the args and stick 'em in this list'. In this case @array is a single argument, so @args should be equal to [EMAIL PROTECTED] If I'm calling the function and I want @array to be treated as anything but a single argument I use [EMAIL PROTECTED] say bar(@array, z);# 2 (or 5?) 5 Double wha? That's even worse. Do you claim that say bar('z', @array) also emits 5? Ick. say bar([EMAIL PROTECTED]);# 4 Yep. So how *do* I pass an unflattened array to a function with a slurpy parameter?
Re: Exposing the Garbage Collector (Iterating the live set)
Luke Palmer [EMAIL PROTECTED] writes: On 7/26/05, TSa (Thomas Sandlaß) [EMAIL PROTECTED] wrote: Piers Cawley wrote: I would like to be able to iterate over all the objects in the live set. My Idea actually is to embedd that into the namespace syntax. The idea is that of looking up non-negativ integer literals with 0 beeing the namespace owner. for ::Namespace - $instance { if +$instance != 0 { reconfigure $instance } } Oh, so a namespace can behave as an array then. Well, to avoid auto-flattening problems in other, more common places, we ought to make that: for *::Namespace - $instance {...} However, this is very huffmanly incorrect. First of all, what you're doing may take a quarter of a second or more for a large program (which isn't a short amount of time by any means). Second, the fact that you're using it means you're doing something evil. Third, only a fraction of 1/omega perl programmers will be using this feature. Therefore, it should probably look like: use introspection; for introspection::ALL_INSTANCES(::Namespace) - $instance {...} And if my proposal or something like it were accepted, the implementation could simply look like: module introspection { class Class is extended { method all_instances($class:) { fail unless $*PLATFORM.GC.can_iterate_over_liveset; $*PLATFORM.GC.grep - $instance { $instance.isa($class) } } } sub ALL_INSTANCES($class) { $class.all_instances } } The point about my proposal to have the garbage collector or something like it expose methods to iterate over the live set isn't that it's syntactically gorgeous, but that it's a useful minimal behaviour that can be used to implement nicer syntaxes which can be loaded as required. If we're going to allow such reflective stuff (on platforms that can do it) then there needs to be some minimal core functionality that other modules can use. The point about iterating over the live set is that it's essentially free until you use it; the garbage collector must *already* hold onto the information needed to do the iteration.
Re: Elimination of Item|Pair and Any|Junction
Autrijus Tang [EMAIL PROTECTED] writes: On Fri, Jul 22, 2005 at 03:40:34PM -0700, Larry Wall wrote: I dunno. I'm inclined to say that it should default to Item|Pair, and let people say Any explicitly if they really want to suppress autothreading. Otherwise conditionals and switches are going to behave oddly in the presence of accidental junctions. Okay. However, in that view, I suspect many builtins will be defined on Item|Pair, for example perl, clone, id, as well as various coercion builtins. Considering that builtins are Code objects but not Routines, maybe they, too, should default to Item|Pair -- except the ones that operates on junctions, of course. This leads me to think that maybe users don't really need to write down the two junctive types, under the hierarchy below: - Object - Any - Item - ...pretty much everything - Pair - Junction - num, int, str... Since junctions are still boxed objects, having the Object type to effectively mean Any|Junction seems natural (everything is an object). Also, since Any unifies Item and Pair, the rule for implicit types of argument becomes: sub ($x) { }# Item $x - $x { } # Any $x- i.e. Item|Pair but not Junction { $^x } # Any $x- i.e. Item|Pair but not Junction Maybe there's a case for introducing Bundle types, akin to CPAN bundles. These would be types only in the very losest sense, that could be used in function prototypes to stand for particular bundles of types. So instead of Any being in the class hierarchy where you propose it'd be a bundle that expanded to the equivalent of doing: any(Object.all_subclasses.grep - $class { !$class.does(Junction) }) That way we get to arrange the class hierarchy in the way that makes the most sense conceptually, but slice still slice it appropriately for Type specifiers. Just a thought.
Re: Do slurpy parameters auto-flatten arrays?
Luke Palmer [EMAIL PROTECTED] writes: On 8/3/05, Aankhen [EMAIL PROTECTED] wrote: On 8/3/05, Piers Cawley [EMAIL PROTECTED] wrote: So how *do* I pass an unflattened array to a function with a slurpy parameter? Good question. I would have thought that one of the major gains from turning arrays and hashes into references in scalar context is the ability to specify an unflattened array or a hash in a sub call without any special syntax... Well, you can, usually. This is particularly in the flattening context. In most cases, for instance: sub foo ($a, $b) { say $a } my @a = (1,2,3); foo(@a, 3); Passes the array into $a. If nothing flattened by default, then you'd have to say, for example: map {...} [EMAIL PROTECTED]; I would assume that the way to implement map is: multi sub map(block, @array) { map block, [EMAIL PROTECTED] } multi sub map(block, [EMAIL PROTECTED]) { ... } If I call map like: map {...} @a, @b, @c; then I would expect the block to be called three times with @a, @b and @c as the respective arguments. I think the problem I have with this is that unless I missed something, the default prototype for a block is [EMAIL PROTECTED] If slurpiness works as described, then $func = { [EMAIL PROTECTED] } $func.(@array) doesn't return the length of the array, but the numification of its first element. It seems to me that a slurpy parameter spec should simply say Grab the rest of the arguments and stick 'em in this array/hash, a function's caller should control the flattening of a particular array argument, not the thing it calls. One of us has obviously misread the appropriate Apocalypse/Synopsis/Exegesis. I have the horrible feeling that it's probably me, but I do think that the interpretation I propose is the least surprising and most useful. By the way, if flattening that way, what's the prototype for zip? We can after all do: zip @ary1, @ary2, @ary3, ... @aryn
Re: Exposing the Garbage Collector
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: Let's say I have a class, call it Foo which has a bunch of attributes, and I've created a few of them. Then, at runtime I do: eval 'class Foo { has $.a_new_attribute is :default10 }'; Assuming I've got the syntax right for defaulting an attribute, I think you need a 'class Foo is extended' to re-open the class. Otherwise you produce a redefinition error if the scope you call eval in already contains---or is that extains because of the name search beeing *outwards*---one you start from scratch. Oh for heaven's sake! That's the last time I go trying to come up with concrete examples for this sort of thing. Of course, you're right, I should have said 'is extended', but if I were doing it for real, the eval would fail and I'd have a meaningful error message. [ An explanation of why this particular case doesn't require iterating over the live set ] I really shouldn't go picking concrete examples that can be worked around should I? Suffice to say that sometimes (say for debugging purposes, or program analysis -- Smalltalk can do some cunning typer inferencing tricks by examining the live set for instance) I would like to be able to iterate over all the objects in the live set. ISTM that exposing the Garbage Collector at the Language level is the neatest way of doing this (or coming up with something like Ruby's ObjectSpace, but conceptually I reckon the GC is the right place to hang it).
Exposing the Garbage Collector
Let's say I have a class, call it Foo which has a bunch of attributes, and I've created a few of them. Then, at runtime I do: eval 'class Foo { has $.a_new_attribute is :default10 }'; Assuming I've got the syntax right for defaulting an attribute, and lets assume I have, the Perl runtime needs to chase down every instance of Foo or its subclasses and add an attribute slot (adding a method to a class is nowhere near as interesting, because every instance of the class shares a single class object). One way to do this is for a class to keep track of all its instances, which is all very well until you start subclassing because subclasses have to both keep track of their instances and inform their superclasses about any new instances, which seems an awfully heavyweight thing to have to do just to be ready for the occasional programmer like me who wants to develop classes in an image based IDE or someone else who wants to add a role to a class at runtime or whatever. Also, the class's links to its instances needs to be week, otherwise you end up with instances that never get collected, which isn't good. It seems to me, that the way to get at all the instances of a class is to ask the Garbage Collector to do the heavy lifting for us, and ideally I'd like to see this exposed at the Perl level. It doesn't really have to expose that many methods of course -- a simple map/grep would do nicely, then it'd be possible to write, say: class Class { method all_instances ($class:) { $*GC.grep {$^obj.isa($class)} } } Note that, *of course* this is slow, but I suggest that this sort of thing should be slow (or, at the very least, you shouldn't require everything else to pay a runtime cost just to allow people to use reflective tools like this).
Re: Do I need has $.foo; for accessor-only virtual attributes?
Sam Vilain [EMAIL PROTECTED] writes: Larry Wall wrote: Users of the class includes people subclassing the class, so to them they need to be able to use $.month_0 and $.month, even though there is no has $.month_0 declared in the Class implementation, only has $.month. We thought about defining the attribute variables that way, but decided that it would be clearer if they only ever refer to real attributes declared in the current class. Clearer in what way? This implies that you cannot; - refactor classes into class heirarchies without performing code review of all methods in the class and included roles. That's why it's generally a bad idea to use the C$.whatever forms outside your basic accessor methods. - wrap internal attribute access of a superclass in a subclass Which is why it's generally a bad idea to use the C$.whatever forms outside your basic accessor methods. This in turn implies that the $.foo syntax is, in general, bad practice! Yup.
Re: What do use and require evaluate to?
Larry Wall [EMAIL PROTECTED] writes: On Tue, Jul 12, 2005 at 08:48:41PM +0300, Gaal Yahas wrote: : I propose to throw away the filesystem coupling, and map from a more : general name of the bit of code we are requiring to a more general : description of which instance of it we actually got. Once modules return : interesting values, it might be useful to keep a copy of that value : somewhere on the value side of %*INC: or else turn it inside out and : stipulate that a standard field in the Module object is where you got : this particular module. Yes, that's basically what I was mumbling about in my response. Now just make sure %*INC is lexically scoped. : Probably, %*INC values should be weak references. Why should they be weak references? If %*INC is lexically scoped then its entries represent this lexical scope's *real* references to modules, and there's no need to weaken them, since it's not functioning as some kind of cache. As long as this lexical scope sticks around, it needs the modules it points to. As soon as the lexical scope is destroyed, it doesn't need them any more. (Counting all closures over this lexical scope as preserving its needfulness, until all such closures are dead objects.) It's my conjecture that any explicit need for weak references probably indicates a design failure somewhere. Something like the mis-scoping of a reference variable, or maybe only something niggly like the absence of a feature like is cached to encapsulate weak semantics. Or maybe something as major as the lack of robust GC, in the case of Perl 5... So long as there's some way of asking the garbage collector for everything in the live set so you can grep through them I'm sure you're right. Because almost everything is extensible at runtime a class is going to need some way of finding all its (and its subclasses) instances so it can update 'em when/if it's definition changes. I'm also trying to think how an object/database mapper could be made to work effectively without being able to keep track of all its managed objects, or would that just be handled through the use of 'is cached'?
Re: Dependency Injection
Larry Wall [EMAIL PROTECTED] writes: On Wed, Jul 06, 2005 at 11:47:47PM +0100, Piers Cawley wrote: : Or you could use a global, but globals are bad... Globals are bad only if you use them to hold non-global values. In this case it seems as though you're just going through contortions to hide the fact that you're trying to do something naturally global. You might argue that a singleton object lets you hide the implementation of the delegation from the world, but there's really not much to implement if you just want to tell the world that whenever the world says LOGGER the world is really delegating to LOGGER::DBI. Plus if you really need to reimplement you just vector the world through LOGGER::SELECTOR or some such. The thing about the version where the language handles the vectoring through Logger, or whatever, is that you can retrofit such indirection without having to make sure all your code uses the global. For instance, in the Test::* world, there's a huge number of test modules that all play nicely because they work with Test::Harness, and that's fine until you reach the point where you want to specialize Test::Harness itself (say you want to write a graphical test runner). With the global variable approach, you have to alter everything that uses Test::Harness, with an injection approach, you only have to make changes to Test::Harness itself. Hmm... thinking about this a little further, the interface I proposed can't be as automagical as simply loading a class that injects into your injectable class because said class could well inherit from another injecting class. You would have to make it a two step process like: use InjectableClass; use InjectingClass; InjectableClass.inject_with(InjectingClass); What I'm after is another way to hide implementation details from client classes and allow programmers to write natural code. One nice thing about a variable is that you're guaranteed to be able to temporize it: temp $*LOGGER = pick_a_logger(); I'm not sure that, in the particular case, that's all that useful. It'd be cool if, say in a debugging situation, I could say that, from now on, all messages to Logger from class Foo are actually dispatched to InstrumentedLogger, and then to turn it off again, but I'm not sure how I'd do that with a global. $Package::Name::OUR::*LOGGER = ::InstrumentedLogger perhaps?
Re: SMD is for weenies
Yuval Kogman [EMAIL PROTECTED] writes: On Fri, Jul 01, 2005 at 13:42:34 +1200, Sam Vilain wrote: Yuval Kogman wrote: As I understand it SMD is now not much more than a mechanism to place a constraint on the MMD, saying that there can only be one method or subroutine with the same short name. Why is this the default? Otherwise you lose this quite useful warning if the signatures didn't match; method foo redefined at ... That's a good point... I'm guessing that the default warnings should have a warning for MMD methods which append to a short name without appearing immediately after each other in the same file. I agree with you MMD is very cool, and I use it a lot. But I don't mind clarifying the intent with multi; this overloading is considered by some to be surprising to new programmers. Prepending 'mutli' is not a problem when I have to type it. It's a problem when others won't type it. When 90% of the module code I'll be using is not MMD compatible, because MMD is not the default, I can't specialize other people's code without editing it (at runtime or at the source level). Overloading won't happen unless people overloading semantics are introduced, and that's exactly what I'd like to do to other people's code occasionally. Then write yourself a module, call it 'multiplicity' say, which would allow you to say use multiplicity; sub foo (...) {...} # foo is a multimethod, even if there's already a 'SMD' # foo in existence. It shouldn't even be that hard, just macroize sub/method/whatever to become multis that first check if there's already a singly dispatched sub with the same name and promoting to multi status if possible. Of course, if you use something like that, you're taking the risks on your own head, but you knew that as soon as you typed 'use multiplicity'. The important thing is that the dispatch and reflection system should be flexible enough to allow you to write something like this.
Re: Summarizer Suggestion...
Matt Fowles [EMAIL PROTECTED] writes: Will~ On 7/6/05, Will Coleda [EMAIL PROTECTED] wrote: It would be nice if the summarizers also summarized the various Planet RSS feeds of journal entries, if those entries were sufficiently relevant. I would be willing to do that, but I can't speak for Piers... From the various journal entries I've ready, they often stand pretty well as summaries anyway. Which is why, in my last summary, instead of summarizing journals I simply pointed to planetsix -- I presume there are others.
Dependency Injection
So, I got to thinking about stuff. One of the more annoying things about writing nicely decoupled objects and applications are those occasions where you want an object to be able to create objects in another class. Say you've provided a singleton interface to your logging system. The naive implementation goes something like: require Logger; has $.logger; method logger { $.logger //= Logger.new } method whatever { ./logger.debug(About to do stuff); .do_some_stuff; ./logger.debug(Did stuff); ... } But that's problematic because we've backed knowledge of the particular class that handles logging into our class. The bad solution to this is to subclass our class if we want a different Logger class (that conforms to the same interface). A slightly better solution is to parametrize the logger class name, probably with a class variable -- but doing that means you have to remember to set the variable for every class you use. Or you could use a global, but globals are bad... It'd be really cool if you could essentially write the naive implementation above and have your application/test/webserver harness decide which particular class will be taken to be the concrete implementation. Something like this: role Logger is Injected { method debug {...} method info {...} ... } Logger::DBI does Logger { ... } Logger::Debugger does Logger { ... } Then the harness that actually sets up the application would simply do use Logger::DBI :dsn..., :user..., :password and Logger::DBI would install itself as the default Logger class. The question is, how does one write Injected to make this work? Or what features do we need to be able to write Injected? Thinking about this, it shouldn't be too hard to implement 'Injected' in Perl 5: sub Injected::AUTOLOAD { no strict 'refs'; die If something's already been instantiated you're screwed if ref($_[0]) or $Injected::injecting; local $Injected::injecting = 1; my $target_role = $_[0] my @possibles = grep {/(.*)::$/ $1-isa($target_role)} keys %::; die Too many possibles if @possibles 1; if (@possibles) { *{$target_role\::} = *{$possibles[0]}; } else { my $default_package = $target_role-default_class; eval require $default_package or die Can't find a default package; *{$target_role\::} = *{$default_package\::}; } {$target_role-can($AUTOLOAD)}(@_); } NB, that's completely untested code, but it, or something like it, should work.
Re: Fwd: [EMAIL PROTECTED]: Re: fixing is_deeply]
Michael G Schwern [EMAIL PROTECTED] writes: On Fri, Jul 01, 2005 at 07:11:26AM +, Smylers wrote: The question you have to ask yourself is why should a reference be treated different from any other value? It is a VALUE. Except it isn't. Or at least, not all the time: it depends how you wish to look at it. If you just consider a reference to be a value (effectively a pointer, a memory address) then you aren't examining a data structure _deeply_; you're just doing a _shallow_ comparision of it as a reference. I think this hits the nail on the head. References are treated differently because we don't look at the reference we look at the data that reference points to. is_deeply() does this fairly consistently ignoring blessing, ties and overloading. Under the proposed logic, this test fails: my $a = []; my $b = []; my $c = []; my $x = [$a, $a]; my $y = [$b, $c]; is_deeply($x, $y); because $x and $y can be altered in exactly the same way yet come out differently. $x-[0][0] = 1; # [[1],[1]] $y-[0][0] = 1; # [[1],[]] There's plenty of other cases where this can happen. If $x is tied. If $x is a string overloaded object. If $x is an object. These can lead to situations where the same operation is applied to both structures yet results in different structures. But we ignore this because is_deeply() has to draw a line between internal and external information somewhere. Its drawn at the reference value. is_deeply() is not about exact equivalence. Its about making a best fit function for the most common uses. I think most people expect [$a, $a] and [$b,$c] to come out equal. I've always thought of Cis_deeply as being about the 'shape' of a data structure. When you think of things in this way, then it seems obvious that given $a = [], $b = [], $c = [] then [$a, $a] and [$b, $c] have substantially different shapes.
Re: OO magic (at least for me)
BÁRTHÁZI András [EMAIL PROTECTED] writes: Hi, I'm wondering, if it's possible with Perl 6 or not? class MyClass { method mymethod($par) { say mymethod called!; } } class ExClass is MyClass { mymethod(12); } # pugs myprog mymethod called! I would like to use mymethod to add ExClass some methods, etc. /// Just another problem, related to the above: class MyClass { method whenmother() { say MyClass is parent now!!!; say Her child name is: ~ ; } } class Child is MyClass { } # pugs myprog MyClass is parent now!!! Her child name is: Child I'd like to hope so. Actually, I don't think that this *specific* functionality should be in the core, but the ability to implement it (just needs a unified notifcation scheme that gets tickled when new classes, methods, subs, packages, etc, get added to the image -- more detailed behaviour is a SMOP).
Re: proposal: binding with a function
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes: As I've said before, Perl supports `alias`--it's just spelled `:=`. Here's a rubyish idiom: my old_behaviour := function; function := sub { try_some_stuff || old_behaviour } Except, with binding it doesn't work like that, you end up with an infinite loop.
Re: AUTLOAD and $_
Luke Palmer [EMAIL PROTECTED] writes: On 6/20/05, chromatic [EMAIL PROTECTED] wrote: On Mon, 2005-06-20 at 12:11 +0200, Juerd wrote: I think there exists an even simpler way to avoid any mess involved. Instead of letting AUTOLOAD receive and pass on arguments, and instead of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its thing, and then have *perl* call the sub? Who says AUTOLOAD will always either call a loaded sub or fail? Uh, what else can it do? It doesn't have to load a sub to return a code reference. For myself, I'd like to see AUTOLOAD with a signature along the lines of: sub AUTOLOAD (Symbol $sym, ArgumentCollection $args, Continuation $cc) returns (Code | Pair) { ... } This presupposes a deal of support infrastructure, but also provides flexibility. For the 'NullObject' case, you'd simply do C$cc() to return directly to the caller, skipping over whatever Perl is up to. 'ArgumentCollection'? Well, that's the activation record and I'd like to see it allowing methods like: my ($foo, $bar, $baz) = $args.parse_signature('Int $foo, String $bar, Code $baz') That way code could probe the argument structure in order to do its own dispatch. As for returning a coderef or a pair. If you return a coderef, Perl simply calls it and throws it away. Returning a pair, with a name (long or short) as the key and the code as the value would make perl bind the code to the given name (which should be compatible with the name passed in in the first place). Details left as an exercise for the interested reader.
Re: When can I take given as read?
Carl Franks [EMAIL PROTECTED] writes: sub factorial (Int $n is topic) { return 1 when 0; return $n * factorial $n; } hmm, could we write... sub foo (Class $self is topic: +$foo, +$bar) { .method; } to avoid having to use ./ ? Yay!
nested subs
So, I was about to write the following test for Pugs: sub factorial (Int $n) { my sub factn (Int $acc, $i) { return $acc if $i $n; factn( $acc * $i, $i+1); } factn(1, 1); } When I thought to check the apocalypses and exegeses and, what do you know, I couldn't find any evidence that nested named functions like this were legal. So, are they legal? And yes, I know there are other ways of doing this, but I like the lack of sigils on the function when you do it this way.
Re: nested subs
Luke Palmer [EMAIL PROTECTED] writes: On 6/16/05, Piers Cawley [EMAIL PROTECTED] wrote: So, I was about to write the following test for Pugs: sub factorial (Int $n) { my sub factn (Int $acc, $i) { return $acc if $i $n; factn( $acc * $i, $i+1); } factn(1, 1); } When I thought to check the apocalypses and exegeses and, what do you know, I couldn't find any evidence that nested named functions like this were legal. So, are they legal? Yep. And they work just as if you had used an anonymous sub there--it closes over lexicals and everything. I should bloody well hope so too.
When can I take given as read?
Suppose I have a simple, single argument recursive function: sub factorial (Int $n) { return 1 if $n == 0; return $n * factorial $n; } Can I write that as: sub factorial (Int $n:) { return 1 when 0; return $n * factorial $n; } NB. Yes, I know it's a pathological example.
Binding slices
Following a conversation with Chip on IRC, is this my @y := @foo[0..][1]; legal?
Re: Binding slices
Luke Palmer [EMAIL PROTECTED] writes: On 6/14/05, Piers Cawley [EMAIL PROTECTED] wrote: Following a conversation with Chip on IRC, is this my @y := @foo[0..][1]; legal? Definitely not. But it sure would be nice if this: my @y := @foo[0...][1]; were. I think that's what I meant to write :)
Re: How much do we close over?
Rob Kinyon [EMAIL PROTECTED] writes: Piers Cawley said: in other words, some way of declaring that a subroutine wants to hang onto every lexical it can see in its lexical stack, not matter what static analysis may say. I'm not arguing with the idea, in general. I just want to point out that this implies that you're going to hold onto every single file-scoped lexical, leading to quite a bit of action-at-a-distance. Well, duh. If eval string isn't a hearty pointer to the This subroutine deliberately takes advantage of action at a distance then I don't know what is. Maybe, instead, you should say sub is lexical_stack(N) where N is the number of scoping levels it will hold onto in addition to any lexical it actually refers to. I would have 0 be the innermost scope, 1 be the enclosing scope, etc. Which is all very well, but you don't necessarily know how deep in the stack you are. I want to be able to write something in such a way that evalling the string works in exactly the same way as it would if I had just written a do block in the first place. sub foo { my $x; ...; return sub { do {...} } } It's an introspection thing. Most of the time you don't want it, but sometimes you do and we really shouldn't be making that impossible.
Re: How much do we close over?
Rod Adams [EMAIL PROTECTED] writes: Piers Cawley wrote: Chip and I have been having a discussion. I want to write: sub foo { my $x = 1; return sub { eval $^codestring } } say foo()($x); I claim that that should print 1. Chip claims it should throw a warning about because of timely destruction. My claim is that a closure should close over the entire lexical stack, and not simply those things it uses statically. Chip claims the opposite, arguing that timely destruction implies that this is absolutely the right thing to do. It's also quicker. I'm going to have to side with Piers on this one. My feeling is that having a reference to a closure accessible in memory should keep all the possible lexicals it can access in memory as well. That said, I can the compiler optimizing memory consumption by destroying all the outer lexicals that it can prove will never be used by the inner closure. However, the presence of an eval' in the closure makes such a proof tenuous at best. On the other hand, one could easily view the eval as constructing yet another closure, and it's unclear if we wish for that closure to be able to skip the first level outer closure to directly access the 2nd level outer lexicals. In that respect, I could see things Chip's way. As for the warning, it should only be a warning if strictures are on, for using the now undeclared '$x' inside the eval. But dammit, I'm doing runtime evaluation of code strings, I don't care about quicker. If it's not the default can it please be mandated that there be some way of doing: sub foo { my $x = 1; return sub is lexically_greedy {eval $^codestring} } in other words, some way of declaring that a subroutine wants to hang onto every lexical it can see in its lexical stack, not matter what static analysis may say. Well, you could always do something like: sub foo { my $x = 1; return sub {my $x := $OUTER::x; eval $^codestring} } But I'm spending too much time in other languages lately to remember exactly how $OUTER::x is spelled for certain. One could probably even write a macro that auto-binds all the lexicals in the outer scope to the current scope. Only if I actually know what variables which were within scope when that inner sub was compiled are going to be used by my passed in code string. I really don't want to have to write a macro to walk the OUTER:: chain in order to build a something like: sub { my $foo = $OUTER::foo; my $bar = $OUTER::OUTER::bar; ...; eval $^codestring } Just to pull everything into scope. And even if I could do that, what I actually want to be able to do is something like this: $continuation.bindings.eval_in_this_scope($^codestring); Which can be done today in Ruby and which is one of the enabling technologies for tools like Rails.
Re: Attack of the fifty foot register allocator vs. the undead continuation monster
Chip Salzenberg [EMAIL PROTECTED] writes: On Wed, Jun 08, 2005 at 10:26:59PM +0100, The Perl 6 Summarizer wrote: Loop Improvements Oh no! It's the register allocator problems again. One of these days I swear I'm going to swot up on this stuff properly, work out whether it's really the case that full continuations break any conceivable register allocator and summarize all the issues for everyone in a nice white paper/summary. It's not really that complicated. It just takes a long time to explain. -- Dr. Howland Owll, on SubGenius doctrine Consider this code: sub example1 { my $a = foo(); print $a; my $b = bar(); print $b; } It's obvious that $a and $b can be allocated the same register because once $b has been set, $a is never used again. (Please ignore that $a and $b are variables that can't be stored purely in registers. The real world case that I'm illustrating deals with temporaries and other values that lack user-visible names. But the issue is best illustrated this way.) Now consider this: sub example2 { my $a = foo(); do { print $a; $b = bar(); print $b; } while ($b); } You can see that it's now *not* OK to allocate $a and $b to the same register, because the flow of control can jump back to the print $a even after $b is assigned. Look at the first function again, and consider what happens if foo captures its return continuation _and_bar_invokes_it_. It would effectively amount to the same issue as example2: sub foo { $a = 1; foo(); _implicit_label_for_return_continuation: print $a; $b = bar(); print $b; } bar() { if rand() 0.5 { goto _implicit_label_for_return_continuation } return lucky; } Therefore, register allocation must allow for implicit flow of control from *every* function call to *every* function return ... or, more precisely, to where *every* continuation is taken, including function return continuations. Buf if you fallow the calling conventions that looks like: sub foo { $a = 1. $c = 10; print $c save_dollar_a_and_only_dollar_a_because_im_going_to_use_it_after_this_function_call foo() _implicit_label_for_return_continuation: restore_dollar_a _ooh_i_dont_have_to_save_anything $b = bar() _nor_do_i_have_to_restore_anything print $b } That's what caller saves means. You only have to save everything that you're going to care about after the function returns. You don't have to save the world, because if it was important it's already been saved further up the call chain. This means, of course, that the continuation needs to save the state of the restore stack, but I thought we already knew that. Of course, if you're going to actually use GOTO to get to some label that you should only get to via a continuation (as you do in the code example) then you deserve to get everything you've got coming to you. A continuation must contain everything needed to restore the user registers to the correct state no matter how many times they were taken. I really don't see how this affects register allocation; the call to bar doesn't need to save $a because it's not referred to (lexically) after the call returns. So what if the call to bar might take a continuation. Taking that continuation should be exactly equivalent to returning from the call to foo. You really have to stop thinking of continuations as gotos.
Re: Attack of the fifty foot register allocator vs. the undead continuation monster
Chip Salzenberg [EMAIL PROTECTED] writes: On Sun, Jun 12, 2005 at 03:15:22PM +0100, Piers Cawley wrote: But if you fallow the calling conventions that looks like: sub foo { $a = 1. $c = 10; print $c save_dollar_a_and_only_dollar_a_because_im_going_to_use_it_after_this_function_call foo() _implicit_label_for_return_continuation: restore_dollar_a _ooh_i_dont_have_to_save_anything $b = bar() _nor_do_i_have_to_restore_anything print $b } You have greatly misunderstood. We're talking about how foo manages its callee-saves registers. The registers involved, the ones that I'm calling $a and $b, are P16-P31. Of course, if you're going to actually use GOTO to get to some label that you should only get to via a continuation ... For purposes of allocating the callee-saves registers, a continuation may as well _be_ a goto. No it's not. A continuation should carry all the information required to restore the registers to the correct state when it is taken. A goto doesn't. For the purposes of allocating the registers in foo you can allocate $a to P16, and $b to p16, because when the call to bar takes the continuation back to bar, the 'restore' phase should grab $a from the continuation and bung it back on P16. The continuation doesn't even need to know where to restore $a to, because the 'caller restores' code should take care of that. Don't feel bad, though. I thought the same thing the first time *I* heard about this problem. I think you should have held that thought.
Re: Attack of the fifty foot register allocator vs. the undead continuation monster
Matt Fowles [EMAIL PROTECTED] writes: Chip~ On 6/12/05, Chip Salzenberg [EMAIL PROTECTED] wrote: I'd like like to note for other readers and the p6i archives that Piers has failed to grasp the problem, so the solution seems pointless to him. I'm sorry that's the case, but I've already explained enough. This response worries me firstly because of its rudeness and second because of the problem itself. As I see it there are four possibilities a: 1) Chip is right, Piers is wrong. This is a complex problem and refusing to explain it means that others will doubtless also misunderstand it, which you have a chance to preempt here. 2) Chip is wrong, Piers is right. This is a complex problem and refusing discussion on it would be a costly mistake. 3) Chip is right, Piers is right. The two of you have are working from a different base set of definitions/axioms or misunderstood each other in some other way. 4) Chip is wrong, Piers is wrong. Shutting down open conversation so forcefully and caustically will prevent discussion in the future and this problem will continue to haunt parrot as no viable solution has been seen. Regardless of which of these possibilities is true. I see a need for more discussion of this issue. Preferably a discussion that does not degrade into backhanded insults. I have my own ideas about this problem, but I will save that for another response. Don't worry Matt, we're still talking. It takes more than sarcasm to stop me.
How much do we close over?
Chip and I have been having a discussion. I want to write: sub foo { my $x = 1; return sub { eval $^codestring } } say foo()($x); I claim that that should print 1. Chip claims it should throw a warning about because of timely destruction. My claim is that a closure should close over the entire lexical stack, and not simply those things it uses statically. Chip claims the opposite, arguing that timely destruction implies that this is absolutely the right thing to do. It's also quicker. But dammit, I'm doing runtime evaluation of code strings, I don't care about quicker. If it's not the default can it please be mandated that there be some way of doing: sub foo { my $x = 1; return sub is lexically_greedy {eval $^codestring} } in other words, some way of declaring that a subroutine wants to hang onto every lexical it can see in its lexical stack, not matter what static analysis may say.
Re: return() in pointy blocks
Luke Palmer [EMAIL PROTECTED] writes: On 6/8/05, Piers Cawley [EMAIL PROTECTED] wrote: In other words, it outputs: Foo Foo # dies Yep. My mistake. If that works, then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } $code($cc); } Which I personally think is rather cute. Even if I can't quite bring myself to believe it's that simple... Yeah, that's pretty. But that will bite people who don't understand continuations; it will bite people who don't understand return; it will even bite people who understand continuations, because they can be made in such an awkward form so easily. Having worked through the little and seasoned Schemers, I'm actually at the point where I can happily think that 'return' is deep scary magic. What I *want* is a 'proper' continuation, but this would have been close enough for government work until the real ones came along. Currently call/cc is done like this: sub call_with_current_continuation(code) { code(?CALLER_CONTINUATION); } But that might be broken in pugs at the moment. Doesn't that call code with the continuation of the caller of call_with_current_continuation, when it *should* call code with the continuation of call_with_current_continuation?
Re: return() in pointy blocks
Larry Wall [EMAIL PROTECTED] writes: On Wed, Jun 08, 2005 at 10:51:34PM +, Luke Palmer wrote: : Yeah, that's pretty. But that will bite people who don't understand : continuations; it will bite people who don't understand return; it : will even bite people who understand continuations, because they can : be made in such an awkward form so easily. Right--we don't want mere mortals to be able to get at continuations quite that easily, whether they think they want them or not. Shame. If you go monkeying with continuations without knowing what they do, then of course you deserve everything you have coming to you, but is that really any reason for making them hard to get at when you *do* need them? I'm not denying that they should be hard to get accidentally, but it would be good to know how to get them deliberately.
Non-deterministic programming in Perl 6
So, the return in pointy sub thread got me thinking about useful uses of return in pointy subs that involve being able to return multiple times. And this is what I came up with, it's an implementation of 'choose': my give_up = sub { fail Ran out of choices } sub choose ([EMAIL PROTECTED]) { my old_give_up = give_up; my $try = - @choices { if [EMAIL PROTECTED] { give_up = old_give_up; give_up } else { my ($choice, @newchoices) = *choices; give_up = - { return $try(@newchoices) } $choice; } } $try(@all_choices); } How do you use that I hear you ask: my $x = choose(1,3,5); my $y = choose(1,5,9); # say Trying $x * $y; # Uncomment for an insight into how this works. give_up unless $x * $y == 15; say Found $x * $y = 15; Yes, that is an artificial example. If you can't use a returning pointy block more than once, then this becomes: sub callcc (Code block) { block(?CALLER_CONTINUATION) } my give_up = sub { fail Ran out of choices } sub choose ([EMAIL PROTECTED]) { callcc - cnt { my $try = - @choices { if [EMAIL PROTECTED] { give_up = old_give_up; give_up } else { my ($choice, @newchoices) = *choices; give_up = sub { cnt($try(@newchoices)) }; $choice; } } $try(@all_choices); } } Tracing the flow of control in both these examples is left as an exercise for the interested reader. The only catch is, neither of them works in Pugs. Yet.
Re: return() in pointy blocks
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. How do you reach the second 'Boo'? Iff - does not create a Sub but a Block instance then Luke's code can be interpreted as a much smarter version of I really wish you'd quote in more detail, it makes it a real PITA to go back and find the explanatory code. sub foo () { return - { return 42 } } my $code = foo(); # ^--- continuations points to the RHS of the assignment say Boo!; $code(); So, this is what happens. 1. foo() returns a coderef to the RHS of the assignment. 2. The coderef gets assigned to $code. 3. say Boo! 4. We invoke the coderef, which returns 14 to continuation which was current when it was created. 5. That means 42 gets returned to the RHS of the assignment 6. say Boo! 7. Try to invoke the literal 42. 8. Die. In other words, it outputs: Foo Foo # dies sub foo() { enter: 42; if $?RETURN_LABEL { goto $?RETURN_LABEL } return; } say Boo!; say goto foo::enter; # goto sets up $?RETURN_LABEL say after goto; which of course prints Boo 42 after goto The smartness is in the value that prefix:{'-'} returns while in the snippet above it is explicitly coded. Or do I completely misunderstand the distinction between blocks and closures? It seems so.
Re: return() in pointy blocks
Piers Cawley [EMAIL PROTECTED] writes: TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. How do you reach the second 'Boo'? Iff - does not create a Sub but a Block instance then Luke's code can be interpreted as a much smarter version of I really wish you'd quote in more detail, it makes it a real PITA to go back and find the explanatory code. sub foo () { return - { return 42 } } my $code = foo(); # ^--- continuations points to the RHS of the assignment say Boo!; $code(); So, this is what happens. 1. foo() returns a coderef to the RHS of the assignment. 2. The coderef gets assigned to $code. 3. say Boo! 4. We invoke the coderef, which returns 14 to continuation which was current when it was created. 5. That means 42 gets returned to the RHS of the assignment 6. say Boo! 7. Try to invoke the literal 42. 8. Die. In other words, it outputs: Foo Foo # dies If that works, then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } $code($cc); } Which I personally think is rather cute. Even if I can't quite bring myself to believe it's that simple...
Re: return() in pointy blocks
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes: Piers Cawley wrote: [..] then I think it means we can write: sub call-with-current-continuation(Code $code) { my $cc = - $retval { return $retval } For the records: the return here is the essential ingredient, right? Without it the block would be evaluated or optimized away to an undef or some such. Yes. Without the return you just get block that returns the value its last expresion to the place from which it (the pointy sub) was called, rather than to the place that the subroutine that created it was called from. $code($cc); } Which I personally think is rather cute. Me too! Even if I can't quite bring myself to believe it's that simple... I have convinced myself. How can I be of assistance on your side? How's your Haskell?
Re: return() in pointy blocks
Luke Palmer [EMAIL PROTECTED] writes: On 6/7/05, Matt Fowles [EMAIL PROTECTED] wrote: On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? I don't like this because the function bar is getting oddly prematurely halted. Then let's put it this way: sub foo () { for 0..10 { when 6 { return 42 } } return 26; } And if that didn't do it, then let's write it equivalently as: sub foo () { map(- $_ { return 42 }, 0..10); return 26; } Do you see why the return binds to the sub rather than the pointy now? Also, we're going to be avoiding the return continuation problem with: sub foo() { return - { return 42 }; } my $code = foo(); say Boo!; $code(); Says not: Boo Boo Boo ... But: Boo Can't return from subroutine that already returned at eval line 2. My preference is for: Boo Boo Can't dereferene literal numeric literal 42 as a coderef. Actually, my preference is for not writing such silly code in the first place, but there you go.
Re: return() in pointy blocks
Ingo Blechschmidt [EMAIL PROTECTED] writes: Hi, sub foo (Code $code) { my $return_to_caller = - $ret { return $ret }; $code($return_to_caller); return 23; } sub bar (Code $return) { $return(42) } say foo bar; # 42 or 23? I think it should output 42, as the return() in the pointy block $return_to_caller affects foo, not the pointy block. To leave a pointy block, one would have to use leave(), right? That's how it's defined in the relevant Apocalypse. And that's how I hope it'll stay.
Re: Perl6 and support for Refactoring IDE's
Stevan Little [EMAIL PROTECTED] writes: On May 25, 2005, at 5:39 AM, Piers Cawley wrote: One of the 'mental apps' that's been pushing some of the things I've been asking for in Perl 6's introspection system is a combined refactoring/debugging/editing environment for the language. Maybe I have been reading too much about Smalltalk meta-classes lately, but in doing some draft ideas of the Perl6 meta-model for Pugs, I realized that given a really solid class/metaclass introspection system and access to the interpreter level meta-meta-classes, it would be possible to easily write a class browser much like Smalltalk. Yes. The application in my head looks very a Smalltalk environment. The way I see it working is that the language itself has a bunch of minimal hooks that get triggered by various phases of compilation etc. Your editor then becomes something that instruments the compiler in such a way that loading a file for editing compiles it, but the compilation process hangs populates the data structures you need for editing. So, when you go to edit, say: class Collection { method inject_into ($self: $initial_value is copy, *block) { $self.each :{ $initial_value = block($initial_value, $_) } return $initial_value; } } You'd end up with a Class object which would have all sorts of interesting things added to it, including collections of instance variables, class variables, methods etc. Methods would have metadata about the environment in which they were evaluated (so when you edit a method you could recompile it in the correct environment), the file they're found in, their source code (possibly attributed to allow for syntax highlighting), the resulting AST, etc. Once you have such a rich set of metadata to hand, it becomes a simple matter of programming to add all sorts of handy features, refactorings, breakpoints, whatever... The point being that you don't really need a massive amount of support from the core language to do all this. At a pinch you can take advantage of the fact that the grammar is replaceable and core classes are extensible (and if they're not, you just stick them in boxes for the editor's purposes). And to extend that to also be a refactoring browser would require the meta-meta-class system to be able to generate and emit code, which, if we properly model the meta-meta-classes should also be fairly simple as well. We've got eval for that. Assuming you can do eval with arbitrary bindings (and if necessary you can drill down to parrot for it) you just do something like: Class.can('fred').environment.eval($freds_new_sourcecode) Of course, if you alter a macro you're going to have to reevaluate pretty much all the source code, but so what? And of course all this is even simpler if the interpreter is written in Perl6 (although the cyclical nature of that can be dizzying at times). It really doesn't have to be. It'd be nice, but not necessary. You just have to make sure you can extend the runtime using perl. And macros already do that. However adding debugging support to this is another matter all together, and it is only partially useful to the non-OO programmer. Not that hard to be honest. The same instrumented interpreter techniques can be used to write the debugger.
Re: Perl6 and support for Refactoring IDE's
Luke Palmer [EMAIL PROTECTED] writes: On 5/6/05, J Matisse Enzer [EMAIL PROTECTED] wrote: I've become scared that if Perl is to continue to be viable for large, complex, multi-developer projects that the tools need to serious catch-up with what is available for Java, for example. Things like: - Refactoring Support (see http://www.refactoring.com/) - CVS and/or Subversion integration - Support for integrating regression tests and auto-building - Automated syntax and dependency checking I've been using Eclipse, with the EPIC plugin (http://e-p-i-c.sourceforge.net/) and so far I like it. It uses Devel::Refactor to support extract subroutine, but a lot more is needed to match what you can do with Java these days. What are others' thoughts on this? I think you're absolutely right. Perl should have an IDE with Eclipse-like context-sensitivity and refactoring support. However, it's hardly in Perl's philosophy or interest to bless one. One thing is for sure. Perl 6 is providing enough introspection and parsing capabilities to make it possible to write a context-sensitive IDE, unlike Perl 5 (well, Perl 5 made it *possible*, I suppose, but Perl 6 will make it obvious). Perl 6 is exposing its whole grammar at the language level, so you can say give me a syntax tree for this chunk of code and it will. Even if there are modules that change the syntax with macros (though your editor might have trouble understanding what the macros mean). One of the 'mental apps' that's been pushing some of the things I've been asking for in Perl 6's introspection system is a combined refactoring/debugging/editing environment for the language. One of the annoyances of the 'only perl can parse Perl' thing is not so much the truth of the statement, but that perl 5 doesn't allow you to ask about the parsed code in ways that would be useful for an IDE. Perl 6 promises to change that -- it should be possible to either write a fantastic Perl 6 IDE in perl itself, or to write a codegrokker object that can be used by some pre existing IDE. In other words, Perl 6 is open to the possibility of such an IDE, and is going to provide the machinery necessary to build a really good one, but I doubt it will become a development milestone. What about the debugger?
Re: Undef issues
Adrian Taylor [EMAIL PROTECTED] writes: Hi, Over the weekend I added some tests on 'undef' behaviour (t/builtins/undef.t): These behave as expected: eval_is('undef * 2', undef, 'undef * 2'); That's not what I'd expect. I'd expect it to return 0 and throw a warning about numification.
Re: Virtual methods
Aaron Sherman [EMAIL PROTECTED] writes: On Wed, 2005-05-18 at 10:51, Luke Palmer wrote: Except that mixins like this always treat things as virtual. Whenever you mixin a role at runtime, Perl creates an empty, anonymous subclass of the current class and mixes the role in that class. Since roles beat superclasses, you'll always override your own methods. Ok, good point (I've even pointed that out to others before, and I missed it)... I know that's the way it works, but now it's really bothering me. There are many gotchas that fall out of that. For example, you might have a special role that overrides .print to handle structured data, so your code says: my Foo $obj; given $obj { when StructuredPrintRole { # Someone's already taken care of it, possibly # adding a more specialized role, so leave it # alone. } default { # Add in a boring default handler $obj does StructuredPrintRole } } $obj.print($structured_data); Woefully, you lose is Foo happens to be DECLARED with StructuredPrintRole, and it overrode print. But, if it just inherited a print(), then it works. In other words, this code will mysteriously fail the second someone innocently adds a print method to Foo! Action at a distance... my head hurts. Aaron, you do realise that that's quite obscene code don't you? I mean, you're doing a case statement based on the type of its topic, and to compound the evils, you're changing how your topic's print method works *everywhere* simply to get your 'special' print behaviour. If you must do something like this (and call it print), then write it as a multimethod or something.
Re: turning off warnings for a function's params?
David Storrs [EMAIL PROTECTED] writes: I image we've all written logging code that looks something like this (Perl5 syntax): sub foo { my ($x,$y) = @_; note(Entering frobnitz(). params: '$x', '$y'); ... } This, of course, throws an 'uninitialized value in concatenation or string' warning when your test suite does this: is( foo(undef, undef), undef, foo(undef, undef) gives undef ); In a testing environment, I don't want to see this warning. In a production environment, I do. Furthermore, when I want it gone, I want it gone from every instance of Cnote, without having to change something in every location. I suppose I could change all my logging calls to look like this: { if ( $DEBUG ) { no warnings 'uninitialized'; note(); } else { note(); } } But that's really ugly, takes up a lot of space, is confusing, and is redundant. How would I best solve this problem in Perl6? Write an appropriate macro: warns(is( foo(undef, undef), undef, foo(undef, undef) gives undef), uninitialized value in concatenation or string); That way you get to ensure that the warning gets thrown correctly if undef is passed, but you don't get the warning mucking up your test output.
Re: Blocks, continuations and eval()
wolverian [EMAIL PROTECTED] writes: On Fri, Apr 08, 2005 at 12:18:45PM -0400, MrJoltCola wrote: I cannot say how much Perl6 will expose to the high level language. That is what I'm wondering about. I'm sorry I was so unclear. Can you tell me what your idea of a scope is? I'm thinking a continuation, and if that is what you are thinking, I'm thinking the answer to your question is yes. Yes. I want to know how Perl 6 exposes continuations, and how to get one for, say, the current lexical scope, and if it has a method on it that lets me evaluate code in that context (or some other way to do that). As I understand what Larry's said before. Out of the box, it doesn't. Apparently we're going to have to descend to Parrot to write evalcc/letcc/your-preferred-continuation-idiom equivalent.
Re: Blocks, continuations and eval()
Larry Wall [EMAIL PROTECTED] writes: On Tue, Apr 12, 2005 at 11:36:02AM +0100, Piers Cawley wrote: : wolverian [EMAIL PROTECTED] writes: : : On Fri, Apr 08, 2005 at 12:18:45PM -0400, MrJoltCola wrote: : I cannot say how much Perl6 will expose to the high level language. : : That is what I'm wondering about. I'm sorry I was so unclear. : : Can you tell me what your idea of a scope is? I'm thinking a : continuation, and if that is what you are thinking, I'm thinking the : answer to your question is yes. : : Yes. I want to know how Perl 6 exposes continuations, and how to get one : for, say, the current lexical scope, and if it has a method on it that : lets me evaluate code in that context (or some other way to do that). : : As I understand what Larry's said before. Out of the box, it : doesn't. Apparently we're going to have to descend to Parrot to write : evalcc/letcc/your-preferred-continuation-idiom equivalent. We'll make continuations available in Perl for people who ask for them specially, but we're not going to leave them sitting out in the open where some poor benighted pilgrim might trip over them unawares. Oh goody! Presumably we're initially talking of a simple 'call_with_current_continuation'?
Re: return of copies vs references
Darren Duncan [EMAIL PROTECTED] writes: At 7:10 AM +0100 3/29/05, Piers Cawley wrote: Doesn't that rather depend on the type of the attribute? Personally, if I get an object back from accessor method then I expect that any modifications of that object's state will be seen the next time I look at the results of that accessor method. This is a direct result of the way reference types work, and the world is a better place because of it. If you want a (deep) copy of the returned object you should say so: my $res = $object.attribute.clone; I recanted what you're replying to last week. Essentially, I agree with you that references of non-scalar values should be returned by default, and that the method must do an explicit copy if that's what they want returned. Things are much simpler that way, and its how Perl 5 worked. -- Darren Duncan Bah! Must start keeping up to date with the list again.
Re: .method == $self.method or $_.method?
Larry Wall [EMAIL PROTECTED] writes: I've been thinking about this in my sleep, and at the moment I think I'd rather keep .foo meaning $_.foo, but break the automatic binding of the invocant to $_. Instead of that, I'd like to see a really, really short alias for $self. Suppose we pick o for that, short for object. Then we get self calls of the form: o.frobme(...) I really, really don't want to see .foo meaning anything but $_.foo, so how about arranging things so that the invocant becomes $_ iff you don't give it a name. So: method whatever { # $_ is whatever's invocant } method whosit ($self:) { # $_ is unbound, so: .this # fails ... } Note that this would also work for mappy things with pointy subs used to name arguments. method whatever { map { .this } .list_of_contents; # Works, but is weird... map - $x { .do_something_with($x.result) } # .do_something uses the # method's invocant. } Same applies to given: method foo { given .parent - $p { ... # $_ is foo's invocant } given .parent { ... # $_ is the result of calling .parent } }
Re: return of copies vs references
Darren Duncan [EMAIL PROTECTED] writes: At 11:26 PM -0700 3/16/05, Luke Palmer wrote: For each of the above cases, is a copy of or a reference to the attribute returned? For each, will the calling code be able to modify $obj's attributes by modifying the return values, or not? Well if you're making accessors, why the heck are you making them private? But I can't really answer your question, because it depends on how you write the accessors. I am writing accessors to mediate with the attributes, which are all private, and whose implementation may change over time. What I want, in the normal case, is that calling code which invokes my methods will get a copy of attributes which it can modify, that won't affect the original attribute values. When I last asked a related question here, I was told that simply returning an attribute will allow the caller to modify the original attribute by default. I wanted to make sure this didn't happen. It is possible that there was a misunderstanding regarding the previous question, and the default action is in fact a copy. Doesn't that rather depend on the type of the attribute? Personally, if I get an object back from accessor method then I expect that any modifications of that object's state will be seen the next time I look at the results of that accessor method. This is a direct result of the way reference types work, and the world is a better place because of it. If you want a (deep) copy of the returned object you should say so: my $res = $object.attribute.clone;
Re: Objects, classes, metaclasses, and other things that go bump in the night
Dan Sugalski [EMAIL PROTECTED] writes: At 11:13 AM +0100 12/14/04, Leopold Toetsch wrote: Dan Sugalski [EMAIL PROTECTED] wrote: subclass - To create a subclass of a class object Is existing and used. Right. I was listing the things we need in the protocol. Some of them we've got, some we don't, and some of the stuff we have we probably need to toss out or redo. add_parent - To add a parent to the class this is invoked on become_parent - Called on the class passed as a parameter to add_parent What is the latter used for? To give the newly added parent class a chance to do some setup in the child class, if there's a need for it. There probably won't be in most cases, but when mixing in classes of different families I think we're going to need this. The chap who's writing Ruby on Rails, a very capable framework reckons that some of these 'meta' method calls that Ruby has in abundance have really made his life a lot easier; they're not the sort of things you need to use very often, but they're fabulously useful when you do.
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Leopold Toetsch [EMAIL PROTECTED] writes: ... While S registers hold pointers, they have value semantics. Is that guaranteed? Because it probably needs to be. It's the current implementation and tested. This would restore the register contents to the first state shown above. That is, not only I and N registers would be clobbered also S registers are involved. That's correct. What's the problem? Okay, you've created an infinite loop, but what you're describing is absolutely the correct behaviour for a continuation. Ok. It's a bit mind-twisting but OTOH it's the same as setjmp/longjmp with all implications on CPU registers. C has the volatile keyword to avoid clobbering of a register due to a longjmp. Above code could only use P registers. Or in other words: I, N, and S registers are almost[1] useless. No they're not. But you should expect them to be reset if you take a (full) continuation back to them. The problem I have is: do we know where registers may be reset? For example: $I0 = 10 loop: $P0 = shift array dec $I0 if $I0 goto loop What happens if the array PMC's Cshift get overloaded and does some fancy stuff with continuations. My gut feeling is that the loop might suddenly turn into an infinite loop, depending on some code behind the scenes ($I0 might be allocated into the preserved register range or not depending on allocation pressure). Second: if we don't have a notion that a continuation may capture and restore a register frame, a compiler can hardly use any I,S,N registers because some library code or external function might just restore these registers. This is, of course, why so many languages that have full continuations use reference types throughout, even for numbers. And immutable strings...
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Further to my last response. If you have things set up so that you can return multiple times from the same function invocation then the return continuation should have been replaced with a full continuation before the first return, so even the first return will use copying semantics, and the registers will always be restored to the state they were in when the function was first called, which is absolutely the right thing to do. Here is again the example I've brought recently. Please go through it and tell me what's wrong with my conclusion. $I0 = 42 # set I16, 42 42 $N0 = 2.5# set N16, 2.5..101... $S0 = a# set S16, a0x1004 - a $P0 = a# set P16, a0x2008 - a loop: foo()# set P0, ...; invokecc We have some temporary variables and a function call. Variables are used beyond that point, so the register allocator puts these in the preserved register range. The function Cfoo() might or might not capture the continuation created by the Cinvokecc opcode. Let's assume, it is captured, and stored into a global, if it wasn't already, i.e. the first time. According to Dan's plan, the function return restores the register contents to the state of the creation of the return continuation, which is shown in the right column. $I0 += 1 # add I16, 1 43 $N0 *= 2.0 # mul N16, 2.0.101 $S0 .= b # concat S16, b 0x1008 - ab inc $P0 # inc P16 0x2008 - b dec a# dec P17 0x200c - 1 if a goto loop # if P17, loop A note WRT strings: the concat might or might not assign a new string to S16. It depends on the capacity of the string buffer. But generally: string operations do create new string headers with a different memory address like shown here. While S registers hold pointers, they have value semantics. Is that guaranteed? Because it probably needs to be. Now we loop once over the function call. This creates a new return continuation and on function return registers are restored to their new values (44, 10.0, abb, c). All fine till here. The loop counter a reaches zero. Now the next instruction is another function call. bar()# set P0, ... invokecc The bar() function extracts the return continuation captured in the first call to foo() from the global and invokes it. Control flow continues right after the invokecc opcode that called foo(). This would restore the register contents to the first state shown above. That is, not only I and N registers would be clobbered also S registers are involved. That's correct. What's the problem? Okay, you've created an infinite loop, but what you're describing is absolutely the correct behaviour for a continuation. If you need any state to be 'protected' from taking the continuation then it needs to be in a lexical or a mutated PMC. This is just how continuations are supposed to work. Above code could only use P registers. Or in other words: I, N, and S registers are almost[1] useless. No they're not. But you should expect them to be reset if you take a (full) continuation back to them. Presumably if foo() doesn't store a full continuation, the restoration just reuses an existing register frame and, if foo has made a full continuation its return does a restore by copying?
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Leopold Toetsch [EMAIL PROTECTED] writes: Matt Fowles [EMAIL PROTECTED] wrote: Thanks for the clear explanation. I did not realize that S registers could switch pointers, that does make things a little harder. I have a recommendation for a possible hybrid solution. Incur the cost of spilling I,S,N registers heavily. Restore the state of P register. My conclusion was that with the copying approach I,S,N registers are unusable. But you only need to copy when the frame you're restoring is a full continuation Yes. With the effect that semantics of I,S,N (i.e. value registers) suddenly changes. I'd submit that, in the vast majority of cases you're not going to be dealing with full continuations, and on the occasions when you are the programmer using them will be aware of the cost and will be willing to pay it. *If* the programmer is aware of the fact that a subroutine can return multiple times, he can annotate the source so that a correct CFG is created that prevents register reusing alltogether. The problem is gone in the first place. *If* that's not true, you'd get the effect that suddenly I,S,N registers restore to some older values which makes this registers de facto unusable. But they're bloody value registers. They're *supposed* to restore to the state they were in when the function was originally called. Which is what copying semantics does.
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Leopold Toetsch [EMAIL PROTECTED] writes: Matt Fowles [EMAIL PROTECTED] wrote: Thanks for the clear explanation. I did not realize that S registers could switch pointers, that does make things a little harder. I have a recommendation for a possible hybrid solution. Incur the cost of spilling I,S,N registers heavily. Restore the state of P register. My conclusion was that with the copying approach I,S,N registers are unusable. But you only need to copy when the frame you're restoring is a full continuation Yes. With the effect that semantics of I,S,N (i.e. value registers) suddenly changes. I'd submit that, in the vast majority of cases you're not going to be dealing with full continuations, and on the occasions when you are the programmer using them will be aware of the cost and will be willing to pay it. *If* the programmer is aware of the fact that a subroutine can return multiple times, he can annotate the source so that a correct CFG is created that prevents register reusing alltogether. The problem is gone in the first place. *If* that's not true, you'd get the effect that suddenly I,S,N registers restore to some older values which makes this registers de facto unusable. Further to my last response. If you have things set up so that you can return multiple times from the same function invocation then the return continuation should have been replaced with a full continuation before the first return, so even the first return will use copying semantics, and the registers will always be restored to the state they were in when the function was first called, which is absolutely the right thing to do.
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Matt Fowles [EMAIL PROTECTED] wrote: Thanks for the clear explanation. I did not realize that S registers could switch pointers, that does make things a little harder. I have a recommendation for a possible hybrid solution. Incur the cost of spilling I,S,N registers heavily. Restore the state of P register. My conclusion was that with the copying approach I,S,N registers are unusable. But you only need to copy when the frame you're restoring is a full continuation (and, actually, if copy on write works at a per register level, copy on write might be the way to go). If it's a return continuation you can simply use the stored state. I'd submit that, in the vast majority of cases you're not going to be dealing with full continuations, and on the occasions when you are the programmer using them will be aware of the cost and will be willing to pay it.
Re: continuation enhanced arcs
Luke Palmer [EMAIL PROTECTED] writes: Piers Cawley writes: I'd submit that, in the vast majority of cases you're not going to be dealing with full continuations, and on the occasions when you are the programmer using them will be aware of the cost and will be willing to pay it. Yeah probably. Except the problem isn't the cost. The problem is the semantics. If you copy the registers, then when you invoke the continuation, their *values* restore to what they were when you made the continuation. These are not proper semantics, and would result in subtle, incorrect infinite loops. PMCs don't relocate, so the values you're restoring are simply the addresses of said PMCs. The Numeric registers are value registers anyway so no problem there (since there's no way of making a pointer to the contents of such a register AFAICT). I'm not sure about string registers. And anyway, copying is how it used to work, and work it did, albeit slowly.
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Leopold Toetsch [EMAIL PROTECTED] writes: We don't have a problem WRT register preservation, the problem arises due to register re-using. Ah! [a light goes on over Piers's head]. Or am I missing something fundamental? I don't know ;) I was. Hmm... bugger. So, unless we make the register allocator solve the halting problem, the rule becomes If you're playing silly beggars with continuations and you're expecting to get at something in a 'surprising' way, stuff it in a lexical or we guarantee that you will be anally violated by an enraged waterbuffalo that's just sick to death of non-determinism? This would make quite a fine explanation in the docs, except that's a bit unclear about stuff *it*. The waterbuffalo is concerned of preserved *temporary* variables too. I just thought of a heuristic that might help with register preservation: A variable/register should be preserved over a function call if either of the following is true: 1. The variable is referred to again (lexically) after the function has returned. 2. The variable is used as the argument of a function call within the current compilation unit. Condition 2 is something of a bugger if you have big compilation units, but register allocation is always going to be a pain when there are big compilation units around.
Re: continuation enhanced arcs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Okay, I'm confused, I thought that the whole point of a caller saves, continuation passing regime was that the caller only saves what it's interested in using after the function returns. We don't have a problem WRT register preservation, the problem arises due to register re-using. ... Exactly *where* that return happens, and whether it happens more than once, is completely irrelevant from the point of view of the caller. The return can only happen, where the normal function call would have returned, but anyway. ... ISTM that the register allocator should work on the principle that anything it didn't save before it made the call will be toast afterwards. Yes. But - please remember your example Fun with nondeterministic searches. Here's the relevant piece of code from main: arr1=[1,3,5] arr2=[1,5,9] x = choose(arr1) y = choose(arr2) $P0 = find_lex fail $P0() You know, both choose calls capture the continuation and backtrack via fail (basically). But the register allocator isn't aware of that. The control flow graph (CFG) is linear top down, with new basic blocks starting after each function call. arr2 is obviously used around a call and allocated in the preserved (non-volatile) register area. This works fine. Now the register allocator assigns a register to $P0. It finds the register that arr2 had usable, because in a linear CFG, there's no way that arr2 might be used again. So that register is considered being available. Now if $P0 happens to get the register that arr2 had, backtracking through the call to fail() obviously fails, as arr2 is now the Closure PMC. And that was exactly the case. Ah! [a light goes on over Piers's head]. Or am I missing something fundamental? I don't know ;) I was. Hmm... bugger. So, unless we make the register allocator solve the halting problem, the rule becomes If you're playing silly beggars with continuations and you're expecting to get at something in a 'surprising' way, stuff it in a lexical or we guarantee that you will be anally violated by an enraged waterbuffalo that's just sick to death of non-determinism?
Re: continuation enhanced arcs
Okay, I'm confused, I thought that the whole point of a caller saves, continuation passing regime was that the caller only saves what it's interested in using after the function returns. Exactly *where* that return happens, and whether it happens more than once, is completely irrelevant from the point of view of the caller. ISTM that the register allocator should work on the principle that anything it didn't save before it made the call will be toast afterwards. Doing anything more sophisticated than optimizing register allocation on a sub by sub basis seems like a license for getting completely and utterly plaited. Or am I missing something fundamental?
Re: Closures and subs
Leopold Toetsch [EMAIL PROTECTED] writes: Piers Cawley [EMAIL PROTECTED] wrote: Leopold Toetsch [EMAIL PROTECTED] writes: Klaas-Jan Stol [EMAIL PROTECTED] wrote: Hello, I've been playing with closures and subs but I have a little bit of trouble with those. newsub $P0, .Closure, _foo $P0(q) newsub $P0, .Closure, _foo $P0(q) Closures have to be distinct. Does this *really* mean that, if I create a closure in a function and return it to my caller, that closure can only be invoked once? No, it can be invoked as often you like. But above case seems to be different and very similar to what I already asked: (define (choose . all-choices) (let ((old-fail fail)) (call-with-current-continuation You remember that snippet, it's now a test in t/op/gc.t. I had to insert the line below XXX and use a second closure, which has the arr2 in it's context. newsub choose, .Closure, _choose x = choose(arr1) # XXX need this these closures have different state newsub choose, .Closure, _choose y = choose(arr2) The question was, if that's technically correct. Ah... of course, I was asking a stupid question. Always the most plausible hypothesis I think. -- Piers Oh, predicting the future's easy, you just make a continuation at the point you're asked, say anything and head off into the future to find what happens, then take the continuation back to the question and give a more accurate answer. -- me in #parrot
Re: Why is the fib benchmark still slow - part 1
Miroslav Silovic [EMAIL PROTECTED] writes: Leopold Toetsch wrote: I believe that you shouldn't litter (i.e. create an immediately GCable object) on each function call - at least not without generational collector specifically optimised to work with this. The problem isn't the object creation per se, but the sweep through the *whole object memory* to detect dead objects. It's of course true, that we don't need the return continuation PMC for the fib benchmark. Well, creation is also the problem if you crawl the entire free heap before triggering the next GC round. You get a potential cache miss on each creation and on each mark and on each destruction. To keep GC out of the way, the entire arena has to be confined to cache size or less. But a HLL translated fib would use Integer PMCs for calculations. Hmm, I'm nitpicking here, but it's not how e.g. Psyco works. It specialises each function to specific argument types and recompiles for each new argument type set. Assuming that you'll call only very few functions with more than 1-2 type combinations, this is a good tradeoff. It also removes a lot of consing, especially for arithmetics. ... This would entail the first generation that fits into the CPU cache and copying out live objects from it. And this means copying GC for Parrot, something that (IMHO) would be highly nontrivial to retrofit. A copying GC isn't really hard to implement. And it has the additional benefit of providing better cache locality. Nontrivial to retrofit or not, we need a generational GC. The catch with generation GC is that, once you have guaranteed destructors being called promptly, you still have to sweep the whole arena every time you leave a scope.
Re: Closures and subs
Leopold Toetsch [EMAIL PROTECTED] writes: Klaas-Jan Stol [EMAIL PROTECTED] wrote: Hello, I've been playing with closures and subs but I have a little bit of trouble with those. newsub $P0, .Closure, _foo $P0(q) newsub $P0, .Closure, _foo $P0(q) Closures have to be distinct. Does this *really* mean that, if I create a closure in a function and return it to my caller, that closure can only be invoked once? If it does, this is slightly more broken than a very broken thing.
Re: Are we done with big changes?
Jeff Clites [EMAIL PROTECTED] writes: On Nov 1, 2004, at 6:14 AM, Dan Sugalski wrote: Because I need to get strings working right, so I'm going to be implementing the encoding/charset library stuff, which is going to cause some major disruptions. Please tag cvs before checking this in. Release candidate?
Re: [CVS ci] indirect register frames 14 - cache the register frame
Dan Sugalski [EMAIL PROTECTED] writes: At 2:30 PM -0500 11/2/04, Matt Fowles wrote: All~ I don't like the idea of having to dig down through the entire return chain promoting these guys. Is there a reason not to use DOD/GC to recycle continuations? Yes. Speed. While you can skip some of the digging (since you can stop at the first promoted one) the reality is that 90%+ of the return continuations will *never* need promoting. Not bothering to make the return continuations true full continuations until they're actually needed as one lets us immediately recycle return continuations as soon as they're used in the near-overwhelming majority of the cases -- that is, when nothing can possibly have a hold of 'em. That leaves a lot fewer objects for the DOD to sweep through, as well as speeding up allocation (since we're more likely to have ones at hand, and likely in cache too) of the things in the first place. And, dammit, making a full continuation isn't something a programmer should do lightly.
Re: [OT] Perl 6 Summary for 2004-10-01 through 2004-10-17
Aldo Calpini [EMAIL PROTECTED] writes: Larry Wall wrote: I suppose if I were Archimedes I'd have climbed back out and shouted Eureka, but as far as I know Archimedes never made it to Italy, so it didn't occur to me... well, Archimedes *was* italian. for some meaning of italian, at least. he was born in Syracuse (the one in Sicily, not the one in the state of NY obviously :-). he lived and studied in Egypt, but most of his life was spent in Syracuse. granted, Sicily at that time was more a Greek region than an Italian one as it is today, but well, geographically speaking, it is in Italy. and of course, Venice was founded ~700 years after Archimedes death, so he really had no chance of falling into your same canal. But the odds are good that at least one of the water molecules in said canal passed some of its time in Archimedes body (or one of its constituent atoms did).
Re: [pid-mode.el] cannot edit
Stéphane Payrard [EMAIL PROTECTED] writes: On Fri, Oct 01, 2004 at 06:09:37PM +0200, Jerome Quelin wrote: Hi, I tried the pir-mode provided in the editor/ subdir. And when opening a .imc file (I've associated .pir with pir-mode + font-lock-mode), I cannot type spaces or carriage returns: (24) (warning/warning) Error caught in `font-lock-pre-idle-hook': (invalid-regexp Invalid syntax designator) And the minibuffer tells me: Symbol's function definition is void: line-beginning-position I'm using xemacs 21.4.14 Is the pir-mode.el file complete? Or am I encountering a bug in it? This function is defined in emacs: line-beginning-position is a built-in function. (line-beginning-position optional N) Return the character position of the first character on the current line. With argument N not nil or 1, move forward N - 1 lines first. If scan reaches end of buffer, return that position. The scan does not cross a field boundary unless doing so would move beyond there to a different line; if N is nil or 1, and scan starts at a field boundary, the scan stops as soon as it starts. To ignore field boundaries bind `inhibit-field-text-motion' to t. This function does not move point. switch to emacs. :) Or patch pir-mode.el, your choice.
Re: Continuation re-invocation
Jeff Clites [EMAIL PROTECTED] writes: Two questions: 1) Is it supposed to be possible to invoke a given continuation more than once, or is it used up once invoked? Yes, you should be able to invoke one more than once. 2) Am I supposed to be able to jump down the stack by invoking a continuation? To be specific, if A calls B calls C, and C invokes the return continuation which takes it directly back to A, can something later invoke the return continuation which leads to B? (Emphasizing there the notion that something skipped over a continuation, then later came back and used it.) Yes.
Re: towards a new call scheme
Leopold Toetsch [EMAIL PROTECTED] writes: Dan Sugalski wrote: At 4:15 PM +0200 9/23/04, Leopold Toetsch wrote: get_cc(OUT Px) # 1) get current continuation, i.e. the return cont. In a rare, possibly unique burts of opcode parsimoniousness... perhaps this would be a good thing for the interpinfo op. That's fine too. return_cc() # 2) return via current continuation 1) is only needed for special porposes, like passing the continuation on to a different place. The normal way to return from a sub will be 2) If that's in, access to CP1 as a return continuation will be deprecated. Well... should we? We're still passing the return continuation *in* in P1, unless you want to move it out and unconditionally make it a parameter to invoke. Well, basically, if an interpreter template is used (hanging off the subroutine), the previous interpreter template is the return continuation. That means that for the usual case (function call and return) there isn't any need to construct a return continuation and put it somewhere. The return continuation would only be needed to create a real continuation out of it and pass it along somewhere. If that calling scheme doesn't fly, its still better to have specific locations in the interpreter context that hold the sub and the return continuation to allow simple function backtrace for the error case or introspection. That's currently not possible, because P0 and P1 can be swapped out into the register backing stack and reused to hold something totally different. I think I'd also like to make a change to sub invocation, too, to allow passing in alternate return continuations, which makes tail calls easy. Ok. Good point. We could get rid of Cinvoke Px (call the sub in Px w/o calling conventions) in favor of Cinvoke_with_retc Px. Anyway, the visible part of a return continuation (in above opcode or Cget_cc would be a continuation. The normal case (call/return) could just have that continuation internally in the context. No additional PMC is constructed ifn't needed. I could be wrong here, but it seems to me that having a special 'tailinvoke' operator which simply reuses the current return continuation instead of creating a new one would make for rather faster tail calls than fetching the current continuation out of the interpreter structure, then invoking the target sub with with this new continuation (ISTM that doing it this way means you're going to end up doing a chunk of the work of creating a new return continuation anyway, which rather defeats the purpose.)
Re: Current state?
Jared Rhine [EMAIL PROTECTED] writes: [Patrick == [EMAIL PROTECTED] on Wed, 8 Sep 2004 11:51:18 -0600] Patrick ...in the immediate future we'll be wanting rules/grammar Patrick tests (to test the grammar engine) more than we'll need Patrick perl 6 code, although we'll certainly take that as well. If you wanted to describe the form such tests might take, maybe Herbert will get excited enough to pitch in with such tests. I grok the difference between the grammar engine and the actual compiler, but I'm blanking on how to describe the process of writing tests that aren't simple Perl 6 code snippet style tests at this early stage. How about: /a pattern/ target_string matches? $1 $2 $3... another_target matches? $1 ... /another pattern/ ... The game is to get a bunch of tests written. Given a sufficiently regular layout Luke and Patrick can no doubt write some code that will massage things into something that can get run under some test harness.
Re: Iterators and Cfor
Aaron Sherman [EMAIL PROTECTED] writes: On Thu, 2004-09-09 at 13:14, Larry Wall wrote: So whereas Ruby's syntax actually tends to push you toward .each iterators, Perl 6's syntax will be fairly neutral on the subject, or maybe biased every so slightly away from method iteration by the width of about one character: for @foo { ... } @foo.each:{ ... } But then, a good Ruby programmer would have put a space where there's a colon anyway, so maybe it's a wash. If I wanted to make it even I'd pick something shorter than each, I suppose. Except all is already taken. I suppose there's something to be said for: @foo.for:{ ... } act any are ask cog cue did ere for get got has hop jet job kin let map mix net now one ore per pro put run set tag I won't describe why I think each one would be appropriate, since if it's not obvious, it's a bad choice ;-) I find myself wondering if this is going to allow people to write smalltalk style method selectors... @foo.inject:0 into: - $accum, $each { $accum + $each }
Re: Current state?
Herbert Snorrason [EMAIL PROTECTED] writes: Since this list has been started, I'd assume that means work on the final Perl6 compiler is about to start. (Although, with this crowd, you never do know...) In the interest of a layman's curiosity: What's the current status? (And I already wonder if this won't make the summaries even more irregular. ;) I hope not. I'm slowly getting back to a weekly schedule after the summer.
Re: Reverse .. operator
Joe Gottman [EMAIL PROTECTED] writes: In perl 6, the statement @foo = (1.. 5) ; is equivalent to @foo = (1, 2, 3, 4, 5); Is there similar shorthand to set @foo = (5, 3, 3, 2, 1) ? I know you can go @foo = reverse (1 ..5); but this has the major disadvantage that it cannot be evaluated lazily; reverse has to see the entire list before it can emit the first element of the reversed list. Would @foo = (5 .. 1 :by(-1)); do the trick? If so, would the same trick work for @bar = ('e' .. 'a' :by(-1)); ? @foo = 5.down_to(1) Where down_to is method Number::down_to ($self : Number $target) { return if $self $target; return $self, ($self - 1).down_to($target); } You might have to do some monkeying around with a range object or something to make it appropriately lazy, but that's a mere detail. Or you could implement it as an operator. Or...
Re: Numeric semantics for base pmcs
Leopold Toetsch [EMAIL PROTECTED] writes: Dan Sugalski [EMAIL PROTECTED] wrote: At 8:45 PM +0200 8/24/04, Leopold Toetsch wrote: Dan Sugalski [EMAIL PROTECTED] wrote: Nope -- we don't have bigints. :) Pardon, sir? We've got the big number code, but I don't see much reason to distinguish between integers and non-integers at this level -- the only difference is exponent twiddling. Ah, ok. BigInt as a degenerated BigNum. I still prefer the notion that adding or multiplying to integers give a BigInt on overflow. While at num vs int: do we automatically downgrade to int again? 6.0/2.0 = 3.0 or 3 ? No. Once a real, always a real. I see no harm in collapsing appropriate rationals to ints mind...
Re: Tight typing by default?
Dan Sugalski [EMAIL PROTECTED] writes: It seems pretty clear that the general opinion is that operations should produce the tightest reasonable type for an operation--integer multiplication should produce an integer unless it can't, for example. For our purposes I think the typing should go: platform int-float-bignum with an operation producing a type no tighter than the loosest type in the operation. (so int/float gives a float, float-bignum gives a bignum) This seem reasonable? No. int-bignum-float In other words, floats only happen if you specifically introduce them (or take a square root or something).
Re: The new Perl 6 compiler pumpking
Dan Sugalski [EMAIL PROTECTED] writes: There's not been a big public announcement, so it's time to change that. I'd like everyone to give a welcome to Patrick Michaud, who's volunteered to officially take charge of getting the Perl 6 compiler module written. I've put in yet another nudge to get the parrot-compilers list started, and get the perl6-internals list renamed to parrot-internals (which is what it really is) so we can get things properly sorted out, as I expect Patrick will be digging into the fun stuff pretty darn soon. Mmm... three list to summarize...
Re: This week's summary
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes: Piers Cawley wrote: Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes: Care to explain what those are, O great math teacher? What's a math teacher? It's the right^H^H^H^H^HAmerican way to say maths teacher. You mean American and 'right' are not equivalent? Wow.
Re: This week's summary
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes: The Perl 6 Summarizer wrote: The infinite thread Pushing onto lazy lists continued to exercise the p6l crowd (or at least, a subset of it). Larry said that if someone wanted to hack surreal numbers into Perl 6.1 then that would be cool. Care to explain what those are, O great math teacher? What's a math teacher?
Re: String interpolation
Larry Wall [EMAIL PROTECTED] writes: On Tue, Jul 20, 2004 at 11:00:39PM -0700, chromatic wrote: : On Tue, 2004-07-20 at 19:35, Luke Palmer wrote: : : The New Way (tm) to do that would probably be sticking a role onto the : array object with which you're dealing: : : my @foo does separator('//') = (1,2,3,4,5); : say [EMAIL PROTECTED]; # 1//2//3//4//5 : : Shh, no one's let slip the idea of curried roles yet! I'm not even : certain A12 mentioned parametric roles, let alone first-class roles. Well, A12 did talk about parametric roles, but I glossed over the first-class roles a bit. I didn't want to scare people with $foo does $bar though, of course, there's no reason in principle you shouldn't be able to do that as a run-time operation. You just can't instantiate a role object. The murky area in the middle is, of course, how you specify an initial value aimed at the attributes of a particular role without creating a real object containing just those values. Passing around lists of pairs is probably good enough for that, as long as you can keep straight which list of pairs is intended to initialize which roles. I really hope you change your mind about this; the sooner I can get that wild and crazy list of pairs nicely stashed in their appropriate role objects, the happier I'll be about the resilience of my code.
Re: String interpolation
Damian Conway [EMAIL PROTECTED] writes: I can't say I'm keen on making {...} special in strings. I felt that the $(...) and @(...) were a much cleaner and more general solution. The prospect of backslashing every opening brace in every interpolated string is not one I relish. Maybe we could write macros to provide a Lispish 'metaquoted' environment for when one is writing template code which wouldn't interpolate *anything* unless it was in C$(...) or C@(...).
Re: the whole and everything
Leopold Toetsch [EMAIL PROTECTED] writes: Dan Sugalski [EMAIL PROTECTED] wrote: Leo, we've talked about this before. The sensible and straightforward thing to do in a case like this is to tag in the sub pmc which register frames are used by the sub. And what, if the sub calls another sub? Then the call to the inner sub saves the registers that are used by the inner sub.
Re: scalar subscripting
Luke Palmer [EMAIL PROTECTED] writes: Gautam Gopalakrishnan writes: Hello, I've tried the archives and the 'Perl 6 essentials' book and I can't find anything about string subscripting. Since $a[0] cannot be mistaken for array subscripting anymore, could this now be used to peep into scalars? Looks easier than using substr or unpack. Hope I've not missed anything obvious. Well, no, it can't really. $a[0] now means what Perl 5 called $a-[0] (or @$a[0]). So it's still an array subscript, it's just subscripting $a, not @a. So, it should be possible to define method postcircumfix:[] is rw { ... } in the String class to do the right thing? Or even to define it in some Sequence trait that both arrays and strings share? Of course, the putative method would have to take into account the calling context's Unicode behaviour, but I can't see why it shouldn't be possible.