Re: Exceptuations
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. 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. CATCH { when some_kind_of_error { $!.continue($appropriate_value_for_some_kind_of_error) } } That just gives me the willies, I'm afraid. -- Peter Haworth [EMAIL PROTECTED] Disconcerting Haworth Fortress Unicycling Melody Gundam -- http://www.channel4.com/4later/bits/manga.html
Re: Exceptuations
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. Think of receiving a 'shelf picker died of lung cancer' exception when you just ordered a book from your favorite book dealer. Irrespective of the seriousness to the shelf picker, but how would you expect a customer to handle such an exception? This kind of exception should never get so far up the call chain, except possibly as a nested cause of a more general exception. The customer is in no position to get the book dealer to choose a different stock picker - that's up to the order picking department of the book shop. If it doesn't get handled there, then maybe the book shop can try sourcing the book externally, and if that fails, they may defer your order until later. The shop could ask the customer's opinion as to the suitability of each of these options, but the customer shouldn't have to know how the shop is implemented and make such decision unprompted. Even given a continuation to some low level routine, anything the caller does is likely to be too far removed to make it sensible to resume the continuation. Eiffel deals with this by brutally its Design By Contract magic bullet: Since all the code catching the exception knows about is its own implementation, the only sane option it has is to try performing the subtask in a different way. Here's how Eiffel's rescue/retry might work in perl6, where rescue is spelled CATCH. class Picker{ # An individual order picker can pick a book, but may unfortunately # die of lung cancer, or just fail to find the book method pick($book){ fail Err::LungCancer if .is_smoker(); ... fail Err::BookNotFound if ...; } } class PickingDept{ # The picking department employs pickers to pick books # If an employee dies of lung cancer while picking an order, # they are removed from the roster, and a different picker is chosen # If the department doesn't have enough free pickers, # it just throws a too busy exception # Due to the retry semantics, the department will keep choosing pickers # until one of them can pick the book, or they all die of lung cancer, # (or they're all busy doing something else) method pick($book){ my $picker=.find_free_picker(); $picker.pick($book); ... CATCH{ when Err::NoPickersAvailable { fail Err::DeptTooBusy; } when Err::LungCancer { .fire_picker($picker); # Harsh, but we won't find him again retry; # This re-runs the tried block (method) from the top } when Err::BookNotFound { fail Err::OutOfStock; } # Optimistic, maybe default { fail; } } } } class BookStore{ # The book store has multiple picking departments, so if one of them fails # to find a book, the others can be tried. If that fails, they could order # the book from the wholesaler and defer the order, but I'm too lazy method order($book){ for @.depts - $dept { try{ $dept.pick($book); return; CATCH{ 1; } # We'll just try the next one } } fail Err::BookNotFound; } ... } class Customer{ # The customer doesn't have any say in how bookshops are run, so all # they can do if their order is refused, all they can do is try another # shop, or give up and go home method buy_book($book){ $random_bookshop.order($book); CATCH{ fail Err::BookObviouslyDoesntExist; } } } -- Peter Haworth [EMAIL PROTECTED] Hestons' First Law: I qualify virtually everything I say.
Re: Nested captures
On Mon, 09 May 2005 22:51:53 +1000, Damian Conway wrote: # Perl 6... # $1 $2$3 $4$5 $6 $tune_up6 = rx/ (don't) (ray) (me) (for) (solar tea), (d'oh!) # $1 $2 $3$4$5 | (every) (green) (BEM) (devours) (faces) /; Does numbering of captures after an alternation continue as if the alternative with the most captures matched? # $1$1 $2$3, even if (a) matched rx/ [ (a) | (b) (c) ] (d) /; If you explicitly number the first capture in one alternative, does that affect the numbering of the other alternatives? # $4$4 rx/ [ $4:=(a) | (b) ] /; Note that, outside a rule, C@1 is simply a shorthand for C@{$1} Is @/ also a shorthand for @{$/} ? -- Peter Haworth [EMAIL PROTECTED] I am continually amazed by the intuitive straightforwardness of the interface of my microwave and oven. If they were designed by the people who design computer interfaces, it would take both hands and several minutes just to set the timer.-- Adam Rice
Re: New S29 draft up
On Mon, 21 Mar 2005 08:41:27 -0800, Larry Wall wrote: Okay, I've come around to liking it, but I think we have to say that 0x, 0d, 0o, 0b, and whatever else we come up with are just setting the default radix. If a string comes in with an explicit 0x, 0d, 0o, or 0b, we believe that in preference to the operator. Don't we trust the programmer more than the data? I want this code to produce 4660, 22136, 2832, 3394; not 4660, 22136, 4, 42. for '1234','5678','0b10','0d42' { say 0x $_; } -- Peter Haworth [EMAIL PROTECTED] It's not a can of worms, it's a tank of shai-hulud. -- Jarkko Hietaniemi
Re: .method == $self.method or $_.method?
On Fri, 18 Mar 2005 09:45:57 -0800, Larry Wall wrote: I think we'll need to figure out how to shorten $_.foo instead. It looks short enough to me already. More importantly, its meaning is immediately obvious. Either that, or there has to be a way to explicitly make $_ the invocant of a subblock. How about something like this? method foo{ .bar; # Acts on self for @stuff { .bar; # Acts on self } for @stuff - $_ :self { .bar; # Acts on self, which is currently $_ } } Seems like overkill for trivial blocks though: map - $_ :self { .bar } 1..10; but you can still just write $_.bar Maybe we could allow $_ to be elided? map - :self { .bar } 1..10; At the moment I'm trying to see if I could get used to ..method meaning $_.method, and whether it buys me anything psychologically. I still prefer $_.method Suppose you are one of those rare people who actually checks the return value of print to see if you filled up the disk: if print {...} That doesn't parse currently ... (Backtracking the parser is probably not the right answer.) If you're going to the trouble to check that (which I do, sometimes), surely two extra characters [$_ or ()] aren't that much of a problem? You probably wouldn't be using implicit variables, anyway. A backtracking parser seems pretty scary to me. If it takes a lot of work for the compiler to figure things out, it's going to be even harder for the programmer. -- Peter Haworth [EMAIL PROTECTED] I think this is one of those traumatic things eggs have to face to prepare a good omelette. -- Jarkko Hietaniemi
Re: Synopsis 4 draft 1
On Thu, 19 Aug 2004 19:45:37 -0700, Larry Wall wrote: To process two arrays in parallel, use either the zip function: for zip(@a,@b) - $a, $b { print [$a, $b]\n } or the zipper operator to interleave them: for @a ¥ @b ¥ @c - $a, $b, $c { print [$a, $b, $c]\n } n-ary zip() is simple enough, but the infix ¥ makes zipping more than two lists somewhat entertaining. Without iterators doesn't work well: @a ¥ @b produces (@a[0],@b[0],@a[1],@b[1],...) which is what we wanted, but @a ¥ @b ¥ @c produces (@a[0],@c[0],@b[0],@c[1],@a[1],@c[2],@b[1],...) which isn't. The compiler *could* be made to detect such cases, and turn them into zip(@a,@b,@c) but that seems like piling even more onto the poor compiler's plate, which already has to be the size of the whole table. It also makes things harder for evil coders who want to define their own behaviour for ¥. If we implement ¥ as an iterator (which is surely the plan), we can get more fancy. With two lists as arguments, we return zip(@a,@b), and if either argument is itself a zip iterator, we decompose it to get the original lists, and return zip(*lists_from(@a),*lists_from(@b)). Great. But what if what you actually wanted was the horrible thing that the naive non-iterator approach gives you with three lists? Do you have to say this instead? *(@a ¥ @b) ¥ @c Yuck, that's two thirds of the iteration benefit lost, or all of it if either of @a or @b are infinite. A Creturn always exits from the lexically surrounding sub or method definition (that is, from a function officially declared with the Csub, Cmethod, or Csubmethod keywords). Pointy subs and bare closures are transparent to Creturn. If you pass a reference to a closure outside of its official sub scope, it is illegal to return from it. Presumably this illegality only applies to closures not officially declared as subs, methods or submethods? -- Peter Haworth [EMAIL PROTECTED] Her vocabulary was as bad as, like, whatever.
Re: backticks
On Fri, 16 Apr 2004 23:45:48 +0200, Juerd wrote: Jonathan Scott Duff skribis 2004-04-16 15:51 (-0500): Except that you've put things in this explanation that shouldn't be there IMHO. The %varnamekey is a special case, but not of getting a single item from a hash, rather it's a special case of a one element list generated from evaluating to the element. So, if you remove that bit, it's the same as the two below just with different syntax. I think %hashkey key key is best explained as %hash{ key key key } with implicit curlies, not as an alternative to curlies. In that case, why aren't you suggesting something more in line with that? Here's what I'd like to see instead of your suggestion: %hashkey key key === %hash{key key key} %hash'key'=== %hash{'key'} %hashkey=== %hash{key} That has * as few keystrokes as perl5's $hash{key} * delimiters at both ends, so you can even use non-bareword constants * existing syntax reused in the same way as the variant * interpolation allowed in the double quoted variant. That said, I really wish we could keep perl5's $hash{key}. It's obviously a subscript, and I use constant bareword keys much more frequently than zero-arg sub/builtin calls in hash subscripts. -- Peter Haworth [EMAIL PROTECTED] The capacity of human beings to bore one another seems to be vastly greater than that of any other animals. some of their most esteemed inventions have no other apparent purpose, for example, the dinner party of more than two, the epic poem, and the science of metaphysics. -- H. L. Mencken
Re: Conditional Creturns?
On Tue, 1 Apr 2003 22:01:48 +0300, arcadi shehter wrote: Damian Conway writes: given baz(@args) { return $_ when defined } given baz(@args) { return $_ when $_ 0 } # etc. since we have 2 forms of return -- return and leave , may be we can make return also to be a topicalizer for the rest of experssion , and then : return baz(@args) when $_ 0 ; return baz(@args) when defined ; return baz(@args) when true ; Damian's solution looks a lot better to me. I'm going to be surprised by the behaviour of code that works like yours for a long time before I get used to it. -- Peter Haworth [EMAIL PROTECTED] I have to continue using UUCP for sentimental reasons -- Ian Lance Taylor
Re: Variable Types Vs Value Types
On Wed, 8 Jan 2003 15:39:52 -0500, Dan Sugalski wrote: At 7:29 PM -0700 1/7/03, John Williams wrote: Perhaps you could explain how the $0 object will work in your mind. A5 assert that $0 is a object, and it behaves as an array and a hash, depending on how you subscript it. Typeglobs are gone, and we're all hoping the TIE interface is gone too, so how will this effect be accomplished? All variables in parrot are implemented as PMCs, and all PMCs may be accessed with a string, integer, or PMC subscript or set of subscripts. For PMCs that don't do subscripting this will be a fatal error, for those that do it'll do whatever the PMC is supposed to do. (In the case of $0, do the lookup) That's phrased like it's the type of the subscript value which determines whether it's a hash-like or array-like access. Shouldn't it be the type of brackets which do that? In other words, I don't want to see this happen: $a[1]; # array-like $a['1'];# hash-like $a{1}; # array-like $a{'1'};# hash-like It should be like this: $a[1]; # array-like $a['1'];# array-like $a{1}; # hash-like $a{'1'};# hash-like Maybe it is the right way round, and I've read your remarks the wrong way. Or maybe it is the value type which determines the type of access at the PMC level, and it's up to the compiler to force the type based on the brackets. -- Peter Haworth [EMAIL PROTECTED] After all, what is your hosts' purpose in having a party? Surely not for you to enjoy yourself; if that were their sole purpose, they'd have simply sent champagne and women over to your place by taxi. -- P J O'Rourke
RE: right-to-left pipelines
On Tue, 10 Dec 2002 13:02:18 -0800, Brent Dax wrote: Peter Haworth: # @b = @a.grep { /\S/ }, $c; # # how does the compiler know whether $c is an argument to grep, # or another element to be assigned to @b? The same way it does when it sees a normal sub? I know, late binding and all that. But when you think about it, a lot can be done to simulate the conditions otherwise. For example, with a definition like this: class Foo { method bar($self: $baz) { ... } } And a call like this: @b=$foo_obj.bar $baz, $quux; Where we can see *at runtime* that $quux is too many arguments, we can just append it to the end of bar()'s return value. (This would only happen when there were no parentheses.) But at runtime, we don't necessarily have a good idea of what the original code looked like (we've compiled to bytecode, and the user may have stripped all the useful metadata from the .pbc file), or a way to generate new bytecode on the fly (the user may have opted to exclude the runtime eval capability). For this to work, we'd have to compile every possible variation of the syntax tree, and decide which of them was appropriate at runtime. Ick. In a strictly typed language you can do this without too many surprises. I don't think it's appropriate for Perl, except possibly for certain special cases like blocks as the only argument. -- Peter Haworth [EMAIL PROTECTED] 'As Annie Oakley almost said, Anything you can do, I can do meta.' -- Larry Wall
Re: right-to-left pipelines
On 10 Dec 2002 11:41:23 +, Simon Cozens wrote: [EMAIL PROTECTED] (Damian Conway) writes: I don't think the method-call syntax allows it. I think methods need their parens. So we need: (@foo, @bar) := @a . grep( { $_ 0} ) . sort( { $^b = $^b } ) . part( [/foo/, /bar/] ); *Why* do methods need their parens? If methods can be specified to possibly take a block, such as grep and sort do, then they shouldn't need parens. Or at least, I know a language in which this is possible... :) To know whether the method takes a block, you need to know how it's been declared. In other words, the type of @a needs to be known to find grep's declaration. In turn, grep must specify its return type in order to find sort's declaration, and sort must specify its return type so that part's declaration may be found. That's all fine for the standard/builtin methods on arrays, but its a bit unperl-like to force users to highly specify everything. Of course, if they do declare methods with all the bells and whistles, they get the benefit of not having to use parens later on. -- Peter Haworth [EMAIL PROTECTED] Although they all look the same to me, doormats and other furnishings probably have a strict social heirarchy. Every chair a god. Every item of pottery from the Franklin mint, an angel. Man, I love decor. -- Ashley Pomeroy
Re: right-to-left pipelines
On 10 Dec 2002 15:34:11 +, Simon Cozens wrote: [EMAIL PROTECTED] (Peter Haworth) writes: To know whether the method takes a block, you need to know how it's been declared. In other words, the type of @a needs to be known to find grep's declaration. Well, that's what always happens on a method call. At run time, yes. However, at compile time, due to Perl's dynamic nature, you don't know how methods have been declared unless the programmer is using the optional BD features. In turn, grep must specify its return type in order to find sort's declaration, No, not at all. As I've said, you assume that all methods *can* take a block. Fair enough; that simplifies things somewhat. However, you can't tell how many arguments they take. How do you parse this without the programmer specifying a great deal more than they're used to in Perl 5? $foo.bar $baz,$qux Is it $foo.bar($baz),$qux or $foo.bar($baz.$qux) or even a syntax error (though this would require bar()'s declaration to be known at compile time): $foo.bar() $baz,$qux -- Peter Haworth [EMAIL PROTECTED] Spider Boardman: I'm having fun with it. Dan Sugalski: Inside the [perl] tokenizer/lexer? This has got to be the scariest thing I've heard in a long time. You are a sick, sick man.
Re: right-to-left pipelines
On 10 Dec 2002 17:25:34 +, Simon Cozens wrote: [EMAIL PROTECTED] (Peter Haworth) writes: Fair enough; that simplifies things somewhat. However, you can't tell how many arguments they take. How do you parse this without the programmer specifying a great deal more than they're used to in Perl 5? $foo.bar $baz,$qux I see no block here. I'm just talking about passing a block to a method. You think I'm talking about a clever way of specifying a block's argument signature. I'm not. Actually, I was accepting your point about block arguments not needing parens, and generalising it to other kinds of arguments. You want this to work: @b = @a.grep { /\S/ }; instead of/as well as this: @b = @a.grep( { /\S/ } ); I can agree that it's much cleaner looking. However, I want to be sure that it doesn't introduce ambiguity. If the programmer wants $c on the end, and writes this: @b = @a.grep { /\S/ }, $c; how does the compiler know whether $c is an argument to grep, or another element to be assigned to @b? Maybe a method can either be called with a parenthesised argument list, no arguments (without parens), or with a single paren-less block. That also gets around the chaining issue of: @a.grep { /\S/ }.grep { .foo }; If the block is surrounded by implicit parens, that stops it getting parsed as: @a.grep( { /\S/ }.grep( { .foo } )); Anyway, my point was that methods with paren-less arguments are either ambiguous or greedy, unless you restrict the types of arguments this applies to. If it's just blocks, them I'm fine with it. -- Peter Haworth [EMAIL PROTECTED] The usability of a computer language is inversely proportional to the number of theoretical axes the language designer tries to grind. -- Larry Wall
Re: Superpositions and laziness
On Tue, 12 Nov 2002 21:11:36 +, Piers Cawley wrote: Michael Lazzaro [EMAIL PROTECTED] writes: On Friday, November 8, 2002, at 07:03 AM, Adam D. Lopresto wrote: I still prefer cached, which sounds less lingo-ish than memoized but reads better than same (Same as what?). Insert obligatory reference to Eiffel here, which IIR uses the word once: But that means once per system, not once per unique argument list. -- Peter Haworth [EMAIL PROTECTED] Interesting trivia: If you took all the sand in North Africa and spread it out... it would cover the Sahara desert.
Re: Continuations
On Wed, 06 Nov 2002 10:38:45 +1100, Damian Conway wrote: Luke Palmer wrote: I just need a little clarification about yield(). Cyield is exactly like a Creturn, except that when you call the subroutine next time, it resumes from after the Cyield. how do you tell the difference between a recursive call and fetching the next element? How would you maintain two iterators into the same array? The re-entry point isn't stored in the subroutine itself. It's stored (indexed by optree node) in the current subroutine call frame. Which, of course, is preserved when recursive iterator invocations recursively yield. So to get the same yield context, each call to the coroutine has to be from the same calling frame. If you want to get several values from the same coroutine, but from different calling contexts, can you avoid the need to wrap it in a closure? sub iterate(@foo){ yield $_ for @foo; undef; } # There's probably some perl5/6 confusion here sub consume(@bar){ my $next = sub{ iterate(@bar); }; while $_ = $next() { do_stuff($_,$next); } } sub do_stuff($val,$next){ ... if $val ~~ something_or_other() { my $quux = $next(); ... } } -- Peter Haworth [EMAIL PROTECTED] ...I find myself wondering if Larry Ellison and Tim Curry were separated at birth...hmm... -- Tom Good
Re: Perl6 Operator List (REMAINING ISSUES)
[Apologies for late reply, but it takes a long time to read this many messages] On Wed, 30 Oct 2002 16:37:09 -0800, Michael Lazzaro wrote: 1) Need a definitive syntax for hypers, ^[op] and «op» have been most seriously proposed -- something that keeps a bracketed syntax, but solves ambiguity issues. 2) Possible inclusion of unary prefix ^, meaning complement. (Assuming doesn't conflict with (1)) If ^ means xor (and complement), then we can't use it for hypering. Consider this example: @a ^[alpha_op] +3 You can parse this in two ways: * array a, hyperop alpha_op, unary plus, literal 3 * array a, binary xor, call alpha_op and put result in arrayref, binary plus, literal 3 The operator doing the least at present seems to be ! (my recent attempts to reclaim it aside). If we keep ^ as the only xor/complement operator, we can use ! as the hyperoperator indicator without ambiguity: @a ![alpha_op] +3 Or (since people seem to like using ^ for hyperness), we could steal ! back as doing all the xor/complement things that ^ is doing now, and leave ^ doing just hyperstuff. This stops ! being a (mostly) synonym for ^, which I didn't really like, but does bring back the confusion between !! and ||. If we want to have a sigil meaning the next set of brackets surround a hyperoperator, it pretty much can't be the same as any of the other operators, since that introduces ambiguity all over the place. This is unfortunate, since perl seems to use every printable ASCII character for something. Using French quotes gets around this, since they aren't being used for anything else. OT3H, I can't find the «» keys on my keyboard, but I'm sure I'm just not looking hard enough. -- Peter Haworth [EMAIL PROTECTED] Are you the police? No ma'am, we're musicians.
Re: [RFC] Perl6 Operator List, Take 5
On Wed, 30 Oct 2002 15:31:24 -0800, Michael Lazzaro wrote: Meaning that the list: +^- force to numeric context, complement ~^- force to string context, complement simply becomes: ^ - complement (type-specific) Does this include booleans? I really liked the idea that not and xor were just the same operator, but unary/binary. Otherwise, we have ! for boolean negation only, while ^ does the same thing for other types, as well as xor for everything. I don't mind leaving ! in as a synonym. -- Peter Haworth [EMAIL PROTECTED] Send this via the BT scuz-a-filtron -- Andy Wardley
Re: Object Instantiation
On Fri, 11 Oct 2002 14:05:30 -0700, Michael Lazzaro wrote: Maybe postfix ! on a class name means to autoinstantiate an object of the named class only if/when first accessed: our FancyCache $cache; # declare, but leave undef our FancyCache! $cache; # undef, but new() it if/when we need it our $cache returns FancyCache!; # the same (That's just a joke. Um, I think. Hmm...) Apart from the auto bit of autoinstantiate, that's almost what it means in Eiffel, except there it's a prefix !! operator. Actually, you can specify a subclass between the two shrieks, but perl lets you do that by sticking Class:: on the method name, which means we'd only need one shriek: # ! is the new .= our FancyCache $cache; # declare but leave undef our FancyCache $cache ! new; # create new instance our FancyCache $cache ! ReallyFancyCache::new; # create subclass instance Eiffel does let you omit the name of the constructor if there is a single argumentless constructor, but Eiffel constructors are all marked as such, which (at least so far) Perl6 constructors aren't. -- Peter Haworth [EMAIL PROTECTED] The Hotmail migration is becoming the IT equivalent of painting-the-Forth- bridge, evidently. Once you've think you've finished migrating one end, more FreeBSD boxes reappear at the other. So you have to start all over again. -- http://www.theregister.co.uk/content/28/23348.html
Re: Private contracts?
On Thu, 3 Oct 2002 18:46:14 -0400, Michael G Schwern wrote: method foo($this, $that) is memoized is something is pre { $this = 42 } is pre { $that == $this / 2 } is pre { now we have a little bit more room to play with using a differnt indentation style } is post { but post conditions are still distanced from the code which return()s } { ... } I realize that conditions are technically part of the signature, but putting them in there paints us into a stylistic corner. This is the one nice thing about the Pascal-like syntax of Eiffel. It allows this situation to be unambiguous and sensibly ordered (as well as giving each condition labels, so that violations can be better reported): foo(this: ThisType, that: ThatType): FooType IS REQUIRE small: this = 42 half: that = this / 2 DO -- implementation goes here ENSURE fooed_ok: RESULT = baz(this) + that END If you're declaring an abstract feature, just replace the whole DO clause with DEFERRED. Also notice how Eiffel's syntax also somehow makes statement terminators completely optional. Aren't sub declarations in Perl 6 all expressions? Why couldn't we put the post condition at the end, then? sub foo($this, $that) is memoized is something is pre{ $this = 42 } is pre{ $that == $this / 2 } { # implementation goes here } is post{ # postcondition 1 } is post{ # postcondition 2 } If you want an abstract method, just omit the implementation block. -- Peter Haworth [EMAIL PROTECTED] Maybe that's [Java's] niche, its a language for people who like pain. -- Dean Wilson
Re: Private contracts?
On Thu, 3 Oct 2002 19:16:09 -0400, Michael G Schwern wrote: On Thu, Oct 03, 2002 at 04:47:26PM -0500, Garrett Goebel wrote: A derived interface can loosen input constraints... so it must be able to either satisfy all inherited pre-conditions _or_ its own pre-conditions. Looking around, this seems to be regarded as something of a compromise because truly determining what a real logical weaking is is hard. That *is* a logical weakening. Just because the inherited precondition is C x 10 , doesn't mean that the weakened condition has to be of the form C x 9 or any other value lower than 10. C a || b is weaker than C a Are there other ways to do it, just to mull them over? -- Peter Haworth [EMAIL PROTECTED] I remember being impressed with Ada because you could write an infinite loop without a faked up condition. The idea being that in Ada the typical infinite loop would be normally be terminated by detonation. -- Larry Wall
Re: Regex query
On 24 Sep 2002 05:21:37 -0400, Aaron Sherman wrote: On Tue, 2002-09-24 at 01:46, Trey Harris wrote: sub push(@target is rw, *@list); Well, yes, but that wasn't the point. The C*@list will force array flattening, thus push @a, [1,2,3], 4; will (according to Larry's stated desire to unify arrays and references to arrays in terms of behavior) result in four elements getting pushed onto C@a, not two. But the decision on how arguments get passed happens at compile time, not run time. At that point we can tell the difference between an explicit arrayref and a flattened array: push @a,1,2,3; # 1 - list push @a,(1,2,3); # 2 - list push @a,[1,2,3]; # 3 - scalar push @a,@b; # 4 - list push @a,*@b; # 5 - list push @a,\@b; # 6 - scalar push @a,[@b];# 7 - scalar 1 and 2 are the same; parens in a list don't have any effect, and push receives three elements in its @list parameter. 3 is an explicit arrayref so gets passed as a single scalar. This is a simple and obvious distinction for the programmer to make. 4 and 5 are the same due to the *@ prototype; push receives the contents of @b in its @list parameter. 6 is an explicit arrayref, so that's what push gets given. I would argue that 7 is like 6, except that it copies @b's elements. -- Peter Haworth [EMAIL PROTECTED] Reporter: Mr Gandhi, what do you think of Western Civilization? Gandhi: I think it would be a good idea.
Re: Hypotheticals again
On Wed, 4 Sep 2002 17:29:27 -0400 (EDT), Trey Harris wrote: In a message dated Wed, 4 Sep 2002, Jonathan Scott Duff writes: So, each time I use a hypothetical, I have to be concious of which variables are currently in scope? Perl can't help be with this task because how does it know if I meant to hypothetically clobber that lexical or store something in the match object. This is only really a problem if you expect let variables to always show up in the match object and sometimes they don't. So why not make it so that let also always causes these variables to appear in the match object? It should. I think everyone has been proceeding under the assumption that they are. If you use a variable name already defined, then you set both the match object's attribute of the same name (minus the sigil if sigil is '$') *and* the external variable. That was certainly my assumption, and I'm fine with that. However, what if, for some reason, you don't want to set the lexical which happens to be in scope. Or if you do, but you spell it wrong? There needs to be some way of indicating whether or not the lexical gets set - that way the strict pragma (or perl6 equivalent) can catch typos. -- Peter Haworth [EMAIL PROTECTED] To be considered half as good as Microsoft, Linux has to work twice as fast. Fortunately, this is easy.
Re: Hypothetical variables and scope
On Mon, 2 Sep 2002 23:50:18 -0400 (EDT), Trey Harris wrote: In a message dated 2 Sep 2002, Aaron Sherman writes: { my $x = 2; my $y = The grass is green; $y =~ /(gr\w+) {let $x = $1}/; } Yes. $0{x} would be set to grass. A lexical variable has been defined in the same scope as the hypothetical with the same name, so its value is set hypothetically (is hypothetically bound to?) $0{x}. When the rule succeeds, $x's hypothetical value is made permanent. module foo; rule gr_word { (gr\w+) {let $x = $1} } my code use foo; my $x = 2; The grass is green =~ /gr_word/; No. $0{x} would be set to grass. $x would stay as 2. $x is in a different scope from the hypothetical, so it doesn't get touched. Presumably there is some variant of the strict pragma which would catch misspellings of $x. Actually, I'd like to see something explicit in the rule which states whether the hypothetical binding applies to the surrounding scope as well as to the match variables. Unfortunately, the only way I can think of doing this is to state $OUTER::x, which is pretty horrible, and doesn't give the impression that both the external variable and the match variable are being bound. Also the different operators used (:= inside the rule, = inside the code) seems a bit confusing to me; I can't see that they're really doing anything different: / $x := (gr\w+) /vs/ (gr\w+) { let $x = $1 } / Shouldn't they both use C := ? -- Peter Haworth [EMAIL PROTECTED] Some more data? No, no more. Please, no more... -- Yanick, examining perl's strange behaviour
Re: Autovivi
On Wed, 14 Aug 2002 15:40:35 -0600 (MDT), Luke Palmer wrote: We could make arglists exactly equivilent to the way they're done in Perl 5, which is a good way. sub foo($a, $b, *@c) {...} Would be exactly equivilent to Perl 5's sub foo { my ($a, $b, @c) = @_; ... } Since variables are copy-on-write, you get the speed of pass-by-reference with the mutability of pass-by-value, which is what everyone wants. No you don't. Since the arguments have to be copied into the local variables, you get the speed of pass-by-value along with its mutability. That doesn't sound like what everyone wants to me. If you have this, why would you want to do enforced const reference? Because it's the safest and fastest option. Of course this isn't what everyone wants, either. However, by making the programmer explictly ask for the other options (of which there are sevaral), we only give them exactly what they want. Perl 5 gives you the most flexible way by default (pass by ref, modifiable), and makes one other option (pass by val, modifiable) easy, but has occassionally surprising results, such as autovivification. -- Peter Haworth [EMAIL PROTECTED] E is for emacs, which rebinds your keys, and F is for fsck, which rebuilds your trees. G is for grep, a clever detective, while H is for halt, which may seem defective.
Re: Continuations for fun and profit
On Mon, 8 Jul 2002 16:54:16 -0400, Dan Sugalski wrote: while ($foo) { $foo--; } Pretty simple. (For illustrative purposes) To do that with continuations, it'd look like: $cont = take_continuation(); if ($foo) { $foo--; invoke($cont); } When you invoke a continuation you put the call scratchpads and lexical scratchpads back to the state they were when you took the continuation. If you restore the lexicals, how does this ever finish? -- Peter Haworth [EMAIL PROTECTED] It's not a can of worms, it's a tank of shai-hulud. -- Jarkko Hietaniemi
Re: Continuations for fun and profit
On Tue, 9 Jul 2002 16:42:03 +0100, Peter Haworth wrote: When you invoke a continuation you put the call scratchpads and lexical scratchpads back to the state they were when you took the continuation. If you restore the lexicals, how does this ever finish? Never mind. It's the *access* to the lexicals, not their values. -- Peter Haworth [EMAIL PROTECTED] Would you like ambiguity or something else? Press any key to continue or any other key to quit
Re: Apocalypse 4 : The Strange Case of the STRANGE CASE
On Wed, 23 Jan 2002 08:30:41 -0800 (PST), Larry Wall wrote: Andy Wardley writes: : Same with 'last/NEXT' - they're so similar : in concept that the implementation details should not matter. You mean last/LAST and next/NEXT, I suspect. But there's another argument for case differentiation. By this argument, the rethink should go in the opposite direction, giving us catch/CATCH. I like that, especially because it makes the try with no CATCH read better: try { ... } # But what happens if we fail? catch { ... } # Implicit CATCH, now made explicit! -- Peter Haworth [EMAIL PROTECTED] Jerry Springer- champion of the American free man or penile freak master? -- something Ashley Pomeroy read in _the Guardian_
Re: Some Apocalypse 4 exception handling questions.
On Tue, 22 Jan 2002 10:03:08 -0800 (PST), Larry Wall wrote: At the moment, I see this: -2. PRE in order, inherited, no side effects -1. FIRST in order 0. inline code normal flow 1. CATCH, CONTROLsingular 2. NEXT, LAST, KEEP, UNDOin reverse order 3. POST in reverse order, inherited, no side effects This is all very sensible, and I completely agree with it. However, don't we need some restrictions on what can go in PRE and POST blocks to ensure that they are still valid in inherited methods? class A; sub foo($bar,$baz){ PRE{ $bar10 } my $qux=$baz; POST{ $qux==$baz } } class B is base(A); # I forget the syntax for inheritance sub foo($x,$y){ # Insert any old random code here } Presumably, PRE/POST blocks will only be able to access their sub's arguments, since the derived class' sub may not declare the same variables as the base class (see $qux above). Or, maybe you just can't inherit from methods with such conditions, but I think that's putting the restriction in the wrong place. Or, you only inherit conditions which are inheritable, but that defeats the whole scheme. Also, these references have to be compiled into accesses to the argument list, rather than to the lexicals, otherwise they won't be any use at all to the derived class. Of course, this might be how references to sub arguments are compiled anyway, in which case there's no problem. -- Peter Haworth [EMAIL PROTECTED] Master, does Emacs have the Buddha nature? the novice asked. The Chief Priest had been in the temple for many years and could be relied upon to know these things. He thought for several minutes before replying, I don't see why not. It's got bloody well everything else.
Re: Thoughts on constancy/currying
On Fri, 9 Nov 2001 09:08:04 -0800 (PST), Larry Wall wrote: Piers Cawley writes: : sub assert_with_func (^sub is constant, $^expected is constant, : $^got, $message) : { : ^sub($expected, $got) or die $message || $default_message; : } : : Here's hoping it will work. That's my intention. Great, since this is the first rendition of that code which I can actually understand. However, Piers' typo brings up another question. In the body of such a sub, is it OK to leave out the carets, like $got and $expected do, or are they required, like ^sub ? -- Peter Haworth [EMAIL PROTECTED] In Cyberspace no one can hear you scream, unless they have a sound card.
Re: McNamara's C$# as a property of any array element
[Apologies for the late reply. Still catching up] On Thu, 17 Aug 2000 20:51:01 -0500, David L. Nicol said: What if its a method of anything in an array? $_ is already a reference to the object on the array in for loops rather than a copy of it. What if we make change be not something about for loops, but about anything in an array? print "The index, in its array, of $_ is $CORE::ARRAY_INDEX{$_}" where %CORE::ARRAY_INDEX is a very magical system-provided hash that tells us the index in its array of something that is in an array. It is often undefined; and would get tricky but definable for objects that can be in multiple containers at once, I'd think it would be the index of the item in the most recent container it was accessed from. If we are going to have arrays that can be sparse, we've pretty much got to keep track of this info somehow anyway, so might as well give a way to access it. What's wrong with defining each() on arrays? while(my($i,$v)=each @array){ print "Element at $i is $v\n"; } Then if you have a sparse array, you only get the defined elements, otherwise you get all of them. Whether for iterates over the defined elements of a sparse array, or all of them is another question. If that gets optimized into an iterator, you're only likely to get the defined elements, because that'll probably use the same mechanism as each(). I suppose there could be two mechanisms, then implementors could choose whether to make them do the same or different things. Otherwise, there should be some way of specifying that you want all elements (or only defined, whatever the default isn't) when creating an iterator or using a for loop on an array. # This is the easy bit my $iter1=$array-iter_all; my $iter2=$array-iter_def; my $iter3=$array-iter; # Default to iter_def ? # This isn't for(@$array){} # default iterator for($array-iter_all){} # Change for to call iterators? for($array-iter_def){} I suppose this also gives you the choice with each(): while(my($i,$v)=each @$array){} # Default iterator while(my($i,$v)=each $array-iter_all){} # All elements while(my($i,$v)=each $array-iter_def){} # Defined elements This is looking like for/each should act on iterators "natively", and create an iterator if given a list/hash.