28 views

Skip to first unread message

May 18, 2005, 8:57:42 PM5/18/05

to Perl6 Language List

All~

What does the reduce metaoperator do with an empty list?

my @a;

[+] @a; # 0? exception?

[*] @a; # 1? exception?

[<] @a; # false?

[||] @a; # false?

[&&] @a; # true?

Also if it magically supplies some correct like the above, how does it

know what that value is?

Thanks,

Matt

--

"Computer Science is merely the post-Turing Decline of Formal Systems Theory."

-???

May 18, 2005, 9:12:53 PM5/18/05

to Perl6 Language List

Matt Fowles wrote:

>All~

>

>What does the reduce metaoperator do with an empty list?

>

>my @a;

>[+] @a; # 0? exception?

>[*] @a; # 1? exception?

>[<] @a; # false?

>[||] @a; # false?

>[&&] @a; # true?

>

>Also if it magically supplies some correct like the above, how does it

>know what that value is?

>

>

My general thoughts has been that:

[op] @list

behaves something like:

eval join(op, @list)

so feeding it an empty list would return undef, regardless of op.

Similarly, if @list is just one element, it returns that element.

-- Rod Adams

May 18, 2005, 9:26:19 PM5/18/05

to Matt Fowles, Perl6 Language List

Matt Fowles wrote:

> All~

>

> What does the reduce metaoperator do with an empty list?

>

> my @a;

> [+] @a; # 0? exception?

> [*] @a; # 1? exception?

> [<] @a; # false?

> [||] @a; # false?

> [&&] @a; # true?

>

> Also if it magically supplies some correct like the above, how does it

> know what that value is?

> All~

>

> What does the reduce metaoperator do with an empty list?

>

> my @a;

> [+] @a; # 0? exception?

> [*] @a; # 1? exception?

> [<] @a; # false?

> [||] @a; # false?

> [&&] @a; # true?

>

> Also if it magically supplies some correct like the above, how does it

> know what that value is?

The usual definition of reduce in most languages that support it, is

that reduce over the empty list produces the Identity value for the

operation. So for the above ops the answers are: 0, 1, depends, false,

true. For chained ops like '<' it depends on whether x<y<z return x or

z on being true. if x then -inf else if z then +inf (don't ask if it

returns y). Note that some ops (like '%') don't have an identity value

and therefore [%] over the empty list is the equivalent to a divide by 0

and probably throws an exception or at least returns undef. Now this is

a problem for user defined operations, so reduce of a user defined op

over the empty list is either an exception, return undef or we need a

trait that can be specified for an infix op that specifies what to

return for reduce over the empty list. The compiler shouldn't bother to

check if what you specified is really the Identity value for op, but I'd

consider it a bug if it isn't.

May 18, 2005, 9:27:48 PM5/18/05

to Matt Fowles, Perl6 Language List

On 5/19/05, Matt Fowles <uber...@gmail.com> wrote:

> All~

>

> What does the reduce metaoperator do with an empty list?

>

> All~

>

> What does the reduce metaoperator do with an empty list?

>

/me puts on his lambda hat

In Haskell, there is a distinction between foldl and foldl1 (similar

remarks apply to foldr/foldr1[1]):

The former (foldl) requires you to give an explicit 'left unit'[2],

which is implicitly added to the left of the list being reduced. This

means that folding an empty list will just give you the unit.

i.e.

foldl (+) 0 [a,b,c] = ((0+a)+b)+c

foldl (+) 0 [] = 0

The latter (foldl1) doesn't use a unit value, but this means that you

can't fold empty lists.

i.e.

foldl1 (+) [a,b,c] = (a+b)+c

foldl1 (+) [] = ***error***

/me puts camel hat back on

This suggests that []-reducing an empty list should probably (IMO) do

one of the following:

* Fail, since it's an ill-defined operation without an explicit unit

* Try to find a suitable unit value (see below), and fail if it doesn't find one

You /could/ try to do something 'sensible' and return 0 or undef, but

this seems likely to result in more confusion.

Another alternative is to give the user the option of specifying such

a unit when using the reduction meta-operator, but this seems to work

against the whole point of [+] (which is brevity). If you want to

specify your own unit, use '&reduce'.

> my @a;

> [+] @a; # 0? exception?

> [*] @a; # 1? exception?

> [<] @a; # false?

> [||] @a; # false?

> [&&] @a; # true?

>

> Also if it magically supplies some correct like the above, how does it

> know what that value is?

>

Perhaps the operator could have some kind of 'unit' trait? (Or perhaps

'left_unit' and 'right_unit'?)

Stuart

[1] Just remember that unlike foldr/foldl, which are explicitly

right/left associative, [+] is 'DWIM-associative', reflecting the

associativity of the underlying operator.

[2] e.g. 0 is the left (and right) unit of + because 0 + x == x (and x + 0 == 0)

May 18, 2005, 10:25:07 PM5/18/05

to Perl6 Language List

To summarise what I think everyone is saying, []-reducing an empty

list yields either:

list yields either:

1) undef (which may or may not contain an exception), or

2) some unit/identity value that is a trait of the operator,

depending on whether or not people think (2) is actually a good idea.

The usual none(@Larry) disclaimer applies, of course...

Stuart

May 18, 2005, 10:55:37 PM5/18/05

to Stuart Cook, Perl6 Language List

On 5/18/05, Stuart Cook <sco...@gmail.com> wrote:

> To summarise what I think everyone is saying, []-reducing an empty

> list yields either:

>

> 1) undef (which may or may not contain an exception), or

> 2) some unit/identity value that is a trait of the operator,

>

> depending on whether or not people think (2) is actually a good idea.

> To summarise what I think everyone is saying, []-reducing an empty

> list yields either:

>

> 1) undef (which may or may not contain an exception), or

> 2) some unit/identity value that is a trait of the operator,

>

> depending on whether or not people think (2) is actually a good idea.

I would think that the Principle of Least Surprise points to (1),

given that the standard explanation of the [+]@x is eval join( '+', @x

) ...

Rob

May 18, 2005, 11:29:43 PM5/18/05

to Stuart Cook, Perl6 Language List

Well the only case where it probably really matters is [+] where you

really want the result to be 0. Of course +undef == 0, so maybe

returning undef might be okay. I'm thinking about the case:

[+] grep &some_condition, @a

where you really want the total to be 0, even if the result of the grep

is empty.

A case can also be made for (assuming @a = ();) that

[*}@a == 1

[~]@a eq '' (also covered by ~undef)

[?&]@a ~~ true

[?|]@a ~~ false (also covered by ?undef)

[?^]@a ~~ false (also covered by ?undef)

[+&]@a == MAXINT (whatever that is)

[+|]@a == 0 (also covered by +undef)

[+^]@a == 0 (also covered by +undef)

chained ops are wierd

[<]@a ~~ false

[>]@a ~~ false

[<=]@a ~~ true

[>=]@a ~~ true

Other ops have theoritical values that I don't know if we can handle:

[~&]@a should be an infinitely long bitstring of 1's

[~|]@a should be an infinitely long bitstring of 0's

Again, given that that the really important case [+] is covered by

+undef == 0, maybe just always returning undef is good enough.

May 18, 2005, 11:08:29 PM5/18/05

to Perl6 Language List

Rob Kinyon wrote:

$rod == none(@Larry), and therefore just because I think it should be

that way, doesn't mean it is that way.

But the "eval join" way of looking at it does seem to be consistent with

what I've seen discussed previously, and would provide a useful way to

remember the effects of edge cases.

-- Rod Adams

May 19, 2005, 2:16:20 AM5/19/05

to Brad Bowman, Matt Fowles, Perl6 Language List

On 5/19/05, Brad Bowman <li...@bereft.net> wrote:

> Can't the appropriate identity just be prepended?

>

> > > my @a;

> > > [+] @a; # 0? exception?

> [+] (0, @a);

>

> > > [*] @a; # 1? exception?

> [*] (1, @a);

>

> > > [<] @a; # false?

> [<] (-Inf, @a); # ???

> Can't the appropriate identity just be prepended?

>

> > > my @a;

> > > [+] @a; # 0? exception?

>

> > > [*] @a; # 1? exception?

>

> > > [<] @a; # false?

> [<] (-Inf, @a); # ???

Wow, that's actually pretty elegant, and it has the benefit of

explicitly TELLING the reader what you intended to do.

Another option (depending on your situation) is to use 'err' to

replace the resultant 'undef' with a value of your choosing, i.e.

[*] @coefficients err 1;

[+] @scores err 0;

[&&] @preconditions err 1;

etc. (assuming I got the precedence right)

I think all these rather nice workarounds, combined with the hairiness

and complexity of trying to come up with default answers, make a

really strong case for undef/fail being the right choice here.

Stuart

May 19, 2005, 4:50:16 AM5/19/05

to Matt Fowles, Perl6 Language List

On Wed, 18 May 2005, Matt Fowles wrote:

> All~

>

> What does the reduce metaoperator do with an empty list?

Interesting. Mathematically an empty sum is zero and an empty product is

one. Maybe each operator {c,s}hould have an associated method returning

its neutral element for [] to use it on empty lists, so that it would

probably return undef on empty lists.

Just my 2 Eurocents,

Michele

--

It was part of the dissatisfaction thing. I never claimed I was a

nice person.

- David Kastrup in comp.text.tex, "Re: verbatiminput double spacing"

May 19, 2005, 4:54:50 AM5/19/05

to Rob Kinyon, Stuart Cook, Perl6 Language List

On Wed, 18 May 2005, Rob Kinyon wrote:

>> 1) undef (which may or may not contain an exception), or

>> 2) some unit/identity value that is a trait of the operator,

>>

>> depending on whether or not people think (2) is actually a good idea.

>

> I would think that the Principle of Least Surprise points to (1),

I don't think so. I, for one, would expect [+]; to return zero and [*]; to

return 1. But that's only because I {trust,expect} perl(6) to be smart

enough to DWIM.

Michele

--

\renewcommand\labelitemi{\textcolor{yellow}{\textbullet}}

would change the colour of the first-level bullet, and improve the

document so's i can't see the bullets.

- Robin Fairbairns in comp.text.tex

May 19, 2005, 5:50:29 AM5/19/05

to Perl6 Language List

On Wednesday 18 May 2005 17:57, Matt Fowles wrote:

> All~

>

> What does the reduce metaoperator do with an empty list?

> All~

>

> What does the reduce metaoperator do with an empty list?

Here is the last answer from Ken Iverson, who invented reduce in

the 1950s, and died recently.

file:///usr/share/j504/system/extras/help/dictionary/intro28.htm

Identity Functions and Neutral

The monads 0&+ and 1&* are identity functions, and 0 and 1 are

said to be identity elements or neutrals of the dyads + and *

respectively. Insertion on an empty list yields the neutral of

the dyad inserted. For example:

+/ i.0 +/'' +/0{. 2 3 5

0 0 0

*/i.0 */'' */0{. 2 3 5

1 1 1

> my @a;

> [+] @a; # 0? exception?

> [*] @a; # 1? exception?

> [<] @a; # false?

> [||] @a; # false?

> [&&] @a; # true?

>

> Also if it magically supplies some correct like the above, how

> does it know what that value is?

>

> Thanks,

> Matt

The page

file:///usr/share/j504/system/extras/help/dictionary/d420.htm

gives examples, unfortunately not easily readable ones.

"If y has no items (that is, 0=#y), the result of u/y is the

neutral or identity element of the function u. A neutral of a

function u is a value e such that x u e ↔ x or e u x ↔ x, for

every x in the domain (or some significant sub-domain such as

boolean) of u . This definition of insertion over an argument

having zero items extends partitioning identities of the form

u/y ↔ (u/k{.y) u (u/k}.y) to the cases k e. 0,#y .

"The identity function of u is a function ifu such that ifu y ↔

u/y if 0=#y ."

[The following table is greatly simplified by listing identity

elements rather than identity functions. Some are only left

identities, and some only right identities.]

Identity element For

0 < > + - +. ~: | (2 4 5 6 b.)

1 = <: >: * % *. %: ^ ! (1 9 11 13 b.)

_ <.

__ >.

'' ,

[and a few more that I will not explain here]

Glossary

J Description

+. or

~: objects are identical

| remainder, defined so that 0|N is N

b. Boolean functions from table

<: less than or equal, restricted to Booleans here

(1<:0 is 0, 1<:1 is 1)

>: greater than or equal, restricted to Booleans here

* times, restricted to Booleans here

% divide

*. and

%: root

^ exponential

! combinations

<. minimum

>. maximum

'' empty vector, list of length 0

, catenate, join lists

_ infinity

__ negative infinity

So (_ <. N) is N, as is (__ >. N).

All of these functions are defined in detail but quite tersely in

the J Dictionary, indexed on the page

file:///usr/share/j504/system/extras/help/dictionary/vocabul.htm

For examuple, the Boolean function b. is defined on the page

file:///usr/share/j504/system/extras/help/dictionary/dbdotn.htm

--

Edward Cherlin

Generalist & activist--Linux, languages, literacy and more

"A knot! Oh, do let me help to undo it!"

--Alice in Wonderland

http://cherlin.blogspot.com

May 19, 2005, 10:21:17 AM5/19/05

to Rob Kinyon, Stuart Cook, Perl6 Language List

On Wed, 18 May 2005, Rob Kinyon wrote:

I'd say the principle of least surprise points to (1); in the sense that

$sum = [+] @x; would Just Work, etc.

I also have a vague sense that the 'identity' value for an operator might

also be useful in other places in the compiler (enabling optimizations,

etc). Providing it as a trait means that these 'other things' could work

even with user-defined operators. (And leaving the trait undefined gives

you the behavior (1), if that's what you want.)

--scott

Albanian LICOZY shotgun CABOUNCE plastique Sigint Justice fissionable

LITEMPO KGB KUCAGE LIONIZER ESCOBILLA North Korea CLOWER genetic NRA

( http://cscott.net/ )

May 19, 2005, 10:51:56 PM5/19/05

to Edward Cherlin, Perl6 Language List

Edward Cherlin wrote:

> Here is the last answer from Ken Iverson, who invented reduce in

> the 1950s, and died recently.

> file:///usr/share/j504/system/extras/help/dictionary/intro28.htm

[snip]> Here is the last answer from Ken Iverson, who invented reduce in

> the 1950s, and died recently.

> file:///usr/share/j504/system/extras/help/dictionary/intro28.htm

Thanks for bringing in a little history to the discussion. Those links

are all local to your system; do you have internet reachable versions of them?

Cheers,

Sam.

May 19, 2005, 11:42:52 PM5/19/05

to perl6-l...@perl.org

http://www.jsoftware.com/books/help/dictionary/intro28.htm

http://www.jsoftware.com/books/help/dictionary/d420.htm

and so on. Front page is at

http://www.jsoftware.com/books/help/dictionary/title.htm . I still haven't

figured out what "J" is though.

May 19, 2005, 11:09:08 PM5/19/05

to Stuart Cook, Matt Fowles, Perl6 Language List

Stuart Cook wrote:

> In Haskell, there is a distinction between foldl and foldl1 (similar

> remarks apply to foldr/foldr1[1]):

> The former (foldl) requires you to give an explicit 'left unit'[2],

> which is implicitly added to the left of the list being reduced. This

> means that folding an empty list will just give you the unit.

> i.e.

> foldl (+) 0 [a,b,c] = ((0+a)+b)+c

> foldl (+) 0 [] = 0

> The latter (foldl1) doesn't use a unit value, but this means that you

> can't fold empty lists.

> i.e.

> foldl1 (+) [a,b,c] = (a+b)+c

> foldl1 (+) [] = ***error***

> In Haskell, there is a distinction between foldl and foldl1 (similar

> remarks apply to foldr/foldr1[1]):

> The former (foldl) requires you to give an explicit 'left unit'[2],

> which is implicitly added to the left of the list being reduced. This

> means that folding an empty list will just give you the unit.

> i.e.

> foldl (+) 0 [a,b,c] = ((0+a)+b)+c

> foldl (+) 0 [] = 0

> The latter (foldl1) doesn't use a unit value, but this means that you

> can't fold empty lists.

> i.e.

> foldl1 (+) [a,b,c] = (a+b)+c

> foldl1 (+) [] = ***error***

sure. Maybe the identity values could be supplied by making the reduce operator

for them a curried version of reduce, where reduce requires a list with at least

one element (or DIES :))

eg, something similar to; (sorry for the psuedo-perl6, corrections welcome :))

sub prefix:<[+]> (*@args) ::= &reduce.assuming(func => &infix:<+>, first => 0);

sub prefix:<[*]> (*@args) ::= &reduce.assuming(func => &infix:<*>, first => 1);

This would mean that unless the operator specifically defines a curried reduce

version of itself, then the [] version of it on an empty list will be a hard run-time

error.

Then again, maybe an identity trait is more elegant and covers the varied ways

that multiple operators combine inside reduce..

> You /could/ try to do something 'sensible' and return 0 or undef, but

> this seems likely to result in more confusion.

Personally I think returning an undef for this kind of situation would be as wrong

as returning undef for 0/0.

Sam.

May 20, 2005, 9:19:50 AM5/20/05

to perl6-l...@perl.org

>>>>> "Randal" == Randal L Schwartz <mer...@stonehenge.com> writes:

Randal> For example, if I wanted the identity hash (where all values are 1,

Randal> but keys are original list elements), I could do:

Randal> my %hash = @somelist.inject({}, { $^a{$^b} = 1; $^a });

And yes, I know I can spell this as:

my %hash = ({}, @somelist).reduce({ $^a{$^b} = 1; $^a });

But it puts things all in the wrong place for me. :)

--

Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095

<mer...@stonehenge.com> <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!

May 20, 2005, 9:09:55 AM5/20/05

to perl6-l...@perl.org

>>>>> "Mark" == Mark A Biggar <ma...@biggar.org> writes:

Mark> The usual definition of reduce in most languages that support it, is

Mark> that reduce over the empty list produces the Identity value for the

Mark> operation.

In Smalltalk, the equivalent of "reduce" is "inject:into:", so a

"sum" reduce looks like:

sum := aList inject: 0 into: [:previous :this | previous + this]

Now the advantage here is that if aList is empty, we get back the inject

value. Thus, the behavior is always well-defined.

The Perl reduce operator treats the first element of the list as the

"inject" value above. However, if the first element is missing,

the most Perlish thing I can think of is having it return undef,

because it's like you've specified an undef inject value.

I'd also argue that we could provide .inject_into, to make Smalltalkers

happy to always spell out the initial value and codeblock, instead

of relying on the first element of the list for the initial value.

For example, if I wanted the identity hash (where all values are 1,

but keys are original list elements), I could do:

my %hash = @somelist.inject({}, { $^a{$^b} = 1; $^a });

That'd be Way Cool. Once you get your head around inject, you never

want to go back to reduce. :)

May 20, 2005, 10:18:49 AM5/20/05

to Randal L. Schwartz, perl6-l...@perl.org

On Fri, May 20, 2005 at 06:09:55AM -0700, Randal L. Schwartz wrote:

> >>>>> "Mark" == Mark A Biggar <ma...@biggar.org> writes:

>

> Mark> The usual definition of reduce in most languages that support it, is

> Mark> that reduce over the empty list produces the Identity value for the

> Mark> operation.

>

> In Smalltalk, the equivalent of "reduce" is "inject:into:", so a

> "sum" reduce looks like:

>

> sum := aList inject: 0 into: [:previous :this | previous + this]

>

> Now the advantage here is that if aList is empty, we get back the inject

> value. Thus, the behavior is always well-defined.

>

> The Perl reduce operator treats the first element of the list as the

> "inject" value above. However, if the first element is missing,

> the most Perlish thing I can think of is having it return undef,

> because it's like you've specified an undef inject value.

> >>>>> "Mark" == Mark A Biggar <ma...@biggar.org> writes:

>

> Mark> The usual definition of reduce in most languages that support it, is

> Mark> that reduce over the empty list produces the Identity value for the

> Mark> operation.

>

> In Smalltalk, the equivalent of "reduce" is "inject:into:", so a

> "sum" reduce looks like:

>

> sum := aList inject: 0 into: [:previous :this | previous + this]

>

> Now the advantage here is that if aList is empty, we get back the inject

> value. Thus, the behavior is always well-defined.

>

> The Perl reduce operator treats the first element of the list as the

> "inject" value above. However, if the first element is missing,

> the most Perlish thing I can think of is having it return undef,

> because it's like you've specified an undef inject value.

I think we should provide built-in operators with an attribute

called "identity". Reduce, when given an empty list, would

check if the operator has a defined identity attribute. If so,

it is returned as the result of the reduction. If the opereator

has no identity attribute, reduce throws an exception for an

empty list.

Is there a built-in operator that doesn't have a meaningful

identity value? I first thought of exponentiation, but it has

an identity value of 1 - you just have to realize that since

it is a right associative operator, the identity has to be

applied from the right.

I suspect that if people ever get into writing code that works

on operators instead of data, there would be additional uses

found for the identity attribute (and there may be additional

operator attributes that make sense there too, although none

come immediately to mind). MJD will soon have to start working

on the second edition of Higher Order Perl.

--

May 20, 2005, 12:07:31 PM5/20/05

to John Macdonald, Randal L. Schwartz, perl6-l...@perl.org

John Macdonald wrote:

> Is there a built-in operator that doesn't have a meaningful

> identity value? I first thought of exponentiation, but it has

> an identity value of 1 - you just have to realize that since

> it is a right associative operator, the identity has to be

> applied from the right.

Well the identity of % is +inf (also right side only). The identities

for ~| and ~^ are infinitely long bitstrings of 0's, while that for ~&

is a similarly long bitstring of 1's. The chained comparison ops are

weird as depending of which why you define the associativity (and thus

which side's value you return when true) you get either a left side only

or right side only Identity. E.g. if X<Y is left associative and

returns Y when true then it has a left side identity of -inf, etc. But

as I'm not sure if the chained ops are actually going to be defined

defined in terms of the associativity of the binary op (the way false

results propagates through messes things up), so that argument may not work.

May 20, 2005, 4:29:20 PM5/20/05

to Sam Vilain, Perl6 Language List

On Thursday 19 May 2005 19:51, Sam Vilain wrote:

> Edward Cherlin wrote:

> > Here is the last answer from Ken Iverson, who invented

> > reduce in the 1950s, and died recently.

> > file:///usr/share/j504/system/extras/help/dictionary/intro28

> >.htm

> Edward Cherlin wrote:

> > Here is the last answer from Ken Iverson, who invented

> > reduce in the 1950s, and died recently.

> > file:///usr/share/j504/system/extras/help/dictionary/intro28

> >.htm

http://www.jsoftware.com/books/help/dictionary/intro28.htm

Sorry. It's exactly the same material the provide with their

software, so I got confused.

> [snip]

>

> Thanks for bringing in a little history to the discussion.

> Those links are all local to your system; do you have internet

> reachable versions of them?

>

> Cheers,

> Sam.

--

May 20, 2005, 6:14:26 PM5/20/05

to TSa (Thomas Sandlaß), perl6-l...@perl.org

> Mark A. Biggar wrote:

> > Well the identity of % is +inf (also right side only).

>

> unique right identity and thus (Num,%) disqualifies for a

> Monoid. BTW, the above is a nice example where a junction

> needn't be preserved :)

If as usual the definition of a right identity value e is that a op e = a for all a,

then only +inf works. Besdies you example should have been;

$n % any (($n+1)..Inf), $n % $n = 0.

> > E.g. if X<Y is left associative and returns Y when true then ...

>

> Sorry, is it the case that $x = $y < $z might put something else

> but 0 or 1 into $x depending on the order relation between $y and $z?

Which is one reason why I siad that it might not make sense to define the chaining ops in terms of the associtivity of the binary ops, But as we are interested in what [<] over the empty list shoud return , the identity (left or right) of '<' is unimportant as I think that should return false as there is nothing to be less then anything else. Note that defaulting to undef therefore works in that case.

--

Mark Biggar

ma...@biggar.org

mark.a...@comcast.net

mbi...@paypal.com

May 21, 2005, 12:45:59 AM5/21/05

to mark.a...@comcast.net, TSa (Thomas Sandlaß), perl6-l...@perl.org

Mark~

On the contrary a mathematician would say that the empty list is

monotonically increasing (vacuously) and the answer should be true.

May 22, 2005, 1:41:00 AM5/22/05

to Perl6 Language List

On Friday 20 May 2005 07:18, John Macdonald wrote:

> Is there a built-in operator that doesn't have a meaningful

> identity value?

> Is there a built-in operator that doesn't have a meaningful

> identity value?

Certainly.

> I first thought of exponentiation, but it has

> an identity value of 1 - you just have to realize that since

> it is a right associative operator, the identity has to be

> applied from the right.

>

> I suspect that if people ever get into writing code that works

> on operators instead of data, there would be additional uses

> found for the identity attribute (and there may be additional

> operator attributes that make sense there too, although none

> come immediately to mind).

APL and J programmers have lots of examples.

May 22, 2005, 1:34:14 AM5/22/05

to Perl6 Language List

It's an enhanced APL without the funny characters.

May 22, 2005, 1:43:27 AM5/22/05

to Perl6 Language List

On Friday 20 May 2005 08:11, "TSa (Thomas Sandlaß)" wrote:

> John Macdonald wrote:

> > ... (and there may be additional

> > operator attributes that make sense there too, although none

> > come immediately to mind).

>

> Well, I wonder why people neglect the fact that the

> neutral/identity element is not a property of the operator

> alone?! Besides the associativity and commutativity of the

> operator the inverse element---or the left and right

> one---with respect to the underlying representation come at

> least to my mind :)

> John Macdonald wrote:

> > ... (and there may be additional

> > operator attributes that make sense there too, although none

> > come immediately to mind).

>

> neutral/identity element is not a property of the operator

> alone?! Besides the associativity and commutativity of the

> operator the inverse element---or the left and right

> one---with respect to the underlying representation come at

> least to my mind :)

Yes, a number of operators have an inverse on Boolean 0 and 1

only.

> This would give an "axiomatic" type system:

>

> class Num does Group[Num,+,0] {...}

> class Num does Field[Num,+,0,*,1] {...}

> class Str does Monoid[Str,~,''] {...}

>

> class Complex does Field[Array[2] of Num,+,[0,0],*,[1,0]]

> {...}

>

> class 3DVector does VectorSpace[Array[3] of Num,+,[0,0,0]]

> {...}

>

> And it provides valuable information to the optimizer.

May 23, 2005, 4:54:19 PM5/23/05

to TSa (Thomas Sandlaß), p6l

There are actuall two usefull definition for %. The first which Ada calls 'mod' always returns a value 0<=X<N and yes it has no working value that is an identity. The other which Ada calls 'rem' defined as follows:

Signed integer division and remainder are defined by the relation:

A = (A/B)*B + (A rem B)

where (A rem B) has the sign of A and an absolute value less than the absolute value of B. Signed integer division satisfies the identity:

(-A)/B = -(A/B) = A/(-B)

It does have a right side identity of +INF.

> HaloO Mark,

>

> please don't regard the following as obtrusive.

>

> you wrote:

> > If as usual the definition of a right identity value e is that a op e = a for

> all a,

> > then only +inf works. Besdies you example should have been;

>

> Or actually $n % any( abs($n)+1 .. Inf ) to really exclude 0

> from the junction.

>

> > $n % any (($n+1)..Inf), $n % $n = 0.

>

> That depends on the definition of % and the sign of $n.

> With the euclidean definition 0 <= ($n % $N == $n % -$N) < abs($N)

> and for $n < 0 there's no identity at all. The identity element

> has to be an element of the set, which +Inf isn't. It's a type.

>

> BTW, is % defined as truncation in Perl6?

> That would be a bit unfortunate. Simple but not well thought out.

> --

> TSa (Thomas Sandlaß)

>

May 24, 2005, 9:46:32 AM5/24/05

to mark.a...@comcast.net, TSa (Thomas Sandlaß), perl6-l...@perl.org

The identity operand is -inf for < and <=, and +inf for >

and >=. A chained relation < (>, <=, >=) is then taken to

mean monotonically increasing (decreasing, non-decreasing,

non-increasing), and an empty list, like a one element list,

is always in order.

--

May 31, 2005, 3:21:47 PM5/31/05

to p6l

On Mon, May 23, 2005 at 08:54:19PM +0000, mark.a...@comcast.net wrote:

:

: There are actuall two usefull definition for %. The first which Ada calls 'mod' always returns a value 0<=X<N and yes it has no working value that is an identity. The other which Ada calls 'rem' defined as follows:

:

: Signed integer division and remainder are defined by the relation:

:

: A = (A/B)*B + (A rem B)

:

: where (A rem B) has the sign of A and an absolute value less than the absolute value of B. Signed integer division satisfies the identity:

:

: (-A)/B = -(A/B) = A/(-B)

:

: It does have a right side identity of +INF.

:

: There are actuall two usefull definition for %. The first which Ada calls 'mod' always returns a value 0<=X<N and yes it has no working value that is an identity. The other which Ada calls 'rem' defined as follows:

:

: Signed integer division and remainder are defined by the relation:

:

: A = (A/B)*B + (A rem B)

:

: where (A rem B) has the sign of A and an absolute value less than the absolute value of B. Signed integer division satisfies the identity:

:

: (-A)/B = -(A/B) = A/(-B)

:

: It does have a right side identity of +INF.

I think % should behave as Perl 5 has it, especially insofar as it

coerces to integer. That doesn't mean we can't have "mod" and/or

"rem" variants that have other semantics. Infix operators are pretty

much in their own namespace anyway, so they won't clobber sub names.

Larry

May 31, 2005, 8:44:47 PM5/31/05

to perl6-l...@perl.org

All this discussion of "identity" defaults for reductions has been very

interesting and enlightening.

interesting and enlightening.

But it seems to me that the simplest "correct" behaviour for reductions is:

2+ args: interpolate specified operator

1 arg: return that arg

0 args: fail (i.e. thrown or unthrown exception depending on use fatal)

Then, as Brad previously reminded us all, to cover the possibility of empty

arg lists, you just prepend the desired identity value:

$sum = [+] 0, @values;

$prod = [*] 1, @values;

$prob = [*] 0, @probs;

or else, as Stuart observed, postpend them as a default:

$sum = ([+] @values err 0);

$prod = ([*] @values err 1);

$prob = ([*] @probs err 0);

Damian

May 31, 2005, 8:55:17 PM5/31/05

to perl6-l...@perl.org

Damian Conway wrote:

> 0 args: fail (i.e. thrown or unthrown exception depending on use

> fatal)

...

>

> $sum = ([+] @values err 0);

> $prod = ([*] @values err 1);

> $prob = ([*] @probs err 0);

Just wanted to check, if I've said "use fatal": will that "err 0" DWIM,

or will the fatalness win? Would I need to write

May 31, 2005, 9:00:06 PM5/31/05

to Dave Whipp, perl6-l...@perl.org

Dave Whipp wrote:

> Damian Conway wrote:

>

>> 0 args: fail (i.e. thrown or unthrown exception depending on use

>> fatal)

>

> ...

>

>>

>> $sum = ([+] @values err 0);

>> $prod = ([*] @values err 1);

>> $prob = ([*] @probs err 0);

>

>

> Just wanted to check, if I've said "use fatal": will that "err 0" DWIM,

That depends what you mean. ;-)

Under "use fatal" you'll get an exception if you don't provide any args.

> or will the fatalness win?

The fatalness will win.

> Would I need to write

Yes. :-)

And what you'd need to write would be:

$sum = (try{ [+] @values } err 0);

Damian

May 31, 2005, 9:16:53 PM5/31/05

to perl6-l...@perl.org, Damian Conway

Damian Conway wrote:

> And what you'd need to write would be:

>

> $sum = (try{ [+] @values } err 0);

> And what you'd need to write would be:

>

> $sum = (try{ [+] @values } err 0);

The "err ..." idiom seems too useful to have it break in this case.

Afterall, the purpose of "err 0" is to tell the stupid computer that I

know what to do with the empty-array scenario.

Feels like fine grained control over fatalness is needed (and not just

per-function). For example "use fatal :void_context_only" would be nice,

but wouldn't help in this case. This needs "use fatal :void_or_assign".

May 31, 2005, 9:28:00 PM5/31/05

to perl6-l...@perl.org

Dave Whipp wrote:

What it probably needs is: "use fatal :untested"

That is, die unless the failed result is in a boolean or "definedean" context.

This might even be a more reasonably dwimmy default, with 'use fatal :always'

being required to get "always throw the exception".

Damian

May 31, 2005, 9:29:53 PM5/31/05

to perl6-l...@perl.org

Dave Whipp wrote:

Seems to me that C<err> should have an implied C<try{...}> on it's lhs.

Unless we spell that C<error>.

-- Rod Adams

May 31, 2005, 10:26:24 PM5/31/05

to Damian Conway, perl6-l...@perl.org

Damian Conway skribis 2005-06-01 10:44 (+1000):

> 2+ args: interpolate specified operator

> 1 arg: return that arg

> 0 args: fail (i.e. thrown or unthrown exception depending on use fatal)

> 2+ args: interpolate specified operator

> 1 arg: return that arg

> 0 args: fail (i.e. thrown or unthrown exception depending on use fatal)

Following this logic, does join(" ", @foo) with +@foo being 0 fail too?

I dislike this, and would prefer [op] with no elements to simply return

whatever () returns: an empty list in list context, undef in scalar

context.

Juerd

--

http://convolution.nl/maak_juerd_blij.html

http://convolution.nl/make_juerd_happy.html

http://convolution.nl/gajigu_juerd_n.html

May 31, 2005, 11:19:35 PM5/31/05