in reply to Perl6: Parting of @Arrayed See

I admit up front that at this point I am too lazy to read that thread right now but too impatient to wait with my question till later.

What I wonder is whether this can be used to supersede the rather unintuitive

my (@dir, @other); push @{ -d ? \@dir : \@other } for readdir DH;
Obviously one could say my (@dir, @other) = part [ -d, ! -d _ ] readdir DH; but I'd like to avoid the duplication. Maybe the following is possible? my (@dir, @other) = part [ -d, 1 ] readdir DH;

That would work assuming that the second test will only catch elements not already caught by the first one. I'm not sure that would be ideal though - it would limit the use of part to mostly a "catch both grep". On the other hand, if it may copy any element to any number of result lists, that specific use would require redundant tests.

Hmm..

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re: Perl6: Parting of @Arrayed See
by mojotoad (Monsignor) on Dec 15, 2002 at 10:54 UTC
    Said Aristotle:
    What I wonder is whether this can be used to supersede the rather unintuitive
    my (@dir, @other); push @{ -d ? \@dir : \@other } for readdir DH;

    First of all, I love this perl5 idiom of conditional dereferencing. It is succinct for perl enthusiasts, though probably non-obvious to those new to the language. Hence to your question, can it be more elegant in the part concept described for perl6.

    I thought of this as well. For your concept, a simple bang shortcut might suffice (I think this is what you intended, actually):

    my(@dir, @other) = part [ -d, ! ] readdir DM;

    This was probably what you proposed, sans-typo. The only difference is a '1', which leads me to believe you neglected a shift key (?).

    The general case, however, is something I had already considered. It's not merely the negation of a single conditional, it's the leftovers, the default, of the prior conditionals. So we get something like:

    (@foo,@bar,@zap,@slop) := part [ /foo/, /bar/, /zap/, ! ] @source;

    There's the modified beast. A nice fluffy beast. I like it. (I think basing the 'slop' on a surplus of receiving arrays might be pushing the obfu a bit much)

    Matt

    P.S. Is it just me, or is this starting to resemble a case statement embedded in a loop?

      Oh, I do like the ternary deref too - it's just I prefer to use map and grep wherever sensible since they're expressions.

      I did indeed mean 1 as in if(1) though. In other words, an expression that is always true and thus catches all elements that fall through to it. I'm not sure how a singular bang is supposed to be parsed - I wouldn't like it to be a special case just for part.

      On the other hand, the /foo/, /bar/, /zap/ could (and maybe should, which is what I'm wondering) return duplicate elements, that is, any list element might match several of those and would then show up in several of the result lists. That would be handy for single-pass processing of very large lists.

      I am thinking that it might be best to allow for a mixing of both semantics, that is, any true expression may or may not consume the element or pass it on. But how could this best be expressed?

      Makeshifts last the longest.

        Actually, they're even working on that. Because of new language regularization, grep (and map and part) will be a slightly different syntax in Perl 6:

            grep { block } <~ @array

        Which allows for left-to-right pipelines:

            @in ~> grep { block } ~> @out

        And, via unary ~>, allows for duplicates:

        given(@foo) { ~> grep { cond1 } ~> @out1; ~> grep { cond2 } ~> @out2; ... }
        cond1 and cond2 do not need to be mutually exclusive (and probably shouldn't be, since otherwise you could use part).

        Disclaimer: This is true this week. God only knows if it'll be true next week. ;^)

        =cut
        --Brent Dax
        There is no sig.