develooper Front page | perl.perl6.language | Postings from January 2002

Re: [dha@panix.com: Re: ^=~]

Thread Previous | Thread Next
From:
Damian Conway
Date:
January 21, 2002 15:50
Subject:
Re: [dha@panix.com: Re: ^=~]
Message ID:
3C4CA928.104AB90@conway.org
> Hmm.  A hyperdwim operator.  So that means that
> 
>     @result = @a ^=~ @b
> 
> is the same as
> 
>     @result = map -> $a; $b { $a =~ $b } (@a; @b)
> 
> Or something resembling that that actually works...
> 
> Hmm.  I suppose it could be argued that a C<for> in list context:
> 
>     @result = for @a; @b -> $a; $b { $a =~ $b }
> 
> should have the same effect.  I almost like that.

It would be nice to retire C<map>.
And list-context C<for> is an elegant and more-powerful solution.

However, it doesn't generalize to cover C<grep> well, or C<reduce>,
or C<fold>, C<spindle>, or C<mutilate> (or whatever you're actually
going to call the various multidimensional restructuring methods ;-).

You *could* instead consider reversing the arguments to all the list
manipulation operators:

	@result = map @data { mapping() }
	@result = grep @data { selector() };
	@result = sort @data { comparison() };
	@result = reduce @data { combinator() };

Then you would have the possibility of:

	@result = map @data -> $x { mapping($_, $x) }
	@result = map @data1;@data2 -> $x1;$x2 { $x1 =~ $x2 }
	@result = grep @data -> $a, $b { two_at_a_time($a, $b) };

In addition, the slightly odd, right-to-left evaluation of pipelined
data would be (partially) rectified. The Perl5-ish:

	@sorted_by_size = 
		map { $_->[0] } 
			sort { $a->[1] <=> $b->[1] } 
				map { [$_, -s] } 
					@files;

would become:

	@sorted_by_size = 
		map sort map @files
			{ [$_, -s] }
				{ $^a[1] <=> $^b[1] }
					{ $_[0] };

Though I suppose the method call approach solves that nicely too:

 	@sorted_by_size = 
		@files.map( { $_[0] })
			  .sort({ $^a[1] <=> $^b[1] })
			  .map( { [$_, -s] });

with the operations reading left-to-right, down the page.			 


Of course, now that I consider it, also solves most of the original problem:

	@result = @data.map(->$x { mapping($_, $x) });
	@result = @data.grep(->$a,$b { two_at_a_time($a, $b) });

It would be nice if it also solved the "parallel iteration" case, but
I guess that's rare and complex enough that a real C<for> is warranted anyway.

I suppose this discussion also raises the vexed question whether ??::
can also be put out to pasture in favour of:

	$val = if $x { 1 } else { 2 }

Or if the latter should perhaps be added as an alternative to:

	$val = $x ?? do{ something_more_complex_than_an_expression }
			  :: do{ operation_at_lower_precedence_than_ternary };

at least.

Not to mention:

	@squares = while <> { $_**2 };


Damian

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About