Re: RFC 76 (v1) Builtin: reduce

2000-08-28 Thread Stephen P. Potter

Lightning flashed, thunder crashed and "Ed Mills" [EMAIL PROTECTED] whispe
red:
| So we establish a var $something=n where n is the array origin.

You mean something like $[, which we've had for many, many years.  And
which for many, many years we've discouraged the use of?

   $[  The index of the first element in an array, and of
   the first character in a substring.  Default is 0,
   but you could theoretically set it to 1 to make
   Perl behave more like awk (or Fortran) when
   subscripting and when evaluating the index() and
   substr() functions.  (Mnemonic: [ begins
   subscripts.)

   As of release 5 of Perl, assignment to `$[' is
   treated as a compiler directive, and cannot
   influence the behavior of any other file.  Its use
   is highly discouraged.

Please, let's not.  It was more confusing than it was worth the first time.

-spp



Re: RFC 76 (v1) Builtin: reduce

2000-08-27 Thread Nathan Wiger

Damian Conway wrote:
 
 But ^1, ^2, etc. have *nothing* to do with $1, $2, except analogically.
 And I'm removing that analogy from the next version of the RFC! ;-)
 
 They have *everything* to do with $_[0], $_[1], $_[2], etc.

I realize this, but I don't think most people will see it that way. I
see the analogy part much more clearly. Having ^1 and $1 be the same
makes a lot more sense than having $1 and ^0 both be the start.

Why? Consistency is key. With arrays, people understand that [0] is the
first element because they're dealing with a computer.

But with regexps (and HOFN), we're now into stuff that's good for
humans. And the "First" element should be "^1", just like for regexps.
Unless you want to start telling people that the "Zeroeth" element is
"^0".

But having the "First" element be "0" makes *no* sense. Not for humans.
It never has.

 In fact, every kind of indexing in Perl -- *except* $1, $2, etc. --
 starts at zero. Fixing $0's semantics would be far more consistent than
 breaking ^0.

That's fine too - if we want to do this, let's! Honestly. I say:

   1. Make $ARGV[0] have the program name

   2. Make $0 be the first regexp match

But I see two problems with this:

   1. Now "for (@ARGV) breaks"

   2. The "first" argument is now "0" again

Please! Make the "first" be ^1. It's more consistent and makes more
sense for us humans. 

We're not "breaking ^0" either - it doesn't exist yet. Rather, we're
fixing it before the bug hits the customer. I guarantee you this will be
a common mistake, I've done tons of work in real-life user-interface
testing. Users see *simple* analogies, not deep ones ("^1 like $1, the
first one")

If I ask you to count to ten, which number do you start with?

-Nate



Re: RFC 76 (v1) Builtin: reduce

2000-08-27 Thread Ed Mills

Making 0 the first element makes as much sense as 1- just a convention.

However there is precedence for letting the user decide. Does anyone else 
remember

  )ORIGIN 1

? So we establish a var $something=n where n is the array origin.

I don't think I'd ever use it personally, having been a c "kinder", but I 
don't presume to thinkk like everyone else and others may be more strongly 
fixated on another origin.






From: Nathan Wiger [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
CC: [EMAIL PROTECTED], Glenn Linderman [EMAIL PROTECTED]
Subject: Re: RFC 76 (v1) Builtin: reduce
Date: Sun, 27 Aug 2000 19:02:25 -0700

Damian Conway wrote:
 
  But ^1, ^2, etc. have *nothing* to do with $1, $2, except analogically.
  And I'm removing that analogy from the next version of the RFC! ;-)
 
  They have *everything* to do with $_[0], $_[1], $_[2], etc.

I realize this, but I don't think most people will see it that way. I
see the analogy part much more clearly. Having ^1 and $1 be the same
makes a lot more sense than having $1 and ^0 both be the start.

Why? Consistency is key. With arrays, people understand that [0] is the
first element because they're dealing with a computer.

But with regexps (and HOFN), we're now into stuff that's good for
humans. And the "First" element should be "^1", just like for regexps.
Unless you want to start telling people that the "Zeroeth" element is
"^0".

But having the "First" element be "0" makes *no* sense. Not for humans.
It never has.

  In fact, every kind of indexing in Perl -- *except* $1, $2, etc. --
  starts at zero. Fixing $0's semantics would be far more consistent than
  breaking ^0.

That's fine too - if we want to do this, let's! Honestly. I say:

1. Make $ARGV[0] have the program name

2. Make $0 be the first regexp match

But I see two problems with this:

1. Now "for (@ARGV) breaks"

2. The "first" argument is now "0" again

Please! Make the "first" be ^1. It's more consistent and makes more
sense for us humans.

We're not "breaking ^0" either - it doesn't exist yet. Rather, we're
fixing it before the bug hits the customer. I guarantee you this will be
a common mistake, I've done tons of work in real-life user-interface
testing. Users see *simple* analogies, not deep ones ("^1 like $1, the
first one")

If I ask you to count to ten, which number do you start with?

-Nate

_
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.

Share information about yourself, create your own public profile at 
http://profiles.msn.com.




Re: RFC 76 (v1) Builtin: reduce

2000-08-21 Thread Jeremy Howard

Bart Lateur wrote:
 On Thu, 17 Aug 2000 07:44:03 +1000, Jeremy Howard wrote:

  $a and $b were done for speed: quicker to set up those global
  variables than to pass values through the stack.

 The solution is to pass args in as $_[0] and $_[1].

 sort { $_[0] = $_[1] } @list

 is very ugly.

 I *like* the syntax of

 sort { $a = $b } @list

My original post actually said that the reason for this is that you can then
write:

  sort { ^0 = ^1 } @list;

...which is pretty Perlish.





Re: RFC 76 (v1) Builtin: reduce

2000-08-21 Thread Damian Conway

Still, 

   sort { $_[0] = $_[1] } @list

is very ugly.

Hence:

sort ^a = ^b, @list;

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-19 Thread Jeremy Howard

Array and placeholder indices both start at *zero*!
Array and placeholder indices both start at *zero*!
Array and placeholder indices both start at *zero*!
Array and placeholder indices both start at *zero*!
- Original Message -
From: "Damian Conway" [EMAIL PROTECTED]
To: "Jarkko Hietaniemi" [EMAIL PROTECTED]; "Larry Wall" [EMAIL PROTECTED]; "Jeremy
Howard" [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED]
Sent: Saturday, August 19, 2000 3:22 PM
Subject: Re: RFC 76 (v1) Builtin: reduce


 Except that Perl 6 people will know all about numbered parameters, so
they
 will write:

   @out = sort ^2 cmp ^1, @in;

 and it will work just as they expect!

 As long as they expect it to fail miserably! :-(

 Now, go home and write it out 100 times:

 "Array and placeholder indices both start at *zero*!"

 Damian






Re: RFC 76 (v1) Builtin: reduce

2000-08-19 Thread Damian Conway

 Now, go home and write it out 100 times:

 "Array and placeholder indices both start at *zero*!"

Array and placeholder indices both start at *zero*!
Array and placeholder indices both start at *zero*!
Array and placeholder indices both start at *zero*!
Array and placeholder indices both start at *zero*!

Cunning devil. Base 2!

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-19 Thread Damian Conway

I think this does the right thing too:

  @out = sort ^0 cmp ^a, @in;

Since numbered placeholders have higher priority than named, it
should create the function

  sub ($, $a) { $_[0] cmp $_[1] }
When the curry is evaluated, the a: parameter is bound to $_[1]
and the b: parameter fills in $_[0].

Yes.

If this code is used instead:

  @out = sort ^1 cmp ^a, @in;

Then a different function would be generated:

  sub ($a, $) { $_[1] cmp $_[0] }

But the code still works.

Yes.

That's kind of interesting -- the numbered placeholders define the
ordering for the parameters passed anonymously, while the named
placeholders define ordering for the parameters passed by keyword.

I keep feeling like there's something here to trip on, but I
can't find it.

Well, this:

  @out = sort ^a cmp ^0, @in;

fails very badly (but could generate a "parameter $b not used in call to
curried expression" warning under Cuse strict 'parameters').

Also:

  @out = sort ^z cmp ^a, @in;

is counterintuitive (but would also generate a warning)

And both:

  @out = sort ^l cmp ^0, @in;

and

  @out = sort ^1 cmp ^O, @in;

are very nasty in a sans serif font :-)


P.S. What the heck kind of sort is that?! O(N**3) random permutation
 sort?

Yup. Don't you just love it?! :-)



Re: RFC 76 (v1) Builtin: reduce

2000-08-18 Thread Damian Conway

Larry pointed out:

Yes, but has anyone pointed out that
   
   @out = sort ^b cmp ^a, @in;
   
won't do what people will certainly think it ought to?

It *will*, if Csort *names* the two values it passes to the
comparator!

E.g.:

sub sort (^comparator, @list) {
for (1..@list**3) {
my ($i, $j) = (rand(@list), rand(@list));
@list[$i,$j] = @list[$j,$i]
unless $comparator-(a: $list[$i], b: $list[$j]);
}
return @list;
}


(And now you know why I never fill in the IMPLEMENTATION section ;-)

Damian




Re: RFC 76 (v1) Builtin: reduce

2000-08-18 Thread Jeremy Howard

Larry Wall wrote:
 Jarkko Hietaniemi writes:
 :   (Yes, there is a small aesthetic edge in using $a vs $_[0], but I
still
 :   consider the $ and $b to be warts.)
 :  
 :  And anyhow, this will work just fine (see RFC 23):
 : 
 :$sum = reduce ^a + ^b, @numbers;
 :
 : I have been amply reminded of this, thanks :-)  (Too little time
 : to spend on RFCs...)

 Yes, but has anyone pointed out that

@out = sort ^b cmp ^a, @in;

 won't do what people will certainly think it ought to?

Except that Perl 6 people will know all about numbered parameters, so they
will write:

  @out = sort ^2 cmp ^1, @in;

and it will work just as they expect! (See RFC 23 for information about how
numbered, named, and anonymous placeholders get filled in).





Re: RFC 76 (v1) Builtin: reduce

2000-08-18 Thread Glenn Linderman

Clever, and really obscure; wouldn't this then require that _everyone_ that
writes a curried expression for the sort sub use ^a  ^b, and that everyone
writing a non-curried sort sub name their parameters a and b?  I guess that
wouldn't necessarily be bad, but it would be restrictive.

Damian Conway wrote:

 Larry pointed out:

 Yes, but has anyone pointed out that

@out = sort ^b cmp ^a, @in;

 won't do what people will certainly think it ought to?

 It *will*, if Csort *names* the two values it passes to the
 comparator!

 E.g.:

 sub sort (^comparator, @list) {
 for (1..@list**3) {
 my ($i, $j) = (rand(@list), rand(@list));
 @list[$i,$j] = @list[$j,$i]
 unless $comparator-(a: $list[$i], b: $list[$j]);
 }
 return @list;
 }

 (And now you know why I never fill in the IMPLEMENTATION section ;-)

 Damian

--
Glenn
=
There  are two kinds of people, those
who finish  what they start,  and  so
on... -- Robert Byrne


___
Why pay for something you could get for free?
NetZero provides FREE Internet Access and Email
http://www.netzero.net/download/index.html



Re: RFC 76 (v1) Builtin: reduce

2000-08-18 Thread Damian Conway

Except that Perl 6 people will know all about numbered parameters, so they
will write:

  @out = sort ^2 cmp ^1, @in;

and it will work just as they expect!

As long as they expect it to fail miserably! :-(

Now, go home and write it out 100 times:

"Array and placeholder indices both start at *zero*!"

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-18 Thread Glenn Linderman

Damian Conway wrote:

 Clever, and really obscure;

 "Invisible", rather than "obscure", I would say.
 DWIMity of the first order. :-)

 wouldn't this then require that _everyone_ that
 writes a curried expression for the sort sub use ^a  ^b, and that everyone
 writing a non-curried sort sub name their parameters a and b?

 No, that's the lovely part. If you use positional placeholders or the
 anonymous placeholder, the resulting curried function has *unnamed*
 parameters, so the *order* of the arguments passed by Csort is all
 that matters.

So that's what I missed, that you expect named actual parameters to be legally
passable to subs with unnamed formal parameters.  I would consider that
inappropriate, needing at least a warning.  If people want to use named parameters
with a sub with unnamed formal parameters, they should curry a wrapper.

 So all of these work as expected (as a consequence of the standard
 semantics of named parameters):

 @sorted = sort ^b = ^a, @list;# reverse sort
 @sorted = sort ^1 = ^0, @list;# reverse sort

I note your use of ^0 and ^1 where I and another poster both used ^1  ^2.  I wonder
how many people will have to learn about ^0 if you implement it as a positional
placeholder.  Note that regexp produces $1, $2 ..., not $0.  And people really do
count from 1, until they've been indoctinated that computer arrays start at 0.  But
placeholders are not an array.

 @sorted = sort ^_ = ^_, @list;# normal sort
 @sorted = sort {$_[1] = $_[0]}, @list;# reverse sort
 @sorted = sort sub{$_[1] = $_[0]}, @list; # reverse sort

 The only case that traps the unwary is:

 @sorted = sort ^y = ^x, @list;# normal sort!

 But I don't think Larry was worried about that -- just about the inevitable
 resonances with the late unlamented $a and $b.

 Damian

--
Glenn
=
There  are two kinds of people, those
who finish  what they start,  and  so
on... -- Robert Byrne



_NetZero Free Internet Access and Email__
   http://www.netzero.net/download/index.html



Re: RFC 76 (v1) Builtin: reduce

2000-08-18 Thread Damian Conway

So that's what I missed, that you expect named actual parameters to
be legally passable to subs with unnamed formal parameters. I would
consider that inappropriate, needing at least a warning.

Perhaps under:

use strict 'parameters';

   
If people want to use named parameters
with a sub with unnamed formal parameters, they should curry a wrapper.

Which Csort could, of course, also do (if it was decided that bully-boy,
fascist named parameters were the more appropriate default ;-).


I note your use of ^0 and ^1 where I and another poster both used
^1  ^2. I wonder how many people will have to learn about ^0 if
you implement it as a positional placeholder. Note that regexp
produces $1, $2 ..., not $0. And people really do count from 1,
until they've been indoctinated that computer arrays start at 0.
But placeholders are not an array.

No indeed. They are short-hand for indexing operations into an array (@_).
And array indices *do* start from zero.

In contexts like this (and others such as Cgrep) the omission of ^0
from a comparator would surely evoke a diagnostic.

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-17 Thread Ariel Scolnicov

Nathan Torkington [EMAIL PROTECTED] writes:

 Piers Cawley writes:
The $a and $b of the sort comparator were A Bad Idea to begin with.
   
   Ditto. Can we ditch these in Perl 6? Don't see why $_[0] and $_[1] can't
   be used, or even a more standard $1 and $2. Either one makes it more
   obvious what's being operated on.
  
  $1  $2 could be somewhat dangerous in a sub that might have regexen
  in it...
 
 $1 and $2 are a poor choice because of regexps.
 
 $a and $b were done for speed: quicker to set up those global
 variables than to pass values through the stack.  The documentation
 for perl5's sort function says that passing as arguments is
 considerably slower.  I don't think you can handwave and say "oh,
 that's an implementation detail".  I think it's an implementation
 detail that's bloody hard to fix, especially for things like code
 references passed to sort:
 
   sort $some_ref @unordered
 
 Perl can't do anything at compile-time to tell sort where lexicals
 in the sort sub are.

Then it doesn't have to.  But if the sub is explicitly specified
(maybe according to the easy-closure RFCs) then it *can* do it
efficiently.  In most cases I've seen, when a complex order criterion
is used sort gets passed Csort {complex_criterion($a,$b)} @list, so
we're saving little.

Document that if you're "too clever" then you lose speed (for a
suitable value of "too clever").  But at least make the simple cases
easy.


 So I don't have a solution, I just have more detail on the problem. 

-- 
Ariel "Glad I'm on -language and not on -internals" Scolnicov



Re: RFC 76 (v1) Builtin: reduce

2000-08-16 Thread Piers Cawley

Nathan Wiger [EMAIL PROTECTED] writes:

 Jarkko Hietaniemi wrote:
 
  The $a and $b of the sort comparator were A Bad Idea to begin with.
 
 Ditto. Can we ditch these in Perl 6? Don't see why $_[0] and $_[1] can't
 be used, or even a more standard $1 and $2. Either one makes it more
 obvious what's being operated on.

$1  $2 could be somewhat dangerous in a sub that might have regexen
in it...




Re: RFC 76 (v1) Builtin: reduce

2000-08-16 Thread Nathan Torkington

Piers Cawley writes:
   The $a and $b of the sort comparator were A Bad Idea to begin with.
  
  Ditto. Can we ditch these in Perl 6? Don't see why $_[0] and $_[1] can't
  be used, or even a more standard $1 and $2. Either one makes it more
  obvious what's being operated on.
 
 $1  $2 could be somewhat dangerous in a sub that might have regexen
 in it...

$1 and $2 are a poor choice because of regexps.

$a and $b were done for speed: quicker to set up those global
variables than to pass values through the stack.  The documentation
for perl5's sort function says that passing as arguments is
considerably slower.  I don't think you can handwave and say "oh,
that's an implementation detail".  I think it's an implementation
detail that's bloody hard to fix, especially for things like code
references passed to sort:

  sort $some_ref @unordered

Perl can't do anything at compile-time to tell sort where lexicals
in the sort sub are.

So I don't have a solution, I just have more detail on the problem. 

Nat



Re: RFC 76 (v1) Builtin: reduce

2000-08-16 Thread Jeremy Howard

Nathan Torkington wrote:
 Piers Cawley writes:
The $a and $b of the sort comparator were A Bad Idea to begin with.
  
   Ditto. Can we ditch these in Perl 6? Don't see why $_[0] and $_[1]
can't
   be used, or even a more standard $1 and $2. Either one makes it more
   obvious what's being operated on.
 
  $1  $2 could be somewhat dangerous in a sub that might have regexen
  in it...

 $1 and $2 are a poor choice because of regexps.

 $a and $b were done for speed: quicker to set up those global
 variables than to pass values through the stack.  The documentation
 for perl5's sort function says that passing as arguments is
 considerably slower.  I don't think you can handwave and say "oh,
 that's an implementation detail".  I think it's an implementation
 detail that's bloody hard to fix, especially for things like code
 references passed to sort:

   sort $some_ref @unordered

 Perl can't do anything at compile-time to tell sort where lexicals
 in the sort sub are.

 So I don't have a solution, I just have more detail on the problem.

The solution is to pass args in as $_[0] and $_[1]. Using higher-order
function notation allows these args to be named however you like:

  sort ^left cmp ^right, @list;
  sort ^1 cmp ^2, @list;
  sort ^_ cmp ^_, @list;





Re: RFC 76 (v1) Builtin: reduce

2000-08-15 Thread Adam Krolnik



Following the lead of the sort operator, it would be a little
simpler to see reduce expressions use $a and $b instead of
$_[0], $_[1].

E.g.

Summation:

 $sum = reduce{$a + $b} 0, @numbers;
 $sum = reduce sub{$a + $b},0, @numbers;



 Production:

 $prod = reduce{$a * $b}1, @numbers;
 $prod = reduce sub{$a * $b},   1, @numbers;



Following grep, map, sort, reduce should be able to 
accept all these forms - currently the form seems to be like
sort than grep and map.

  reduce $a + $b, @list  # grep, map
  reduce{$a + $b} @list  # grep, map, sort
  reducesum2  @list  # sort
  reduce sub{$a + $b}, @list # sort


Adam Krolnik
Verification Mgr.
LSI Logic Corp.
Plano TX. 75074



Re: RFC 76 (v1) Builtin: reduce

2000-08-15 Thread Jarkko Hietaniemi

On Tue, Aug 15, 2000 at 11:31:50AM -0500, Adam Krolnik wrote:
 
 
 Following the lead of the sort operator, it would be a little
 simpler to see reduce expressions use $a and $b instead of
 $_[0], $_[1].

The $a and $b of the sort comparator were A Bad Idea to begin with.
There's nothing wrong with using the standard @_.  The $a and $b just
introduce yet another special case, which among other things makes it
very hard to warn about dubious uses of users' variables named $a or $b.
(Yes, there is a small aesthetic edge in using $a vs $_[0], but I still
consider the $ and $b to be warts.)

-- 
$jhi++; # http://www.iki.fi/jhi/
# There is this special biologist word we use for 'stable'.
# It is 'dead'. -- Jack Cohen



Re: RFC 76 (v1) Builtin: reduce

2000-08-15 Thread Nathan Wiger

Jarkko Hietaniemi wrote:

 The $a and $b of the sort comparator were A Bad Idea to begin with.

Ditto. Can we ditch these in Perl 6? Don't see why $_[0] and $_[1] can't
be used, or even a more standard $1 and $2. Either one makes it more
obvious what's being operated on.

It also fixes the "'use strict' ignores $a and $b problem" mentioned
repeatedly on p5p.

-Nate



Re: RFC 76 (v1) Builtin: reduce

2000-08-15 Thread Jeremy Howard

Jarkko Hietaniemi wrote:
 On Tue, Aug 15, 2000 at 11:31:50AM -0500, Adam Krolnik wrote:
  
  
  Following the lead of the sort operator, it would be a little
  simpler to see reduce expressions use $a and $b instead of
  $_[0], $_[1].
 
 The $a and $b of the sort comparator were A Bad Idea to begin with.
 There's nothing wrong with using the standard @_.  The $a and $b just
 introduce yet another special case, which among other things makes it
 very hard to warn about dubious uses of users' variables named $a or $b.
 (Yes, there is a small aesthetic edge in using $a vs $_[0], but I still
 consider the $ and $b to be warts.)
 
And anyhow, this will work just fine (see RFC 23):

  $sum = reduce ^a + ^b, @numbers;





Re: RFC 76 (v1) Builtin: reduce

2000-08-15 Thread Jarkko Hietaniemi

  (Yes, there is a small aesthetic edge in using $a vs $_[0], but I still
  consider the $ and $b to be warts.)
  
 And anyhow, this will work just fine (see RFC 23):
 
   $sum = reduce ^a + ^b, @numbers;

I have been amply reminded of this, thanks :-)  (Too little time
to spend on RFCs...)

-- 
$jhi++; # http://www.iki.fi/jhi/
# There is this special biologist word we use for 'stable'.
# It is 'dead'. -- Jack Cohen



Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread Bart Lateur

On 11 Aug 2000 09:30:03 +0300, Ariel Scolnicov wrote (and quoted):

  reduce avg $identity, @list

This was my first point regarding Creduce -- not all functions have
an identity element.  One should note that in general

(reduce avg $x,@list) != (reduce sum 0,@list)/@list

for Iany value of $x; your reduction is Inot the right way to
compute an average (I don't know if it was meant to be or not, but it
got me).

If you can tell me why you wish to perform this reduction, you should
also be able to figure out an identity element.  You're computing

(($list[0]+$list[1])/2 + $list[2])/2 + ...

for some reason. 

I have some reservations about this reduce() thing. Plain and simple
incorporating it into the core language would introduce the chance for
lots of buggy programs, like the example Arial gave. In fact, I think
that *most* programs that use reduce() would be buggy. But there is more
still.

On a more theoretical plane, what does

reduce { $_[0] OP $_[1] } $x, $y, $z;

represent? Is it the programmer's idea of this?

$x OP $y OP $z

But, is that:

($x OP $y) OP $z

or

$x OP ($y OP $z)

We are used to thinking of associative operators, like "+" and "*",
where it makes no difference. A simple replacement by "-" is already a
counter example. The "average" example above, is too. (An "operator" and
a "function" are basically the same thing with a different notation.) I
think that *virtually all* programs that people would write using
reduce(), would fall into this category.

Besides, in functions like map() and grep(), execution order shouldn't
matter. I think that *still* the processing order of the arguments isn't
officially stated as "always from left to right" (as with the coma
operator), even though highly respected Perl hackers like Abigail (see
comp.lang.perl.misc) strongly depend on it. So, what's it going to be
here? I think that if your code depends on execution order, you
shouldn't be using this functional programming paradigm.

I think we don't really need reduce(). There are well working,
relatively simple, and *far more transparent* alternatives, at least,
for Perl. We do have OP= operators, after all. For example:

$total = 0;
map { $total += $_ } @list;  # if you insist...
return $total;

How is this so bad, compared to:

reduce { $_[0] + $_[1] } @list

Is the latter shorter? Hardly. Would it be faster? I doubt it. Is it
more transparent to see what it does, or is supposed to do? NOT AT ALL.

-- 
Bart.



Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread Graham Barr

On Thu, Aug 10, 2000 at 07:22:21PM -0400, Chaim Frenkel wrote:
 Okay, then for
 
   reduce avg $identity, @list
 
 What should $identity be?

I would like to see what avg would be, given that each time it
would be passed the previous result (or the first element) and
the next element.

So without using an external variable to keep count of how many
elements had been processed so far it could not be done. So you
would probably do it like

  (reduce __+__ 0, @list) / @list.

This will ensure that the sum is defined.

However this is probably just a bad exanple of why not to require an
identity element.

A better example might be trying to perform join, with reduce eg

  reduce __.','.__ $identity, @list

Which would not work for any value of $identity unless you did

  reduce __.','.__ shift @list, @list

which is probably a good example why not to require an identity element.

Graham.

  "AS" == Ariel Scolnicov [EMAIL PROTECTED] writes:
 
 AS Think of the first element of the list as different from the rest --
 AS it is the initial value to reduce from (for + and *, you'll usually
 AS pick an appropriate identity element).  By writing
 
 AS @sum = reduce __+__ 0, @numbers
 
 AS you deal elegantly with both cases.
 
 AS NOTE: I find this trick very elegant.  I wish it were my trick,
 AS instead of Damian's...
 
 -- 
 Chaim Frenkel  Nonlinear Knowledge, Inc.
 [EMAIL PROTECTED] +1-718-236-0183
 



Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread John Porter

Damian Conway wrote:
 
 More and more I lean towards a scalar-only reduce.

Yep!


 Simpler semantics and you can always ref a L(OL(OL(OL...etc.))) if you need
 multidimensionals.

Combined with highlander variables, and there ceases to be a problem.

-- 
John Porter




Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread Piers Cawley

John Porter [EMAIL PROTECTED] writes:
  Simpler semantics and you can always ref a L(OL(OL(OL...etc.))) if you need
  multidimensionals.
 
 Combined with highlander variables, and there ceases to be a problem.

Will you stop with the highlander variables?

-- 
Piers




Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread John Porter

Bart Lateur wrote:
 
 I have some reservations about this reduce() thing. Plain and simple
 incorporating it into the core language would introduce the chance for
 lots of buggy programs, like the example Arial gave. In fact, I think
 that *most* programs that use reduce() would be buggy. 

Whenever people try to use language features with which they are but
passingly familiar (or grossly unfamiliar), buggy programs result. 
Again, your argument could also be applied to OO -- but perl isn't
dropping OO any time soon.


 We are used to thinking of associative operators, like "+" and "*",
 where [operator order] makes no difference.
 
 Besides, in functions like map() and grep(), execution order shouldn't
 matter. I think that *still* the processing order of the arguments isn't
 officially stated as "always from left to right" ...
 So, what's it going to be here?

The answer to this objection is simply to declare an official order
of execution.  Left-to-right.


 I think that if your code depends on execution order, you
 shouldn't be using this functional programming paradigm.

Wrong.  Functional programming is in some sense merely procedural
programming but without side-effects.  There's no golden rule of FP
saying execution order is irrelevant; and I don't see how there could
be.  Maybe you're getting it confused with declarative programming...


 I think we don't really need reduce().

Some people thought perl would have been better off without OO, too.
Should Larry of listened to them?  Or should he have listened to the
significantly larger number of people (including himself) who though
OO would be a good addition to perl?


 There are well working,
 relatively simple, and *far more transparent* alternatives, at least,
 for Perl. 

So, you're saying recursion should be eliminated from perl.
I don't think that's gonna fly.


   $total = 0;
   map { $total += $_ } @list;  # if you insist...
   return $total;
 
 How is this so bad, compared to:
 
   reduce { $_[0] + $_[1] } @list
 
 Is the latter shorter? Hardly. 

Huh?  It's significantly shorter.  It's one statement vs. three, and
requires no temporary variables.


 Would it be faster? I doubt it. 

What do you base that on?  The fact that the reduce() version would
involve so many more costly perl OPs?

-- 
John Porter




Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread Graham Barr

On Fri, Aug 11, 2000 at 10:51:45AM -0400, John Porter wrote:
 Damian Conway wrote:
  
  More and more I lean towards a scalar-only reduce.
 
 Yep!

Have you stollen my brain :)

Graham.



Re: RFC 76 (v1) Builtin: reduce

2000-08-11 Thread Damian Conway

A better example might be trying to perform join, with reduce eg

  reduce __.','.__ $identity, @list

Which would not work for any value of $identity unless you did

  reduce __.','.__ shift @list, @list

which is probably a good example why not to require an identity element.

Just to clarify: the proposal does not (and will not) *require* an
identity element.

prototype('CORE::reduce') == '@'.

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Ariel Scolnicov

Perl6 RFC Librarian [EMAIL PROTECTED] (but actually it was Damian
Conway) writes:

 If the original list has no elements, Creduce immediately returns Cundef.

I like everything except this part.  Reducing an empty list should be
an error.

Returning undef (or anything else, really) breaks the algebraic
equivalence that

f((reduce \f, LIST), $x) eq (reduce \F, LIST, $x)

Since this is the single most important property of reduce (indeed, it 
is the *only* property of reduce), I don't see what we get by breaking 
it.

Also, the RFC should specify that the function is always evaluated in
a scalar context (for things to make sense).

-- 
Ariel Scolnicov|"GCAAGAATTGAACTGTAG"| [EMAIL PROTECTED]
Compugen Ltd.  |Tel: +972-2-6795059 (Jerusalem) \ We recycle all our Hz
72 Pinhas Rosen St.|Tel: +972-3-7658514 (Main office)`-
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555http://3w.compugen.co.il/~ariels



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Damian Conway

I don't see it.

   1 == f((reduce +, undef), 1) == reduce +, undef, 1

undef isn't an empty list, it's a one element list.

Consider the other "common" reduction:

sub f { $_[0] * $_[1] }

Now:

f((reduce \f, ()), 1) == 0 # f(undef,1) - f(0,1) - 0
   
But
reduce \f, (), 1 == 1  # list flattens to (1),
# single element immediately returned


I really would like to be able to pass around an empty list and get
a _reasonable_ answer. Having to check the list for emptyness before
passing it in just seems dirty. One doesn't have to do this for anyother
looping operator in the language.

   for (@empty) {}
   grep {} @empty
   map {} @empty

None of which *combines* its (possibly non-existent) values together.
   
  
AS Also, the RFC should specify that the function is always evaluated in
AS a scalar context (for things to make sense).

Why? reduce should be able to reduce a set of matrices to a matrix. Or
actually any aggregate (plural whatzit).

I think this is too limiting.

Depending upon the context reduce should return undef, an empty list,
or other empty plural whatzit.

H. I need to see more debate on this before I decide what to propose
in the next version of the RFC.

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Ariel Scolnicov

Chaim Frenkel [EMAIL PROTECTED] writes:

  "AS" == Ariel Scolnicov [EMAIL PROTECTED] writes:
 
  If the original list has no elements, Creduce immediately returns Cundef.
 
 AS I like everything except this part.  Reducing an empty list should be
 AS an error.
 
 AS Returning undef (or anything else, really) breaks the algebraic
 AS equivalence that
 
 AS f((reduce \f, LIST), $x) eq (reduce \F, LIST, $x)
 
 I don't see it.
 
   1 == f((reduce +, undef), 1) == reduce +, undef, 1

You're confusing "f()" and "+" here, and (on the LHS) "undef" with
"()".  What you're claiming is that

f(undef, 1) eq 1

for any function f().  While this is true (in Perl) for C__+__, it's
not even true for C__*__.  And of course there's nothing you can do
about user-specified functions f().

 I really would like to be able to pass around an empty list and get
 a _reasonable_ answer. Having to check the list for emptyness before
 passing it in just seems dirty. One doesn't have to do this for anyother
 looping operator in the language.
 
   for (@empty) {}
   grep {} @empty
   map {} @empty
 
 etc.

Think of the first element of the list as different from the rest --
it is the initial value to reduce from (for + and *, you'll usually
pick an appropriate identity element).  By writing

@sum = reduce __+__ 0, @numbers

you deal elegantly with both cases.

NOTE: I find this trick very elegant.  I wish it were my trick,
instead of Damian's...

[...]

-- 
Ariel Scolnicov|"GCAAGAATTGAACTGTAG"| [EMAIL PROTECTED]
Compugen Ltd.  |Tel: +972-2-6795059 (Jerusalem) \ We recycle all our Hz
72 Pinhas Rosen St.|Tel: +972-3-7658514 (Main office)`-
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555http://3w.compugen.co.il/~ariels



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Damian Conway

By writing @sum = reduce __+__ 0, @numbers 
you deal elegantly with both cases.

NOTE: I find this trick very elegant.  I wish it were my trick,
instead of Damian's...

Damian wishes it were Damian's, but is sure it's at least a few hundred
years old :-)

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Damian Conway

Couldn't reduce return a list just through concatenating its elements? For
instance:

  @a = (1,3,2,4,3,6,4,8);
  @sum = reduce( (^total, ^x+^y ), @a );  # (4,6,9,12)

Currying placeholders are scalars, so you want:

  @sum = @{reduce (@^total, ^x+^y ), [], @a };

More and more I lean towards a scalar-only reduce.

Simpler semantics and you can always ref a L(OL(OL(OL...etc.))) if you need
multidimensionals.

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Jeremy Howard

Chaim Frenkel wrote:
 Okay, then for

 reduce avg $identity, @list

 What should $identity be?

What's wrong with:

  $average = reduce (^last+^this, @^list) / scalar @^list;
  print $average-([1,3,5]);   # Prints '3'

You don't need to explicitly add a '0' to the front of the summed list.
Although I guess for a geometric average you have to be more careful:

  $geo_average =
reduce (defined(^last)?^last:1 * ^this, @^list)
** (1/scalar @^list);
  print $geo_average-([1,2,4]);   # Prints '2'





Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Glenn Linderman

Damian Conway wrote:

 Currying placeholders are scalars

Is that a general truth?  It wasn't obvious from RFC 23... If you rev it, perhaps
you could make that clearer.

Looking back, the defining example did give a list of (;) in the prototype.  I
suppose it would be pretty complex to infer the type from the expression, unless
the placeholder syntax were extended to ^$_, ^@_, ^%_, and similar for named and
positional placeholders...  Seems like if we get matrix ops (via other RFCs) that
we might want to curry them?

Here I was thinking a placeholder was a whatzitz whatzitz; of unknown cardinality.
Is it, or not?

--
Glenn
=
There  are two kinds of people, those
who finish  what they start,  and  so
on... -- Robert Byrne



_NetZero Free Internet Access and Email__
   http://www.netzero.net/download/index.html



Re: RFC 76 (v1) Builtin: reduce

2000-08-10 Thread Damian Conway

 Currying placeholders are scalars

Is that a general truth?

Yes. It proceeds from the fact that $_[0], $_[1], ect are scalars.

   
It wasn't obvious from RFC 23... If you
rev it, perhaps you could make that clearer.

Will do.

   
Looking back, the defining example did give a list of (;) in
the prototype. I suppose it would be pretty complex to infer the
type from the expression, unless the placeholder syntax were
extended to ^$_, ^@_, ^%_, and similar for named and positional
placeholders... Seems like if we get matrix ops (via other RFCs)
that we might want to curry them?

That's why I think we ought to strict with array refs for multidimensional
data.

   
Here I was thinking a placeholder was a whatzitz whatzitz; of
unknown cardinality. Is it, or not?

Not. It's always a slot for a scalar.

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-09 Thread Chaim Frenkel

Please consider the possiblity of tristate logic (RFC TBD.) ala, SQL.

Assuming a "use tristate", undef + number = undef

This might require that the reduce function be able to ignore undefs.
Either always under the tristate pragma. Or on a case by case basis.

Also you haven't specified if the arguments to reduce are evaluated
lazily.

chaim

 "PRL" == Perl6 RFC Librarian [EMAIL PROTECTED] writes:

PRL The first call to the reduction subroutine will be passed the first N
PRL elements of the list, and subsequent calls will be passed the result of
PRL the previous call and the next N-1 elements in the list, until no more
PRL elements remain in the list. If fewer than N-1 elements remain on the
PRL final call, all the remaining elemetns are passed.

PRL If the original list has no elements, Creduce immediately returns Cundef.
PRL If the original list has a single element, that element is immediately returned
PRL (without every calling the reduction subroutine).
PRL Otherwise, the result of the final reduction call is the result returned
PRL by Creduce.

PRL If the reduction subroutine is ever terminated by a call to Clast,
PRL the enclosing Creduce immediately returns the last reduction value
PRL (i.e. Cundef on the first reduction call, $_[0] otherwise)

-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: RFC 76 (v1) Builtin: reduce

2000-08-09 Thread Bart Lateur

On 09 Aug 2000 13:49:24 -0400, Chaim Frenkel wrote:

Assuming a "use tristate", undef + number = undef

This might require that the reduce function be able to ignore undefs.
Either always under the tristate pragma. Or on a case by case basis.

grep defined, LIST

-- 
Bart.



Re: RFC 76 (v1) Builtin: reduce

2000-08-09 Thread Chaim Frenkel

 "DC" == Damian Conway [EMAIL PROTECTED] writes:

DC I'm not sure how this would affect the proposal. If an item in the
DC list being reduced is undef, it appears in the reduction
DC subroutines arg list as undef.  The reduction subroutine can then
DC handle it (or not) as it chooses.

DC For example, to short-circuit if the reduction ever becomes undef:

DC $sum = { defined $_[0] or last; $_[0]+$_[1] } 0, @numbers;

Actually, it would be easier to do in reduce, the undefs should
simply be ignored.

Otherwise having the user code it, becomes

{ defined $_[0]  defined $_[1] ? $_[0] + $_[1] 
: defined $[0] ? $_[0] : $_[1] }

Pretty ugly.

And for the N case, it gets even uglier. So reduce should be able
to supply the next N-1 defined() values.

chaim
-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: RFC 76 (v1) Builtin: reduce

2000-08-09 Thread Damian Conway

Actually, it would be easier to do in reduce, the undefs should
simply be ignored.

Otherwise having the user code it, becomes

   { defined $_[0]  defined $_[1] ? $_[0] + $_[1] 
   : defined $[0] ? $_[0] : $_[1] }

Pretty ugly.

And for the N case, it gets even uglier. So reduce should be able
to supply the next N-1 defined() values.

$def_sum = reduce { $_[0]+$_[1] } grep {defined} @numbers;

Damian



Re: RFC 76 (v1) Builtin: reduce

2000-08-09 Thread Randal L. Schwartz

 "Chaim" == Chaim Frenkel [EMAIL PROTECTED] writes:

DC For example, to short-circuit if the reduction ever becomes undef:

DC $sum = { defined $_[0] or last; $_[0]+$_[1] } 0, @numbers;

Chaim Actually, it would be easier to do in reduce, the undefs should
Chaim simply be ignored.

If I understand you correctly, I want to disagree with you.

What if the "reduce" was to count the number of undefs?

  $count = reduce { $a + not defined $b } 0, @some_list;

Do not discard undef from the source list.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!



Re: RFC 76 (v1) Builtin: reduce

2000-08-09 Thread Damian Conway

Builtin: reduce

There are some things unspecified. Specifically 'special' reduce variables. 
You've got:

 $sum = reduce {$_[0]+$_[1]} 0, @numbers;
 $sum = reduce ^_+^_,0, @numbers;
 $min = reduce ^x = ^y ? ^x : ^y,  @numbers

I see $_[foo], ^_, and ^somename. I understand how we get to $_[foo], and I 
can intuit what ^_ means (though it should be specified, I think), but what 
about ^name?

All covered in the higher order functions RFC.

Did I not include a reference to that?
Oops, no I didn't. Apologies.

Damian