RE: seperate() and/or Array.cull
Michael G Schwern: # You can do it with a map without much trouble: # # my @indexes = map { /condition/ ? $i++ : () } @stuff; Unless I'm mistaken, that won't work, since $i only gets incremented on matches. I think this: my @indexes = map { $i++; /condition/ ? $i : () } @stuff; Will work fine, though. Or, in the spirit of use-a-foreach-like-a-for (and my favorite WTDI): my @indexes = grep { $stuff[$_] =~ /condition/ } 0..$#stuff; As you might guess, I'm a (not very vocal) proponent of adding a way to get at a foreach's (or map's or grep's) current index. (Hmm, can this be done with XS? Must research...) # Its so rare that you work by array index in Perl. Usually # things flow together element by element. Sort of like how Funny, I tend to find myself working by-element fairly often, usually when I have to remove elements in the middle of a loop--something Perl doesn't like. :^( (Not that I don't understand *why* Perl doesn't allow it--just that it can be an inconvenience.) # you rarely handle strings character by character which can # severely confuse C programmers. Well, that's a silly way of working anyway. ;^) --Brent Dax [EMAIL PROTECTED] @roles=map {Parrot $_} qw(embedding regexen Configure) If you want to propagate an outrageously evil idea, your conclusion must be brazenly clear, but your proof unintelligible. --Ayn Rand, explaining how today's philosophies came to be
For's parallel iteration (was Re: seperate() and/or Array.cull)
From: Brent Dax [EMAIL PROTECTED] Date: Thu, 5 Dec 2002 00:28:52 -0800 Michael G Schwern: # You can do it with a map without much trouble: # # my @indexes = map { /condition/ ? $i++ : () } @stuff; Unless I'm mistaken, that won't work, since $i only gets incremented on matches. I think this: my @indexes = map { $i++; /condition/ ? $i : () } @stuff; Will work fine, though. Or, in the spirit of use-a-foreach-like-a-for (and my favorite WTDI): my @indexes = grep { $stuff[$_] =~ /condition/ } 0..$#stuff; Fantastic! One that doesn't use a variable temporary variable. We all write too quickly to catch errors like the one above. Except yours seems to be clean. Anyway---back to relevant topics. As you might guess, I'm a (not very vocal) proponent of adding a way to get at a foreach's (or map's or grep's) current index. (Hmm, can this be done with XS? Must research...) In Perl 5 that would be nice. In Perl 6 though, it is not necessary: for zip(@array, 0..Inf) - $v, $c { ... } That parallel iteration is just getting more and more useful (although this is a particularly ancient case). We've already been through A4, but the idea of Cfor has changed since then (I think). I don't like Czip as a name for such a thing. for interleave(@array, 0..Inf) {...} Too long. for slice (@array, 0..Inf) {...} for collate (@array, 0..Inf) {...} for parallel(@array, 0..Inf) {...} for braid (@array, 0..Inf) {...} for thread (@array, 0..Inf) {...} for weave (@array, 0..Inf) {...} The sequential list generator would almost certainly be Ceach, if we need one at all. for @array {...} for each @array: {...} for each(@array, @barry) {...} for @array, @barry {...} # Is this legal? That last one might iterate through the arrays themselves, not their elements, which would be useful on the blue moon nights. ?? Or is it still: for @array ; 0..Inf - $v ; $c { ... } I hope not. Not to delay the next Apocalypse, or anything :( Luke
Re: seperate() and/or Array.cull
Michael G Schwern writes: I'd love to be able to do it with a grep like thing. (@switches, @args) = seperate /^-/, @ARGV; Yes. I've written that function in Perl 5, which isn't ideal, because you have to return array refs, not arrays. However, I don't think it should be called 'seperate'. I also don't think it should be called 'separate', because that word seems to be commonly misspelled... It's hard to come up with a good name, though. Bad ones I've thought of include: grepboth - The unpleasant name my Perl 5 implementation has split - Overloaded meaning -- but we could perhaps get away with scalar-split and array-split being different characterize - Or do I mean 'characterise'? partition classify - These are the two I dislike least @switches = @ARGV.cull /^-/; Array.cull would remove and return a list of every element in @ARGV which matched. I'm not so fond of that -- I don't think it's as obvious that you're doing a two-way classification. -- Aaron Crane * GBdirect Ltd. http://training.gbdirect.co.uk/courses/perl/
RE: seperate() and/or Array.cull
Aaron Crane: However, I don't think it should be called 'seperate'. I also don't think it should be called 'separate', because that word seems to be commonly misspelled... That seems like an excellent argument for calling it 'separate'. Perhaps it will be the first of many spelling-improving keywords, enforced by syntax highlighting of course. grin Philip Disclaimer This communication together with any attachments transmitted with it ('this E-mail') is intended only for the use of the addressee and may contain information which is privileged and confidential. If the reader of this E-mail is not the intended recipient or the employee or agent responsible for delivering it to the intended recipient you are notified that any use of this E-mail is prohibited. Addressees should ensure this E-mail is checked for viruses. The Carphone Warehouse Group PLC makes no representations as regards the absence of viruses in this E-mail. If you have received this E-mail in error please notify our ISe Response Team immediately by telephone on + 44 (0)20 8896 5828 or via E-mail at [EMAIL PROTECTED] Please then immediately destroy this E-mail and any copies of it. Please feel free to visit our website: UK http://www.carphonewarehouse.com Group http://www.phonehouse.com
Re: seperate() and/or Array.cull
Michael G Schwern wrote: and that's just entirely too much work. I'd love to be able to do it with a grep like thing. (@switches, @args) = seperate /^-/, @ARGV; seperate() simply returns two lists. One of elements which match, one of elements which don't. I think Perl 6 will allow the above syntax to work rather than having to play with array refs. It would be nice to make it work with more than two arrays too. Something like this: (@upper, @lower, @mixed) = @array.sep { when /^[A-Z]*$/ {0} when /^[a-z]*$/ {1} default {2} } But it looks a bit dangerous, because the following won't work if @array has numbers in it: (@false_members, @true_members) = @array.sep { $_ }; # bad Maybe the solution is to make it hash-wise: %hash = @array.sep { when /^[A-Z]*$/ {'uppercase'} when /^[a-z]*$/ {'lowercase'} default {'mixedcase'} } -angel
RE: seperate() and/or Array.cull
Angel Faus: Maybe the solution is to make it hash-wise: %hash = @array.sep { when /^[A-Z]*$/ {'uppercase'} when /^[a-z]*$/ {'lowercase'} default {'mixedcase'} } I agree that general partitioning is 'better' than a fixed binary proposal, but what is gained over the full code except a tiny bit of sugar? for (@array) { when /^[A-Z]+$/ { push %hash{'uppercase'}, $_ } when /^[a-z]+$/ { push %hash{'lowercase'}, $_ } default { push %hash{'mixedcase'}, $_ } } On the other hand, perhaps binary-partitioning is sufficiently common to warrant Schwern's abbreviated syntax: (@switches, @args) = separate /^-/, @ARGV; Which in full would be something like: for (@ARGV) { when /^-/ { push @switches, $_ } default { push @args, $_ } } Philip Disclaimer This communication together with any attachments transmitted with it ('this E-mail') is intended only for the use of the addressee and may contain information which is privileged and confidential. If the reader of this E-mail is not the intended recipient or the employee or agent responsible for delivering it to the intended recipient you are notified that any use of this E-mail is prohibited. Addressees should ensure this E-mail is checked for viruses. The Carphone Warehouse Group PLC makes no representations as regards the absence of viruses in this E-mail. If you have received this E-mail in error please notify our ISe Response Team immediately by telephone on + 44 (0)20 8896 5828 or via E-mail at [EMAIL PROTECTED] Please then immediately destroy this E-mail and any copies of it. Please feel free to visit our website: UK http://www.carphonewarehouse.com Group http://www.phonehouse.com
How do you return arrays?; was: RE: seperate() and/or Array.cull
In thinking about how to write a partition function (or separate, or whatever you want to call it) it occurs to me that you might want some sort of reverse-varargs behavior, like my (@a, @b, @c, @d) = @array.partiton { $_ % 4 }; So in this case, partition is supposed to determine, on the fly, how many classes to return (or return all the classes it makes, and let an exception take mismatches). How do we do that? And in general, without resorting to something hideous like scanf, is there going to be some more-advanced want() variant that allows saying @a, $i, $j, @b, %w, $k, @c = scramble(...); ?? =Austin --- HellyerP [EMAIL PROTECTED] wrote: Angel Faus: Maybe the solution is to make it hash-wise: %hash = @array.sep { when /^[A-Z]*$/ {'uppercase'} when /^[a-z]*$/ {'lowercase'} default {'mixedcase'} } I agree that general partitioning is 'better' than a fixed binary proposal, but what is gained over the full code except a tiny bit of sugar? for (@array) { when /^[A-Z]+$/ { push %hash{'uppercase'}, $_ } when /^[a-z]+$/ { push %hash{'lowercase'}, $_ } default { push %hash{'mixedcase'}, $_ } } On the other hand, perhaps binary-partitioning is sufficiently common to warrant Schwern's abbreviated syntax: (@switches, @args) = separate /^-/, @ARGV; Which in full would be something like: for (@ARGV) { when /^-/ { push @switches, $_ } default { push @args, $_ } } Philip Disclaimer This communication together with any attachments transmitted with it ('this E-mail') is intended only for the use of the addressee and may contain information which is privileged and confidential. If the reader of this E-mail is not the intended recipient or the employee or agent responsible for delivering it to the intended recipient you are notified that any use of this E-mail is prohibited. Addressees should ensure this E-mail is checked for viruses. The Carphone Warehouse Group PLC makes no representations as regards the absence of viruses in this E-mail. If you have received this E-mail in error please notify our ISe Response Team immediately by telephone on + 44 (0)20 8896 5828 or via E-mail at [EMAIL PROTECTED] Please then immediately destroy this E-mail and any copies of it. Please feel free to visit our website: UK http://www.carphonewarehouse.com Group http://www.phonehouse.com
RE: seperate() and/or Array.cull
On Thursday, December 5, 2002, at 10:09 AM, Michael Lazzaro wrote: What about divvy (or are we already using that for something else?) my(@a,@b) = divvy { ... } @c; Other possibilities from the ol' thesaurus: Callot, Cdeal, Cdole, Cdispense. @$#@%*. Trying to do too many %#@%@ things at once. I meant 'divvy' instead of 'seperate', not 'purge', obviously (duh). I like Angel's general theorizing, but maybe we base it on Cfor instead of Cgiven? thinking aloud... Note that this does not generalize for cases 2. If you want to split things into, say, three different lists, or five, you have to use a 'given', and it gets less pleasant. Perhaps a Cdivvy can be a derivation of Cgiven or Cfor by dividing the streams, either like this: my(@a,@b,@c,@d) = divvy { /foo/ :: /bar/ :: /zap/ :: } @source; or this (?): divvy( @source; /foo/ :: /bar/ :: /zap/ ) - @a, @b, @c, @d; where C:: is whatever delimiter we deem appropriate, and an empty test is taken as the otherwise case. Just pondering. Seems like a useful variation on the whole Cgiven vs. Cgrep vs. Cfor theme, though. MikeL
Advanced Contexts (was: RE: seperate() and/or Array.cull)
On Thursday, December 5, 2002, at 07:53 AM, Austin Hastings wrote: And in general, without resorting to something hideous like scanf, is there going to be some more-advanced want() variant that allows saying @a, $i, $j, @b, %w, $k, @c = scramble(...); This is a terribly important question, for divvy() and everything else. Whether or not the description of context of a sub/block has the same robustness as the arguments of that sub/block has big implications for multimethods, among other things. I would hope that, minimally, the return type is considered part of the (multimethod) signature, and that you can test for at least the scalar types: my int $i = bar(...);# so these are my str $s = bar(...);# the same sub, but my MyClass $o = bar(...);# different multimethod variants. In my fantasy world (which I visit quite often), P6 context has descriptive capabilities matching those that can be assigned to args. (@a,@b)= foo(...); # same sub, (@a,@b,@c) = foo(...); # different multimethod variants. my int @arr = zap(...); # ... you get the idea ... my num @arr = zap(...); my MyClass @arr = zap(...); my Array of Array of Hash of MyClass @arr = zap(...); That last one leads to the obvious question of what Cwant returns in the case of compound types: my Array of Array of Hash of MyClass @arr = zap(...); ... then inside zap ... want scalar; # false; want list;# true (but what spelling?) want Array; # true (but what spelling?) want Array of Array; # true want Array of Array of Hash; # true want Array of Array of Hash of MyClass; # true want Hash; # false want MyClass;# false want Array of int; # false my $want = want; # 'Array of Array of Hash of MyClass'; (?) my @want = want; # qw(Array, Array, Hash, MyClass); (?) If we have such functionality, than divvy() and other multimethods can be tailored to DWYM even in quite specific contexts, and a lot of things become much easier. MikeL
Re: seperate() and/or Array.cull
Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm Date: Wed, 4 Dec 2002 18:26:17 -0800 From: Michael G Schwern [EMAIL PROTECTED] Content-Disposition: inline Sender: Michael G Schwern [EMAIL PROTECTED] X-SMTPD: qpsmtpd/0.12, http://develooper.com/code/qpsmtpd/ (The post about 'purge' just made me remember this idea) Lets say you have a list of program arguments. @ARGV = ('foo', '--bar=baz', 'yar'); and you want to seperate that into two lists. One of switches and one of normal args. You can't just use a grep, you'd have to do this: my @switches = (); my @args = (); foreach (@ARGV) { if( /^-/ ) { push @switches, $_; } else { push @args, $_; } } Or the concise, kindof-unreadable way: push (/^-/ ?? @switches :: @args), $_ for @*ARGS; It's too bad Perl5 croaks in so many different ways for the equivalent (the extra parens around push's arglist and the fact that /^-/ ? @s : @a isn't an array :( ) About your idea, though, I'm rather indifferent. However, a friend of mine once asked me if Perl had search or find operation, returning the Iindex of matching elements. Now am I just being braindead, or is Perl actually missing this operation? Do you really have to: my $index; for @a { last if la_dee_daa; $index++; } That can't be right But if it is, perhaps a Cfind function alongside Cmap and Cgrep would do. This is all premature---we have to wait for A28 before we start suggesting any of these. But we'll be ready for 2012! ;) Luke
Re: seperate() and/or Array.cull
On Wed, Dec 04, 2002 at 08:08:48PM -0700, Luke Palmer wrote: About your idea, though, I'm rather indifferent. However, a friend of mine once asked me if Perl had search or find operation, returning the Iindex of matching elements. Now am I just being braindead, or is Perl actually missing this operation? Do you really have to: my $index; for @a { last if la_dee_daa; $index++; } That can't be right You can do it with a map without much trouble: my @indexes = map { /condition/ ? $i++ : () } @stuff; Its so rare that you work by array index in Perl. Usually things flow together element by element. Sort of like how you rarely handle strings character by character which can severely confuse C programmers. What was your friend trying to do? -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Stupid am I? Stupid like a fox!
Re: seperate() and/or Array.cull
Date: Wed, 4 Dec 2002 19:21:27 -0800 From: Michael G Schwern [EMAIL PROTECTED] On Wed, Dec 04, 2002 at 08:08:48PM -0700, Luke Palmer wrote: About your idea, though, I'm rather indifferent. However, a friend of mine once asked me if Perl had search or find operation, returning the Iindex of matching elements. Now am I just being braindead, or is Perl actually missing this operation? Do you really have to: my $index; for @a { last if la_dee_daa; $index++; } That can't be right You can do it with a map without much trouble: my @indexes = map { /condition/ ? $i++ : () } @stuff; Braindead. Right. :) Its so rare that you work by array index in Perl. Usually things flow together element by element. Sort of like how you rarely handle strings character by character which can severely confuse C programmers. Agreed completely. I was surprised when he asked me that I had come this far without ever needing it. Kinda like the C for loop; I never use that anymore. What was your friend trying to do? Don't remember. Thanks for pointing the map thing out, though. Luke