On Fri, Nov 18, 2005 at 03:31:10AM +0200, Ilmari Vacklin wrote:
: Hi all,
: 
: I think that grep should be renamed to something English and more, well,
: semantic. 'Filter' comes to mind as a suggestion. I realise there's a
: lot of cultural background (from Unix and Perl 5) that favours 'grep',
: but I think it's more important to name the language elements
: consistently (the right kind of consistency, I hope).

The name is relatively unimportant in the overall scheme of things.
I'm more worried about the fact that it's difficult to partition a
list into multiple lists in one pass without declaring temp arrays.

: It's also possible to retain 'grep' as an alias (or add the new name as
: an alias), but generally I've found having the same thing with multiple
: names doesn't help at all (I'm looking at you, Ruby).

If we had some kind of partitioning operator, it'd probably be generalized
to sorting into bins by number, where 0 and 1 are degenerate cases for
booleans.  But since we'd almost certainly make the general form

    (@bin0, @bin1, @bin2...) := classify { calc_int($_ } LIST;

It so happens that something like grep would still be useful for
the case where you're only interested in things that didn't go into
@bin0.  And my point is that maybe grep ends up being some more
general form that selects that bin.

But we're probably missing a different useful generalization here.
In Perl 5, to set a slice, you have to write

    %hash{ @keys } = @values;

whereas in Perl 6, it'd be nice to be able to say that with all
the keys and values on the right side somehow.  Notionally:

    %hash = (@keys[0] => @values[0], 
             @keys[1] => @values[1], 
             @keys[2] => @values[2], 
             ...);

which says that we want a classify primitive that somehow can turn
LIST and calc_int($_) into

    calc_int(LIST[0]) => LIST[0],
    calc_int(LIST[1]) => LIST[1],
    calc_int(LIST[2]) => LIST[2],

And then you just assign that to @bins, or filter on the pair keys
to get derived functions like grep.  I guess you can write that
right now as

    map { calc_int($_) => $_ } LIST

I guess that might combine with our new "pair" subscripts to tell assignment
that you want to assign pairs, not values:

    @bins:[] = label { calc_int($_) } LIST;

and the corresponding string version:

    %bins:{} = label { calc_str($_) } LIST;

Or if we decide :[]/:{} are too hard to see, and go with magical .pairs
and .kv instead (and it would have to be magical to work in lvalue
context):

    @bins.pairs = label { calc_int($_) } LIST;
    %bins.pairs = label { calc_str($_) } LIST;

I'm assuming there that assignment to .pairs is non-destructive.
Generally if you want to be destructive you should be using "my"
anyway.  But maybe we need to clean up the "push" vs = infelicity
as well, and make an assignment operator that pushes.

Then we could have 

    %bins.pairs = label { calc_str($_) } LIST;

be destructive and

    %bins.pairs ,= label { calc_str($_) } LIST;

means

    %bins.pairs = %bins.pairs, label { calc_str($_) } LIST;

which the non-destructive variant that is equivalent to

    push %bins.pairs, label { calc_str($_) } LIST;

Though arguably you could go at it from the other direction, and if
we are making magical lvalue methods like .pairs and .kv, then clearing
an array is just another adverbial method:

    %bins.clear.pairs = label { calc_str($_) } LIST;

or some such.  But I still don't really like magical methods
that aren't really methods.  I'd rather keep them modifiers or
pseudo-functions that can be visually distinguished from true methods.

    additional(pairs(%bins)) = label { calc_str($_) } LIST;
    clobber(pairs(%bins)) = label { calc_str($_) } LIST;
    additional(kv(%bins)) = labelkv { calc_str($_) } LIST;
    clobber(kv(%bins)) = labelkv { calc_str($_) } LIST;

or whatever.  But it'd be even nicer if we could avoid the pseudofunction
syntax as well.   It does seem rather nice to attach the clobber/nonclobber
distinction to the assignment, so maybe
 
    pairs(%bins) = label { calc_str($_) } LIST;
    pairs(%bins) ,= label { calc_str($_) } LIST;
    kv(%bins) = labelkv { calc_str($_) } LIST;
    kv(%bins) ,= labelkv { calc_str($_) } LIST;

is the cleanest solution.  If we came up with a better syntax to mark
macros and pseudofunctions then we could use it, on the order of:

    pairs[%bins] = label { calc_str($_) } LIST;
    pairs[%bins] ,= label { calc_str($_) } LIST;
    kv[%bins] = labelkv { calc_str($_) } LIST;
    kv[%bins] ,= labelkv { calc_str($_) } LIST;

or some kind of container coercion:

    (%bins but Pair) = label { calc_str($_) } LIST;
    (%bins but Pair) ,= label { calc_str($_) } LIST;
    (%bins but Kv) = labelkv { calc_str($_) } LIST;
    (%bins but Kv) ,= labelkv { calc_str($_) } LIST;

My brainstormer module is tired now.

Larry

Reply via email to