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.
[ANNOUNCE] Test::SerialFork
The uploaded file Test-SerialFork-0.01.tar.gz has entered CPAN as file: $CPAN/authors/id/P/PM/PMH/Test-SerialFork-0.01.tar.gz size: 3891 bytes md5: 087b258311b0265ad96946bfd7feb0e9 This module allows you to run the same test multiple times, with different parameters. The forking isolates the runs from each other, so that interpreter-wide changes made by one test run don't affect the others. This module is somewhat similar to Test::MultiFork, in that the test process forks a specified number of times, and runs your tests in each child process. The difference is that SerialFork only does one fork at a time, where MultiFork does them all at once. It's also much easier to give descriptive labels with SerialFork, so the output of the test program is much clearer. -- Peter Haworth [EMAIL PROTECTED] perl -Mstrict -we '$_ = goto F.print chop;\n=rekcaH lreP rehtona tsuJ;F1:eval' -- Abigail
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
PDD15: per-class attribute offsets
I have some issues with the way attributes are referenced. According to the PDD: classoffset Ix, Py, Sz Returns the offset of the first attribute for class Sz in object Py. getattribute Px, Py, Iz Returns attribute Iz of object Py and puts it in Px. Note that the attribute number is an absolute offset. So, compilers are expected to know the relative offsets of attributes within each class? That's reasonable enough, assuming that attributes are only directly accessed by code whose objects' classes have been declared. addattribute Px, Sy Add attribute Sy to class Px. This will add the attribute slot to all objects of class Px and children of class Px, with a default value of Null. Should we just try to ensure that any class which wants to add attributes to itself always uses the named version of getattribute? Do we allow code which modifies other classes' attribute lists? Do we need to mark classes as numeric/named attribute access, and restrict addattribute's use to classes which use named attributes? As well as involving much finding of instances, and moving of their attribute values, this isn't thread safe (please excuse my lack of PASM syntax knowledge): classoffset Ioff, Pobj, Sclass # Some other thread calls addattribute on Pobj's class getattribute Pattr,Pobj,Ioff # Now we have the value of the wrong attribute in Pattr -- Peter Haworth [EMAIL PROTECTED] There is no reason to use multithreading except if you are a marketing guy at Sun or Microsoft and your analysis says that it is cheaper to ram multithreading down people's throats than to fix the insanely huge process creation latency of your broken poor excuse of an operating system. -- Felix Leitner
Re: Some namespace notes
On Thu, 15 Jan 2004 23:00:53 -0800, Jeff Clites wrote: I think we shouldn't try to do any sort of cross-language unification. That is, if we some day have a Parrot version of Java, and in Perl6 code I want to reference a global created inside of some Java class I've loaded in, it would be clearer to just reference this as java.lang.String.CASE_INSENSITIVE_ORDER, even inside of Perl6 code-- rather than having to do something like java::lang::String::CASE_INSENSITIVE_ORDER. Parrot itself would be completely ignorant of any concept of a separator character--these would just be uninterpreted strings, and foo::bar and foo.bar would be separate namespaces, whatever the language. What about languages which have the same separator, such as '::' (perl5, perl6, ruby) or '.' (java, python)? They are going to be unified either way. I think it's confusing to try to unify namespaces across languages, and doesn't buy us anything. Without namespace unification, how else are you going to even specify File::Spec from java, or java.lang.string from perl5? We can obviously invent suitable syntax for perl6, so that it can cope with arbitrarily named packages, but we don't have that luxury with most of the other languages we want to support. Then the question becomes, What about namespace clashes?, which Tim has already addressed. -- Peter Haworth [EMAIL PROTECTED] Perl 5's goal was to make easy things easy, and hard things possible. We want Perl 6 to make easy things trivial, hard things easy, and impossible things merely hard. -- Damian Conway, _Linux magazine_ 2003-04
Re: Object freezing
On Tue, 21 Oct 2003 13:20:34 -0400 (EDT), Dan Sugalski wrote: On Tue, 21 Oct 2003, Jeff Clites wrote: 2) I don't see it as a huge problem that serialization code could end up creating additional objects if called from a destroy() method. User code may, parrot may not. The reasons are twofold--while parrot will let you shoot yourself in the foot, it provides the gun, not the foot. It should also be possible for carefully written destroy methods to serialize but not eat any headers or memory. (I can see this being the case in some embedded applications or systems) If we make it so freezing is not a guaranteed possibility at destroy time then this can't happen and it lessens the utility of the system some. We can, if we choose, loosen the restriction later if sufficient reason is presented. Can't really tighten it, though, so for now... -- Peter Haworth [EMAIL PROTECTED] But do not program in COBOL if you can avoid it. -- The Tao of Programming
Re: Object freezing
On Tue, 21 Oct 2003 11:39:38 -0400 (EDT), Dan Sugalski wrote: On Tue, 21 Oct 2003, Juergen Boemmels wrote: This is a question of what is allowed at destruction time. You don't want to allow memory allocation, but allow freezing. That gets hard, because you need at least allocate the STRING where you want to put your frozen stream. It's more a question of what we we require the engine to do, vs what user code is allowed to do. A user program is allowed to write code that can fail at destroy time, however the infrastructure we provide (including, in this case, freezing--while I don't like it there's no choice) can't fail that way. It's the reason the DOD and GC systems don't allocate memory (or didn't--they shouldn't) when they run. The engine's not allowed to have failure modes in critical sections. How can you serialise without using any extra memory? Even if you stream the serialised data directly to disk one byte at a time (which could fail just as easily as allocating memory to hold the serialised data in memory), serialisation of anything more complex than a native type is inherently recursive. Either you use up call stack space recursing over the PMCs, or you need an explicitly manage a stack/queue of PMCs not yet serialised. Have I missed some wonder of modern computing, or just something so obvious I can't see it? -- Peter Haworth [EMAIL PROTECTED] What's so unpleasant about being drunk? You ask a glass of water. -- Douglas Adams, HHGTTG
Ignore (was Re: Object freezing)
On Fri, 24 Oct 2003 17:33:17 +0100, Peter Haworth wrote: [stuff he didn't mean to send] Sorry. Looks like I hit Send instead of Cancel. -- Peter Haworth [EMAIL PROTECTED] this system is slightly less secure than putting your IP address and root password in big letters in a 30-second Superbowl commercial. (Though I may be wrong--it's possible I'm underestimating the danger) -- Dan Sugalski
RE: [RfC] vtable-dump
On Thu, 4 Sep 2003 09:02:18 -0400 (EDT), Dan Sugalski wrote: On Wed, 3 Sep 2003, Gordon Henriksen wrote: A seen hash is also threadsafe, can be interrupted by DoD, and is safe for recursion. (By threadsafe, I mean that unchanged data structures can be safely serialized from multiple threads without ill effect or possibility of deadlock.) While a seen hash is DOD-interruptable (which, admittedly, the scheme I'm preferring isn't, or is with a *lot* of care) it's also slower and requires a lot more resources when running. If you're freezing a large graph of PMCs, that's going to take up a lot of memory, however you do it (other than streaming to disk). What happens when you run out, and need to garbage collect? With your scheme, this is a big problem, since as you say, it's either not possible or needs a lot of care. Actually, it seems like it would need unfeasible amounts of care to me, such as recording which PMCs are flagged so the flags can be restored after DOD. Then where's the benefit over a seen hash? With the seen hash approach, I wouldn't expect the hash itself to take nearly as much space as the frozen structure; a GC run in the middle of freezing should only be a problem if you run out of *unreclaimable* memory. -- Peter Haworth [EMAIL PROTECTED] Nothing in the definition of the word `word' says that a word has to be in a dictionary to be called one. -- Anu Garg
Re: [RfC] vtable-dump
On Wed, 3 Sep 2003 09:24:22 +0200, Leopold Toetsch wrote: One general traverse() vtable is just the simpler interface IMHO. Running through each aggregate just once plus updating a seen_hash seems simpler and faster to me and doesn't have any negative impact on PMC size and DOD speed. And also makes it threadsafe? If a shared PMC is frozen simultaneously by two threads under Dan's scheme, will the right thing happen? I can't help being worried about interactions between any two operations which use flags on the PMCs to makr their progress (such as freezing and DOD, or two freezes). Bear in mind that I have never used threads and can't remember how they work in parrot, so this may be an irrelevant question. -- Peter Haworth [EMAIL PROTECTED] You're not going to watch the eclipse in yesterday's underpants?
Re: Objects, methods, attributes, properties, and other related frobnitzes
On Fri, 14 Feb 2003 15:56:25 -0500, Dan Sugalski wrote: I got clarification. The sequence is: 1) Search for method of the matching name in inheritance tree 2) if #1 fails, search for an AUTOLOAD 3) if #2 fails (or all AUTOLOADs give up) then do MM dispatch Shouldn't we be traversing the inheritance tree once, doing these three steps at each node until one works, rather doing each step once for the whole tree. MM dispatch probably complicates this, though. If my derived class has an autoloaded method which overrides the base class' method, I don't want the base class method to be called, just because parrot does things in a peculiar order. Well, I know it's the same order that perl5 does things, but it's still peculiar. -- Peter Haworth [EMAIL PROTECTED] I'm converting my data to 64-bit signed times, stored big-endian in 8 bytes, followed by 8 bytes for nanoseconds and attoseconds just in case. This won't last for more than a few hundred billion years, but neither will the Sun, and in any case I plan to throw a big programming party on 1 January 21 to upgrade to 128 bits.-- Dan J. Bernstein
Re: Objects, finally (try 1)
On Wed, 15 Jan 2003 01:00:59 -0500, Dan Sugalski wrote: At 8:53 PM -0800 1/14/03, Adriano wrote: I think what Jonathan asked for was an operator for returning a method (as an object) which can be invoked later with some arguments (or even applied with a partial list of arguments for currying). This would be a lot more useful than a yes-or-no answer about the existence of a method. I thought about this--it's what the find_method vtable method was for in the first place. Unfortunately, as was pointed out to me, there's no good way to cache the result, since it could potentially be wrong by the time the method is actually called. Is that such a big deal? The same problem exists in perl 5 with the following code: if(my $meth=$obj-can($action)){ # Stuff could happen here which redefines the method in $obj's class # However, I know it won't get redefined because I wrote the whole system $obj-$meth(); }else{ die Some custom error message or appropriate action; } Surely it's up to the person/compiler writing the code to decide whether it matters that the method has been redefined in the meantime. We shouldn't prevent something useful just because it's not universally applicable. -- Peter Haworth [EMAIL PROTECTED] I can talk on this stuff for hours when given insufficient discouragement. -- Dan Sugalski
Re: Objects, finally (try 1)
On Fri, 10 Jan 2003 11:49:14 -0500, Dan Sugalski wrote: At 1:37 PM + 1/10/03, Peter Haworth wrote: On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: #10 We do MI, but we don't instantiate a class' attributes multiple times if its in the hierarchy for a class more than once. If it is, the leftmost instance is real, the rest are virtual This will mean we can't support Eiffel Nope. :) I realised this soon after leaving for the weekend, thus leaving myself looking stupid for an extended period of time :-) Eiffel's classes, IIRC, are compile-time fixed so it can do the necessary code cloning and renaming magic to make it all work. Exactly. At the implementation level you end up directly inheriting once from the offending class, and reimplementing some/all of the features for the repeated inheritance, either directly in the derived class, or in a specially constructed modified copy of the base class which is only used for inheritance by the derived class. I'm not an Eiffel programmer either, but I have read OOSC, so I know enough to make me dangerous. -- Peter Haworth [EMAIL PROTECTED] An IRC channel, in ERROR?! On Undernet no less?! THE DEUCE YOU SAY!! Next thing you're going to tell me the commentary on Slashdot isn't totally impartial! -- Michael G Schwern
Re: Objects, finally (try 1)
On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: #10 We do MI, but we don't instantiate a class' attributes multiple times if its in the hierarchy for a class more than once. If it is, the leftmost instance is real, the rest are virtual This will mean we can't support Eiffel, which allows repeated real inheritance of the same class. It does this by allowing renaming at the feature level (thats attributes and methods in perl) when inheritance is declared. Repeated inherited features are shared if they keep the same name (and they really are the same feature), or split if they don't. -- Peter Haworth [EMAIL PROTECTED] Warning! Your Operating System is out of date! It can be replaced by a more memory abusive Operating System. Please contact your System Vendor for details.
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: String Literals, take 3
On Tue, 10 Dec 2002 16:08:25 -0500, Joseph F. Ryan wrote: Peter Haworth wrote: On Thu, 05 Dec 2002 15:17:57 -0500, Joseph F. Ryan wrote: Again, C STRING.split(' ') is different than C STRING.split(/\s+/) . The latter will add an empty element to the beginning of the string if there is leading whitespace, which is not the behaivor will have (if it acts like qw(), at any rate.) I hate this special case. Why is there no way of specifying the removal of leading empty elements with any other separator string? Given that strings and regular expressions are different types of objects, maybe the single whitespace rule could be extended to any single character delimeter That's still an unchangeable special case. In some circumstances, I might want leading empty fields when I specify space as the separator, and in others I might want them stripped with any random separator string or regex. There needs to be a way to explicitly specify whether leading blanks are required. -- Peter Haworth [EMAIL PROTECTED] I think that was lobotomy rather than trepanation wasn't it? Important to understand the difference if you're considering trepanning yourself at home -- Robin Houston
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: String Literals, take 3
On Thu, 05 Dec 2002 15:17:57 -0500, Joseph F. Ryan wrote: Again, C STRING.split(' ') is different than C STRING.split(/\s+/) . The latter will add an empty element to the beginning of the string if there is leading whitespace, which is not the behaivor will have (if it acts like qw(), at any rate.) I hate this special case. Why is there no way of specifying the removal of leading empty elements with any other separator string? -- Peter Haworth [EMAIL PROTECTED] [Microsoft is] a potential threat to our nation's economic well-being. -- Stanley Sporkin
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: String Literals, take 3
On Thu, 5 Dec 2002 04:05:05 -0500, Tanton Gibbs wrote: A string inside a \qq[] construct acts exactly as if it were an interpolated string. Note that any end-brackets, ], must be escaped within the the \qq[] construct so that the parser can read it correctly. Note that an end-bracket, ], must be escaped within the \qq[] construct. This allows the parser to correctly parse the construct. Don't embedded qq[] strings obey the normal qq[] rules? That is, will all brackets need escaping, or just unbalanced brackets? I'd hope for the latter. -- Peter Haworth [EMAIL PROTECTED] i've just returned after having no internet connection for the past 48+ hours (my isp had a router go down). christ, one more hour and i would've gone sane. -- alek benedict
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 Tue, 12 Nov 2002 14:30:24 +, Peter Haworth wrote: 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? I'm an idiot. Why not make the closure a coroutine itself? sub consume(@bar){ my $next=sub{ yielf $_ for @bar; return; }; while my $val = $next() { do_stuff($val,$next); } } sub do_stuff($val,$next){ ... if $val ~~ something_or_other() { my $quux = $next(); ... } } -- Peter Haworth [EMAIL PROTECTED] The term `Internet' has the meaning given that term in section 230(f)(1) of the Communications Act of 1934. -- H.R. 3028, Trademark Cyberpiracy Prevention Act
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: [netlabs #801] [PATCH] PerlArray in scalar context
On Wed, 4 Sep 2002 22:51:53 -0700 (PDT), Sean O'Rourke wrote: On Wed, 4 Sep 2002, Brent Dax wrote: Sean O'Rourke: # On Wed, 4 Sep 2002, Brent Dax wrote: # What if (say) @b is a two-dimensional array? # # Then you get interesting values of undef :). Seriously, I # suspect one of the following: # # 1 - runtime error # 2 - each row (or column) of @b numified to its length # 3 - the first element of each row/col of @b # 4 - the other arrays boosted to the highest dimension # # I like #2, because it is easy and keeps hyper-operation # simple. If those aren't just numeric operators, but some It's already been defined to be #4. Where? I just re-skimmed A3 and E3, but didn't find that. All A3 says is that scalars get promoted to arrays, which makes sense. Going any further doesn't necessarily DWIM. Argh. Then I need to whinge a bit -- what if it's a ragged array? What if different elements have different dimensions themselves, e.g. [1,[2,3]]? I think there's serious can-of-worms potential here, and by making hyping more intelligent, we'll actually make it useful in fewer cases. I defintely agree. Wouldn't it be simpler to just ignore the extra-dimensionality? Especially when it's a user defined operator; it could actually want one scalar and one array operand. Maybe we should have multiple carets to denote hyper-hyper-operators if that's what the user wants: @a = @b ^^* @c; If hyperoperators get transformed into loops behind the scenes, this shouldn't be too hard to implement. -- Peter Haworth [EMAIL PROTECTED] Override self destruct? (y/n@^%i@$# NO CARRIER
Re: [netlabs #801] [PATCH] PerlArray in scalar context
[OSCON has left me way behind in reading my mail, so apologies for the late reply] On Wed, 14 Aug 2002 16:45:09 -0500 (CDT), David M. Lloyd wrote: Here's how I'd expect these expressions to be executed internally, in gross pseudocode, ignoring for the moment the multimethod vaporware: $r = $a + $b; # $a-add($a, $b, $r) $r = @a + $b; # $t = @a-get_pmc(@a); $t-add($t, $b, $r) $r = $a + @b; # $t = @b-get_pmc(@b); $t-add($a, $t, $r) $r = @a + @b; # $t = @a-get_pmc(@a); $u = @b-get_pmc(@b); # $t-add($t, $u, $r); get_pmc() seems a bit vague to me. Shouldn't it be get_scalar(), or even get_number()? I've reordered the next bit to make my point more obvious. @r = @a ^+ @b;# @a-add(@a, @b, @r), easy As Sean says in his reply, making the array vtable perform hyper operations probably means having some code duplication. However, you can get around this by using a helper function which will do the hyper bits, iterating through a pair of array PMCs, applying a supplied function (with a supplied default for the case where one array is exhausted). This means that array vtable functions would mostly just consist of calls to the helper function. However, see below. @r = @a ^+ $b;# Does this distribute? If so, # @a-add(@a, $b, @r) else see above It does distribute. However, you can't do the detection of this case entirely in the vtable, because then C @a ^+ $b and C @a ^+ @$b would end up being indistinguishable (though you probably wouldn't do the first very often with an arrayref). Having the iteration done in the bytecode could make this simpler, although at the expense of needing more bytecode. You can probably have bytecode ops specifically for hyping operators though, so it might not be too bad. Also, it means we can use the same mechanism for hyping non-vtable methods. @r = $a ^+ @b;# See above Yes, but I'm not convinced that scalar-type PMCs should be responsible for detecting array-type PMCs passed as the second operand. Having the bytecode do the iteration in this case means that the appropriate vtables get used, and the scalar-type vtable routines don't get complicated with hyperoperator decisions, which will probably be a minority of cases for the first operand being a scalar. @r = $a ^+ $b;# Something that makes one-elment arrays and # uses add method on array object? Or perhaps # error Bytecode iteration means that this just ends up calling the normal scalar op, and stuffing the result into an array. Looks like I'm in favour of bytecode iteration for hyperoperators after all. -- Peter Haworth [EMAIL PROTECTED] I is for indent, which rarely amuses, and J is for join, which nobody uses. K is for kill, which makes you the boss, while L is for lex, which is missing from DOS. -- The ABC's of Unix
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: matrix design
On Thu, 20 Jun 2002 11:11:39 -0600 (MDT), Luke Palmer wrote: If the hyperness of a vmethod depends on the type of PMC it belongs to, we need to force every operand to a specific type (scalar or list/array), even if it looks like it's already the right type: $r = \@a; # Or is it just $r=@a ? $r + 3; What the hell? I'm confused here. What are you trying to do? We don't want to accidentally turn that into a hyperplus on @a's PMC, when it should really be a plus on the scalar version of @a. Which is a reference. You're adding to a reference? You can't do that (or does it somehow scalarify to the length or something?). I was thinking it would be the length. Apocalypse 2 doesn't mention this explicitly, but mentions that +%hash will return the number of elements. It should be safe to assume that +@array does the same. -- Peter Haworth [EMAIL PROTECTED] If you are going to have delusions, you may as well have really good ones -- Marcus Cole, B5
A5 implies perl6's real timescale
A5 says this: I'm accepting the basic premise of this RFC that the ?...? construct is going away, one way or another. and perlop (from 5.6.1) says this: ?PATTERN? ... This usage is vaguely deprecated, which means it just might possibly be removed in some distant future version of Perl, perhaps somewhere around the year 2168. That's a long time for implementation :-) Well, this is really only a problem for p52p6, I suppose. -- Peter Haworth [EMAIL PROTECTED] At IBM, we have no hesitation to steal or borrow other companies' technologies ... well, we don't steal of course. -- Bill Etherington
Re: Non-vtable functionality on PMCs?
On Tue, 21 May 2002 12:18:50 -0400, Dan Sugalski wrote: At 8:44 AM -0500 5/20/02, brian wheeler wrote: I've been trying to catch up with parrot again (darn it, babies take more time than I thought :) and I've come up with a question... how do you do other things to PMCs that aren't normal ops? Call methods on the perl-level classes that map to the PMCs. What if the functionality required isn't available through any number of vtable method calls? Is this what user/language defined ops are for, or do even more vtable methods have to be defined? If the latter, where do we stop? In particular, I was wondering about shift/unshift, push/pop on the PerlArray PMC. Am I missing something obvious? Ah, those. In that case you use the vtable methods I've forgotten. :) Will these all map to a splice vtable method, or will there be a method for each? -- Peter Haworth [EMAIL PROTECTED] I defy you to use the documentation to understand ... the ANSI C++ draft standard. It's not for nothing that comp.lang.std.c++ has a FAQ sixteen times the thickness of the Hong Kong phone book. -- Felix Gallo
Re: parrot rx engine
On Wed, 30 Jan 2002 17:45:58 +, Graham Barr wrote: On Wed, Jan 30, 2002 at 09:32:49AM -0800, Brent Dax wrote: # rx_setprops P0, i, 2 # branch $start0 # $advance: # rx_advance P0, $fail # $start0: # rx_literal P0, a, $advance # # First, we set the rx engine to case-insensitive. Why is that bad? It's # setting a runtime property for what should be compile-time # unicode-character-kung-fu. Assuming your CPU knows what the gritty # details of unicode in the first place just feels wrong, but I digress. That i does a once-off case-folding operation on the target string. All other input to the engine MUST already be case-folded for speed. Hm, is that going to work ? What about a rx like /^a(?i:b)C/ where the case insensitivity only applies to part of the pattern ? Or worse, in /^a(b)c/i, where you want to capture the original character, not the case-folded version? -- Peter Haworth [EMAIL PROTECTED] The term `Internet' has the meaning given that term in section 230(f)(1) of the Communications Act of 1934. -- H.R. 3028, Trademark Cyberpiracy Prevention Act
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: Thoughts on constancy/currying
[Apologies if you see this as a duplicate. I sent the original to perl6-all by mistake] On Thu, 08 Nov 2001 11:10:43 +, Piers Cawley wrote: I keep coming back to the ruby/smalltalk block approach assert_with_func := { | ^sub is constant, $^expected is constant, $^got, $message | ^sub($^expected, $^got, $message); }; Note that the suggested syntax is merely a 'port' from Ruby. I've not really considered whether this syntax would fit well with perl. The first | is reasonably obvious, but I'm not sure we can reliably spot the closing one. I remember fretting about the same thing when I wrote a Smalltalk parser, and being surprised when it turned out not to be an issue. I think this was due to the limited kinds of expressions Smalltalk allows, but it was over a decade ago, and my memory may be faulty. Anyway, couldn't you say this? assert_wth_func := sub(^sub is constant, $^expected is constant, $^got, $message){ ^sub($^expected, $^got, $message); }; I'm not sure if that still curries appropriately, though. -- Peter Haworth [EMAIL PROTECTED] ``Sarathy was concerned by the use of a whole bit for this task'' -- Simon Cozens
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.