Re: pluralization idea that keeps bugging me
To me this sounds like use Lingua::EN::Pluralize::DSL; which would overload your grammar locally to parse strings this way. However, due to i18n reasons this should not be in the core. It might make sense to ship a slightly modernized Locale::MakeText with Perl 6 so that it can be used in the compiler itself, but unless a fully open ended system like L::MT is included I think having anything at all might be damaging, because this will encourage people to use the partial solution that is already built in instead of the complete on eon the CPAN (c.f. many core modules). -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418
Re: pluralization idea that keeps bugging me
On Sat, Jan 26, 2008 at 18:43:50 -0800, Jonathan Lang wrote: Right. One last question: is this (i.e., extending a string's grammar) a keep simple things simple thing, or a keep difficult things doable thing? I'm going to guess somewhere in between. It should be about the same level of complexity as Filter::Simple, except with much finer control and more correctness. I'm not the best person to answer this though. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpGuOUMaC21l.pgp Description: PGP signature
Re: pluralization idea that keeps bugging me
On Sat, Jan 26, 2008 at 18:12:17 -0800, Jonathan Lang wrote: This _does_ appear to be something more suitable for a Locale:: module. I just wonder if there are enough hooks in the core to allow for an appropriately brief syntax to be introduced in a module: can one roll one's own string interpolations as things stand? E.g., is there a way to add meaning to backslashed characters in a string that would normally lack meaning? You can subclass the grammar and change everything. Theoretically that's a yes =) -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpY4J1EXkC6j.pgp Description: PGP signature
Re: PERL arrays
On Tue, Jun 05, 2007 at 14:36:51 -0700, [EMAIL PROTECTED] wrote: how do i declare loop through and print a 4 dim array in PERL You listen in class. Or buy a book. Sorry, but we're not here to do your homework, and this is not a general Perl help mailing list. You can also probably get by this far using some online tutorial. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpIQKKbvB8dY.pgp Description: PGP signature
Re: Should a dirhandle be a filehandle-like iterator?
Why bother, actually, when it can just be a lazy list... Opendir and closedir are very oldschool, and can be retained for whatever technical detail they are needed, but in most modern code I think that: for readdir($dir_name) { .say } should work as well. The act of opening a directory is something I never quite got... Even a directory with millions of entries is still peanuts in todays memory sizes, and if it does need to be iterated very carefully the old variants can still be around. readdir() returning a list doesn't have to be inefficient but it's easier to screw up with it and make it bloat. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpNgghKAUJR3.pgp Description: PGP signature
Interrogating closures
Hi, I think a partial unification of objects and code refs in userspace is going to be a nice features. Closures allow people to put arbitrary complexity into a very simple api that is, in OO terms, just one method (the actual function call). Consequentially the closure may never reveal any information about it's actual behavior. I think the convenience of closures can be enhanced by allowing closures to declare that certain captured variables are in fact instance data (see below for ideas on how). A trivial example: my @callback_list; $some_object.register_callback(sub { for @callback_list - f { f() } }); sub add_callback (f) { push @callback_list, f; } This allows to register a number of callbacks to $some_object using a simple combinator. The problem is that without writing the add_callback api we lose the ability to modify this list, effectively forcing us to create an api. Perhaps a better approach is to create a callbackregistry class: class CallbackRegistry { has @callbacks; method trigger { for @callbacks - f { f() }; } method make_meta_callback { sub { self.trigger }; # interesting question here... can we close over lexical subs like self? } } Then we make a callback registry, and do something like $some_object.register_callback( $registry.make_meta_callback()); Essentially what this is doing is reimplementing the concepts of closures in OO terms. This layer could be removed by doing something like this: # first we define the API of the closure class ListOfCallbacksCallback isa Closure { has @callbacks; } my @callbacks; sub { @callbacks } but ListOfCallbacksCallback; # not quite sure of this Essentially this would overload sub capture, and make it into a constructor call of some sort. Variable renaming facilities would be nice, but even just a capture containing the body and all the closed over variables would be cool. This keeps things concise and lightweight, but does add the ability to inspect (via a well defined api) what a closure is encapsulating, etc. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpiHn7ODKbF4.pgp Description: PGP signature
Closures, compile time, pad protos
Hi, Anatoly and I don't know what this bit of code prints: foo(); foo(); for 1..3 { my $x ::= 3; sub foo { say ++$x }; say ++$x }; Is it 4, 5, 6, 6, 6 or 4, 5, 3, 3, 3? It's almost definitely not 4, 5, 6, 7, 8. I can't rationalize 4, 5, 6, 7, 8 while maintaining the notion that $x is actually lexical. To rationalize the other examples: 4, 5, 6, 6, 6 means that the foo declaration does not capture over an instance of the $x bar, but the actual value in the pad proto itself (the value that will be the default value of newly allocated $x variabless). 4, 5, 3, 3, 3 means that at compile time all variables are instantiated once for BEGIN time captures. Observe: foo(); bar(); for 1..3 { my $x; sub foo { say ++$x } sub bar { say ++$x } say ++$x; } prints 1, 2, 1, 1, 1 because $x is allocated once at compile time and captured into both foo and bar, and then separately allocated once more for each iteration of the loop. If this is indeed the case, then there is a semantics problem: foo(); foo(); for 1..3 { my $x; BEGIN { $x = 3 }; sub foo { say ++$x }; say ++$x }; Must be 4, 5, 1, 1, 1. This is because BEGIN { } and the foo share the same compile time allocated copy of $x, but this is not the copy in the loop. A related issue is: foo(); foo(); for 1..3 { my $x = 10; sub foo { say ++$x }; say ++$x; } Is that 11, 12, 10, 10, 10, or 11, 12, 13, 13, 13, or 1, 2, 10, 10, 10? Lastly, sub foo { my $x; sub { sub { say ++$x } } }; my $bar = foo(); my $gorch = $bar.(); $gorch.(); $gorch.(); my $quxx = $bar.(); $quxx.(); $quxx.(); obviously results in the sequence 0, 1, but does the second call to $bar create a new sequence in $quxx, or is that instance of $x shared between $gorch and $quxx? Intuitively i'd say it is shared, which means that the outer sub declaration implicitly captures $x as well. Can anyone confirm? Obviously my $zot = foo().(); $zot.(); $zot.(); Does create a new sequence. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgplPyMaquTyx.pgp Description: PGP signature
Re: Closures, compile time, pad protos
And what about: foo(); for 1..3 { my $x ::= 3; sub foo { say ++$x }; say ++$x }; BEGIN { foo(); foo(); } or worse: sub moose { my $x = 3; sub foo { say ++$x; } BEGIN { foo(); moose(); foo(); } foo(); moose(); foo(); *foam oozes out of ears* -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpQTxvdv3gAY.pgp Description: PGP signature
Re: Closures, compile time, pad protos
On Wed, Nov 22, 2006 at 18:55:15 +0100, Juerd wrote: Yuval Kogman skribis 2006-11-22 16:01 (+0200): my $x ::= 3; sub foo { say ++$x }; Why would you be allowed to ++ this $x? It's bound to an rvalue! Perhaps my $x ::= BEGIN { Scalar.new( :value(3) ) } What we meant to be doing was to pre-set this value at compile time to 3. That doesn't really matter though -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpz0EsZwn4z2.pgp Description: PGP signature
Re: return Types: what are the enforcement details?
On Tue, Aug 29, 2006 at 19:49:38 -0500, Mark Stosberg wrote: I'm interested in helping to write some tests for return types, but I'd like some clarifications about them first. Are they just declarations that help Perl optimize stuff, or they actually contracts? 'of' is the contractual form, 'returns' is a constraint but it's more like a cast. demo: sub foo of Array { my %h = ( a = 1 ); return %h; } sub zoo returns Array { my %h = ( a = 1 ); return %h; } # Hashes are happily returned, despite the Array return types. my %b = foo(); say %b.perl; my %c = foo(); say %c.perl; ^-- z ? Intuitively I would say that both subroutines force the hash into an array, at minimum, and foo might be checked more thoroughly. In the case of foo(), foo itself might not compile, or my %b = foo() might not compile, or both. In the case of zoo(), i think it's just a runtime conversion to an array. There's no reason why this conversion can't happen explicitly as well as implicitly, like with my %h = () = %other_hash. However, conversions that cannot be made could be cought at compile time, emitting a warning on an error depending if the runtime is a warning or an error. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpZuk0rgo5oy.pgp Description: PGP signature
Re: Curious corner cases concerning closure cloning
On Mon, Aug 14, 2006 at 16:01:47 +, Luke Palmer wrote: What do these do? Intuition based answers: for 1,2 { my $code = { my $x; BEGIN { $x = 42 } $x; }; say $code(); } I think the closure would be emitted equivalently to my $x = 42, or perhaps $x is not in the BEGIN blocks scope at all. for 1,2 { my $code = { state $x; BEGIN { $x = 42 } # mind you, not FIRST $x++; }; say $code(); say $code(); } Again, assuming the BEGIN { } body is not even compile but it's side effect is meaningful, this is the same as state $x = 42; but starting to get a little tougher to justify. Perhaps it does that, but also emits a warning e.g. 'implicit initial value for future-scoped lexical' or something like that. for 1,2 - $x { END { say $x } } undef, because END is like a declaration putting the closure in some global, and doesn't actually happen at runtime. Otoh for 1,2 - $x { state $y = $x; END { say $y } } Might work -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp2ibIxnkvaI.pgp Description: PGP signature
Re: request addition of immutable Blob type
What about str? Or is it called buf now? -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpaF4yq94mUW.pgp Description: PGP signature
Re: weak roles
On Tue, Aug 08, 2006 at 09:05:07 +0200, Mark Overmeer wrote: Sometimes, the external interface of a module looks the same, and there are cases where the internals behave as such as well. In general, however, the internals are more different then the user code shows. That makes your proposal unworkable. The whole point is to implement the same interface in terms of different internals. For different approaches to tackle the (in this case e-mail) problems you need different internal helper objects, different methods, different attributes. It is in general hard to force an extra interface definition inside the same class. That's why they are in separate roles that are off by default. These roles are orthogonal. But that's not all. A header contains fields, which are usually objects as well. How would you include variation in those in the definition? Every off by default role is distinct. You cannot use them simultaneously if they conflict. And different versions of one module which use your Email::Abstract module? You must not try to understand the structure of other modules into such a detail, because you cannot maintain it. Huh? Delegates are not sufficient to implement such couplings between unrelated modules: you commonly need serious parameter rewrites. Delegates are nice within a homogeneous concept. Email::Abstract works. It's not the most pleasant thing, which is why it's problematic, but it *does* do the job. The only way I have found to work is with wrapper objects which translate between the two modules. a.k.a a delegate The advantanges are that you have localized the hassle of interfacing to one class, and you hide the internal complexity of both sides (OO is about abstraction!). Which is much more work than what roles make you do. Of course, we could use the Email::Abstract interface as a base- class to all email related modules, but you know that this wouldn't work for the Perl community... Base classes, as opposed to roles, don't work well at *all* for these types of scenarios. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpYxhcH0dDFZ.pgp Description: PGP signature
Re: weak roles
On Tue, Aug 08, 2006 at 09:05:07 +0200, Mark Overmeer wrote: Of course, we could use the Email::Abstract interface as a base- class to all email related modules, but you know that this wouldn't work for the Perl community... Actually I'd like to expand on this. There are two problem with your solution, that are not community related. The first is that this is no different from using the role Email::Abstract or whatever it'll be in the classes. Roles can be abstract, too. The second is the issue i raised though - when It's too difficult to put together two (or more) abstract roles (or base classes) in the same class, you may declare how to do all of them in a conflicting way. That is you can be both Email::Abstract and Email::Abstract::Better, even though they define different interfaces by simply declaring that you cannot be both of them at the same time, and whoever is invoking the methods must explicitly say which behavior it prefers. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpZ2Gw5Yibt7.pgp Description: PGP signature
Type annotation on expressions
Is there any way to type annotate a single expression, without using a temporary variable? my Moose $x = $y; # definitely a Moose now, may have been coerced foo( $x );# foo() doesn't necessarily say it wants Moose Is it possible to say this one expression? Haskell's syntax is shiny but everybody wants the colon: foo( ( $x :: Moose ) ); If we do find something (please ignore the fact that :: is probably not going to be the syntax), are these two the same? my $x = ( $y :: Moose ); my Moose $x = $y; -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp7JsfFQH2g5.pgp Description: PGP signature
Re: Type annotation on expressions
On Tue, Aug 08, 2006 at 11:12:11 +0100, Daniel Hulme wrote: I may be in a little world of my own here, but isn't this what 'as' is supposed to do? foo($x as Moose); as is a method invocation not a type annotation... It's related, but not the same (last I heard) -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp2Cu6VazVqf.pgp Description: PGP signature
Re: weak roles
On Tue, Aug 08, 2006 at 11:14:40 +, Luke Palmer wrote: Mail::TheOneTrueWay.new.header; # which one? Either neither, or the default one (which is declared default by the class). A related question: if Mail::SomeAPI and Mail::SomeOtherAPI both exported a method, say send, and you mentioned it outside the weak role blocks, which one does it call. If mentioned means used, then that's a conflict. If it gets that far you *really* need a delegate. If mentioned means declared than neither - it's the same one for both. Well, yeah, but I think they're the right solution. They may be right, but it's hard to get an organically growing community to design their code for them. I personally prefer delegates for almost any design dillema, but most CPAN modules aren't that way. snipped stuff about adaptors Yes, this is necessary for anything heavyweight and probably better design, but again, hard to encourage on a wide scale. Oh, and hello everyone. Long time no see :-) Welcome back =) -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpdqdaI70kz3.pgp Description: PGP signature
Re: Type annotation on expressions
Actually this particular example is just like coercion, and it's a bad one sorry. It's much more relevant for: fun( $x.foo :: Bar ); in order to annotate the return type for a call's context even if the 'fun' function's signature accepts Any. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpSGrwfd8t6b.pgp Description: PGP signature
Re: weak roles
On Tue, Aug 08, 2006 at 11:35:30 +, Luke Palmer wrote: On 8/8/06, Yuval Kogman [EMAIL PROTECTED] wrote: I personally prefer delegates for almost any design dillema, but most CPAN modules aren't that way. Well, what way are they? Usually not polymorphic at all. We have the capabilities to do very flexible polymorphism with delegation today. Roles aren't necessary from a purist perspective, they just make it much easier to do very flexible polymorphism more often since it'll be easier. How else has this problem been solved? I dunno... If a function declares a parameter as a SomeAPI and then passes it on to a helper function, which leaves it untyped, which then calls header, what happens? Since your proposal is lexical, SomeOtherAPI's is called, which is probably not what was intended. My original idea was that this is again an ambiguity error - without the helper function stating which role it's using it cannot dispatch the header method at all, since it's in a role-conflicted state. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp4dRrnCkIMb.pgp Description: PGP signature
Re: weak roles
On Tue, Aug 08, 2006 at 12:00:03 +, Luke Palmer wrote: The difference, though, is that this ambiguity error happens at call-time, whereas most ambiguity errors happen at composition time. As I saw it it's not really a role, it's more of a no-op coercion. Instead of actually writing an adaptor class, you could get off cheaply if the adaptor doesn't need any more instance data than is already provided by the main object. So yes, it's runtime, but it doesn't matter. It strikes me that there is a happy medium. class Mail::TheOneTrueWay { has $.some_api adapts Mail::SomeAPI { method header; # this method has different semantics for # each role. It would normally conflict. } has $.some_other_api adapts Mail::SomeOtherAPI { method header; } method body; # this method is shared between the two roles } Which would pull all that multiple delegation bullshit in my earlier post. Creating the class is just as easy, and using it involves putting .some_api and .some_other_api in appropriate places like a delegation interface. It's not quite as DWIMmy, but the class doesn't do either role so errors will be caught quickly. It is also annotation-agnostic. Hmm... Are the 'adapts' things actual class bodies? Like an inner class? -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpt3fkl5vE9I.pgp Description: PGP signature
Re: Type annotation on expressions
On Tue, Aug 08, 2006 at 11:42:15 +, Luke Palmer wrote: I'm not up-to-date on coersion; last I checked it was hand-wavily defined. Currently it's a unary multimethod: my $hamburger = $cow.as(Food); However, the MMD rules are counterintuitive for dispatch rules. The reason annotation came up is because I felt it shouldn't be a parameter at all, but a nullary multimethod on the return value: my $hamburger = $cow.as :: Food; Larry had mentioned that return.signature is basically the invocation context. If we do have a n ullary `as` the annotations are essentially parameters on the anonymous function that is the CPS continuation. That continuation's signature is used to perform MMD dispatch on 'as' by matching the -- stuff in opposite priority order. The current problem is: 12:15 audreyt Point is Shape; 3DPoint is Point 12:15 audreyt er I mean Poind3d 12:15 audreyt Point3d 12:15 audreyt you have an object $o 12:15 audreyt you want to get back Point 12:15 audreyt say $o.as(Point).x 12:16 audreyt $o is actually of class Moose 12:16 audreyt Moose has 12:16 audreyt multi method as (Shape) 12:16 audreyt multi method as (Point3d) 12:16 audreyt if we list as using the normal MMD rule 12:16 audreyt proto as ($) {} 12:16 audreyt then Point comes in and Shape is selected 12:17 audreyt but we want Point3d 12:17 audreyt not Shape, to win 12:17 nothingmuch isn't .as(Point) going to fail if it returns a Shape? 12:17 nothingmuch i mean 12:17 nothingmuch the rules here are reversed 12:17 nothingmuch Point is not a parameter to .as in the natural sense 12:17 audreyt it is going to fail only if we consider the return type http://colabti.de/irclogger/irclogger_log/perl6?date=2006-08-08,Tuesel=359#l545 for more discussion. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpbTNX1bN0Zz.pgp Description: PGP signature
weak roles
The CPAN has many reinvented wheels. This happened since we have so many authors (== opinions) over so many years. For example, we have Mail::Message to Email::Simple, to Mail::Internet to They all do the same thing differently. Then there is Email::Abstract, which provides a simplified API for all of these together, so that modules like Mail::Thread can work with either. With the introduction of roles, supposedly this is going to be less of a problem. Email::Abstract would ideally be a role that the organically grown message abstracting classes just 'do'. However, suppose that Email::Abstract itself would be reinvented. The message modules now have to choose between either Email::Abstract or Email::Abstract::Better as the one role to do (since they probably conflict), or it will have to do weird magic to disambiguate in a context sensitive way. I think a nice idea to work around this would be to introduce weak roles, that are lexically scoped. The way it could work is a bit like this: class Mail::TheOneTrueWay { does Mail::SomeAPI is weak { method header; # this method has different semantics for # each role. It would normally conflict. } does Mail::SomeOtherAPI is weak { method header; } method body; # this method is shared between the two roles } Then, when a module is expecting a message object it declares the role it wants this object to do for this scope: sub analyze_mail ( Mail::SomeAPI $message ) { $message.foo; # unambiguous } This way coercion can be avoided, which means that keeping mutable coerced objects synchronized is no longer necessary, thus simplifying the code path and encouraging even more pluggability/polymorphism. I'm not sure on the behavior of $obj.does outside of the role strenghning scope. I am pretty sure that this should be purely lexical, and not dynamic, even for .does (if it's true on the inside). Perhaps an invokation of an ambiguous method is an error for the caller ($object responds to N flavours of the header method, you must explicitly say which flavour you prefer right now). Delegates are another way around this but let's face it: 1. they're not as popular as they should be 2. they're more classes to write 3. they're harder to use Consequentially we have fairly few delegate based APIs for these problems (Email:Abstract is the only one I know). -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpsRApD6diiG.pgp Description: PGP signature
underscores in the core lib
Hi, Audrey mentioned that Perl 6 is trying to avoid underscores in the core library. It came up when I asked why valid isn't called value_id because if ( $user_input.valid ) { } reads fairly confusingly. So, a few questions: 1. what is the official naming style for the Pelr 6 standard library (not just functions, but methods for core objects, the MOP, the compiler toolchain, the truely absolutely core modules, etc). 2. What is bad about underscores? From what I know most people tend to think that $object.do_that_action is the clearest way of naming methods, and the technical reasons to avoid these (long symbol names, lots of typing) are no longer really valid nowadays (with editor autocompletion, etc). 3. why are some core methods named ALLCAPS (BUILD, BUILDALL)? Or perhaps more accurately, which types of other methods should also be in ALLCAPS? and is ALL_CAPS also OK? Or is that for constants? 4. If really make a departure from short names, will things that sort of model POSIX (IO, etc) have short synonyms? or will these be named in their short form? A request to the thread participants - please try and form your arguments on a good for everyone level, not just what your personal preferences are. I don't think that anyone's opinion matters except @Larry's, and you're not going to change their minds if you simply present stylistic argumetns. --- My own spiel: I would like to see a slight departure from the C-style naming convention (which I must admit i really really dislike - remembering std c library names when you don't use them all the time is tricky, and consequentially so is looking them up in the docs). I would very much like Perl 6 to be a language that's easy to read as you go along, where consulting the documentation isn't always necessary to understand what's going on. A unix head may read: $file.chown( $user ); wait( $pid ); easily, but anyone with sufficient understanding of the program's behavior can understand what $file.change_owner( $user ); wait_for_process( $process_id ); is without being aware of the conventions. Of course, this has downsides too- it defies an existing convention, (These are standins for old UNIX functions which everyone already knows). However, we will also have new APIs, like the OO meta model: my @attrs = $meta.attributes; # shallow my @deep = $meta.compute_all_attributes; # deep, also from superclasses Than my @attrs = $meta.attrs; my @deep = $meta.compattrs; -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpVoL9QodN0W.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
On Fri, Jul 14, 2006 at 11:42:24 +0100, Smylers wrote: I'm afraid I still don't get it. Or rather, while I can manage to read an explanation of what one of these operators does and see how it applies to the variables in the examples next to it, I am struggling to retain a feeling of _why_ I would want to use any of these operators in real-life Perl 6 code. To compare deep structures ;-) Already in Perl 5 having 2 different equality operators is something that learners often stumble over. But only for low level types. To see if two objects are the same, or two hashes, you need to use Data::Compare, or to overload either == or eq, neither of which is a perfect fit. I have to catch my flight, so I'll explain more later. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp4zdMSoN13m.pgp Description: PGP signature
Re: optimizing with === immutable comparitor
On Fri, Jul 14, 2006 at 00:30:20 -0700, Darren Duncan wrote: This may go without saying, but ... ... This is a VM issue. It clarifies semantics, and the runtime VM may choose to do this freely for simple values (but not for objects which just pretend using .id). In short: yes, the semantics allow that, but it has nothing to do with the language it might not even be faster. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp2roLoyDefj.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
On Fri, Jul 14, 2006 at 09:22:10 -0700, Dave Whipp wrote: Darren Duncan wrote: Assuming that all elements of $a and $b are themselves immutable to all levels of recursion, === then does a full deep copy like eqv. If at any level we get a mutable object, then at that point it turns into =:= (a trivial case) and stops. ( 1, 2.0, 3 ) === ( 1,2,3 ) True or false? false More imprtantly, how do I tell perl what I mean? The best I can think of is: [] (@a »==« @b) Vs [] (@a »eq« @b) Neither - it's on the natural types. If the types are different it's != -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpdVijcRjp0Q.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Thu, Jul 13, 2006 at 00:55:30 -0700, Darren Duncan wrote: So, in the general case, it would seem best if the binary operator === was just an ordinary method that each class provides, rather than requiring classes to defined a .id. Or in addition to this to help with performance, a .id can exist anyway that optionally returns an appropriate hash of an object. But what is the benefit here? Keying by object is a difficult topic. In Perl 5 you sometimes want to key by refaddr (more often than not) because you are associating new metadata with the instance, that does not belong inside the instance. On the other hand you also often want something like $obj to be the key, if it can properly stringify, so that an object like a currency: my $x = Currency.new( code = USD ); my $y = Currency.new( code = USD ); $hash{$x} = 1; say $hash{$y}; # 1 will DWIM. But this really depends on both the item being used, *and* the way it is being used. So I can see the value of making the second type of keying possible and easy with an .id method (which at the very lowest level can probably just emit e.g. a YAML representation of an object to ensure uniqueness, if performance is *really* not an issue). But this does not relate to equality, it's only useful for defining it. We were essentially questioning the reason === is specced to behave as it currently does, because we feel that it's not very useful if it's not clear cut that it should either *really* compare, or not compare at all. And if it doesn't compare, we'd like a deep comparison operator in S03. Built-in mutable types, like Array or Hash, would not override the Object-defined ===, which is equivalent to =:=, nor the built-in .id, which returns the object itself. This is reasonable in practice because the contents of those containers could be changed at any time, especially if the containers are aliased to multiple variables that are outside of the testing code's control. The only thing that can be guaranteed to be constant over time is that whether or not an object is itself, as determined by =:=. By contrast, if === were to do a deep copy with mutable types, the results could not be trusted to be repeatable because the moment after === returns, the container's value may have changed again, so actions done based on the === return value would be invalid if they assumed the value to still be the same at that time, such as if the mutable type was used as a hash key and was to be retrievable by its value. The behavior for arrays is useless to me, because I already have =:=. I can write a hybrid ===/=:= operator for very special cases, but 99% of the time I want to ask do these (arrays|hashes) contain the same values *right now*? User defined types can choose on their own whether to override === and/or .id or not, and they would use their own knowledge of their internal structures to do an appropriate deep comparison. There is no need to try to generate some kind of unique numerical .id for arbitrarily complex objects. That creates a mess - sometimes objects compare themselves based on their value, and sometimes based on their containing slot. These are very different semantics. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpxFsetaGrOi.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
So, Larry assisted by Audrey explained the purpose of === vs eqv vs =:=. It makes sense now, but I still feel that as far as ergonomics go this is not perfect. Then again, I trust that Larry's opinion is probably better and at the very least more likely to be accepted than mine ;-) [1] So, this is the deal: === is for checking immutable equality. This is a bit nasty to explain. eqv is going to be deep comparison, like most of us thought '===' was going to be (I had initially thought that eqv was renamed to === when === started popping up). =:= is something completely different, but will be easy to explain in a moment. What it means for something to be immutable can be demonstrated rather easily here: my $x = 10; my $y = $x; $x === $y; # true $y++: $x === $y; # false Since numbers (and also strings) are simple values, that are not modified in place (at least not explicitly), but are instead copied and modified or just replaced when you change them, the .id of the thing inside $x and $y is bound to the value. You could rationalize this such that .id is the same if and only if it doesn't actually matter (and never will matter) if the value is in the same chunk of memory or a separate one, as far as the runtime is concerned. Arrays and hashes, and other complex types can, on the other hand have parts of them transformed without first cloning everything (which is precisely why they're useful). The underlying idea is that === can be used to test if two values are *always* going to be the same (if they're container gets a different value in it that does not mean that they are no longer the same). eqv, on the other hand is used to test whether or not two values are the same right now, without making any implications as to what their values will be later on, since they may mutate. This is deceivingly like == and eq if you assume that numbers and strings are changed, instead of replaced. Lastly, =:= is really variable($x) === variable($y) - that is, whether or not the container is the same value or not. This basically checks whether either $x or $y was at some point bound to the other, or in specific situations whether they're tied to the same representation even if they are different containers. Overridding .id is useful for when you want to imply that two items are exactly the same and will always be the same and will never change as far as their comparison is concerned (both eqv and === will always be true), even if the default implementation of === does not return true due to technical details. === can be thought of as .id eqv .id. I hope this clears things up, and thanks again, Larry and Audrey, for clearing this up. I'd like for someone with better english skills to summarize into an S03 patch please. It needs to be much shorter =) [1] My preferred ergonomics: 1. eqv goes away 2. what was eqv is renamed to === 3. === becomes =:=, which has a constant feel to it 4. =:= is rarely useful IMHO, so you can just type variable($x) =:= variable($y) Ciao -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpU0Qe5CPlhQ.pgp Description: PGP signature
Re: Run time dispatch on ~~
On Thu, Jul 13, 2006 at 15:44:33 -0400, Aaron Sherman wrote: Now, let's look at some of the good that ~~ does for us: $a ~~ Some string # sameness $a ~~ 5 # sameness $a ~~ -{...} # test $a ~~ /.../ # regex matching That's great, and we don't want to mess with any of it. But, then we have: $a ~~ $b# uh... something One compelling reason to have them behave exactly the same is to allow refactoring. If i'm using the same pattern on several inputs i'd like to maybe delegate this to a helper sub that will actually run the ~~ for me, in some way, and i'd like 100% compatibility. Also, sometimes i am matching on behalf of my caller, this is very common in dispatch algorithms, or things like tree visitors: my @list = $tree.filter_children( $match ); # very generic and useful -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp8KEQiTHBTj.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
On Thu, Jul 13, 2006 at 12:50:19 -0700, Larry Wall wrote: On Thu, Jul 13, 2006 at 09:32:08PM +0300, Yuval Kogman wrote: : [1] My preferred ergonomics: : : 1. eqv goes away : 2. what was eqv is renamed to === : 3. === becomes =:=, which has a constant feel to it : 4. =:= is rarely useful IMHO, so you can just type : variable($x) =:= variable($y) It is important for eqv to be alphabetic so we can have the functional form take an optional signature parameter to specify what is compared. There's no contradiction, === could be an alias to eqv ;-) -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpPDRBxXCeip.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
On Thu, Jul 13, 2006 at 21:55:15 -0700, Jonathan Lang wrote: Apparently, there are _four_ basic kinds of comparison: the ones mentioned above, and == (I believe that eq works enough like == that whatever can be said about one in relation to ===, =:=, or eqv can be said about the other). I'd be quite interested in an expansion of David's example to demonstrate how == differs from the others. sub infix:== ( Any $x, Any $y ) { +$x === +$y; # propagate coercion failure warnings to caller } sub infix:eq ( Any $x, Any $y ) { ~$x === ~$y } -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp3B4GnByYFK.pgp Description: PGP signature
===, =:=, ~~, eq and == revisited (blame ajs!)
Over at #perl6 we had a short discussion on =:=, ===, and ~~, mostly raised by ajs's discussion on Str items and ===. After a brief discussion we managed to formulate several questions that we feel are slightly to totally unresolved. 1. what is .id on references? Is it related to the memory slot, like refaddr() in Perl 5? 2. is .id *always* a low level type representation of the object's value? It's specced that low level typed items have the same ID when they have the same value. What about complex types? 3. Are these descriptions of the operators correct? ~~ matches the left side to a description on the right side =:= makes sure the objects are actually the same single object (if $x =:= $y and you change $x.foo then $y.foo was also changed... is this .id on refs?) Is =:= really eq .id? or more like variable($x).id eq variable($y).id? === makes sure that the values are equivalent ( @foo = ( 1, 2, 3 ); @bar = ( 1, 2, 3); @foo === @bar currently works like that, but @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); @foo === @bar does not (in pugs). This is not useful because we already have this return false with =:=). If they are not correct, why is there an overlap between =:=? Why is it hard to deeply compare values in 2006 without using e.g. Data::Compare? 4. will we have a deep (possibly optimized[1]) equality operator, that *will* return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); op(@foo, @bar)? Is it going to be easy to make the newbies use that when they mean it's the same, like they currently expect == and eq to work on simple values? 5. is there room for a new opperator? =::= makes sure the memory slot is the same (might be different for simple values). refaddr($x) == refaddr($y) in Perl 5 =:= makes sure that .ids are the same, and is useful if the .id method is meaningful for an object. A bit like Test::More::is( $x, $y ) but without the diagnosis in Perl 5, or abusing eq if the object doesn't overload stringification. === makes sure the values are the same even if they are copies/clones/whatever. Data::Compare in Perl 5. A bit like what people overload == for in Perl 5 right now (which confuses numerical equality with true equality, so we want to phase that out). ~~ makes sure the value on the right side describes the value on the left side. Reminiscient of Test::Deep::cmp_deeply, with all the various matching magic. Thanks, [1] It could, of course, be just =:= === inside, and it could optimize arrays to check length first, and it could cache checksums and it could do whatever - please don't bring this up as a performance issue, it is one of correctness and ergonomics that must be resolved first. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpI98L8HHVih.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
If we do have deep value equality checks, then default == and eq are probably: sub infix:== ( $x, $y ) { +$x === +$y; } sub infix:eq ( $x, $y ) { ~$x === ~$y; } So that the compare-as-sometype behavior is retained from perl 5 without introducing new complexity to the objects being compared as strings/numbers. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpefrROP9pJ6.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
Jedai and I went through some of pugs current implementations. Here's a list of what we expect the operators to return and what they currently do. This does not exactly agree with S03 right now, but is our opinion. Force into a type before comparing values: 42 == 42 - true, same numeric value 42 == 42 - true, same numeric value 42 == 42 - true, same numeric value 42 == 42.0 - true, same numeric value 42 eq 42.0 - false, different string value 4 eq 4 - true, same string value Well typed value comparison: 42 === 42 - true, the same type 42 === 42 - false, not the same type 42 === 42 - true, the same type 42 === 42.0 - false, different value in natural type (string values) (1, 2, 3) === (1, 2, 3) - true, same value ([1, 2 ], 3 ) === ([1, 2 ], 3) - true, same value - BROKEN (actually false, since refs are not the same). S03 thinks this is actually OK. [1, 2, 3] === [1, 2, 3] - true, same value, (S03 says that this is actually broken, because references should not be the same (we disagree)) my @foo = (1, 2, 3); my @bar = @foo; @foo === @bar - true, same value. my @foo = ([1, 2], 3); my @bar = @foo; @bar === @foo - true, same value - BROKEN (S03 actually agrees with us here, since the ref is the same in this case) Slot/container equality (this is actually up to debate, but this is what we would expect if it was refaddr($x) == refaddr($y)): [ 1, 2, 3 ] =:= [ 1, 2, 3 ] - false, different containers - BROKEN (actually true) my $foo = [ 1, 2, 3 ]; $foo =:= $foo - true, same container my $foo = [ 1, 2, 3 ]; my $bar := $foo; $bar =:= $foo - true, same container my $foo = [ 1, 2, 3 ]; my $bar = $foo; $bar =:= $foo - true, ref to same container, or false since different container, unsure - currently true my @foo = (1, 2, 3); my @bar = @foo; @foo =:= @bar - false, container should be different - BROKEN (actually true) my @foo = (1, 2, 3); my @bar = @foo; @bar[1] = moose; @foo =:= @bar - false, container should be different. This actually works like we expected, appearantly pugs does some sort of COW Under := slot semantics the first test should be false, the second should be true, the third should be true, the fourth should be false, the fifth should be false, and the sixth should be false. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpNFsdSOd2Lf.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 16:16:13 -0400, Aaron Sherman wrote: Isn't that ~~? Per S03: Array Array arrays are comparablematch if $_ »~~« $x ~~ is really the all-purpose, bake-your-bread, clean-your-floors, wax-your-cat operator that you're looking for. Not at all, because: ( [ 1, 2 ], 3 ) ~~ ( { 1 }, { 1 } ) It's matching, not equality. which is true. Ain't recursive hyperoperators grand? It isn't a hyperoperator, it's just recursive ;-) 2. is .id *always* a low level type representation of the object's value? It's specced that low level typed items have the same ID when they have the same value. What about complex types? It cannot be for complex types or even strings... well, at least it Imust not be Iif we care about performance That's orthogonal. .id is used for hash keys. If you're keying y hubble images then they must be unique for some keyspace, and that's where .id makes a mapping. =:= looks in the symbol table (caveat dragons) to see if LHS refers to the same variable as the RHS. Does this dereference? Probably not, but I'm not sure, based on S03. Then it's a purely lexical opeation, and it doesn't even work for my $x := $array[3]; $x =:= $array[3]; but i'll pretend you didn't say that ;-) -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpPMmzta8SWk.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 17:58:03 -0400, Aaron Sherman wrote: Then ~~ is wrong in that respect, and I think we should be talking about that, not about making === into ~~, but without invoking code when it shouldn't. But it should! It's the smart match! If the rhs matches the code ref (the code ref gets it as an argument it's a match! That's why ~~ isn't a comparison operator, but a smart match operator - it DWIMs *very* deeply. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpyx4u1552HO.pgp Description: PGP signature
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
On Wed, Jul 12, 2006 at 16:16:13 -0400, Aaron Sherman wrote: The other way to think about === would be that it tells you if its LHS *could* be constant-folded onto its RHS (if it were constant for long enough) What is the benefit here? Because of the word deep. Deep implies arbitrary work, which isn't really what you want in such a low-level operator. However, using these operator, one could easily build whatever you like. The number of times i *sigh*ed at having to reinvent deep operators in a clunky way in Perl 5 is really not in line with Perlishness and DWIM. Also ~~ is deep in exactly the same way. Perl is also not low level. I could build it, and I have, but I don't want to. It can short circuit and be faster when the structure is definitely not the same (totally different early on) or definitely the same (refaddr is equal, etc). Should I go on? I'd avoid saying memory, here. Some implementations of Perl 6 might not know what memory looks like (on a sufficiently abstract VM). Slot -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpvVdjsJ0Et9.pgp Description: PGP signature
Re: S?? OS interaction, POSIX and S29
On Tue, Jul 11, 2006 at 16:46:40 -0400, Aaron Sherman wrote: There's a bit at the end of the current S29: =item A/S??: OS Interaction I've taken on a few of these, and in doing so found that I was making some assumptions. I'd like to share those and see if they make sense: * POSIX will be a low-level module that slavishly reproduces the POSIX interfaces as closely as possible (perhaps moreso than Perl 5) * OS, or whatever we call the core OS interaction module, will have an interface which is entirely driven by Perl 6 and may not resemble POSIX much at all. * OS will use POSIX to implement its functionality, so only POSIX need know how to get at the lowest level. Will that be reasonable? Am I stomping on anything? I think OS is kind of bad. Perl 6 is designed to be embeddable, retargetable, etc. Sometimes the environment well be JS like, that is you have (possibly) readonly environment calls (gettimeofday, etc), but not others (IO)... Ideally I would like to have something more partitioned, and with a less binding name than OS. That said, there's no reason why there shouldn't be a convenience wrapper around a more partitioned set of APIs, that provides a more toolchain like approach, and keeps the docs together. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpa4KWeuv2pQ.pgp Description: PGP signature
Re: Classy logging for Classes
On Thu, Jun 22, 2006 at 19:19:47 +0200, Szilakszi Bálint wrote: I'm trying to collect ideas about how could be (optionally available) logging added/implemented for classes, as in logging what methods are called at runtime, the parameters they are called with, etc. without embedding the whole logic in the methods themselves on a one-by-one basis. When the meta object protocol is exposed this will likely be a very simple meta-class mixin role. What I'm specifically looking for would be an instance based idea, so it doesn't permanently overwrite the class and thus consequently switch logging on everywhere that class is used, only for the scope of a given instance of the class. This can probably be hacked at runtime by reblessing the object into a temporarily role-mixed meta class. That said, most of the useful logging i've seen is not automatically generated. Traces are easy to do like this, but high quality logs should be hand rolled so that they convey the most meaningful representation of information. For this, aspect oriented programming can help you separate the logging from the actual body of the method, but this is not always the most correct behavior. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpOth0jMRVt0.pgp Description: PGP signature
Re: easier duck typing in .can
On Sun, Jun 18, 2006 at 18:08:00 +1200, Sam Vilain wrote: Why would you not use .does or .isa there? Are you wanting this to go through all of the Class/Role's methods and check that the $object.can() them? Because if you don't control $object's class you can't change it. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpLRbF8bTTrd.pgp Description: PGP signature
easier duck typing in .can
Synopsis 12 specifies that: .can interrogates any class package's CANDO multimethod for names that are to be considered autoloadable methods in the class but aside from that is just a name - method iterator mapping. Since CANDO is a multimethod, IMHO this can be safely extended to allow: $object.can(Class); $object.can(Role); to better support duck typing. Scenarios in which this is useful are when you are mixing classes. For example, CGI::Cookie and CGI::Simple::Cookie (perl 5 land) have the same interface but don't strictly know about each other. If you want to allow drop-in replacements to some objects then you typically would rather check for duck typing than role consumption. A real life example is CGI::Cookie::Splitter, which really doesn't care (and for good reasons shouldn't care) what the object it's dissecting is, as long as it follows the CGI::Cookie interface. However, since it's not tied to the CGI::Cookie implementation in any way except that CGI::Cookie was the first module to provide that interface, it shouldn't require it. Sometimes in the real world roles or base classes are not as refactored as they should be, and if CGI::Simple::Cookie was given the option of 'doing' CGI::Cookie but getting a headache out of it because CGI::Cookie didn't have foresight to be easily 'done', that shouldn't harm people. Anyway, i'm reiterating why duck typing is good, and everyone probably knows this already. A complementing solution to better support duck type is from the perspective of e.g. CGI::Simple::Cookie in my example: http://search.cpan.org/perldoc?asa This could be somewhat mirrorred as: class Foo { can Bar; # claim that you can do it, and if possible also # get compile time verification } without affecting our hard earned renewed purity of .isa and .does (due to roles in Perl 6). Comments? -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpuJ14rwywVH.pgp Description: PGP signature
Re: A shorter long dot
On Sun, Apr 30, 2006 at 10:49:45 +1000, Damian Conway wrote: This would make the enormous semantic difference between: foo. :bar() and: foo :bar() depend on a visual difference of about four pixels. :-( You're not counting the space around the dot, which counts. To me they look completely different We need to be careful not to require the language to solve problems that are better solved with tools. On that point I agree, but I think it was a question of aesthetics... Juerd? $foo. .bar; $ba. .bar; $x. .bar; $foo.bar; $ba.:bar; $x. :bar; Frankly I don't think there's *that* much of a difference - each has pros and cons. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpWe4XRnb3kg.pgp Description: PGP signature
Re: Fw: ([EMAIL PROTECTED]) Re: A shorter long dot
On Sat, Apr 29, 2006 at 18:12:34 +0100, Nicholas Clark wrote: On Sat, Apr 29, 2006 at 05:59:37PM +0200, Juerd wrote: I get a message like this for every message that I send to this list. Trying to contact [EMAIL PROTECTED] did not result in response or change. Any ideas? Forward that message (with full headers) to [EMAIL PROTECTED] who will then apply the LART. As I figure I'm about to get one, I'll (also) forward mine. Just got one... By LARTing you mean forcibly unsubscribing? because the message was sent to me directly too... -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpXVm8b225FF.pgp Description: PGP signature
Re: A shorter long dot
On Sat, Apr 29, 2006 at 19:03:28 -0700, chromatic wrote: Two invisible things look completely different to you? If dots looked like this: then they would be invisible. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgplPt8CiApME.pgp Description: PGP signature
Re: The whatever context
On Mon, Apr 10, 2006 at 14:25:35 -0700, Larry Wall wrote: : my $x = grep { ... } @list; # returns count I think that's already whatever context. $x contains the resulting array. It's only if you later say +$x that you'll get the number of elems. Just for grep or for any function? If just grep that means that grep simply doesn't use want. If it's any function, then it means that all are constants are list or whatever, and all we really have are coercers. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpOSjPzPmwDK.pgp Description: PGP signature
The whatever context
Hi... I think that Perl 6 should have a whatever context, which is essentially: I want either array or scalar or whatever... You choose so that functions like grep can return an array in whatever context. This is best demonstrated using an example: my $x = grep { ... } @list; # returns count my $x = whatever grep { ... } @list; # the natural context for # grep is array, no matter what the context really is The usefulness of such a construct is two fold: a. creating large anonymous structures with nested references or scalar values without having to think (== good for when you are evaluating a fucntion ref and you don't know what it is, but you want the natural value to be returned). b. writing eval bots and interactive shells: (whatever eval $expr).perl; ;-) -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgp6fwdJ39afS.pgp Description: PGP signature
Re: replacement of $
On Sun, Apr 02, 2006 at 02:04:07 +0300, Larry Wall wrote: ^^^-- (actually that was IDT in the headers) Hi, I'm in Israel and Japan at the same time! Nice one though ;-) plugIf you guys would have participated in the keysigning parties.../plug -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpAaFxAF3CvE.pgp Description: PGP signature
'temp $x;' with no assignment
Hi, my $x = 5; { temp $x; # is $x 5 or undef? } # $x is definately 10 I think it should be 5 inside, because it makes it easy to write things like: my $x = 5; { temp $x++; # $x is 6 } # $x is 5 again and otherwise pretty much DWIMs, except from a historical perspective. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpqVi7l1FtDo.pgp Description: PGP signature
Re: 'temp $x;' with no assignment
On Mon, Mar 27, 2006 at 14:35:52 -0600, Jonathan Scott Duff wrote: On Mon, Mar 27, 2006 at 05:26:48PM +0200, Yuval Kogman wrote: How did $x become 10?!?!? :-) GHC has this lovely error: my brain just exploded I think Perl 6 should have a similar runtime warning about how it's usiong my short term memory for storage ;-) I think that if Ctemp is the new Clocal, then immediately after the Ctemp $x line, $x should hold whatever flavor of undef is appropriate. snip Is there some reason we're huffmannizing snip Because 90% of the code that people use local for in perl 5 is for counting levels and automatically unwrapping them. The other 10% are for more complex values. -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpuO2LOJefPG.pgp Description: PGP signature
Re: 'temp $x;' with no assignment
On Mon, Mar 27, 2006 at 14:54:05 -0600, Jonathan Scott Duff wrote: Make me believe your 90/10 numbers. http://cpansearch.bulknews.net/ is broken right now... =( -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpCMeQfldQFY.pgp Description: PGP signature
where will we die to?
on the #catalyst channel today we had lots of pains debugging where a die will go to eventually, within a cascade of eval { }s and what not. In Perl 6 one thing that could ease this is to be able to easily know where we will die to, without having to walk the stack and checking which scope entries have a catch block. The other thing is to be able to trace an exception: if we have 'die foo but traced' then the exception should print cought at rethrowed as it's doing that. This second thing is much harder for me to pretend to implement -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me tips over a cow: neeyah!! pgpv0ddyWDvMt.pgp Description: PGP signature
Re: where will we die to?
On Thu, Mar 23, 2006 at 08:14:03 -0800, Larry Wall wrote: On Thu, Mar 23, 2006 at 02:27:07PM +0200, Yuval Kogman wrote: How else would you implement it that doesn't impact performance? One of the main reasons for having exceptions is that they're exceptional, and should be pessimized with respect to ordinary code. Having to write a stack introspection routine is not that big of a hardship. Oh, i mean without *manually* walking the stack - present some standard library function like 'caller()' but only for catching frames. This is purely a usability issue... Perhaps Perl 6 should ship with some core modules for development, with this general stuff in place? For example, a help() function, like Python has, things like Devel::DumpVar, Benchmark, Test::WithoutModule, a profiler, Devel::Loaded and other such introspection shortcuts, Devel::SymDump, and even yours truely's Devel::Sub::Which (which will just be a quick hack with the MOP introspection) and Devel::STDERR::Indent ;-) These tools should be useful for writing/hacking the compiler toolchain itself - that is they should operate both within a runtime, and if possible, on the intermediate representations as well. Maybe have the debugger .wrap all CATCH blocks? That sounds nice -- Yuval Kogman [EMAIL PROTECTED] http://nothingmuch.woobling.org 0xEBD27418 pgpb1i4cgMp0u.pgp Description: PGP signature
RFC - weird stuff I had to do (for fun or profit)
Hi, In light of the Perl 6 community's increasing interest in API level design, I'd like people to share old war stories about things they had to do once, but had to jump through hoops to pull off. The point of this excercise is the edge cases of the existing perl builtin functions and core modules can be revisited and maybe better designed. Please reply to this thread with your tales of glory (or failures, and the reason they failed). -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me climbs a brick wall with his fingers: neeyah! pgpTBZ0KCZLiF.pgp Description: PGP signature
Re: RFC - weird stuff I had to do (for fun or profit)
I have two stories related to files. I'll start with the failure: I wanted to write a Test::Harness wrapper that would monitor all the files/directories that the .t files of my test suite opened, and when they change to rerun only the affected tests. I am still planning on hacking this unportably using fs_usage on OSX and strace on linux, using FAM or whatever as the monitoring backend, but i would much rather have a mechanism like LD_PRELOAD for perl, with which i could add fancy hooks for IO operations without resorting to deep magic. The second story is abou Devel::FIXME. Devel::FIXME installs a subreference in @INC, that is always triggerred first. Then it recursively re-requires the file that was asked for, and this time when the callback is triggerred it pretends to fail. When it finds the file using the normal require, it will then read the file line by line, and report all FIXMEs using a cool api to filter unwanted ones. It then has additional boilerplate code to fake the success of an included module. Luckily all require return values are passed in scalar context so I didn't have to worry about *that* ;-) Audrey subsequently told me about the (undocumented) feature that lets you *return* a subroutine ref from a subroutine ref in @INC, that lets you get the source of the file that was normally found line by line for filtering. THat's what Acme::use::strict::with::pride, but I didn't know of it at the time. It's still pretty brutal ;-) Conclusions: I would have been happier if I could have a nice hook interface with which i could trap both module includes, and all IO operations and insert my own magic into the mess to aid me in my *DEVELOPMENT* process (not production related at all =) -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me sneaks up from another MIME part: neeyah! pgp61QjerriQA.pgp Description: PGP signature
Perl 6 design wiki?
I think Perl 6 could use a wiki for several things: 1. creating a place where people can easily find user annotations of the synopses etc 2. scratch pad areas for people to write musings, criticism, discussion and so forth in a way that the community can revise. This complements theh discussion process as carried out on the list because it's not time oriented - people can stumble upon a wiki page at a later date more easily than they would find mailing list archives. 3. a collection of idioms, patterns, ideas, style guides, reccomendations, translation info and so forth - the less formal documentation of a language, if you will. Pugs has example code, some quick start guides, and a few other nice things in it's repository, which are not pugs specific in any way. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpgWg32oL25C.pgp Description: PGP signature
Re: Separate compilation and compile-time things
One way to think of your macro example (instead of the -import one, which is harder to define, i think): Every time you use a module it's used by the compiler, and by the emitted code. The compiler loads the macros, the emitted code loads the non-macro stuff. Since the clsoure is created in the compiler's runtime this is slightly consistent ;-) -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me supports the ASCII Ribbon Campaign: neeyah!!! pgpmGMthxUDLd.pgp Description: PGP signature
Re: Separate compilation and compile-time things
On Thu, Mar 02, 2006 at 15:13:07 +0200, Zohar Kelrich wrote: We were discussing some confusing macro behaviours, when we came upon this curious thing. This code is really simple in p5, as it doesn't really have separate compilation, but in p6, the modules can be pre- compiled or cached. 8-- module ImportHeadache; my $m; sub import() { $m++; } sub report is export { $m }; sub deport {...} #-- Meanwhile, elsewhere! module Elsewhere; use ImportHeadache; # I'm calling import at Elsewhere's compile time! #-- Meanwhile, another elsewhere! module Elsewhere2; use ImportHeadache; # I'm calling import at Elsewhere2's compile time! #-- Main program use v6; use Elsewhere; use Elsewhere2; use ImportHeadache; say report; # What should I say? --8 The result is, of course, (1..3).pick(), depending on whether the modules were compiled by the same compiler instance at the same time. Perl 6 is specced such that it's always separate compilation, so this should probably always be 0, unless you're tying the value to disk. The way it's handled: $m is reallocated every time a module is used, and thrown away after it finished compiling. Then the resulting code will be linked, after $m was garbage collected. This code can be relinked as many times as we want. The problem seems to be that we have statefulness that we expect to survive compilation boundaries. Well, Perl 5 didn't have such boundries =) All statefulness in Perl 6 is not saved. Values and code are dumoped, and will be loaded on every link. This means that this does not get saved back to disk. This also means that linkage could be cached. So, should each compilation unit get a fresh environment? Or should this simply work like I think it currently does, and just hopefully not bite people too often? Should doing what this is trying to do be possible in a different, longer-huffmanized way? I think separate compilation is more consistent - it allows much -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me tips over a cow: neeyah!! pgpvcXIoJdS3m.pgp Description: PGP signature
Re: A proposition for streamlining Perl 6 development
On Wed, Feb 08, 2006 at 12:37:05 -0800, chromatic wrote: On Tuesday 07 February 2006 23:55, Yuval Kogman wrote: Does this imply that we should think up this process? Go ahead. We'll start at the Israel hackathon, with a little preamble. The last time someone tried to set forth a complete specification in a particular order was the Perl 6 documentation project. That didn't work then. I doubt it'll work now, either... Here is my reply on #perl6 to your discussion on Perl 6: My reply: http://colabti.de/irclogger/irclogger_log/perl6?date=2006-02-09,Thusel=11 Your discussion: http://colabti.de/irclogger/irclogger_log/perl6?date=2006-02-08,Wedsel=348#l558 I have doubts that specifying a complete compiler and toolchain without at least some trial and error will work, but I could be wrong. Trial and error is always required, and a very good tool for innovation in the hands of the community. I don't think Big Bang design is ever good, but I also believe a rough plan with easy to understand milestones (as opposed to a daunting cliff) are required, even if not formal or even on paper. Also, I am trying to formulate a plan that will help us write most of the parts in Perl 6, *NOT* Haskell, because I, like you, despite my love for Haskell, think it's just too inaccessible. What I'd like is to optimize the modularization such that Pugs serves as a bootstrap parser/interpreter/compiler - a good solid tool to help us write: The Perl 6 standard library in Perl 6 (with stubs for IO, system calls, and other things that cannot be defined in a pure language) The Perl 6 compiler toolchain in Perl 6 (the linker, compiler, emitters, and an interpreter, too). And then eventually refactor the current state of pugs into a haskell runtime, and and possibly a historical parser/compiler that we can use to compare things to. The way things are headed now, we are just shy of being able to write good tools in Perl 6 using pugs - it's too slow, the object model is not finalized, the grammar is not extensible, etc etc. These are many things that are mentioned in the synopses but not described in enough detail, and if we want the other parts to be in Perl 6 we need these done in haskell first, and then rewritten. If we get them later, we'll have to write the other parts in haskell too. Maybe the right place to start is to gather a list of all of the questions you need to have answered and all of the features people want, and then try to unify them into a Perl 6-ish whole. Yes, that's an excellent start, and in fact, I think this is what Audrey plans on starting with at the prehackathon, when she arrives in Israel and works with Gaal. Unfortunately for myself, I will be unable to follow this discussion as of ~14:00 GMT, today (Feb 9th) as I'm going to visit my grand parents in Austria, and try not to die while snowboarding. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me tips over a cow: neeyah!! pgpat242mSYfq.pgp Description: PGP signature
Re: A proposition for streamlining Perl 6 development
I'd like to have a crack at rephrasing this, since everyone but stevan seems to be getting the wrong impression. Perl 6 has some hard to answer questions. The questions the community has answered so far are: * How the VM will work/look * What the syntax/feature requirements are If we ignore pugs for a second. These are though questions to answer, and I have no criticism whatsoever that they took long to answer. Development speed is *NOT* what this post was about. What I do think is that there is something in the middle of these two big questions, and they are: * How will the Perl 6 compiler be designed (parts, etc) * What are the definitions of some of the standard features mentioned in the Synopses ( S29 is a good start, but we need more than the standard perlfunc) If we let Perl 6 continue to grow organically we will have answers to these questions, but we will likely invest lots of effort in trial and error. I think that some of these questions can be answered based on some up front design, thinking, and decision making, thus helping us direct our trial and error efforts towards a more defined goal. Furthermore, I think this has important implications on the quality of the implementation of the Perl 6 compiler and standard library, and that we should start worrying about that too. The second (much larger) part of the post contains a sort of draft, if you will, of what I think can be a good start towards trying to answer these questions. Thanks -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /methinks long and hard, and runs away: neeyah!!! pgpHSuE6cygmL.pgp Description: PGP signature
A proposition for streamlining Perl 6 development
is to try and separate the parts even more - the prelude is a mess right now, many of it's part are duplicated across the backends, the standard library that is mashed into the prelude, and into pugs core itself, etc. After this step I think the multiple backend approach should be refactored heavily to share as much code as possible, in accordance with the plans I posted (confusingly termed Circular Prelude stuff back then, see also VM support listed above). The biggest missing component of the compiler is: self hosting grammar, real macro support all the way down, a linker (the groundwork for this has improved with the new lexical importing code lately), and type checking. The Perl 5 compatibility layer: an additional deprecated library that emulates the Perl 5 standard library which wasn't absorbed into Perl 6 the perl 5 to perl 6 converter Integration with Ponie to enhance code reuse Additional criticism: Right now the biggest problem in Perl 6 land is project management. We, as a community, are facing a task which is sliced into chunks that are just way too big in my opinion. People burn out. People have to do things more related to day jobs (that's why my pugs hacking is on hold, for example), people think things half way, etc. If we have a layered approach we can concentrate on providing something that is more balanced ... Phew. Ciao! -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me spreads pj3Ar using 0wnage: neeyah!!! pgpkySSgvyN4A.pgp Description: PGP signature
Re: A proposition for streamlining Perl 6 development
I should note, as integral said, that this direction is generally being taken by pugs, now that PIR targetting is being worked out (finally) - i just think it needs to be more explicit and in tune with the @Larry. Also, the way pugs is refactoring implies nothing on refactoring and layering Perl 6's design, which I think is also important. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me does not drink tibetian laxative tea: neeyah! pgpQnTRA3i2ZH.pgp Description: PGP signature
Re: A proposition for streamlining Perl 6 development
On Wed, Feb 08, 2006 at 08:59:35 +0800, Audrey Tang wrote: On 2/8/06, Yuval Kogman [EMAIL PROTECTED] wrote: If Audrey is willing, I think a correct new direction for pugs is to try and separate the parts even more - the prelude is a mess right now, many of it's part are duplicated across the backends, the standard library that is mashed into the prelude, and into pugs core itself, etc. Er, of course I'm willing, that was exactly we've been moving toward in the recent weeks. :-) Though an explicit Standard Library design -- as compared to Perl5's which was grown out gradually by the porters and CPAN folks -- is tricky, and I'm not yet ready for that, lacking a practical understanding of how module interfaces and roles can be applied to this diverse design space. By standard library is i don't mean core modules - it's Perl 6's perlfunc + some really critical pieces. So I will be focusing on Prelude (the part of the language that always gets loaded by default) refactoring as well as providing an OO core calculus that can support this, and take advantage of the target VM's vast library instead of writing them in Perl 6, at least up until 6.2831 (the primary target VM is Perl 5, then Parrot, then JavaScript.) Aye =) -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me wields bonsai kittens: neeyah pgpvIhRiCE7cG.pgp Description: PGP signature
Re: A proposition for streamlining Perl 6 development
On Tue, Feb 07, 2006 at 18:51:03 -0500, David K Storrs wrote: So, to bring it down to brass tacks: there are 5 big chunks (S15, S16, S18, S21, S23) that remain to be be written, a 6th (S08) that needs to be written but will probably be fairly short, and 5 (S28, S30-33) that need to be compiled out of the mass of emails flying through the lists. I know that substantial progress has been in defining the semantics of all of these topics, and I have the impression that it's mostly a question of wrapping up the last 5-20% of each one, compiling all the data, and writing the Synopsis. I'd say that qualifies as light at the end of the tunnel indeed! The point I was trying to raise is that the Synopses are a very high level, top down angle on the language's design. They have *NOTHING* about any implementation details like: the design of the compiler the design of the runtime the design of the object space The layers of Perl 6 (what is an optional module? what is a macro (see also 'use')? what is the core essence of Perl 6?). Except implying that these things will be implemented in Perl 6, and will be somehow worked out. Now, I have no objection to this - the Synopses are sort of like requirement docs. But we do need something that's between where parrot is today, and a top down view of all of Perl 6 - and that's a lot of chunks. What I'm trying to say is that letting the part in the middle grow completely organically and ad-hoc is not a good thing, and that the pugs developers really have no authority as to making design decisions. We need those things to happen and they're getting overlooked, and in my opinion the first step into this is refactoring the design into several layers. Bottom line - there's much more than 5 missing chunks in the design, as I see it - designing the implementation is nontrivial. Also, none of the synopses are really 100% complete - S12 does not detail the meta model's methods and features, for example. The doc explaining macros does not detail what the AST macros get (the definition of the AST). Etc etc etc. These things are also important to implementation, and amount to a huge chunk of code. If we can layer this code, chunk it up, componentize it and make it clean we we can implement it more easily. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me groks YAML like the grasshopper: neeyah!! pgpLHOQziXsCg.pgp Description: PGP signature
Re: A proposition for streamlining Perl 6 development
On Tue, Feb 07, 2006 at 23:11:32 -0800, Allison Randal wrote: On Feb 7, 2006, at 19:21, Stevan Little wrote: Perl 6 will get implemented. Oh, of that I have no doubt. Never did, and neither does Yuval (if I may speak for him while he is asleep :). But all that we are trying to do here is shake out some cobwebs, a little spring cleaning if you will. Excellent. I wish you much fun! :) Does this imply that we should think up this process? If so, I have made many many contributions on this topic to perl6-language on this topic, and I feel like they have been mostly overlooked. If I propose a concrete plan for the implementation of Perl 6 in a layered fashion it will probably be even more overlooked. I have no authority, and this is not something I can do on my own. I am asking for your (all of you) help in clarifying the big void in the middle - the design of the perl 6 runtime, not just syntax/features. What I'm suggesting is a start in this clarification - trying to componentize the existing syntax/feature spec that we do have, so tha the design of the runtime can be simplified and more concrete/attainable. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me does not drink tibetian laxative tea: neeyah! pgp7l1B9MmXgY.pgp Description: PGP signature
Universal Roles, and deriving these roles for any class
Background: At work we have a big C++ project. I just added a new object, and now $boss asked me to add the send/receive interface. These two methods allow an object to be serialized to and from a stream. Essentially it means // superclass methods for core types sendInt(int_member); sendString(string_member); // all object members need to also inherit Serializable obj-send(socket); and receiveInt(int_member); receiveString(string_member); obj = new Object(); obj-receive(socket); etc for each member, in the right order with the right type. This is a dump example since we just do .perl, but let's say pretend for a moment that we don't. Perl 6 has some advantages over C++ that make this trivial (or so I hope): * a meta model (iterate attributes, know their type, etc) * roles (no need to inherit Serializable, this is a bit cleaner) * attitude (this is up for discussion ;-) I'd like to be able to declare my serializable role as a univeral role. This basicaally means: role Serializable { method send ( Stream $fh ) { # iterate all attrs my Serializable $attr = $?SELF.meta.get_attr; ... } method receive ( Stream $fh ) { # iterate all attrs ... } } # core types Num does Serializable { method send ( Stream $fh ) { $fh.print( $?SELF ); } } and then to never say that any class does it. Instead, i'd like to have a duck typing like approach: my Serializable $x = Monkey.new(); # or my $x = Monkey.new but Serializable; # and then $x.send( $socket ); # no ambiguity And then I'd like to have these features: * Have type inferrencing type check the send and receive methods * have it automatically infer that all the attrs of Monkey are also Serializable, due to the fact that send iterates them and declares that * get nice errors that tell me that Moneky can't be Serializable because the member $stream deep inside an object within Monkey (for example, if Anus has Stream ;-) is not Serializable, nor can the Serializable role be automatically applied to it because it has opaque internals. This probably makes more sense for other interfaces. This also reminds me a bit of attribute grammars - i'd like to be able to automatically derive node roles inside AGs by just specifying a generic universal behavior, and behavior for the leaves. Err, comments please =) -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpbl8D1sTOqm.pgp Description: PGP signature
Re: Macros?
On Sun, Jan 29, 2006 at 18:53:25 +, Herbert Snorrason wrote: Perl6 will have macros. Good. Cool. But, sadly, that seems to be close to the most specific thing anyone says about the subject. There is some further discussion in Apocalypse Exegesis 6, but nothing in the Synopsis. Now, considering that macros are a language feature and that the Synopses are presented as the language spec, I wonder if there shouldn't be something there. Exactly what, though, I won't pretend to know. :) Basically the plan is that when an internal AST language is decided upon, the macros will be able to get either the source code text, or an AST. Then the macros have to emit butchered text, or butchered ASTs. Aside from that they are normal perl 6 subroutines, that simply get invoked during compile time instead of during runtime. The AST language (maybe it'll be PIL based) is not yet final, so there's not much to say. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me climbs a brick wall with his fingers: neeyah! pgpjt66A0JBma.pgp Description: PGP signature
Re: Macros?
On Sun, Jan 29, 2006 at 20:29:43 +, Herbert Snorrason wrote: On 29/01/06, Yuval Kogman [EMAIL PROTECTED] wrote: Basically the plan is that when an internal AST language is decided upon, the macros will be able to get either the source code text, or an AST. Two things. First, if the AST path is taken, doesn't that mean that the AST representation has to be compatible between implementations (assuming there'll be more than one)? Yes. Secondly, there's ease of use. ASTs are, at least from what I've seen, pretty verbose. Aren't we trying to make things easy for the programmer? With source text, doing manipulations by hand can be a bother, so that's no solution either... Maybe I'm spoiled by the idea of s-expressions, though. But I get the impression that lispy macros are where the idea comes from... Well, the aim is to get something as nice as lisp macros. Hopefully the AST will be easy enough to chew with the tools provided in the language. Remember, however, that this is not a parse tree, and is thus somewhat simpler. BTW, do we also support parse trees? -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me sushi-spin-kicks : neeyah pgp2T1llLenSI.pgp Description: PGP signature
Re: facades, use_ok, and lexical export
What we need to do is find a way to do this at compile time. One way is to make use_ok a macro. The whole thing with linkage in Perl 6 is that it's supposed to happen at compile time so that things are overall saner, but that it can happen at runtime if we really really mean it. use_ok as a function could simply import $module into the non lexical scope because it's a runtime thing, unless it's made into a macro/some other compile time construct, that is more declarative in nature, and makes the whole process more opaque. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me whallops greyface with a fnord: neeyah!!!
Re: Perl grammar for Perl5 - Perl6
On Wed, Dec 07, 2005 at 16:48:11 -0500, Peter Schwenn wrote: Dear Perl6 Language, I am Perl user from near year 0. For me the easiest way to learn (, track, and get to the point of contributing to) Perl6 would be a Perl grammar (a regex rule set in, preferably, Perl6) that transforms any Perl5 script into a Perl6. Of couse, besides learning Perl6 for a regex'r or Perl5'r such as myself, and tracking, and documenting 6, it would have huge use for Perl5 users making or considering the transition. IMHO machine translation is not that good a way to start learning - the real benefit of Perl 6 is in the features which have no perl 5 equivalents and solve problems much more elegantly. The best thing to do is to hang out on #perl6 and get involved with the test suite, as well as reading the synopses. Perhaps writing a toy program or something like that could also help. For example one can infer the structure and some of the rules from http://svn.openfoundry.org/pugs/docs/other/porting_howto which is however written out in informal (not regex) rules such as $array[idx] - @array[idx] These are rules for humans with lots and lots of context info... Furthermore, they are more of a perl 6 gotcha list, for perl 5 programmers than a translation guide. Is there such a Perl5-Perl6 translator underway? Larry Wall is working on using the perl (5) interpreter to create compiled output (as opposed to just something that executes in memory) that can then be read by a translator without actually parsing perl 5. Before this happens this will be very very hard - the high level language has vast amounts of implications on execution etc, but the opcode tree is much more simpler to predict (for a computer). p.s. The developing form of such a grammar could likely lead to a grammar package which facilitates rule sets for languages in other domains, in terms of illuminating means of choosing among modes for rule ordering, collecting, scoping, re-application, recursion, exclusion and so forth. Since perl 5's actual parser and tokenizer will be used for this it won't be very extensible, but this is important because perl is reallly hard to parse. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me supports the ASCII Ribbon Campaign: neeyah!!! pgpnA5re5zZw2.pgp Description: PGP signature
Re: Capabilities in Perl6?
On Thu, Dec 01, 2005 at 10:54:14 -0500, Rob Kinyon wrote: I just read the slides about CAPerl (http://caperl.links.org/) and it's an interesting idea. The ideas I tossed around regarding the circular prelude should make perl 6 be roughly on the same level as javascript in terms of this security stuff. This is a very good start towards a model where a crippled runtime is mixed with a fully priviliged one, with grey areas in the middle. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpyPn2eh2Y9e.pgp Description: PGP signature
Re: Classification syntax [Was: Renaming grep]
On Fri, Nov 18, 2005 at 11:36:33 -0800, Larry Wall wrote: If we had some kind of partitioning operator, it'd probably be generalized to sorting into bins by number, where 0 and 1 are degenerate cases for booleans. But since we'd almost certainly make the general form (@bin0, @bin1, @bin2...) := classify { calc_int($_ } LIST; For me it seems to make more sense that in the higher-order scheme of things classify presents functions to it's body. Instead of relying on the return value from the body, it gets a number of functions that it can invoke to append a function. This is more general since it allows classification to include duplicates. Grep is simply: sub grep (filter, [EMAIL PROTECTED]) { classify - $x, f { f($x) if filter($x); } [EMAIL PROTECTED]; } -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me does not drink tibetian laxative tea: neeyah! pgp0EJd1MZfCg.pgp Description: PGP signature
Re: Role Method Conflicts and Disambiguation
On Wed, Nov 02, 2005 at 16:37:29 -0600, Jonathan Scott Duff wrote: On Tue, Nov 01, 2005 at 04:02:04PM -0800, Jonathan Lang wrote: True enough; but it needn't be true that d have the same tools available to resolve the conflicts that c has. There are three ways that a role can deal with a conflict: 1. choose one of a set of available methods to call its own. 2. create a version of its own. 3. pass the buck. In the first case, the question is how we define the set of available methods: do we make the full hierarchy of ancestors available to the role, or do we say that only the immediate parents are available? People keep using the word hierarchy when talking about roles and I keep thinking that it is the one word that definitely does NOT apply. Heirarchies are for classes and inheritance relationships, not roles and composition. Uh, roles are composed wrt to the hierarchy of who does who. In my world view, a role that is composed of two other roles has full view of the methods/attributes defined in the roles that compose it because the landscape is quite flat. There are no hills and valleys. When it finally comes down to composing into a class, the class sees all of the methods/attributes provided by each and every role even the role inside a role inside a roles. The composition is basically mixin with some exceptions, but there's still a hierarchy roles A and B are composed into C at compile time. If both A and B define a method foo(), then there is a conflict (immediately, at compile time) unless you've somehow told perl that it should defer composition until it's actually composing classes. Class composition also happens at compile time... There's no reason to make the error occur too early for usefulness to be around. As long as it's not too late ;-) -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpABuzitn7pL.pgp Description: PGP signature
Re: Role Method Conflicts and Disambiguation
On Fri, Oct 28, 2005 at 14:19:46 -0400, Stevan Little wrote: Yuval, On Oct 28, 2005, at 10:59 AM, Yuval Kogman wrote: On Thu, Oct 27, 2005 at 22:19:16 -0400, Stevan Little wrote: Now, at this point we have a method conflict in suspension since (according to A/S-12) method conflicts do not throw an error until a role is composed into a class. This means that when I do this: class MyClass does FooBar {} an exception is thrown. Unless of course MyClass has a foo method, which will disambiguate the conflict. My question then is, can FooBar (the role) disambiguate the foo conflict? IMHO yes, but it doesn't have too. It should be able to leave it to the class to decide. If we allow the class to decide if things break or not, then we potentially allow for the system to be in a very unstable state. A method conflict means that neither method gets consumed, and at that point we have a gapping hole in our class. And compilation will not finish unless the class plugs the hole... role a; role b; role c does a does b; class d does c; If there is a conflict at c, it might be a conflict that c knows how to resolve, or it might be a conflict that c's documentation says the user has to decide on, depending on what they prefer. What I'm saying is that the hole in c can be consumed by d, and if it isn't plugged in either c or d, you get an error. I think it's useful from a role perspective, because that way you can let the user decide on some conflicts. While I can't think of an example, I don't think there is much risk - this doesn't take away functionality. The only issue is that you can compile a role with a conflict and it doesn't complain till you actually use the role (this should be taken care of by writing the simplest of tests for your role). It does open doors for higher complexity composition. Especially if you have a deep hierarchy of role consumption: a b c d \ / \ / e f \- g -/ (role g does e does f, e does a, does b...) Let's say that a and b conflict at 2 points. E can resolve one of them, and leave the other one for g to decide. Perhaps methods in f are used to resolve e with dynamic dispatch: role g does e does f { method conflicts_in_a_and_b ($arg) { given .method_from_role_f($arg) { when Condition { .a::conflicts_in_a_and_b($arg) } defualt { .b::conflicts_in_a_and_b($arg) } } } } This is, IMHO legitimate use. The only restriction should be that when runtime begins no class (or anything that can be instantiated) is allowed to still have a conflict.; In the end, we will have probably looked inside every method defined in Foo, Bar, FooBar and Baz in order to properly write MyClass2. IMHO, this is sort of defeating the usefulness of roles at this point. I disagree - you have to know what a role is actually giving you to exploit it. Too much black boxing makes your programming language seem like a Kafka story. Why? does it introduce bugs? ;-P If you can't see at all into the code you use you eventually run into problems like the shlemiel the painter algorithm for C strings (google to find refs for that, too long to explain here). Frequently when using library code whose documentation is not perfect (and in opensource almost no documentation is ever perfect) I have a great privilige - search.cpan.org has a one click path to seeing the source code of any module i'm considering to install. This allows me to see how something works, estimate how hard it will be to extend it if the need should arise, assess the quality of the code, and make sure I understood things correctly. This spirit of openness should be maintained. You don't have to take apart a role and recompose it and what not, breaking encapsulation. But you should be able to fudge it slightly, because the author of the role might not be getting paid to fix it to your needs, and you may have to get slightly hackish. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me whallops greyface with a fnord: neeyah!!! pgpVo7ZfRizkn.pgp Description: PGP signature
Re: Role Method Conflicts and Disambiguation
On Thu, Oct 27, 2005 at 22:19:16 -0400, Stevan Little wrote: Hello all, I have a question about method conflict resolution works for roles, and I cannot seem to find this in any of the Apoc/Syn documents. Here is the basic issue: role Foo { method foo { ... } method bar { ... } # we will use this later :) } role Bar { method foo { ... } } role FooBar { does Foo; does Bar; } Now, at this point we have a method conflict in suspension since (according to A/S-12) method conflicts do not throw an error until a role is composed into a class. This means that when I do this: class MyClass does FooBar {} an exception is thrown. Unless of course MyClass has a foo method, which will disambiguate the conflict. My question then is, can FooBar (the role) disambiguate the foo conflict? IMHO yes, but it doesn't have too. It should be able to leave it to the class to decide. role FooBar { does Foo; does Bar; method foo { ... } } Now, on the surface this seems obvious, of course the FooBar role should be able to disambiguate. However, when we expand the example other issues show up. role Baz { does Foo; } class MyClass2 does FooBar does Baz {} # Will this die? splice But thats not all, we have a potential problem with foo again. Baz will provide foo from Foo, but FooBar will provide it's own foo (which we used to disambiguate). So our disambiguation is not ambiguated again. /splice yes, since the methods are coming from different context, and they may have different meanings. While FooBar::foo resolves the conflict from the assimilation of Foo::foo and Bar::foo, it does it only within FooBar. If, OTOH we have a diamond inheritence: role A { method foo { ... } } role B does A {}; role C does A {}; class D does A does B { }; I'm not sure we need to resolve the conflict. Now, since MyClass2 actually does Foo twice, does that mean bar creates a conflcit? Since bar would be found through FooBar and Baz. I would think the answer here would be no, and that we would build some kind of unique list of roles so as to avoid repeated consumption like this. No conflict - an assimilated role is identicle to itself even through different paths since it doesn't get access to private or protected member data of it's consuming roles. If, on the other hand, we have role X trusts Foo does Foo { has $:foo; } role Y trusts Foo does Foo { has $:foo; } role Foo { method foo { $:foo++; } } class C does X does Y { } there is a conflict, because Foo is reaching into either X's private member $:foo or Y's private member $:foo (btw, they should never conflict with each other). The moment a method will have behavior that is different in two different role consumptions it will be conflicting, but this will only happen to a method from the same class if it has some private symbols resolved at role composition time using class friendship. I think it is ambiguous, s A (deceptively) simple solution to this is that MyClass2 needs to disambiguate. But this means that our roles are not really black boxes anymore. In order to properly disambiguate this we need to know where all the foo methods are coming from (Foo, Bar and FooBar), and potentially what is inside these foo methods (especially in the case of FooBar since it is attempting to disambiguate, it's behavior could be very specific). It probably would also become important to know what other methods foo interacts with since we potentially have 3 different expected versions of foo. method foo is Foo::foo; or method foo (*$a) { ./Foo::foo(*$a) } or foo ::= Foo::foo; In the end, we will have probably looked inside every method defined in Foo, Bar, FooBar and Baz in order to properly write MyClass2. IMHO, this is sort of defeating the usefulness of roles at this point. I disagree - you have to know what a role is actually giving you to exploit it. Too much black boxing makes your programming language seem like a Kafka story. So what do you all think?? Role method conflicts should only be dealt with if the user knows what the roles are actually doing anyway. This will probably be familiar code, and if not it warrants familiarity. I don't think we can let the user use library code without being aware of the library code internals at all. Abstraction that works like this is usually either crippled or useless. 90% of the time you don't want to know, but there are exceptions. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me sushi-spin-kicks : neeyah pgpuXeiEdVhEc.pgp Description: PGP signature
Re: Role Method Conflicts and Disambiguation
On Fri, Oct 28, 2005 at 10:38:31 -0500, Jonathan Scott Duff wrote: You mean composition. There is no role inheritance :) Oops ;-) I'm assuming you meant class D does B does C { ... } I always do that crap... =( I'm not sure we need to resolve the conflict. It depends on when composition happens. If A is composed immediately into B and C as soon as the role is processed, then when D is being composed, all it sees are a foo method from the B role and a foo method from the C role. If, however, roles aren't composed into other roles but only into classes, then I think that class D does B does C { ... } would be equivalent to class D does A does B does C { ... } since the roles B and C would carry the uncomposed A role along with them. I think of class inheritence (mixin or otherwise) as an N-ary tree with ordered branches. That is, if you inherit two classes, one comes after the other. Roles differ because the tree is unordered and all roles assimilated into a specific consumer must be treated equally (and will thus conflict). This allows roles to be more reusable than classes for generic tasks, because if there is a conflict it usually implies namespace clashes, not extended behavior. Making everything into flattenned set is not a feature. It can be the way things are really implemented later, but it's a lossy representation - information about who 'does' who is lost. In my opinion it's better to compose all role information in the largest chunks possible (read - as late as possible in a given linkage/compilation cycle) for the same reasons that JIT optimizations are more effective: you know much more. However, care must be taken to ensure that this is not too late, to the point that the user does not get useful information. Quoth A12: 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. We can always relax that later if, after many large, longitudinal, double- blind studies, it turns out to be both safe and effective. Has that changed? Also, I don't think that role is something that can be trusted :) A12/S12 only talk about trusting classes. The role doesn't grant trust to a class that consumes it - it simply says the role Foo has access to my guts when I assimilate it. Class trust is something slightly more complex, since it's inherited. I think that excert says It's not clear whether roles should be allowed to make a class trust another class when they are consumed. there is a conflict, because Foo is reaching into either X's private member $:foo or Y's private member $:foo (btw, they should never conflict with each other). Er, there is only one $:foo. X doesn't have any private members, nor does Y (because they're roles). Only C has private members. So, modulo the multiple composition of Foo, I don't think there's a conflict. Really? I didn't know that... In that case roles are broken... They will need instance data (that doesn't conflict when it's private) to support the methods they give their consumers. Is there any good reason to not allow roles to introduce member data into a class? -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me whallops greyface with a fnord: neeyah!!! pgp1rNFr6EZDh.pgp Description: PGP signature
Making Wrong Code Type Wrong
with his examples later on. Here's an excert of Joel's article: In Excel's source code you see a lot of rw and col and when you see those you know that they refer to rows and columns. Yep, they're both integers, but it never makes sense to assign between them. There is a real benefit to be gained here, but the usability of e.g. int formatting functions should not be hindered by overzealous typing. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me has realultimatepower.net: neeyah pgp0aSpBeHuHF.pgp Description: PGP signature
Re: Making Wrong Code Type Wrong
On Tue, Oct 18, 2005 at 21:04:02 +0200, Juerd wrote: Yuval Kogman skribis 2005-10-18 20:38 (+0200): the function encode has the type Unsafe - Safe I read the article before. What occurred to me then did so again now. What exactly do Unsafe and Safe mean? Safe for *what*? That was just a naive example - the words Unsafe and Safe are user defined, and are chosen on a case by case basis in their app. One problem still is that once something is encoded, quoted or escaped it can't always be easily re-encoded. Encoding functions should therefor check if a variable does safe::(none()) and warn or fail if so. I don't see how this relates to the OP, or why encoding functions should implement it like this. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me sneaks up from another MIME part: neeyah! pgpt9EIUEZ61e.pgp Description: PGP signature
Re: Should roles and classes be merged?
On Fri, Oct 14, 2005 at 09:08:45 -0400, Rob Kinyon wrote: couldn't fix it in my head why there were two separate concepts. The difference between a class and a role is in the eyes of their consumer - the way in which a class gets new behavior (inheritence, mixin, or role composition style) is fundamentally the thing that determines whether the consumed thing is a class or a role. Ofcourse, to encourage correct use of a consumable unit of behavior, one can use class or role. However, there is more to it, conceptually - roles make much more sense when parametrized over other types, while classes make more sense unparametrized, due to the way they are used. Last I heard there only roles were allowed to be parametrized, but there really isn't any technical difference between classes and roles in this respect either. Frankly I think that classes make just as much sense when parametrized, but i don't really mind parametrizing roles that are really classes to make anonymous classes. This way it is clear that there can never be uninstantiatable classes around. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me kicks %s on the nose: neeyah! pgpSXywhAFpZI.pgp Description: PGP signature
Book RFC - Migrating to Perl 6
I'd like to start by saying DON'T PANIC! I'm not going to write a book on Perl 6 ;-) Luckily we have people with much more enlish-fu, structured-thought-fu, and general get-it-done-fu... Now let's talk a bit about them: Today Geoff Broadwell raised a book idea for discussion on #perl6. The result was this wiki page: http://pugs.kwiki.org/?MigratingToPerl6 Essentially Geoff's idea was that the book will come out around the same time as Perl 6.0.0, and will be the guide for perl 5 programmers looking to swallow the Perl 6 pill as easily as possible. The wiki page illustrates how we think it will be structured, and how we think it should be written. Please post feedback and criticism on the list, #perl6 or the wiki page. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpeiR4qHQZMr.pgp Description: PGP signature
Re: Closed Classes Polemic (was Re: What the heck is a submethod (good for))
On Wed, Oct 12, 2005 at 13:08:27 -0700, chromatic wrote: Closed classes should not exist. At least, they should only exist if the person *running* Perl 6 wants them to exist -- never if merely the class writer wants to close them. In theory I agree, and I hope that will be the defacto way of doing it, but if perl 6 gets compiled portably to many different bytecodes (which it seems like it will) someone somewhere will write a backend which allows people to encrypt, and people will use it. I think this is something we need to accept, even if it isn't something we like. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me sneaks up from another MIME part: neeyah! pgpDwgwZYGNe6.pgp Description: PGP signature
Re: What the heck is a submethod (good for)
On Thu, Oct 13, 2005 at 05:42:31 +1000, Damian Conway wrote: Luke wrote: Okay, I seriously have to see an example of a submethod in use. class Driver::Qualified { method drive { print Brrrm brrrm! } } class Driver::Disqualified is Driver { submethod drive { die .name(), not allowed to drive } } class Driver::Requalified is Driver::Disqualified {} This is not obvious that the behavior is modified, and it makes other subclasses, like Driver::Disqualified::Drunk and Driver::Disqualified::Suicidal causes the above design choice to make you either update Driver::Requalified and Driver::Disqualified to regular methods, or duplicate code in Driver::Disqualified::*. That much aside, this is not a real world example. Can you try to think of one that really applies? Looking at my past $work projects I can't think of a single instance where submethods would help me code better. On the other hand roles mixin inheritence, private attributes that don't conflict with other private attributes of the same name, better polymorphism, better introspection, and a metamodel could have helped a lot in many places. This has even more implications with closed classes to which you don't have source level access, and if this can happen it will happen - i'm pretty sure that some commercial database vendors would release closed source DBDs, for example. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpb15yuOsYCY.pgp Description: PGP signature
Re: Sane (less insane) pair semantics
On Sun, Oct 09, 2005 at 20:22:59 +0200, Ingo Blechschmidt wrote: Opinions? Yes! -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: *shu*rik*en*sh*u*rik*en*s*hur*i*ke*n*: neeyah pgpPtAVtx26AP.pgp Description: PGP signature
Re: Exceptuations
On Fri, Oct 07, 2005 at 02:31:12 -0400, Austin Hastings wrote: Yuval Kogman wrote: On Thu, Oct 06, 2005 at 14:27:30 -0600, Luke Palmer wrote: On 10/6/05, Yuval Kogman [EMAIL PROTECTED] wrote: when i can't open a file and $! tells me why i couldn't open, i can resume with an alternative handle that is supposed to be the same when I can't reach a host I ask a user if they want to wait any longer when disk is full I ask the user if they want to write somewhere else when a file is unreadable i give the user the option to skip I'm not bashing your idea, because I think it has uses. But I'll point out that all of these can be easily accompilshed by writing a wrapper for open(). That would be the usual way to abstract this kind of thing. Writing a wrapper may be the implementation mechanics: sub safe_open() { call; CATCH { when E::AccessDenied { return show_user_setuid_dialog(); }} } open.wrap(safe_open); But this is just one way to do it, and it fails to provide for helping other people's code: Yuval's GUI environment would offer to fix the problem for ALL file related calls (open, dup, popen, ad nauseum), and would not have to worry about the order in which calls are wrapped. But see below. Stylistically I would tend to disagree, actually. I think it's cleaner to use exception handling for this. Also, this implies that you know that the errors are generated by open. This is OK for open(), but if the errors are generated from a number of variants (MyApp::Timeout could come from anywhere in a moderately sized MyApp), then wrapping is not really an option. I think that what your proposal *really* requires is uniformity. There are other ways to get the same behavior, including an abstract factory interface for exception construction (would provide virtual constructor for exceptions, so permitting userspace to insert a 'retry' behavior), but it has the same vulnerability: the p6core must cooperate in uniformly using the same mechanism to report errors: throw, fail, die, error, abend, whatever it's eventually called. We have: die: throw immediately fail: return an unthrown exception, which will be thrown depending on whether our caller, and their caller - every scope into which this value propagates - is using fatal. This is enough for normal exception handling. As for recovery - the way it's done can be specialized on top of continuations, but a continuation for the code that would run had the exception not been raised is the bare metal support we need to do this. Where this gets taken further by (IMHO overly abstract) exception handling libraries and standardization is a question that application development kits (e.g. Catalyst, GTK, Cocoa) must develop a policy for. return recover_from_error([EMAIL PROTECTED]) what does this do? -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me beats up some cheese: neeyah! pgp3FUsw93RD9.pgp Description: PGP signature
Re: Exceptuations
On Fri, Oct 07, 2005 at 05:23:55 +0100, Piers Cawley wrote: 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. It doesn't really matter since 'fail'ed exceptions will simply be converted to a return with the continued value when resumed, and the question of outer/inner scopes is really irrelevant - it's like tail calls. As for die - since there is no implicit returning in die, it might or might not make sense to try and resume. However, for most situations it still looks to me like 'die foo' could be treated as return in a way. Essentially throwing an error means that the function/method who threw it is giving up since it doesn't know how to resume. If the exception handler can find an alternative for that function, and replace the value, it's immediate caller should get the fixed value, since they are the ones who need the value. Functions which delegate exceptions are, again, just like tail calls. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me wields bonsai kittens: neeyah pgpjB4t4GbwlH.pgp Description: PGP signature
Re: Type annotations
On Fri, Oct 07, 2005 at 12:42:01 +0200, Juerd wrote: For my Int $c = $float, though, I'd want coercion. And I think it is wrong to have such a huge difference between literals and values: if a variable coerces, a literal has to do so too. How do you tell the compiler this must never be a float, ever? There is a conflict between the usefulness of coercion and the usefulness of staticness, and I think we need to be able to express both. Perhaps we need two ways to type annotate: hard annotations - applies to assignment or binding lvalues, and states that the type must be an accurate subtype - no coercion is allowed at all. soft annotations - applies to assignment or binding lvalues, and specifies that the thing contained in it must always be of the annotated type, after the assignment. That is - a value must be coerced as a copy to enter this container if it's type doesn't match. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me sushi-spin-kicks : neeyah pgpT5DKCUCMHu.pgp Description: PGP signature
Re: Exceptuations
On Fri, Oct 07, 2005 at 10:28:13 -0400, Austin Hastings wrote: But the point is that resuming from an exception (or appearing to) is not bound to implemented with continuations. What's the point? Continuations are good for exactly this purpose. Parrot already supports them. I see absolutely no reason why we would want to implement this any other way but using continuations. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: *shu*rik*en*sh*u*rik*en*s*hur*i*ke*n*: neeyah pgpRP3mAuY8ah.pgp Description: PGP signature
Re: Type annotations
On Fri, Oct 07, 2005 at 12:50:09 -0700, chromatic wrote: On Fri, 2005-10-07 at 12:49 +0200, Juerd wrote: Ashley Winters skribis 2005-10-06 19:30 (-0700): my Array $a = 97; # dies eventually, but when? Runtime -- cannot coerce Int value to Array It is fully determinable at compile time. 97 will never be compatible with Array, so I see no reason to wait. If I added a multisub for Array assignment so that assigning an integer value set the length of the array, would 97 be compatible with Array? That's a compile time reachable analysis. If the compiler finds out that: a. no code will be evaled (due to 'use optimize' or just plain lack of require, eval etc in the code) b. there is no compatbile multisub then it should throw an error How about in unreachable code (which I do actually believe compilers can detect some of the time)? These errors should probably still persist, even if dead code is subsequently removed from the bytecode, because dead code can become undead code if certain things change (compile time foldable conditionals over e.g. $*OS are such a scenario) and the same program should be typed the same way everywhere for a given version of Perl. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me does a karate-chop-flip: neeyah!! pgpdHU54ECTW7.pgp Description: PGP signature
Re: Exceptuations
On Wed, Oct 05, 2005 at 13:00:55 -0600, Luke Palmer wrote: I don't think it was a how is this possible, but more of a what business does it have?. And as far as I gathered, they're saying pretty much what you've been saying, but in a different way. It's about the continuation boundary; that is, if you're outside a module, you have no say in how the module does its business. You can continue only at the module boundary, replacing a return value from its public interface. As I see it this is the usefulness of exceptions being handled by distant code. The code in the module inverts it's interface by calling code it doesn't know with a certain parameter, accepting a certain parameter back. That way encapsulation is not broken, but errors that happen deep inside a call chain can be dealt with by code that can interact with the user. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me climbs a brick wall with his fingers: neeyah! pgpmp8WUodYYB.pgp Description: PGP signature
Re: Exceptuations
On Wed, Oct 05, 2005 at 13:41:37 -0700, Dave Whipp wrote: Reading this thread, I find myself wondering how a resumable exception differs from a dynamically scropted function. Imagine this code: This is sort of like what I mean, except that there is no encapsulation breakage, since the interface is inverted. The advantage of this approach is that error handling code in a submodule can benefit from generic, reusable exception handling code that is provided by it's caller. temp sub FileNotWriteable( Str $filename ) { With an exception handler and continuable exceptions you don't have to know what the error handler is, or make sure that the module actually throws the error. The exception handler instead deals with the type of the exception in a generic manner (it doesn't care when the exception was actually generated). The module doesn't need to throw the error it just needs to fail (or delegate a fail), until the failure crosses into a 'use fatal' scope. That way both the catching code and the throwing code are reusable and orthogonal when they are unrelated, but the possibility of coupling handling code with throwing code is still there. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me groks YAML like the grasshopper: neeyah!! pgpzo38NCmZ47.pgp Description: PGP signature
Re: Exceptuations
On Thu, Oct 06, 2005 at 18:11:38 +0100, Peter Haworth wrote: 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. But then we gain nothing CATCH { when some_kind_of_error { $!.continue($appropriate_value_for_some_kind_of_error) } } That just gives me the willies, I'm afraid. Why? when i can't open a file and $! tells me why i couldn't open, i can resume with an alternative handle that is supposed to be the same when I can't reach a host I ask a user if they want to wait any longer when disk is full I ask the user if they want to write somewhere else when a file is unreadable i give the user the option to skip These handlers are progressively more knowlegable of the code they're dealing with, but they don't touch the actual guts - that's the whole merit of continuable exception, because otherwise you might aswell just start over. These are 100% reusable in the first exception handler, and not reusable but still applicable to an opaque call at the last handler. It doesn't matter who opens the file file, the exception handler will produce the same effect but in a different way. CATCH { when Error::IO::... { open ... } when MyApp::Timeout { ask_user_to_continue_or_abort(); } ... } -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me dodges cabbages like macalypse log N: neeyah! pgpQfW4BcQBM2.pgp Description: PGP signature
Re: Type annotations
On Thu, Oct 06, 2005 at 17:44:10 -0600, Luke Palmer wrote: Autrijus convinced me that we have to really nail down the semantics of type annotation without use static. Let's first nail down what I meant by semantics in that sentence. Basically, when do various things get checked? Run time or compile time (not coercion; I have a proposal for that coming). Oh, I'm asking p6l here, not Larry in particular. This part of the language is yet-undesigned, so some arguments one way or the other would be nice to hear. So we're in line one of a Perl program, with static typing/inference disabled (or at least inference *checking* disabled; perl may still use it for optimization). When do the following die: compile time (which includes CHECK time), run time, or never? my Array $a = 97; # dies eventually, but when? my Int $b = 3.1415; # dies at all? Both die at compile time, because the user explicitly contradicted him/herself. This is like saying my int = $x :: float; since they're constants and their types are very well known. sub foo (Int $arg) {...} foo(hello); # should die at the latest when foo() is called Immediately, at compile time, for every caller of foo unless 'no static' or whatever is active for that scope. However, no inferencing is made - this is just 1 level deep. sub bar (Int $arg -- Str) {...} foo(bar(42)); Since -- is explicit I'm not sure if it means infer this even if we're not globally inferring. I lean towards compile time error here since I think it would be nice to have that, but there are some disadvantages. Perhaps this should infer only in the lexical scope that 'sub bar' was defined in, to make sure that error reporting does not confuse naive users of the module that defines foo, without asking for compile time inference. sub static (Code $code, Array $elems -- Array) { [ $elems.map:{ $code($_) } ] } sub dynamic ($code, $elems) { [ $elems.map:{ $code($_) } ] } static({ $_+1 }, dynamic(notcode, [1,2,3,4,5])); dynamic(notcode, static({ $_+1 }, [1,2,3,4,5])); This is only with full inferencing, either lexically enabled as a a pragma (in the scope that invokes), or if enabled globally. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me does a karate-chop-flip: neeyah!! pgpZ0kQYyANwT.pgp Description: PGP signature
Re: Exceptuations
On Thu, Oct 06, 2005 at 14:27:30 -0600, Luke Palmer wrote: On 10/6/05, Yuval Kogman [EMAIL PROTECTED] wrote: when i can't open a file and $! tells me why i couldn't open, i can resume with an alternative handle that is supposed to be the same when I can't reach a host I ask a user if they want to wait any longer when disk is full I ask the user if they want to write somewhere else when a file is unreadable i give the user the option to skip I'm not bashing your idea, because I think it has uses. But I'll point out that all of these can be easily accompilshed by writing a wrapper for open(). That would be the usual way to abstract this kind of thing. Stylistically I would tend to disagree, actually. I think it's cleaner to use exception handling for this. Also, this implies that you know that the errors are generated by open. This is OK for open(), but if the errors are generated from a number of variants (MyApp::Timeout could come from anywhere in a moderately sized MyApp), then wrapping is not really an option. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me groks YAML like the grasshopper: neeyah!! pgppFkb4LL0f1.pgp Description: PGP signature
Re: my $key is sensitive;
On Mon, Oct 03, 2005 at 22:58:28 -0700, Brent 'Dax' Royal-Gordon wrote: For the last couple days, I've been implementing a cryptographic cipher framework for Perl 6. (It's in the Pugs repository if you want to see it.) Dealing with this sort of algorithm has brought forward a feature that I think Perl 6 and Parrot ought to support. Basically, I'd like to be able to mark a variable as sensitive or secret. This implies that the language should overwrite the memory it uses before deallocating it, and that if possible it should tell the virtual memory system to avoid swapping it out. Moreover, it should probably do so recursively, and to any value that has ever been stored in the variable. (In essence, the *variable* marks all *values* it ever contains as sensitive.) This relates to the ideas I had about generalizing the taint mechanism. The idea was basically: every interaction between two pieces of data triggers a multimethod that is the event handler for that interaction With the assumption that static typing will make the calls to these things be compiled only when necessary. Once you have that then you can implement 'is sensitive' as a taint-oriented-role, that installs an event handler for the tainting container and any value, marking a runtime specific flag that means sensitive. That way the implementation of the role is simple. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: uhm, no, I think I'll sit this one out..: neeyah! pgpEWf3pUErQG.pgp Description: PGP signature
Re: Exceptuations
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! The exception handler knows *EVERYTHING* because it knows what exception it caught: CATCH { when some_kind_of_error { $!.continue($appropriate_value_for_some_kind_of_error) } } -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me climbs a brick wall with his fingers: neeyah! pgpZ51c9ny7Ry.pgp Description: PGP signature
Re: Exceptuations, fatality, resumption, locality, and the with keyword; was Re: use fatal err fail
$.path; # what we tried to open has $.code; # the OS error code has $.mode; # the mode we attempted to open it with ... method resume (IO::Handle $thing) { $?SELF.SUPER::resume($thing); } } That way any bit of code that does: CATCH { when Exception::IO::Open { .. } } has documented, encapsulation safe tools to fix IO related errors, by redoing the call to open after remedying the situation. It doesn't need to know what code actually called open(). Nowadays to get standard behavior from a UI toolkit would you have to break abstraction and say My::Toolkit::open(...); to get semantics like a standard administrative access panel. With continuable exceptions you just use plain open, and the UI code can wrap your entire app with a rich standard library of exception handlers. { error_throwing_code(); CATCH { show_dialog_box(); CATCH { throw; # Pass the exception show_dialog_box(); # Retry if I get resumed? } } } That's going to get old, quickly. Just { error_throwing_code(); CATCH { show_dialog_box(); } } since the parent CATCH will resume from *inside* show_dialog_box. The abstraction of continuable exceptions should cascade. But cresume/c should be part of the Exception interface. Aye, see usefulness of this in above example. resuming. This is nice because especially if we're trying to e.g. my @handles = map { open $_ } @file_names; we can let the user skip unreadable files, by using return with no value instead of returning a handle. This is a generic pattern that enhances the user experience by not forcing the user to start over again. For more specific code, i doubt there will be several exceptions of the same kind in a call chain. What's your example there? The err undef fashion, or the pops up a dialog box and then calls setuid()? An exception ahndler that pops up a dialog box. In this case it would be: The file x could not be read: $! chmod it (chmod the file, and reopen it with same args) skip it (resume with no value) abort the program (rethrow instead of resume) Now, if the chmod operation had an exception like permission denied, obviously we are not the owner. To chown the file we need to setuid, and for that we need the user to authenticate. I confess I find that (the dialog box) an amazing piece of work, but in practical terms somebody someplace has to be doing a retry: I don't see how it would work via resuming an exception. That's the point of continuable exceptions. When returning an exception from 'open' which is then thrown due to 'use fatal', the exception handler can then resume from the point where it was thrown, effectively replacing the exception object with a handle, that is then assigned to the variable: my $handle = open file; Under 'no fatal' $handle will have an exception object under 'use fatal' $handle will not be set at all... Unless the exception handler provides a different value to be put into $handle. Unless Damian does it ;) I doubt even Damian likes to have all the lexical scopes his program made boo-boos in stay alive with no GC in case someone at some later point in the program decides that they can fix those errors. Also - after the code happenned, certain blocks of code will be repeated. This might be useful for obfuscation though ;-) My suggestion here is that cwith/c load the dataspace of the continuation atop the current environment. Yes, I see, but instead of doing it that way you can do it more safely with more characters by introspecting the exception object and using well documented attributes instead. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me groks YAML like the grasshopper: neeyah!! pgpzGrZgxcF7q.pgp Description: PGP signature
Re: Exceptuations
On Fri, Sep 30, 2005 at 18:02:46 +0200, TSa wrote: I knew that the statement would emotionalize. Sorry to all who don't like it an this list. But somehow I found it describes the impression on the handling side somewhat. And I thought it illustrates that exceptions shouldn't be considered just another tool. I think you're taking it too seriously. I'm 99% sure Piers was joking. Regardless, exceptions *are* just another tool. They let you write safe code in fewer words and with less distraction. For example, Either you linearly serialize the entire tree of possible events: if (my $handle = open file) { # the handle is open if (my $other_file = open other :w) { for =$handle - $line { unless ($other_file.print($line)) { $*ERR.print(other could not be written to: $!); # disk might be full if (close $other_file) { if (close $handle) { exit 1; } else { ...; exit 1 } } else { ...; exit 1 } } exit 0; } } else { $*ERR.print(could not open other for writing: $!); if (close $handle) { exit 0; } else { $*ERR.print(could not close file: $!); # not logical, # since we don't write to file, but this is safer exit 1; } } } else { print $*ERR, could not open file: $!; exit 1; } or you could throw exceptions: use fatal; my $handle = open file; my $other_file = open other :w; for =$handle - $line { $other_file.print($line); } If you are going to avoid exceptions because they are too much something for your taste, then I think you are misusing a language that has support for exceptions. I really don't understand why this has to do with freedom, or it's restriction. It's your personal (and IMHO bad) taste not to use exceptions for improving your code, but it's still your choice. All I was saying is that you could leverage exceptions by letting the UI code make the handling of exceptions a two way route, instead of one way. CATCH Exception { say Why do you hate freedom? } I don't. But the freedom of the individual ends where the community begins. I think this is a big exaggeration. The community will not be harmed if the individual uses exceptions. On the contrary, i would be much happier to use code that does through exceptions. For example, a very useful perl 5 module, UNIVERSAL::require, lets me write: $class-require or die $UNIVERSAL::require::ERROR; instead of eval require $class; die $@ if $@; but in both cases I have to check for errors, unlike require Class; I still prefer $class-require, though, because it feels more readable to me. I don't say to myself wtf? why is this code doing an eval while reading the code. In perl 6, we would ideally have: use fatal; $class.require; # lives if class exists, dies if class doesn't exist $class.method; # always lives (if method really exists) or use fatal; try { $class.require } # always lives $class.method; # might die, but at least it's obvious or no fatal; $class.require; # always lives\ $class.method; # might die In fact UNIVERSAL::require's author agrees with me: http://use.perl.org/~schwern/journal/26939 Now, if this were #!/usr/bin/perl use fatal; use Pluginish::App; sub infix:s~ ($l, $r) { $l $r }; # spacey concatenator { Pluginish::App-load_plugins; CATCH { when Module::load_error { if (prompt(The module $!.module_name could not be loaded because s~ an error occurred ($!). Try to continue anyway?) { $!.resume(undef); } else { die $!; } } } Pluginish::App-run; -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /methinks long and hard, and runs away: neeyah!!! pgpKTxHNv1uR1.pgp Description: PGP signature
Re: Exceptuations
Hi! On Thu, Sep 29, 2005 at 10:49:40 +0200, TSa wrote: BTW, I would call *intentional* exceptions terrorism. Then I would call terrorism non linear control flow ;-) In that case Afghanistan might be harboring computer scientists that really like CPS, and bush is Java ;-) In lack of a better word I use Event and we get Event::Exception, Event::Control, Event::Warn and possibly Event::Hint, Event::Log and Event::Fun :) An event is something external that happens... It does not affect the control flow of an application. Exceptions work well to describe this: The normal flow is up and down the call graph, laying bread crumbs in the form of a stack, and going back from where you came. Exceptions let you jump instantly to another place in the call graph. All I'm saying is that to complement the normal exceptions jump back out, you can jump out, and jump back in. An event is a general thing that can be implemented with exception like semantics, but implies nothing on the control flow of the program. An error is an exception that happenned because something went badly wrong. Now it's my turn at illustrative metaphors ;-) The call graph is a big maze you go through. When you find an *error*, in the form of a minotaur, you use the exception handling mechanism to run away. You jump instantly to a safe place in the labyrinth. Although this is not consistent with the mythology, presume that the reason you entered the maze was that you were trying to get results. Most exception handlers are safe places when you can gather your self, realize that 'oh crap, i just met a minotaur', and tell whoever you sent you in there that there's no way you're going back in. All I'm trying to say is that when there is an exception - a leap out from a dangerous place to a safe one, due to an error, the code may choose to deal with the error by giving you a big stick. Then you can go back and beat the minotaur into submission, and resume with trying to get results. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me whallops greyface with a fnord: neeyah!!! pgp9mjhsoAPUd.pgp Description: PGP signature
Re: Exceptuations
I'd like to ammend, and perhaps formalize with some definitions from my dictionary, which ships with OSX: error - a mistake... the state or condition of being wrong in conduct or judgement... technical - a measure of the estimated difference between the observed or calculated value of a quantity and it's true value. As i see it: when something you wanted to happen turned out different than you programmed it to: my $handle = open file; # we assume $handle exists print =$handle; # but what if there was an error? exception - a person or thing that is excluded from a general statement or does not follow a rule To lessen the mental load on a programmer, instead of having the programmer write a tree of all the conditions that could happen, the programmer can write only the condition in which the program is actually useful. Any *error* (synch problems between the code and reality) causes an *exception* in this linearization. The control flow is an exception to the norm, because there was an exception in the reality the program was tailored to deal with. The reason we handle exceptions is that sometimes we want the tree approach, because we have well defined behavior for certain paths. Exceptions let us separate code from normal code and code which is *exceptional*, and the reason it is exceptional is usually an error. event - a thing that happens, especially one of importance Every error is an event. Exceptions are one way to deal with events we were not prepared for. But events can also be waited for (select waits for events on many file handles at a time). Every *error* is an *event*, but an *exception* is how you deal with events. The events that cause exceptions by default in perl will be: errors, when 'use fatal' is in effect warnings, but to another handler next, redo, last, return - all control flow events that are exceptions to the single point of entry, single point of exit school of thought. I intentionally did not use the computer related definitions from e.g. wikipedia, because they are more subject to cultural inertia, and we are trying to discover the roots of these borrowed terms. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me groks YAML like the grasshopper: neeyah!! pgpr89lYnXBsX.pgp Description: PGP signature
Re: use fatal err fail
On Thu, Sep 29, 2005 at 12:53:51 +0200, TSa wrote: I don't like it at all. I fear, that we mix two orthogonal concepts just because it is convenient. just because it is convenient is precicely why I like it =) To me the statement return 42; # 1 has to orthogonal meanings: 1) the current scope has reached its (happy) end 2) a specific result was determined return literally means give back. The caller is getting a value that we give. This implies two completely non-orthogonal meanings to me: 1) the scope has reached its happy end 2) it's reached the end because a specific result was determined We can vary on both of these dimensions *independently*! Which gives the remaining three cases: return undef; # 0 unspecific result just 'return' would do. But This is odd, unless the context is void - if the caller is expecting something, wer're not returning an unspecific result - we're returning a value. This value is in bounds (it's a normal perl scalar) and it has a well known meaning that i have have nothing meaning to report. I think this is actually a very concrete result. fail undef; # -1 no return with unspecific reason fail 42;# -2 no return but determined reason Fail is, semantically: (should_die ?? die !! return) and the caller gets to determine the behavior. Whether failures have an extras payload in a simple return value, or whether the payload is carried via an out of bounds route to the closest thing that can handle is really only dependant on how the caller is most comfortable with handling errors. or in yet another way to describe my attitude: the least thing that *defines* an exception is that the dynamic scope in question has reached the conclusion that it is *not* going to give control back to its creator! Not at all! It's simply returning an out of bounds value to the closest caller that is willing to handle out of bounds values. In fact, it's short circuiting to it's caller, to give it control as fast as possible since it doesn't know what to do anymore. The reason exceptions tend to pop upwards more is that they are handled in a way that if the immediate caller doesn't know how to handle it either, it keeps going up the call stack till a calling scope does know what to do, and can explcititly take control. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me beats up some cheese: neeyah! pgpqFx7QmiXTK.pgp Description: PGP signature
Re: Exceptuations, fatality, resumption, locality, and the with keyword; was Re: use fatal err fail
and gives it fractionally worse Huffmanization. Well, there is a conflict here: you want to mark and not mark your errors at the same time. What I want is to catch my errors elsewhere, and still be able to localize their solution. Cleverly, there's already a way to do this: labels. All I need is to know where I'm at, label-wise, and I've got a dandy way to mark my code up. This is feasable... I don't see why it shouldn't be implemented, but frankly I don't see myself using it either. This is because the types of exceptions I would want to resume are ones that have a distinct cause that can be mined from the exception object, and which my code can unambiguously fix without breaking the encapsulation of the code that raised the exception. Take OSX for example - it's very consistent in that you are allowed to try to perform every action you like. Whenever there's a permission denied error, it pops up a password dialog. I think that a nice user oriented environment can benefit from a library of generic exception softners that interact with the user: change the mode of ureadable/writable files enter a password for elevated priviliges decide whether to keep trying when something seems to be timing out etc etc. These are all very specific and reusable, regardless of what we're resuming. This is nice because especially if we're trying to e.g. my @handles = map { open $_ } @file_names; we can let the user skip unreadable files, by using return with no value instead of returning a handle. This is a generic pattern that enhances the user experience by not forcing the user to start over again. For more specific code, i doubt there will be several exceptions of the same kind in a call chain. CATCH { when PrintException { fprintf(STDERR, Could not write %s part, caller.label.tolower.s/part$//); The catch block's caller is greet's caller. I guess you want $!.position.label.yadda or something like that [quote=http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html] The final step in setting up an exception handler is to clean up before allowing control to be passed to a different part of the program. For cleanup we have real useful garbage collection, with a declarative interface to decide on how an object needs to disappear. Resource management is the task of the resource creator, not exception handler, IMHO. It's just too hard to get it right. So your point: But resumptions are going to let us FIX the problem that occurred when we tried to open the 256th filehandle. So all the directory parsing, file exploring, and whatnot is going to be *preserved*. is very valid Thus we don't actually want to automatically finalize all that stuff unless we know for sure that we aren't going to resume: even *later* binding. Continuations give this behavior consistently. They just need to be garbage collected themselves, in a way. What I would like to disallow is the ability to take $! and just .resume it out of the blue in code that isn't an exception handler. That just does't make sense: try { ... } some_other_stuff; $!.resume if $!; [here we go again] needs to bundle along a stack that provides access to the variable scope. Again, that is exactly what a continuation is, and parrot already has them =) Yet another use for a Pascal's cwith/c keyword: I actually quite liked that RFC =) The problem is that records in a static language are static, and hashes are dynamic. There is no way to tell the user at compile time that a variable doesn't exist because we don't know if there's such a hash key. This means that 'use strict' cannot work in a 'with'ed block. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: /me does not drink tibetian laxative tea: neeyah! pgpeUd4pM1XWq.pgp Description: PGP signature