Re: RFC 76 (v2) Builtin: reduce

2000-09-20 Thread John Porter

Graham Barr wrote:
 
 But what does it do if the block
 is a curried function of three arguments, but the list only contains two ?

Return a curried function of one argument, of course.

At least, that's what it *should* do...

-- 
John Porter




Re: RFC 76 (v2) Builtin: reduce

2000-09-20 Thread John Porter

iain truskett wrote:
 
 Return a specified value (such as 'undef'). It would allow for more
 elegant code, I think. The universe is old enough to cope by itself.

When I first read this, I thought it said:

The universe is old enough to copy itself.

!-)

-- 
John Porter




Re: RFC 76 (v2) Builtin: reduce

2000-09-20 Thread John Porter

Nathan Wiger wrote:
 
 Since undef() has established semantics, I don't think these should
 change. I believe taking from RDBMS and adding null() which has the
 correct NULL semantics is the way it should go.

You realize, I hope, that there is no end of different "special non-value"
semantics.  Perl had one, now you're proposing a second.  RDBMS gurus
have as many as 29.  One step down that path is a bad precedent.
undef is sufficient.  Let there be operators for implementing the various
semantics, NOT new special non-value values.

-- 
John Porter

We're building the house of the future together.




Re: RFC 76 (v2) Builtin: reduce

2000-09-20 Thread Glenn Linderman

John Porter wrote:

 Nathan Wiger wrote:
 
  Since undef() has established semantics, I don't think these should
  change. I believe taking from RDBMS and adding null() which has the
  correct NULL semantics is the way it should go.

 You realize, I hope, that there is no end of different "special non-value"
 semantics.  Perl had one, now you're proposing a second.  RDBMS gurus
 have as many as 29.  One step down that path is a bad precedent.
 undef is sufficient.  Let there be operators for implementing the various
 semantics, NOT new special non-value values.

29 different, but complete, sets of operators would be required, and you would
be restricted to using only one of the "special non-value" values at a time.
RDBMS gurus need at least some of their 29 to coexist.   Not a solution.

--
Glenn
=
Even if you're on the right track,
you'll get run over if you just sit there.
   -- Will Rogers



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



Re: RFC 76 (v2) Builtin: reduce

2000-09-20 Thread John Porter

Glenn Linderman wrote:
 Not a solution.

Frankly, you haven't demonstrated that there's a problem.

-- 
John Porter




RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Builtin: reduce

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 10 Aug 2000
  Last Modified: 19 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 76
  Version: 2
  Status: Frozen

=head1 ABSTRACT

This RFC proposes a builtin Creduce function, modelled after Graham Barr's
Creduce subroutine from builtin.pm

=head1 DESCRIPTION

A new builtin -- Creduce -- is proposed. 

This function would take an block, subroutine reference, or curried function 
(hereafter referred to as Ithe reduction subroutine),
and call it repeatedly to reduce the remaining arguments
(hereafter, referred to as Cthe list).

If the reduction subroutine has a prototype, that prototype
determines how many items are reduced at a time. If the reduction subroutine
is a block or has no prototype, two items are reduced each time.

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

In all cases, the elements of the list are lazily evaluated. That is,
any element of the list that is not a literal value is only evaluated
when that element is passed to (and actually used by) the reduction
subroutine.

If the original list has no elements, Creduce immediately throws an
exception. If the original list has a single element, that element is
immediately returned (without ever calling the reduction subroutine).
Otherwise, in a scalar context, the result of the final reduction call
is the result returned by Creduce. In a list context, a list of all
the interim values, plus the final value, would be returned.

If the reduction subroutine is ever terminated by a call to Clast, the
enclosing Creduce immediately returns the last reduction value -- or
list of partial values -- to that point. If the Clast occurs during
the first reduction, an exception is thrown.


=head1 EXAMPLES

Summation:

$sum = reduce {$_[0]+$_[1]} 0, @numbers;
$sum = reduce sub{$_[0]+$_[1]}, 0, @numbers;
$sum = reduce ^_+^_,0, @numbers;

Note that the first element of the list -- zero in this case, 1 in the next
example -- represents the default value if the list is empty.


Production:

$prod = reduce {$_[0]*$_[1]} 1, @numbers;
$prod = reduce sub{$_[0]*$_[1]}, 1, @numbers;
$prod = reduce ^_*^_,1, @numbers;


Minimization:

$min = reduce ^x = ^y ? ^x : ^y,  @numbers
$min = reduce ^x le ^y ? ^x : ^y,  @strings


Minimization to zero:

$min = reduce any(^x,^y)0  last || ^x^y  ^x || ^y,  @numbers


Collection:

@triples = @{ reduce sub($;$$$){ [@{shift},[@_] }, [], @singles };


Separation:

$sorted = reduce { push @{$_[0][$_[1]%2]}, $_[1]; $_[0] }
 [[],[]],
 @numbers;

Accumulative sequence generation:

@increase = reduce ^value + ^delta, $original, @bonuses;

@growth = reduce ^value * ^rate, $principal, @annual_interest_rates;


=head1 IMPLEMENTATION

Extend Graham's builtin, I'd imagine.


=head1 REFERENCES

builtin.pm

RFC: Higher Order Functions




Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Jonathan Scott Duff

On Tue, Sep 19, 2000 at 07:29:56PM -, Perl6 RFC Librarian wrote:
 =head1 TITLE
 
 Builtin: reduce

...

 Collection:
 
 @triples = @{ reduce sub($;$$$){ [@{shift},[@_] }, [], @singles };

You've a typo there, it should be:

@triples = @{ reduce sub($;$$$){ [@{shift},[@_]] }, [], @singles };

 Separation:
 
 $sorted = reduce { push @{$_[0][$_[1]%2]}, $_[1]; $_[0] }
  [[],[]],
  @numbers;

I don't understand this one.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Graham Barr

On Tue, Sep 19, 2000 at 07:29:56PM -, Perl6 RFC Librarian wrote:

 This RFC proposes a builtin Creduce function, modelled after Graham Barr's
 Creduce subroutine from builtin.pm

Please refer to List::Util rather than builtin.pm

the module name was changed as many did not like the name builting, as it was not.

Graham.

 In all cases, the elements of the list are lazily evaluated. That is,
 any element of the list that is not a literal value is only evaluated
 when that element is passed to (and actually used by) the reduction
 subroutine.

Should lists be lazy by default ? I would suggest that is a separate
language issue then reduce and reduce should follow what all other
list operators do.

 If the original list has no elements, Creduce immediately throws an
 exception.

What do you mean by exception, die ? No other builtin dies like that at
runtime. Perhaps a return of undef would be more like other operators.

 If the original list has a single element, that element is
 immediately returned (without ever calling the reduction subroutine).
 Otherwise, in a scalar context, the result of the final reduction call
 is the result returned by Creduce. In a list context, a list of all
 the interim values, plus the final value, would be returned.

Um, if it is returning a list then it is not reducing, is it ?

 If the reduction subroutine is ever terminated by a call to Clast, the
 enclosing Creduce immediately returns the last reduction value -- or
 list of partial values -- to that point. If the Clast occurs during
 the first reduction, an exception is thrown.

Again, no other builting currently throws an exception. If throwing an
exception is to become the norm then that should be a separate RFC suggesting
that builtins throw exceptions, but reduce should do what others do.

Graham.




Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread iain truskett

* Jonathan Scott Duff ([EMAIL PROTECTED]) [20 Sep 2000 07:15]:
 On Tue, Sep 19, 2000 at 07:29:56PM -, Perl6 RFC Librarian wrote:
  =head1 TITLE
  
  Builtin: reduce
[...]
  Separation:
  
  $sorted = reduce { push @{$_[0][$_[1]%2]}, $_[1]; $_[0] }
   [[],[]],
   @numbers;

 I don't understand this one.

$sorted = reduce { push @{ ^0 [ ^1 % 2 ] }, ^1; ^0 }, [[],[]], @numbers;

Hence: given an array of two arrays, put odd numbers (i.e. x % 2 == 1)
in the second array, and even numbers (i.e. x % 2 == 0) in the first one
(the zeroth array). Then return the new (filled out) pair of arrays for
the next number.

I like it.

-- 
iain truskett, aka Koschei.http://eh.org/~koschei/
You know you are addicted to coffee if...
16  Instant coffee takes too long.



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Jonathan Scott Duff

On Wed, Sep 20, 2000 at 07:31:35AM +1100, iain truskett wrote:
 * Jonathan Scott Duff ([EMAIL PROTECTED]) [20 Sep 2000 07:15]:
  On Tue, Sep 19, 2000 at 07:29:56PM -, Perl6 RFC Librarian wrote:
   =head1 TITLE
   
   Builtin: reduce
 [...]
   Separation:
   
   $sorted = reduce { push @{$_[0][$_[1]%2]}, $_[1]; $_[0] }
[[],[]],
@numbers;
 
  I don't understand this one.
 
 $sorted = reduce { push @{ ^0 [ ^1 % 2 ] }, ^1; ^0 }, [[],[]], @numbers;

I guess I'm confused with the syntax.  Shouldn't there be an - in
there?

$sorted = reduce { push @{ ^0-[^1%2] }, ^1; ^0 }, [[],[]], @numbers;

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Jonathan Scott Duff

On Wed, Sep 20, 2000 at 08:22:38AM +1100, iain truskett wrote:
 I'd believe so. I think I mentally assumed that Damian was grabbing a
 syntax trick from another RFC. 

Heh, I think the exact same thing is what confused me  :-)

 I must say that the ^0, ^1 style notation really makes some expressions
 much more legible.

Indeed.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Damian Conway

 This RFC proposes a builtin Creduce function, modelled after
 Graham Barr's Creduce subroutine from builtin.pm

Please refer to List::Util rather than builtin.pm

Noted. Thanks.


the module name was changed as many did not like the name builting,
as it was not.

Bah. I liked it -- I always thought of it as "proactive nominative
determinism" ;-)

   
 In all cases, the elements of the list are lazily evaluated. That is,
 any element of the list that is not a literal value is only evaluated
 when that element is passed to (and actually used by) the reduction
 subroutine.

Should lists be lazy by default ? I would suggest that is a separate
language issue then reduce and reduce should follow what all other
list operators do.

The difference is that I propose that Creduce be able to short-circuit.
Other list operators don't, and the proposal they they be allowed to seems
to have drowned in its own complexities :-(

Perhaps I'll remove that bit and leave it in the hands of the Master Designer.

 
 If the original list has no elements, Creduce immediately throws an
 exception.

What do you mean by exception, die ?

Yes.

   
No other builtin dies like that at
runtime. Perhaps a return of undef would be more like other operators.

That was my original proposal, but it was howled down by the
mathematical elite, who vigorously insisted that it would break the
fundamental mathematical properties of the entire Cosmos, leading to
catastrophic rifts in the timespace continuum. Or something like that.
Eventually, I gave in.

 
 If the original list has a single element, that element is
 immediately returned (without ever calling the reduction subroutine).
 Otherwise, in a scalar context, the result of the final reduction call
 is the result returned by Creduce. In a list context, a list of all
 the interim values, plus the final value, would be returned.

Um, if it is returning a list then it is not reducing, is it ?

Sure it is: cumulatively.


 If the reduction subroutine is ever terminated by a call to Clast, the
 enclosing Creduce immediately returns the last reduction value -- or
 list of partial values -- to that point. If the Clast occurs during
 the first reduction, an exception is thrown.

Again, no other builting currently throws an exception. If throwing
an exception is to become the norm then that should be a separate
RFC suggesting that builtins throw exceptions, but reduce should do
what others do.

Even at the risk of Destroying the Entire Universe???

What do others think?

Damian



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Graham Barr

On Wed, Sep 20, 2000 at 08:35:20AM +1100, Damian Conway wrote:
 No other builtin dies like that at
 runtime. Perhaps a return of undef would be more like other operators.
 
 That was my original proposal, but it was howled down by the
 mathematical elite, who vigorously insisted that it would break the
 fundamental mathematical properties of the entire Cosmos, leading to
 catastrophic rifts in the timespace continuum. Or something like that.
 Eventually, I gave in.

Well mathematitions need to learn that not everything works in a mathematical
way. Some things are just chaotic by nature.

  If the reduction subroutine is ever terminated by a call to Clast, the
  enclosing Creduce immediately returns the last reduction value -- or
  list of partial values -- to that point. If the Clast occurs during
  the first reduction, an exception is thrown.
 
 Again, no other builting currently throws an exception. If throwing
 an exception is to become the norm then that should be a separate
 RFC suggesting that builtins throw exceptions, but reduce should do
 what others do.
 
 Even at the risk of Destroying the Entire Universe???
 
 What do others think?

Ask me again tomorrow, I might change my mind :)

Graham.



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Nathan Wiger

 Even at the risk of Destroying the Entire Universe???
 
 What do others think?

I dunno, seems awfully extreme. Returning undef and testing with "||
die" seems sufficient to me...

   $sum = reduce {$_[0]+$_[1]} 0, @numbers || die "Chaos!!";

Note with the || that way, it'll die immediately if @numbers is empty,
even before destroying the universe.

If a person isn't checking values, they deserve what they get, IMO...

-Nate



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Tom Christiansen

   $sum = reduce {$_[0]+$_[1]} 0, @numbers || die "Chaos!!";

Note with the || that way, it'll die immediately if @numbers is empty,
even before destroying the universe.

Yes, but why are you passing the size of the array in there?

--tom



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Nathan Wiger

Tom Christiansen wrote:
 
$sum = reduce {$_[0]+$_[1]} 0, @numbers || die "Chaos!!";
 
 Note with the || that way, it'll die immediately if @numbers is empty,
 even before destroying the universe.
 
 Yes, but why are you passing the size of the array in there?

'Cause I'm an idiot, apparently...

   $sum = reduce {$_[0]+$_[1]} 0, @numbers or die "Chaos!!";

That's better, assuming reduce() returns undef.

I'm gonna stop writing examples in emails because I always screw them
up...

-Nate



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Damian Conway

   $sum = reduce {$_[0]+$_[1]} 0, @numbers || die "Chaos!!";

Note with the || that way, it'll die immediately if @numbers is empty,
even before destroying the universe.

Yes, but why are you passing the size of the array in there?

:-)

And even if you wrote:

  $sum = reduce(^_+^_, @numbers) || die "Chaos!!";

you're still going to over-react to a zero-sum sequence.

You need:

  defined($sum = reduce ^_+^_, @numbers) || die "Chaos!!";

Damian



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Tom Christiansen

Why not just check @numbers?

--tom



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Damian Conway

Tom suggested:

Why not just check @numbers?

Hear, hear:

$sum = @numbers ? reduce ^_+^_, @numbers : 0;

Moreover, I suspect that the usual idiom will be:

$result = reduce $reducer, $default, @list;

That is:

$sum = reduce ^_+^_, 0, @numbers;

in which case the "empty list" exception never raises (ahem) its ugly head.

I think the consensus is still that reducing an empty list shall throw an
exception.


Damian



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Randal L. Schwartz

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

Perl6 If the reduction subroutine has a prototype, that prototype
Perl6 determines how many items are reduced at a time. If the reduction subroutine
Perl6 is a block or has no prototype, two items are reduced each time.

... is inconsistent with ...

Perl6 If the original list has no elements, Creduce immediately throws an
Perl6 exception. If the original list has a single element, that element is
Perl6 immediately returned (without ever calling the reduction subroutine).

Can we resolve this?  That second paragraph doesn't take into account
what happens when I give 3 elements to a 7-element-at-a-time reduction
formula.

-- 
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 (v2) Builtin: reduce

2000-09-19 Thread Graham Barr

On Tue, Sep 19, 2000 at 04:06:00PM -0600, Tom Christiansen wrote:
 Why not just check @numbers?

Well if the 'use trisate' pragma ever arises (did anyone RFC that ?)

  $a = 1;
  $b = undef;
  $c = $a + $b;

$c is undef, not 1.

Graham.



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Nathan Wiger

Graham Barr wrote:
 
 On Tue, Sep 19, 2000 at 04:06:00PM -0600, Tom Christiansen wrote:
  Why not just check @numbers?
 
 Well if the 'use trisate' pragma ever arises (did anyone RFC that ?)

Following Glenn's lead, I'm in the process of RFC'ing a new null()
keyword and value that will do this:

  $a = 1;
  $b = null;
  $c = $a + $b;

$c is null, not 1.

Since undef() has established semantics, I don't think these should
change. I believe taking from RDBMS and adding null() which has the
correct NULL semantics is the way it should go.

One thing I'll add is the posibility to decide whether you want your
variables initialized to undef() or null():

   use initialize 'null';

Or something like that. Easy integration of DBI here we come...
(hopefully) :-)

-Nate



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Peter Scott

At 04:57 PM 9/19/00 -0700, Nathan Wiger wrote:
Following Glenn's lead, I'm in the process of RFC'ing a new null()
keyword and value that will do this:

   $a = 1;
   $b = null;
   $c = $a + $b;

$c is null, not 1.

Since undef() has established semantics, I don't think these should
change. I believe taking from RDBMS and adding null() which has the
correct NULL semantics is the way it should go.

One thing I'll add is the posibility to decide whether you want your
variables initialized to undef() or null():

use initialize 'null';

Or something like that. Easy integration of DBI here we come...
(hopefully) :-)

What DBI integration does this facilitate?  SQL uses NULL to denote a 
missing table entry.  It's outside the domains of numbers, strings, BLOBs, 
CLOBs, and everything else RDBMSes use.  So is undef in Perl.  The two 
appear made for each other.  I've got DBI modules that translate NULL to 
undef and vice versa and everything works fine.

Why do you want to be able to reproduce the NULL propagating in SQL 
expressions in Perl?  I cannot think of a use.  I can think of plenty of 
confusion caused by a 'null' keyword, which is why I thank Larry et al 
daily that they didn't put one in Perl.  Who else is tired of conversations 
like "... the null string - and by that I mean an empty string, not a 
string containing the NUL character, although of course an empty string 
actually is terminated by the NUL character, but you don't put it in..."

--
Peter Scott
Pacific Systems Design Technologies




Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Tom Christiansen

Following Glenn's lead, I'm in the process of RFC'ing a new null()
keyword and value 

As though one were not already drowning in a surfeit of subtly
dissimilar false values.

--tom



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Damian Conway

  $sum = @numbers ? reduce ^_+^_, @numbers : 0;

Although we're back to the pain of what happens when @numbers is
really fn().  This is unsatisfactorily nonidempotent (aliapotent? :-)

$sum = fn() ? reduce ^_+^_, fn() : 0;

It would seem likely that most would trade space for time and avoid the
second call to fn() with:

my @values = fn();
$sum = @values ? reduce ^_+^_, @values : 0;

In any case, the preferred option should be to provide a default value:

$sum = reduce ^_+^_, 0, @values;

which is always cleaner *and* shorter. :-)

Damian



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Nathan Wiger

 In any case, the preferred option should be to provide a default value:
 
 $sum = reduce ^_+^_, 0, @values;
 
 which is always cleaner *and* shorter. :-)

Ummm...Maybe I'm missing something, but how does reduce() know the
difference between

$sum = reduce ^_+^_, 0, @values;

unshift @values, 0;
$sum = reduce ^_+^_, @values;

$sum = reduce ^_+^_, 0, 1, 2, 3, 4, 5;

Is this just a prototyping issue? And if so, any reason not to make 0
the default value by default?

I'm still uneasy about the throwing exception thing, in case you can't
tell...

-Nate



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Tom Christiansen

Ummm...Maybe I'm missing something, but how does reduce() know the
difference between

$sum = reduce ^_+^_, 0, @values;

unshift @values, 0;
$sum = reduce ^_+^_, @values;

You know, I really find it much more legible to consistently write
these sorts of thing with braces around their code block, just as

@x = map { $_ * 3 }, 4, 5;

is infinitely better than 

@x = map $_ * 3, 4, 5;

--tom



Re: RFC 76 (v2) Builtin: reduce

2000-09-19 Thread Damien Neil

On Tue, Sep 19, 2000 at 08:14:24PM -0600, Tom Christiansen wrote:
 Following Glenn's lead, I'm in the process of RFC'ing a new null()
 keyword and value 
 
 As though one were not already drowning in a surfeit of subtly
 dissimilar false values.

Hear, hear.

Three-valued logic is enough.  Make it four-valued, and my head is
going to explode.

  - Damien