Re: reduce metaoperator on an empty list

2005-06-17 Thread TSa (Thomas Sandlaß)

Damian Conway wrote:

Let's assume that op is overloaded for two completely unrelated types
A and B, which are both defining their respective identity elements
but !(A.identval =:= B.identval). How should the &op multi method object
pick the correct one *without* looking at $value's type?



Your mistake is in thinking that the identity trait is on the operand 
type. It isn't; it's on the operator itself.


I agree, that the pair of operator and type which determines the identity
element can be stored as a trait of the operator implementation. *But* the
operator selection from the multi has to use the type of $value. In
particular it might not be inferable at compile time. Thus the compiler
has to produce MMD code and hook half way into it to perform the selected
call with two args: the identity &op.identval and $value.

Which brings me to the question: is there a syntax to invoke the
target selection from a multi? E.g. &op.select($value,$value) here?
Or is it &op:($value,$value)?
--
TSa (Thomas Sandlaß)




Re: reduce metaoperator on an empty list

2005-06-16 Thread Edward Cherlin
On Thursday 09 June 2005 12:21, John Macdonald wrote:
> On Thu, Jun 09, 2005 at 06:41:55PM +0200, "TSa (Thomas Sandla
�" wrote:
> > Edward Cherlin wrote:
> > >That means that we have to straighten out the functions
> > > that can return either a Boolean or an item of the
> > > argument type. Comparison functions < > <= >= = != should
> > > return only Booleans,
> >
> > I'm not sure but Perl6 could do better or at least trickier
> > ;) Let's assume that < > <= >= when chained return an
> > accumulated boolean and the least or greatest value where
> > the condition was true. E.g.
> >
> >   0 < 2 < 3   returns  0 but true
> >
> >   1 < 2 < 1   returns  1 but false
> >
> >   4 < 5 < 2   returns  2 but false
> >
> > Then the reduce versions [<] and [<=] naturally come out as
> > min and strict min respectively.
> >
> > Is it correct that [min] won't parse unless min is declared
> > as an infix op, which looks a bit strange?
> >
> > if 3 min 4 { ... }

That's how it was done in APL. In fact, that's how every dyadic 
(two-argument) function was done in APL. It looks strange at 
first, but the syntax is simpler.

"I eat my peas with honey.
I've done it all my life.
It makes them taste real funny,
But it keeps them on the knife."

> The natural method of implementation would imply that the
> final is returned:
>
> 0 < 2 < 3   returns  3 but true
>
> 1 < 2 < 1   returns  1 but false
>
> 4 < 5 < 2   returns  2 but false
>
> The application of each stage of the chain has to remember
> the right hand value (for the next stage of the comparison)
> as well as the accumulated boolean result.  When the boolean
> result is true, that has < and <= returning the max, and > and
>
> >= returning the min - the opposite of what you asked above.

In J one can do (<)/ 0 1 1, evaluated as
0<(1<1)
0<0
0

Then, since 0<0 is 0, and 0<1 is 1, 0 is a left identity of < 
(restricted to Booleans), and http://cherlin.blogspot.com


Re: reduce metaoperator on an empty list

2005-06-09 Thread Sam Vilain

TSa (Thomas Sandlaß) wrote:

I'm not sure but Perl6 could do better or at least trickier ;)
Let's assume that < > <= >= when chained return an accumulated
boolean and the least or greatest value where the condition was
true. E.g.
  0 < 2 < 3   returns  0 but true
  1 < 2 < 1   returns  1 but false
  4 < 5 < 2   returns  2 but false


An interesting idea, but seems a bit heavy..


Is it correct that [min] won't parse unless min is declared
as an infix op, which looks a bit strange?
if 3 min 4 { ... }


Sure.  Again there is a Haskell example to heed closely here; for instance, the 
function:

   divMod :: (Integral a) => a -> a -> (a, a)

Can be written as either;

   divMod 42 9

or:

   42 `divMod` 9

The reverse direction is ();

   (+) :: (Num a) => a -> a -> a

   (+) 7 5

   7 + 5

Sam.


Re: reduce metaoperator on an empty list

2005-06-09 Thread Damian Conway

Edward Cherlin wrote:


You haven't convinced me, but rather than flog a dead horse,
I'll just suggest that we both reserve the right to say "I
told you so" when there are several years' worth of Perl 6
code out there, and we see how common our respective examples
are.
 
No need to wait. There is a ton of APL and J code to inspect. 
Having predefined identity elements for reductions on empty 
arrays is widely exploited. 


I would be more convinced by this body of experience if I felt that the wide 
exploitation of implicit identity elements actually helped improve the 
predictability and maintainability of programs written in those languages, 
neither of which is renowned for its accessibility to ordinary programmers. ;-)


Damian


Re: reduce metaoperator on an empty list

2005-06-09 Thread Damian Conway

TSa (Thomas Sandlaß) wrote:


Let's assume that op is overloaded for two completely unrelated types
A and B, which are both defining their respective identity elements
but !(A.identval =:= B.identval). How should the &op multi method object
pick the correct one *without* looking at $value's type?


Your mistake is in thinking that the identity trait is on the operand type. It 
isn't; it's on the operator itself.




Or is the
intent to enforce a unique identity value for each operator like 0 for +
and 1 for *?


Almost. Remember that overloaded operators are also distinguishable by their 
operand types, so you can specify separate identity values for C<&infix:<+>(Num, 
Num)> and C<&infix:<+>(Matrix, Matrix)>.




There's actually a second problem. Will the &op.does(identval) condition
be true or false if the &op multi contains some targets with and some
without an identval?


The op will have already been selected by the MMD mechanism before that question 
is asked.




Finally I don't understand how the knowledge about a pending assignment
eases the choice problem for the multi. Note that the choice of
assignment operator depends on the return value of the operator and
the type of which the lhs is undef.


The MMD mechanism sorts out which op is required, either by looking at the 
static type of the lhs variable, or by treating the undef as a coercion 
(Manhattan distance = 1)


Damian


Re: reduce metaoperator on an empty list

2005-06-09 Thread John Macdonald
On Thu, Jun 09, 2005 at 06:41:55PM +0200, "TSa (Thomas Sandlaß)" wrote:
> Edward Cherlin wrote:
> >That means that we have to straighten out the functions that can 
> >return either a Boolean or an item of the argument type. 
> >Comparison functions < > <= >= = != should return only Booleans,
> 
> I'm not sure but Perl6 could do better or at least trickier ;)
> Let's assume that < > <= >= when chained return an accumulated
> boolean and the least or greatest value where the condition was
> true. E.g.
> 
>   0 < 2 < 3   returns  0 but true
> 
>   1 < 2 < 1   returns  1 but false
> 
>   4 < 5 < 2   returns  2 but false
> 
> Then the reduce versions [<] and [<=] naturally come out as min
> and strict min respectively.
> 
> Is it correct that [min] won't parse unless min is declared
> as an infix op, which looks a bit strange?
> 
> if 3 min 4 { ... }

The natural method of implementation would imply that the
final is returned:

0 < 2 < 3   returns  3 but true
  
1 < 2 < 1   returns  1 but false
  
4 < 5 < 2   returns  2 but false

The application of each stage of the chain has to remember
the right hand value (for the next stage of the comparison)
as well as the accumulated boolean result.  When the boolean
result is true, that has < and <= returning the max, and > and
>= returning the min - the opposite of what you asked above.
When the numbers are not in the desired order, it would be
nice to shirtcircuit and not continue on with the meaningless
comparisons as soon as one fails - which means that the max
or min value could not be known.

Whatever is chosen, though, still has to make sense for other
chained comparisons:

$v != $w < $x > $z == $z

cannot sensibly return either the max or the min (which would
it choose?).

I'd be inclined to have the result be val but true/false
where val is the right hand operand of the final comparison
actually tested.  When a consistant set of operators is used
(a mixture of <, <=, and ==; or a mixture of >, >=, and ==)
- then a true boolean result also provides the max (or min
respectively) value, while a false boolean result provides
the value of the first element that was out of order.

-- 


Re: reduce metaoperator on an empty list

2005-06-09 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

: Might I add that it should read
: 
:   $var = (&op.does(identval) ??

:   &op.identval($value) :: undef) op $value;
: 
: The rational is, that &op is subject to MMD, so the .identval method

: should be dispatched as well. Actually &op.identity($value) reads
: quite natural and self documenting if the parameter is required.

I don't think there's a double dispatch there.


What do you mean with double dispatch? A single MMD on two arguments
or two dispatches after each other?



 I think &op just knows
it can default its left argument to an existing attribute value if it
(somehow) knows it's part of an assignment op.  There's not a lot of
payback in getting all abstract here, as far as I can see.


Let's assume that op is overloaded for two completely unrelated types
A and B, which are both defining their respective identity elements
but !(A.identval =:= B.identval). How should the &op multi method object
pick the correct one *without* looking at $value's type? Or does the
indentval role force their takers to provide all infix ops with a
test for undef args and a fallback to the respective identity value?
If that is the case, the test for the role is superfluous. Or is the
intent to enforce a unique identity value for each operator like 0 for +
and 1 for *?

There's actually a second problem. Will the &op.does(identval) condition
be true or false if the &op multi contains some targets with and some
without an identval?

Finally I don't understand how the knowledge about a pending assignment
eases the choice problem for the multi. Note that the choice of
assignment operator depends on the return value of the operator and
the type of which the lhs is undef.

Regards,
--
TSa (Thomas Sandlaß)




Re: reduce metaoperator on an empty list

2005-06-09 Thread TSa (Thomas Sandlaß)

Edward Cherlin wrote:
That means that we have to straighten out the functions that can 
return either a Boolean or an item of the argument type. 
Comparison functions < > <= >= = != should return only Booleans,


I'm not sure but Perl6 could do better or at least trickier ;)
Let's assume that < > <= >= when chained return an accumulated
boolean and the least or greatest value where the condition was
true. E.g.

  0 < 2 < 3   returns  0 but true

  1 < 2 < 1   returns  1 but false

  4 < 5 < 2   returns  2 but false

Then the reduce versions [<] and [<=] naturally come out as min
and strict min respectively.

Is it correct that [min] won't parse unless min is declared
as an infix op, which looks a bit strange?

if 3 min 4 { ... }

--
TSa (Thomas Sandlaß)




Re: reduce metaoperator on an empty list

2005-06-09 Thread Edward Cherlin
On Tuesday 07 June 2005 22:35, Sam Vilain wrote:
> Let's look at the type of one of the many `reduce' variants in
> Haskell;
>
>foldr1 :: (a -> a -> a) -> [a] -> a
>
> This is the Perl6ish;
>
>sub reduce( ::Code{( ::(someType), ::(someType) ) returns
> ::(someType)} $func, Array of ::(someType) ) returns
> ::(someType);
>
> ie, the function $func supplied must take and return arguments
> of a single type.  So you have come to the same conclusion as
> the FP folk :-).

I agree with that from the APL, J, Haskell, and FP directions and 
several more.

That means that we have to straighten out the functions that can 
return either a Boolean or an item of the argument type. 
Comparison functions < > <= >= = != should return only Booleans, 
IMHO, and the same for the string functions lt and gt and the 
rest. It also means that we need primitive functions (operators) 
like max and min that only return one of the arguments, and that 
can also be used with a reduction operator (metaoperator).
-- 
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


Re: reduce metaoperator on an empty list

2005-06-08 Thread Edward Cherlin
On Tuesday 07 June 2005 08:08, Larry Wall wrote:
> Okay, I've made up my mind.  The "err" option is not tenable
> because it can cloak real exceptions, and having multiple
> versions of reduce is simply multiplying entities without
> adding much power.  So let's allow an optional "identvalue"
> trait on operators.  If it's there, reduce can use it.  If
> it's not, reduce returns failure on 0 args.  Built-in addition
> will have an identity value of 0, while multiplication will
> have an identity value of 1.  String concatenation will have
> "". 

The table of Iverson's chosen identities in J is at 
http://www.jsoftware.com/books/help/dictionary/d420.htm
He uses _ for +Inf and __ for -Inf and does cover < and >.


> We can go as far as having -Inf on [<] and +Inf on [>], 
> but maybe that means we have to define values that are
> positive and negative infinity on strings so we can get [gt]
> and [lt] indentity values. Those might be useful in any event.

My Second System alarm is going off. What is the result of 
(-Inf)~(+Inf) or whatever the syntax would be? Or indeed 
(-Inf)~$String for any string? I know what it means to say that 
+Inf is the identity for a numeric min function, and -Inf for 
max, but an infinite string value baffles me. It would have to 
satisfy -Inf le "", right? But with no values in between?

When considering what extensions to make in APL and J, Iverson 
always asked what identities could be preserved at the 
boundaries. Thus if C is identical to A,B (APL catenation) with 
neither A nor B empty, then f/C is identical to (f/A)f(f/B). So 
using identity elements, we can extend this identity to some 
functions, and to arrays within their domains.

What identities did you have in mind for string infinities? What 
sort of reduction can you do on "Hello, "~(+Inf)~"world"? How 
does it print? What good is it at all?
-- 
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


Re: reduce metaoperator on an empty list

2005-06-08 Thread Edward Cherlin
On Wednesday 01 June 2005 17:18, Deborah Pickett wrote:
> You haven't convinced me, but rather than flog a dead horse,
> I'll just suggest that we both reserve the right to say "I
> told you so" when there are several years' worth of Perl 6
> code out there, and we see how common our respective examples
> are.

No need to wait. There is a ton of APL and J code to inspect. 
Having predefined identity elements for reductions on empty 
arrays is widely exploited. 

-- 
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


Re: reduce metaoperator on an empty list

2005-06-08 Thread Larry Wall
On Tue, Jun 07, 2005 at 10:52:55PM +, Luke Palmer wrote:
: Okay, I was referring more to the implementation.  How do we tell apart:
: 
: 3 < 4 <= 5 == 5
: 
: From
: 
: 3 lt 4 >= 5 != 5
: 
: ?

As long as the actual arguments aren't allowed to be lazy/thunky/iteratey,
they can just be evaluated pairwise like normal.  That does imply some
kind of temporary storage for

3 < =$IN < 5

so that it only reads =$IN once.

Larry


Re: reduce metaoperator on an empty list

2005-06-08 Thread Larry Wall
On Wed, Jun 08, 2005 at 11:40:49AM +0200, "TSa (Thomas Sandlaß)" wrote:
: Damian Conway wrote:
: >So, to clarify again, if $var is undefined, then the assignment:
: >
: >$var op= $value;
: >
: >is equivalent to:
: >
: >$var = (&op.does(identval) ?? &op.identval() :: undef) op $value;
: >
: >Correct?
: 
: Might I add that it should read
: 
:   $var = (&op.does(identval) ??
:   &op.identval($value) :: undef) op $value;
: 
: The rational is, that &op is subject to MMD, so the .identval method
: should be dispatched as well. Actually &op.identity($value) reads
: quite natural and self documenting if the parameter is required.

I don't think there's a double dispatch there.  I think &op just knows
it can default its left argument to an existing attribute value if it
(somehow) knows it's part of an assignment op.  There's not a lot of
payback in getting all abstract here, as far as I can see.

Larry


Re: reduce metaoperator on an empty list

2005-06-08 Thread TSa (Thomas Sandlaß)

Damian Conway wrote:

So, to clarify again, if $var is undefined, then the assignment:

$var op= $value;

is equivalent to:

$var = (&op.does(identval) ?? &op.identval() :: undef) op $value;

Correct?


Might I add that it should read

  $var = (&op.does(identval) ??
  &op.identval($value) :: undef) op $value;

The rational is, that &op is subject to MMD, so the .identval method
should be dispatched as well. Actually &op.identity($value) reads
quite natural and self documenting if the parameter is required.

Hmm, the MMD form identity( &op, $value ) looks even better. This
folds the identity value selection problem back into type-space
and it's runtime agent MMD.
--
TSa (Thomas Sandlaß)



Re: reduce metaoperator on an empty list

2005-06-08 Thread Damian Conway

Larry wrote:


Okay, I've made up my mind.  The "err" option is not tenable because
it can cloak real exceptions, and having multiple versions of reduce is
simply multiplying entities without adding much power.  So let's allow
an optional "identvalue" trait on operators.  If it's there, reduce
can use it.  If it's not, reduce returns failure on 0 args.


So, just to clarify, for the expression:

[op] @list

if C has an C<:identval> trait then the result is:

* &op.identval()if @list == 0
* @list[0]  if @list == 1
* @list[0] op @list[1] op...op @list[-1]if @list > 1

Otherwise the result is:

* fail  if @list == 0
* @list[0]  if @list == 1
* @list[0] op @list[1] op...op @list[-1]if @list > 1

Correct?



But I would like to stress that this is an *optional* property.
We will only define an identity value for those operators for
which it is obvious what an "accumulator" should be initialized to.
(This is probably also the set of operators for which op= doesn't warn
when the left side is undefined, so "identval" is doing double duty.


So, to clarify again, if $var is undefined, then the assignment:

$var op= $value;

is equivalent to:

$var = (&op.does(identval) ?? &op.identval() :: undef) op $value;

Correct?



In Perl 5 we hardwired that, so it'd be nice to generalize the concept
in Perl 6.)


Indeed.



In fact, by the accumulator argument, maybe it should be called
"initvalue" rather than "identvalue".


I'd be very leery of calling it "initvalue", since people are apt to confuse it 
with real initialization. I'd be inclined to call it "identityval" and simply 
say that an undefined variable that is op-assigned defaults to the identity 
value of the operator (if any).


Damian


Re: reduce metaoperator on an empty list

2005-06-07 Thread Ph. Marek
On Tuesday 07 June 2005 23:41, Luke Palmer wrote:
> On 6/7/05, Larry Wall <[EMAIL PROTECTED]> wrote:
> > Okay, I've made up my mind.  The "err" option is not tenable because
> > it can cloak real exceptions, and having multiple versions of reduce is
> > simply multiplying entities without adding much power.  So let's allow
> > an optional "identvalue" trait on operators.  If it's there, reduce
> > can use it.  If it's not, reduce returns failure on 0 args.  Built-in
> > addition will have an identity value of 0, while multiplication will
> > have an identity value of 1.  String concatenation will have "".
> > We can go as far as having -Inf on [<] and +Inf on [>]
>
> < and > still don't make sense as reduce operators.  Observe the table:
>
> # of args   |   Return (type)
> 0   |   -Inf
> 1   |   Num  (the argument)
> 2   |   bool
> ... |   bool
How about using initvalue twice for empty array, ie. always pad to at least 
two values?

So
 $bool = [<] @empty_array; # is false (-Inf < -Inf)
 $bool = [<=] @empty_array; # is true (-Inf <= -Inf)

Which would make some sort of sense - in an empty array there's no right 
element that's bigger than it's left neighbour ...

And if the case [<] @empty_array should return true it's easy to use ?? ::.


Just my ¤0.02.


Regards,

Phil



Re: reduce metaoperator on an empty list

2005-06-07 Thread Sam Vilain

Luke Palmer wrote:

< and > still don't make sense as reduce operators.  Observe the table:
# of args   |   Return (type)
0   |   -Inf
1   |   Num  (the argument)
2   |   bool
... |   bool


Let's look at the type of one of the many `reduce' variants in Haskell;

  foldr1 :: (a -> a -> a) -> [a] -> a

This is the Perl6ish;

  sub reduce( ::Code{( ::(someType), ::(someType) ) returns ::(someType)} $func,
  Array of ::(someType) ) returns ::(someType);

ie, the function $func supplied must take and return arguments of a single
type.  So you have come to the same conclusion as the FP folk :-).

Here I'm using ::(foo) as a coined syntax for a parametric type to the
definition.  `someType' need not be defined anywhere else, but must be
the same within the application of a definition.

IMHO we still need to make some movements towards a specification for how
this sort of thing is specified...

>  I just think we have to give
> nonhomogeneous operators like < some special treatment.  So, from our
> somewhat lexical definition of reduce, I don't think an identity input
> is what we're looking for.  We really want an identity output.

When I last looked, in pugs, functions that return "bool" types are
currently setup to return one or the other argument when used with reduce;
like there is a similar;

  multi
  sub reduce( ::{Code( ::(someType) $a, ::(someType) $b ) returns bool} $func,
  Array of ::(someType) ) returns ::(someType);

This gives meaning to operators like [>], which would return the maximum
value from a list.

Sam.


Re: reduce metaoperator on an empty list

2005-06-07 Thread Luke Palmer
On 6/7/05, Larry Wall <[EMAIL PROTECTED]> wrote:
> On Tue, Jun 07, 2005 at 09:41:49PM +, Luke Palmer wrote:
> : < and > still don't make sense as reduce operators.
> 
> Yeah, I keep confusing them with min and max.
> 
> : That reminds me, how are <, >, etc. defined anyway?  How can we tell
> : them to be list-associative with each other?
> 
> Because they're all of that specific precedence level, which is defined
> to work that way by fiat, I suspect.  (Other operators have to be
> explicitly declared as list associative, and even then are only list
> associative with themselves, not with all other operators in their
> precedence level.)  I suppose it could be construed as some kind of
> default property on the actual precedence level, but it's not clear
> that that would be a useful generalization.

Okay, I was referring more to the implementation.  How do we tell apart:

3 < 4 <= 5 == 5

From

3 lt 4 >= 5 != 5

?

Luke


Re: reduce metaoperator on an empty list

2005-06-07 Thread Larry Wall
On Tue, Jun 07, 2005 at 09:41:49PM +, Luke Palmer wrote:
: < and > still don't make sense as reduce operators.

Yeah, I keep confusing them with min and max.

: That reminds me, how are <, >, etc. defined anyway?  How can we tell
: them to be list-associative with each other?

Because they're all of that specific precedence level, which is defined
to work that way by fiat, I suspect.  (Other operators have to be
explicitly declared as list associative, and even then are only list
associative with themselves, not with all other operators in their
precedence level.)  I suppose it could be construed as some kind of
default property on the actual precedence level, but it's not clear
that that would be a useful generalization.

Larry


Re: reduce metaoperator on an empty list

2005-06-07 Thread Luke Palmer
On 6/7/05, Larry Wall <[EMAIL PROTECTED]> wrote:
> Okay, I've made up my mind.  The "err" option is not tenable because
> it can cloak real exceptions, and having multiple versions of reduce is
> simply multiplying entities without adding much power.  So let's allow
> an optional "identvalue" trait on operators.  If it's there, reduce
> can use it.  If it's not, reduce returns failure on 0 args.  Built-in
> addition will have an identity value of 0, while multiplication will
> have an identity value of 1.  String concatenation will have "".
> We can go as far as having -Inf on [<] and +Inf on [>]

< and > still don't make sense as reduce operators.  Observe the table:

# of args   |   Return (type)
0   |   -Inf
1   |   Num  (the argument)
2   |   bool
... |   bool

There is a pretty fundamental difference between X,X -> X operators
and X,X -> Y operators wrt reduce.  Most languages don't even allow
the latter kind, but I think it would be cool if we did.

I'm not really sure what you mean by "it can mask real exceptions". 
If the operator is defined to require 1 or more (or in the case of
nonhomogeneous operators, 2 or more) arguments, then that is a real
exception.  "err" just fails to be a realistic fallback mode.

In any case, I'm fairly satisfied with your conclusion (but I wasn't
when I began writing this reply :-).  I just think we have to give
nonhomogeneous operators like < some special treatment.  So, from our
somewhat lexical definition of reduce, I don't think an identity input
is what we're looking for.  We really want an identity output.

Binary operators really need two such outputs: one for zero arguments
and one for one argument.  The one argument output can be inferred
from the zero argument output (but not vice versa).  So, we could
define two properties:

is nullaryvalue(-Inf)
is unaryfunction({ 1 })

And, of course, if nullaryvalue is not defined, then we die (or fail)
when zero arguments are given.  unaryfunction will default to {
&op(nullaryvalue, 1) }, or { $_ } if nullaryvalue was not defined,
unless the output type is incompatible with the input type (in which
case we have to die even with one argument).  We could also define the
unaryfunction automatically if a default value is given for one of the
arguments of a binary operator.

But this all ceases to be a problem for list-associative operators,
which presumably take a list of arguments rather than just two.

That reminds me, how are <, >, etc. defined anyway?  How can we tell
them to be list-associative with each other?

Luke


Re: reduce metaoperator on an empty list

2005-06-07 Thread Larry Wall
Okay, I've made up my mind.  The "err" option is not tenable because
it can cloak real exceptions, and having multiple versions of reduce is
simply multiplying entities without adding much power.  So let's allow
an optional "identvalue" trait on operators.  If it's there, reduce
can use it.  If it's not, reduce returns failure on 0 args.  Built-in
addition will have an identity value of 0, while multiplication will
have an identity value of 1.  String concatenation will have "".
We can go as far as having -Inf on [<] and +Inf on [>], but maybe
that means we have to define values that are positive and negative
infinity on strings so we can get [gt] and [lt] indentity values.
Those might be useful in any event.

But I would like to stress that this is an *optional* property.
We will only define an identity value for those operators for
which it is obvious what an "accumulator" should be initialized to.
(This is probably also the set of operators for which op= doesn't warn
when the left side is undefined, so "identval" is doing double duty.
In Perl 5 we hardwired that, so it'd be nice to generalize the concept
in Perl 6.)

In fact, by the accumulator argument, maybe it should be called
"initvalue" rather than "identvalue".

Larry


Re: reduce metaoperator on an empty list

2005-06-06 Thread Rob Kinyon
On 6/6/05, Sam Vilain <[EMAIL PROTECTED]> wrote:
> Roger Hale wrote:
> > This is why I would rather the o -> [o] circumfixion left [o] an infix,
> > not prefix operator.  I would rather be explicit about my identity:
> > $product = 1 [*] @array;
> 
> Hmm.  Not all operators *have* an identity.

So, what's wrong with not providing an identity? It's not like we
cannot have a module that says "[*] will be its own operator that
defaults to 1, [+] will default to 0", and so forth. In fact, I can
easily see a module like that being very useful.

Remember - the language DOES NOT have to provide the sinecure for all
situations. Discussions like this only emphasize that fact. Give it a
module and let it go.

In fact, if there's two different and competing implementations for
the reduce meta-operator, then maybe it's better to provide a
reduce-noident and reduce-ident and let people consciously choose
which one they want to use ...

Rob


Re: reduce metaoperator on an empty list

2005-06-06 Thread TSa (Thomas Sandlaß)

HaloO Roger,

I'm answering here to your other mail as well. In my example
I was intensionally changing from last to first and positive
and negative numbers! This is a sublety of distance preserving,
direction aware counting in multiples of arbitrary
unity---or some such ;)

you wrote:
This is why I would rather the o -> [o] circumfixion left [o] an infix, 
not prefix operator.  I would rather be explicit about my identity:


$product = 1 [*] @array;

$factorial = 1 [*] 1..$n;

$text = "" [~] @lines;

$balance = $balance [-] @debits;
or
$balance [-]= @debits;

which last suggests how you don't always want to start at the identity, 
and how [-] makes sense in this context.


Ahh, yes! That also introduces directionality were you reduce from the
front

   $product = 1 [*] @array;

or the back

   $product = @array [*] 1;

The corresponding unary forms are---syntax aside for the moment---
prefix

   $product = [*] @array; # @array[0] [*] @array[0^..^$.end];

and postfix

   $product = @array [*]; #  @array[0..^$.end-1].reverse [*] @array[-1];

Most interesting is that

   $product = @array [*=]; # collects result in @array[-1] and assigns ref

and

   $product = [*=] @array; # collects result in @array[0] and assigns ref




Now I'm following up from my clock example in the mod/div subthread.
I try to illustrate the advantage of the euclidean definition of modulo
division provided as the built-in op %. Completed with the respective
numerics for / according to the division rule.

   #  negative radix, negative digits
   #  [-12] [-11] [-10]  [-9] [-8] [-7] [-6] [-5] [-4] [-3] [-2] [-1]
@d = <  12010203   04   05   06   07   08   09   10   11 >;
   #  [  0] [  1] [  2] [  3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11]
   #  negative radix, positive digits

This looks like an obvious application of two's complement which
unfortunately doesn't explain why $x % $y should give the same
result as $x % -$y.

Let's look at the weekdays then. Everybody knows that there are seven
days in a week. Handling the days as ints in 0..6 or 1..7 and doing
naive calculations with them results in typical "off by one"
errors---which are unnecessary if e.g. array and enums are doing
proper modulo arithmetic. Then the forward counting weekdays are
0..^7 and the reverse weekdays are -7..^0. A little overwide picture
demonstrating this is appended.

The idea is to have the real content of an array beeing indexed modulo
it's length. Zero length is of course the empty array. Positive length
is the normal forward array. An array with negative length is an array
iterated from the back. An array's index set is thus giving positions
*between* the content cells. An exhausted forward iterator is after the
last entry, an exhausted backwards iterator is before the first. The
actual content is the remainder which points *into* the array. A slice
is just a pair of positions in such an array.

With the above POV, strings become arrays of character describing
sequences of Unicode numbers. ASCII is e.g. Unicode % 127 :)
With left to right beeing positive direction a big endian digit
string has got negative length!

The real fun starts when multi-dimensional arrays are indexed/iterated.
The array
  # 0 |
@a = ( 0+0/3,  0+1/3,  0+2/3;   #   3
   1+0/5,  1+1/5,  1+2/5,  1+3/5, 1+4/5;#  +5
  -1+0/3, -1+1/3, -1+2/3 )  #  +3 == 11 entries
   #   2+0/3,  2+1/3,  2+2/3  | 3
can be indexed e.g. @a[1/4] to give the 0 from the first list. That is,
the integer part of 1/4 gives the index 0 in the outer dimension, while
the remainder 0.25 is mapped to the equally subdivided length of @a[0]

[EMAIL PROTECTED] == 1/(3**-1) == 3 # index set is (0, 1/3, 2/3) »/« 1/3 == 
(0,1,2)

to form the index @a[0][0]. The borderline case is of course
@a[1/3] == @a[0][1]. Well, and [EMAIL PROTECTED] == 1 because it's an array ref.
"Overflowing" to the right like @a[4/3] gives @a[1][1] because the second
subarray is indexed with (0, 0.2, 0.4, 0.6, 0.8) and 0.2 <= 1/3 < 0.4 is
in the second cell. Thus @a[9/8] == @a[1][0]. Finally note that

  @a[2/-3] == @a[-1][-2] == -1+1/3   #  two's complement!
 #2 == 3 * 0 + 2  division rule

is *here* quite the same as the negated/reversed content of

  @a[-2/3] == @a.reversed[-1][1] == 0+1/3  # -2 == 3 * (-1) + 1

while the interpretation is different in general!

The first example goes with a positive, fractional index 2/3
from the back *backwards* into the *last* sub-array. That is
counting 3/3 -> 2/3 -> 1/3 from the end of @a[-1].
The second example goes with a positive, fractional index 1/3
from the front *forwards* into the *last* sub-array. That is
counting 0/3 +> 1/3 +> 2/3 where *> is the endpoint of the
iterator.

The complementary pair of index operations is

  @a[ 2/ 3] == @a[0][2] == 0+2/3   #  2 ==   3 *  0 + 2

  @a[-2/-3] == @a.reverse[-1][-1] == 0+2/3  # -2 == (-3) * 1 + 1

With the first cas

Re: reduce metaoperator on an empty list

2005-06-06 Thread Sam Vilain

Damian Conway wrote:

What you want is:
$product = ([*] @values err 0);
Or:
$factorial = ([*] 1..$n err 1);


The "err" operator bind only to the point on the instruction it is
attached to, ie it's not a shortcut for eval(), right?

I'm just seeing some edge cases here for custom defined operators; you
don't want exceptions getting silently converted to default values...

Sam.


Re: reduce metaoperator on an empty list

2005-06-06 Thread Sam Vilain

Roger Hale wrote:
This is why I would rather the o -> [o] circumfixion left [o] an infix, 
not prefix operator.  I would rather be explicit about my identity:

$product = 1 [*] @array;


Hmm.  Not all operators *have* an identity.

You'd have to write, in that case;

  @array[0] [ƒ] @[EMAIL PROTECTED]

Which isn't great IMHO.

Sam.


Re: reduce metaoperator on an empty list

2005-06-06 Thread Roger Hale

Damian Conway wrote:

Deborah Pickett wrote:

You are going to see empty lists more often than you think in 
expressions like

  $product = [*] @array;
and having to write that as
  $product = [*] 1, @array;
just to protect against a common case doesn't exactly flaunt Perl's 
DWIMmery to me.  I *have* to write 1 there, or otherwise the reduce 
meta-operator isn't calculating the product when there are items in 
@array.  This hardly makes sense from a Huffman perspective.  Someone 
please convince me otherwise.



The problem is that writing 1 there is still wrong in the "no arguments" 
case. The product of zero numbers cannot possibly be one in any common 
sense interpretation. (And, yes, I'm perfectly well aware of the 
mathematical interpretations in which it does make sense...that's not 
the point.)


Sure it is: it's the number you have before you've multiplied any 
numbers into it.  It's the center of the world, for multiplication.  If 
you started anywhere else you wouldn't end up at the correct product. 
If you started at zero you'd never get off the dime.




What you want is:

$product = ([*] @values err 0);


Not what I'd ever want...



Or:

$factorial = ([*] 1..$n err 1);

So what you want is not an identity value as default (which isn't even 
possible for many operators, as Luke pointed out), but a predictable 
failure value as default, so you can intercept that failure and choose 
your own outcome in the edge case.


Damian


This is why I would rather the o -> [o] circumfixion left [o] an infix, 
not prefix operator.  I would rather be explicit about my identity:


$product = 1 [*] @array;

$factorial = 1 [*] 1..$n;

$text = "" [~] @lines;

$balance = $balance [-] @debits;
or
$balance [-]= @debits;

which last suggests how you don't always want to start at the identity, 
and how [-] makes sense in this context.



Unfortunately it doesn't handle the case of join $sep, @strings:

"" [{$^a ~ $sep ~ $^b}] @strings

(yes, I know that's not going to pass lexical analysis) since, as was 
pointed out, you get an extra $sep at the front.



yours,
Roger Hale


Re: reduce metaoperator on an empty list

2005-06-01 Thread Deborah Pickett
On Wed, 1 Jun 2005 19.37, Damian Conway wrote:
> Deborah Pickett wrote:
> > Someone please convince me otherwise.
> So what you want is not an identity value as default (which isn't even
> possible for many operators, as Luke pointed out), but a predictable
> failure value as default, so you can intercept that failure and choose your
> own outcome in the edge case.

You haven't convinced me, but rather than flog a dead horse, I'll just suggest 
that we both reserve the right to say "I told you so" when there are several 
years' worth of Perl 6 code out there, and we see how common our respective 
examples are.  Meanwhile, it's safer to take the "fail" course of action, 
because it can be relaxed later on; the converse couldn't be true.

What you and Luke *have* convinced me of is that the one-element list rule 
isn't right either; for operators like <, it still makes sense to fail in 
some soft way on one-element lists:
  $ordered = ([<] @array) // 1;  # Zero- and one-element arrays get the 1.
I'm starting to agree that there have to be different rules for associative* 
and non-associative reduction.

* Left and right association might need to be different too in terms of the 
order they eat list elements.

-- 
Debbie Pickett
[EMAIL PROTECTED]


Re: reduce metaoperator on an empty list

2005-06-01 Thread Rob Kinyon
> > $ordered = [<] @array;

This is asking "Is @array ordered?" In the case of a 0-element or
1-element array, the answer is "It is not disordered", which means
$ordered is true.

$ordered = ! [!<] @array;

Rob


Re: reduce metaoperator on an empty list

2005-06-01 Thread Dave Whipp

Luke Palmer wrote:


For something like:

$ordered = [<] @array;

If @array is empty, is $ordered supposed to be true or false?   It
certainly shouldn't be anything but those two, because < is a boolean
operator.


I have no problem with 3-state logic systems (true, false, undef) if 
this is what is required to let me choose the corner-case behavior.


Damian previously wrote:
> 2+ args: interpolate specified operator
> 1 arg:   return that arg
> 0 args:  fail (thrown or unthrown exception depending on use fatal)

The 1-arg case doesn't seem to work right with the [<] operator:

  ? [<] 1
  ? [<] 0

If the [<] is taken to mean "ordered", then it doesn't seem right that 
these two tests would give different results. In this case, I need to 
special case both the 0-arg and 1-arg scenarios. We either need to hard 
code these special-cases into perl (belch), or we need to make it easy 
to code both special-cases inline in the code, or we need a better 
general-case rule.


One approach might be to reverse the direction of the definitions. That 
is, instead of defining the binary form and then autogeneralizing in 
terms of "join", we might define operators in terms of thier reduction 
behavior, and then autospecialize to the binary case. Of course, that 
still doesn't help for Damian's "product Vs factorial" example for the 
0-arg case.


Or we take the well trodden road of ignoring mathematical correctness 
and simply state "this is what perl does: take it or leave it".


Re: reduce metaoperator on an empty list

2005-06-01 Thread Michele Dondi

On Wed, 1 Jun 2005, Luke Palmer wrote:


I read that (mathematically) as "for all i, for all j such that j-i=1,
a_i

Yep, it sure is.  Now tell Perl to read it that way for any operator.


Should _I_?!? ;-)

I wonder what a logic-oriented programming language a' la prolog would say 
in this case. Now, Perl6 is supposed to support similar features too - 
maybe the right(TM) answer could be along that way...



Michele
--

primordinarily concerned with providing ...

Neat "word"!
- Donald Arseneau in comp.text.tex


Re: reduce metaoperator on an empty list

2005-06-01 Thread BÁRTHÁZI András

Hi,


You have to either supply an initial value or refactor your logic not
to allow an empty @array (as in the first case).  If you want it some
other way, there are far too many special cases we have to work with,
some of which are just mathematically impossible.

I think `fail`ing is the best bet.


I haven't read the whole thread, so I'm sorry, if it was before. I think 
that a fail is a good idea. Or maybe it should be a warning, and the 
return value should be undef.


I mean:

  [<[EMAIL PROTECTED] === undef < undef;
  [EMAIL PROTECTED] === undef * undef;
  etc.

Bye,
  Andras


Re: reduce metaoperator on an empty list

2005-06-01 Thread Luke Palmer
On 6/1/05, Michele Dondi <[EMAIL PROTECTED]> wrote:
> On Wed, 1 Jun 2005, Luke Palmer wrote:
> 
> >$ordered = [<] @array;
> >
> > If @array is empty, is $ordered supposed to be true or false?   It
> > certainly shouldn't be anything but those two, because < is a boolean
> > operator.
> 
> I read that (mathematically) as "for all i, for all j such that j-i=1,
> a_i

Re: reduce metaoperator on an empty list

2005-06-01 Thread Michele Dondi

On Wed, 1 Jun 2005, Luke Palmer wrote:


   $ordered = [<] @array;

If @array is empty, is $ordered supposed to be true or false?   It
certainly shouldn't be anything but those two, because < is a boolean
operator.


I read that (mathematically) as "for all i, for all j such that j-i=1,
a_i
Why should I read the fucking manual? I know how to fuck!
In fact the problem is that the fucking manual only gives you 
theoretical knowledge which is useless in practice ;)

- Giuseppe "Oblomov" Bilotta in a bunch of usenet groups.


Re: reduce metaoperator on an empty list

2005-06-01 Thread Damian Conway

Deborah Pickett wrote:


You are going to see empty lists more often than you think in expressions like
  $product = [*] @array;
and having to write that as
  $product = [*] 1, @array;
just to protect against a common case doesn't exactly flaunt Perl's DWIMmery 
to me.  I *have* to write 1 there, or otherwise the reduce meta-operator 
isn't calculating the product when there are items in @array.  This hardly 
makes sense from a Huffman perspective.  Someone please convince me 
otherwise.


The problem is that writing 1 there is still wrong in the "no arguments" case. 
The product of zero numbers cannot possibly be one in any common sense 
interpretation. (And, yes, I'm perfectly well aware of the mathematical 
interpretations in which it does make sense...that's not the point.)


What you want is:

$product = ([*] @values err 0);

Or:

$factorial = ([*] 1..$n err 1);

So what you want is not an identity value as default (which isn't even 
possible for many operators, as Luke pointed out), but a predictable failure 
value as default, so you can intercept that failure and choose your own 
outcome in the edge case.


Damian


Re: reduce metaoperator on an empty list

2005-06-01 Thread Luke Palmer
On 6/1/05, Deborah Pickett <[EMAIL PROTECTED]> wrote:
> I'm still in the camp of those wanting each operator to know its own identity
> value (perhaps in terms of a trait).  The identity of multiplication (say) is
> always 1, after all, and it doesn't change depending on when you do
> multiplication in your own code.  In mathematical terms, it's a property of
> the operator, not of how it's used.

Also, in mathematical terms, many operators have no identity.  Also,
if we suppose that every operator does have an identity (a silly thing
to do), then we can't just return that.  It doesn't even make sense
for operators like < whose return type is different from its argument
types (but reduce itself doesn't make a lot of sense for such
operators unless they're list-associative).

For something like:

$ordered = [<] @array;

If @array is empty, is $ordered supposed to be true or false?   It
certainly shouldn't be anything but those two, because < is a boolean
operator.

Coming back to our identities issue, consider:

$mods = [%] @array;

If @array is empty, what is $mods supposed to be?  There's no
reasonable integer that it could possibly be.

You have to either supply an initial value or refactor your logic not
to allow an empty @array (as in the first case).  If you want it some
other way, there are far too many special cases we have to work with,
some of which are just mathematically impossible.

I think `fail`ing is the best bet.

Luke


Re: reduce metaoperator on an empty list

2005-06-01 Thread Deborah Pickett
On Wed, 1 Jun 2005 13.19, Joe Gottman wrote:
> > Juerd asked:
> > >>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 [EMAIL PROTECTED] being 0 
> > > fail too?
> > No. It returns empty string. You could think of C as being
> > implemented:
> >  sub join (Str $sep, [EMAIL PROTECTED]) { reduce { $^a ~ $sep ~ $^b } 
> > "", @list
> > }
> >
> > Just as C is probably implemented:
> >
> >  sub sum ([EMAIL PROTECTED]) { [+] 0, @list }
>If this were the case, then
>   join '~', 'a', 'b', 'c'
>  would equal '~a~b~c' instead of 'a~b~c'

Another broken symmetry.  Ah, Perl 5's full of them, and I see that Perl 6 
will be no exception.  Excuse me while I find my cynic hat . . ah, here it 
is.

I'm still in the camp of those wanting each operator to know its own identity 
value (perhaps in terms of a trait).  The identity of multiplication (say) is 
always 1, after all, and it doesn't change depending on when you do 
multiplication in your own code.  In mathematical terms, it's a property of 
the operator, not of how it's used.

You are going to see empty lists more often than you think in expressions like
  $product = [*] @array;
and having to write that as
  $product = [*] 1, @array;
just to protect against a common case doesn't exactly flaunt Perl's DWIMmery 
to me.  I *have* to write 1 there, or otherwise the reduce meta-operator 
isn't calculating the product when there are items in @array.  This hardly 
makes sense from a Huffman perspective.  Someone please convince me 
otherwise.

Multiplication's an easy example, in any case, and any programmer will know 
the identity is 1.  But look at the confusion here on this list among people 
over the identities for <, >, ** and other beasts.  I've already forgotten 
some of them.

(On another note: I had a thought the other day: [op] produces one thing from 
a list, and »op« produces a list from a list.  When I squint with hindsight, 
it makes more sense to me for »op« to be the one that converges a list to a 
single point, and [op] to do listy things to lists.  I'm not seriously 
suggesting a switch - there's probably parsing issues with the thought - I'm 
just sayin', is all.)

-- 
Debbie Pickett
http://www.csse.monash.edu.au/~debbiep
[EMAIL PROTECTED]


Re: reduce metaoperator on an empty list

2005-05-31 Thread Damian Conway

Joe Gottman pointed out:


No. It returns empty string. You could think of C as being
implemented:

sub join (Str $sep, [EMAIL PROTECTED]) { reduce { $^a ~ $sep ~ $^b } "", 
@list }

>

   If this were the case, then
join '~', 'a', 'b', 'c'
 would equal '~a~b~c' instead of 'a~b~c'


Good point. Thanks. Make that:

sub join (Str $sep, [EMAIL PROTECTED]) {
reduce { $^a ~ $sep ~ $^b } @list || ""
}

Presuming (of course) that my earlier plea that || should preserve context 
across both operands is granted. ;-)


Damian


RE: reduce metaoperator on an empty list

2005-05-31 Thread Joe Gottman


> -Original Message-
> From: Damian Conway [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, May 31, 2005 11:14 PM
> To: perl6-language@perl.org
> Subject: Re: reduce metaoperator on an empty list
> 
> Juerd asked:
> 
> 
> >>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 [EMAIL PROTECTED] being 0 
> > fail too?
> 
> No. It returns empty string. You could think of C as being
> implemented:
> 
>  sub join (Str $sep, [EMAIL PROTECTED]) { reduce { $^a ~ $sep ~ $^b } "", 
> @list }
> 
> Just as C is probably implemented:
> 
>  sub sum ([EMAIL PROTECTED]) { [+] 0, @list }
> 

   If this were the case, then
join '~', 'a', 'b', 'c'
 would equal '~a~b~c' instead of 'a~b~c'

Joe Gottman



Re: reduce metaoperator on an empty list

2005-05-31 Thread Damian Conway

Juerd asked:



   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 [EMAIL PROTECTED] being 0 fail too?


No. It returns empty string. You could think of C as being implemented:

sub join (Str $sep, [EMAIL PROTECTED]) { reduce { $^a ~ $sep ~ $^b } "", 
@list }

Just as C is probably implemented:

sub sum ([EMAIL PROTECTED]) { [+] 0, @list }



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.


I'd have assumed that "empty list in list context, undef in scalar
context" *is* what C returns when C isn't in effect.

Damian


Re: reduce metaoperator on an empty list

2005-05-31 Thread Juerd
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)

Following this logic, does join(" ", @foo) with [EMAIL PROTECTED] 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


Re: reduce metaoperator on an empty list

2005-05-31 Thread Rod Adams

Dave Whipp wrote:


Damian Conway wrote:


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".





Seems to me that C should have an implied C on it's lhs. 
Unless we spell that C.


-- Rod Adams


Re: reduce metaoperator on an empty list

2005-05-31 Thread Damian Conway

Dave Whipp wrote:


Damian Conway wrote:


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".


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


Re: reduce metaoperator on an empty list

2005-05-31 Thread Dave Whipp

Damian Conway wrote:

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".


Re: reduce metaoperator on an empty list

2005-05-31 Thread Damian Conway

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


Re: reduce metaoperator on an empty list

2005-05-31 Thread Dave Whipp

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


Re: reduce metaoperator on an empty list

2005-05-31 Thread Damian Conway
All this discussion of "identity" defaults for reductions has been very 
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


Re: reduce metaoperator on an empty list

2005-05-31 Thread Larry Wall
On Mon, May 23, 2005 at 08:54:19PM +, [EMAIL PROTECTED] wrote:
: 
: There are actuall two usefull definition for %.  The first which Ada calls 
'mod' always returns a value 0<=X

Re: reduce metaoperator on an empty list

2005-05-24 Thread John Macdonald
On Fri, May 20, 2005 at 10:14:26PM +, [EMAIL PROTECTED] wrote:
> 
> > Mark A. Biggar wrote:
> > > Well the identity of % is +inf (also right side only).
> > 
> > I read $n % any( $n..Inf ) == $n. The point is there's no
> > 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 > 
> > 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.

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.

-- 


Re: reduce metaoperator on an empty list

2005-05-23 Thread mark . a . biggar

There are actuall two usefull definition for %.  The first which Ada calls 
'mod' always returns a value 0<=X 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ß)
> 


Re: reduce metaoperator on an empty list

2005-05-23 Thread TSa (Thomas Sandlaß)

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ß)



Re: reduce metaoperator on an empty list

2005-05-21 Thread Edward Cherlin
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 :)

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.

-- 
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


Re: reduce metaoperator on an empty list

2005-05-21 Thread Edward Cherlin
On Friday 20 May 2005 07:18, John Macdonald wrote:
> 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.

-- 
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


Re: reduce metaoperator on an empty list

2005-05-21 Thread Edward Cherlin
On Thursday 19 May 2005 20:42, Andrew Rodland wrote:
> On Thursday 19 May 2005 10:51 pm, 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/intro
> > >28.htm
> >
> >[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?
>
> These seem to be the original sources:
>
> 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.

It's an enhanced APL without the funny characters.

-- 
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


Re: reduce metaoperator on an empty list

2005-05-20 Thread Matt Fowles
Mark~

On 5/20/05, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> 
> > Mark A. Biggar wrote:
> > > Well the identity of % is +inf (also right side only).
> >
> > I read $n % any( $n..Inf ) == $n. The point is there's no
> > 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 >
> > 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.

On the contrary a mathematician would say that the empty list is
monotonically increasing (vacuously) and the answer should be true.

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


Re: reduce metaoperator on an empty list

2005-05-20 Thread mark . a . biggar

> Mark A. Biggar wrote:
> > Well the identity of % is +inf (also right side only).
> 
> I read $n % any( $n..Inf ) == $n. The point is there's no
> 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 
> 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
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED]




Re: [unclassified] Re: reduce metaoperator on an empty list

2005-05-20 Thread Edward Cherlin
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

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.

-- 
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


Re: reduce metaoperator on an empty list

2005-05-20 Thread TSa (Thomas Sandlaß)
Mark A. Biggar wrote:
Well the identity of % is +inf (also right side only).
I read $n % any( $n..Inf ) == $n. The point is there's no
unique right identity and thus (Num,%) disqualifies for a
Monoid. BTW, the above is a nice example where a junction
needn't be preserved :)

E.g. if XSorry, 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?
--
TSa (Thomas Sandlaß)


Re: reduce metaoperator on an empty list

2005-05-20 Thread Mark A. Biggar
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

--
[EMAIL PROTECTED]
[EMAIL PROTECTED]


Re: reduce metaoperator on an empty list

2005-05-20 Thread TSa (Thomas Sandlaß)
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 :)
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.
--
TSa (Thomas Sandlaß)


Re: reduce metaoperator on an empty list

2005-05-20 Thread John Macdonald
On Fri, May 20, 2005 at 06:09:55AM -0700, Randal L. Schwartz wrote:
> > "Mark" == Mark A Biggar <[EMAIL PROTECTED]> 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.

-- 


Re: reduce metaoperator on an empty list

2005-05-20 Thread Randal L. Schwartz
> "Randal" == Randal L Schwartz  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
 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: reduce metaoperator on an empty list

2005-05-20 Thread Randal L. Schwartz
> "Mark" == Mark A Biggar <[EMAIL PROTECTED]> 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. :)

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
 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: reduce metaoperator on an empty list

2005-05-19 Thread Andrew Rodland
On Thursday 19 May 2005 10:51 pm, 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
>
>[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?
>
These seem to be the original sources:

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.


Re: reduce metaoperator on an empty list

2005-05-19 Thread Sam Vilain
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***
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:<[+]> ([EMAIL PROTECTED]) ::= &reduce.assuming(func => &infix:<+>, 
first => 0);
  sub prefix:<[*]> ([EMAIL PROTECTED]) ::= &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.


Re: reduce metaoperator on an empty list

2005-05-19 Thread Sam Vilain
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]
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.


Re: reduce metaoperator on an empty list

2005-05-19 Thread C. Scott Ananian
On Wed, 18 May 2005, Rob Kinyon wrote:
On 5/18/05, Stuart Cook <[EMAIL PROTECTED]> 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.
I would think that the Principle of Least Surprise points to (1),
given that the standard explanation of the [EMAIL PROTECTED] is eval join( '+', 
@x
) ...
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/ )


Re: reduce metaoperator on an empty list

2005-05-19 Thread TSa (Thomas Sandlaß)
Michele Dondi wrote:
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,
I think that the unit/identity/neutral value is a trait of the
operator *and* the type of the values which are expected from
the list/array. If nothing more specific is known it would be
Any ::= Str | Num | Ref | Array | Hash | Code | ...
of which I don't know what the neutral value for +, *, ~, etc.
should be.

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),
Me, too. In particualr since Perl6 has got rich undef semantics.
BTW, is an Undef type specified? Is it a one-below-Any type,
i.e. Any ::= ... | Undef | ...

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.
I would expect the dwimmery beeing a natural outcome of the strong type
system :)
So, if neutral(+,Any) =:= 0 and +Any =:= Num and the empty list returns
any number of undefs you ask it to provide and +undef == 0 then [+];
gives 0. Same reasoning applies for [*] gives 1 and for [~] you get ''
when ~Any =:= Str. All that is more or less my way to repeat what others
have said in this thread.
--
$TSa =:= all( none( @Larry ), one( @p6l ))


Re: reduce metaoperator on an empty list

2005-05-19 Thread Edward Cherlin
On Wednesday 18 May 2005 17:57, Matt Fowles wrote:
> 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 elementFor
 
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


Re: reduce metaoperator on an empty list

2005-05-19 Thread Michele Dondi
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


Re: reduce metaoperator on an empty list

2005-05-19 Thread Michele Dondi
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"


Re: reduce metaoperator

2005-05-19 Thread Edward Cherlin
On Sat, May 07, 2005 at 01>00>08PM -0700, Larry Wall wrote:

> On the other hand, since we've distinguished hyperops on
> infixes from hyperops on unaries, maybe an infix hyperop in
> unary position just does the thing to itself:
>
> @squares = Â*Â @list;
>
> which gives us a sum-of-squares that looks like this:
>
> @sumofsquares = [+] Â*Â @list;

> On the gripping hand, I can't think of any other operators I'd
> be likely to want to do that to, 

Ken Iverson had the same problem in the beginning.
http://www.vector.org.uk/typography/pview.htm
"Even after tasting the fruits of generalizing the Î notation of 
mathematics to the form f/ that permitted the use of functions 
other than addition, it took some time before I recognized the 
advantages of a corresponding generalization of the inner or 
matrix product to allow the use of functions other than addition 
and multiplication."

> so forget it.  Not worth teaching people.  

In languages that have reduce, scan, and inner product, it turns 
out that there are a number of other useful cases besides sum 
and sum of products. Minimax and maximin in game theory, for 
example. Boolean inner products on incidence matrices give a 
result showing which points are connected by paths of length 
two, and higher powers give connectedness on paths of length 
'n', up to the point at which all path-connected components have 
been completely identified. 'And of equals' matches vectors 
(lists) against rows or columns of a table, depending on the 
order of the arguments. There are a number of others in the 
literature, some of them quite common in use. Once reduce, scan, 
and inner product can apply to user-defined functions, the 
possibilities open wide.

Scan is an extension of reduce. It takes every initial segment of 
its vector argument, and does a reduce on it. (For right-to-left 
evaluation as in APL and J, this requires order N squared time 
on non-commutative functions.) J has extended scan to a version 
that operates on final segments. Examples at
file:///usr/share/j504/system/extras/help/dictionary/intro14.htm

This paper applies scans to inner product functions.
http://portal.acm.org/citation.cfm?id=882077
The inner-product scan allows a straight-forward calculation of 
interest-bearing accounts or annuities without a loop in APL.

> Larry 
-- 
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


Re: reduce metaoperator on an empty list

2005-05-18 Thread Stuart Cook
On 5/19/05, Brad Bowman <[EMAIL PROTECTED]> 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);  # ???

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


Re: reduce metaoperator on an empty list

2005-05-18 Thread Brad Bowman

> 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'.

Can't the appropriate identity just be prepended?

> > my @a;
> > [+] @a; # 0? exception?
[+] (0, @a);

> > [*] @a; # 1? exception?
[*] (1, @a);

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


Brad

-- 
People with intelligence will use it to fashion both true and false and will
try to push through whatever they want with their clever reasoning.  This is
injury from intelligence.
  Nothing you do will have effect if you do not use truth. -- Hagakure



Re: reduce metaoperator on an empty list

2005-05-18 Thread Mark A. Biggar
Stuart Cook 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.
The usual none(@Larry) disclaimer applies, of course...
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
[EMAIL PROTECTED] == 1
[EMAIL PROTECTED] eq '' (also covered by ~undef)
[?&[EMAIL PROTECTED] ~~ true
[?|[EMAIL PROTECTED] ~~ false (also covered by ?undef)
[EMAIL PROTECTED] ~~ false (also covered by ?undef)
[+&[EMAIL PROTECTED] == MAXINT (whatever that is)
[+|[EMAIL PROTECTED] == 0 (also covered by +undef)
[EMAIL PROTECTED] == 0 (also covered by +undef)
chained ops are wierd
[<[EMAIL PROTECTED] ~~ false
[>[EMAIL PROTECTED] ~~ false
[<[EMAIL PROTECTED] ~~ true
[>[EMAIL PROTECTED] ~~ true
Other ops have theoritical values that I don't know if we can handle:
[~&[EMAIL PROTECTED] should be an infinitely long bitstring of 1's
[~|[EMAIL PROTECTED] 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.

--
[EMAIL PROTECTED]
[EMAIL PROTECTED]


Re: reduce metaoperator on an empty list

2005-05-18 Thread Rod Adams
Rob Kinyon wrote:
On 5/18/05, Stuart Cook <[EMAIL PROTECTED]> 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.
   

I would think that the Principle of Least Surprise points to (1),
given that the standard explanation of the [EMAIL PROTECTED] is eval join( '+', @x
) ...
 

$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


Re: reduce metaoperator on an empty list

2005-05-18 Thread Rob Kinyon
On 5/18/05, Stuart Cook <[EMAIL PROTECTED]> 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.

I would think that the Principle of Least Surprise points to (1),
given that the standard explanation of the [EMAIL PROTECTED] is eval join( '+', 
@x
) ...

Rob


Re: reduce metaoperator on an empty list

2005-05-18 Thread Stuart Cook
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.

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


Stuart


Re: reduce metaoperator on an empty list

2005-05-18 Thread Stuart Cook
On 5/19/05, Matt Fowles <[EMAIL PROTECTED]> wrote:
> 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)


Re: reduce metaoperator on an empty list

2005-05-18 Thread Mark A. Biggar
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?
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

--
[EMAIL PROTECTED]
[EMAIL PROTECTED]


Re: reduce metaoperator on an empty list

2005-05-18 Thread Rod Adams
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



Re: reduce metaoperator

2005-05-07 Thread Larry Wall
On Sat, May 07, 2005 at 01:00:08PM -0700, Larry Wall wrote:
: On the other hand, since we've distinguished hyperops on infixes from
: hyperops on unaries, maybe an infix hyperop in unary position just
: does the thing to itself:
: 
: @squares = »*« @list;
: 
: which gives us a sum-of-squares that looks like this:
: 
: @sumofsquares = [+] »*« @list;

On the gripping hand, I can't think of any other operators I'd be likely
to want to do that to, so forget it.  Not worth teaching people.  Let's
stick with

@sumofsquares = [+] @list »*« @list;

I'm sure the optimizer can be smart enough to recognize that, if we need
to optimize it.  Should probably recognize

@sumofsquares = [+] @list »** 2

as well.

Larry


Re: reduce metaoperator

2005-05-07 Thread Larry Wall
On Sat, May 07, 2005 at 05:11:19PM +1000, Stuart Cook wrote:
: On 5/7/05, Patrick R. Michaud <[EMAIL PROTECTED]> wrote:
: > It might not be a problem -- I'm thinking we may end up tokenizing
: > most or all of the meta operators, so that [+] would be considered
: > its own token, and then the "longest matching token" rule
: > would be sufficient to disambiguate the terms:
: > 
: >   $x = [+1, -2, +3]; # token [ indicates a term
: >   $y = [+] @stuff; # token [+] indicates a meta-op prefix operator
: 
: Does that mean postfix meta-ops that modify syntax become possible?
: (Not necessarily a good idea, mind you, but possible...)

Vaguely.  One could imagine for instance a hyper variant that says
"do this to yourself", and this could force interpretation of the preceding
operator as an infix operator rather than a unary.  So despite the
fact that there's a unary *, this

@squares = *«« @list;

could be the same as

@squares = @list »*« @list

I'm inclined to agree that it's not a terribly good idea to have
a metaoperator that does retroactive violence to the meaning of
an operator.  (Note that +« doesn't actually change the meaning of
the +.)

On the other hand, since we've distinguished hyperops on infixes from
hyperops on unaries, maybe an infix hyperop in unary position just
does the thing to itself:

@squares = »*« @list;

which gives us a sum-of-squares that looks like this:

@sumofsquares = [+] »*« @list;

That's...interesting...and it doesn't retroactively change the meaning
of *, since it's got the » out front, which currently has no meaning
when a term is expected, unless I'm going completely senile.  Every day
it gets a little harder to distinguish my senility from my insanity...

Larry


Re: reduce metaoperator

2005-05-07 Thread Stuart Cook
On 5/7/05, Patrick R. Michaud <[EMAIL PROTECTED]> wrote:
> It might not be a problem -- I'm thinking we may end up tokenizing
> most or all of the meta operators, so that [+] would be considered
> its own token, and then the "longest matching token" rule
> would be sufficient to disambiguate the terms:
> 
>   $x = [+1, -2, +3]; # token [ indicates a term
>   $y = [+] @stuff; # token [+] indicates a meta-op prefix operator

Does that mean postfix meta-ops that modify syntax become possible?
(Not necessarily a good idea, mind you, but possible...)


Stuart


Re: reduce metaoperator

2005-05-06 Thread Patrick R. Michaud
On Fri, May 06, 2005 at 12:23:49PM +1000, Stuart Cook wrote:
> On 5/6/05, Stuart Cook <[EMAIL PROTECTED]> wrote:
> > (snip) As long as each meta-operator
> > explicitly knows what type of regular operator it accepts (and
> > produces), there shouldn't be any problems with ambiguity.
> > 
> 
> Having posted that, I immediately thought of some problems:
> 
> If a meta-operator has
> {meta-fixity => prefix|circumfix, result-fixity => prefix}
> then it can be confused with a term, e.g.:
> 
> $x = [+1, -2, +3]; # opening [ indicates a term
> $y = [+] @stuff; # opening [ indicates a meta-op producing a prefix operator
> 
> This might confuse the parser, though I suppose you could always try
> both possibilities and see which one works.

It might not be a problem -- I'm thinking we may end up tokenizing 
most or all of the meta operators, so that [+] would be considered 
its own token, and then the "longest matching token" rule
would be sufficient to disambiguate the terms:

  $x = [+1, -2, +3]; # token [ indicates a term
  $y = [+] @stuff; # token [+] indicates a meta-op prefix operator

Or, the entry for the reduce meta operator might look something like

%prefixmetaops[ rx / \[ %infixops \] / ] = ...

in which case the parser would still be able to easily disambiguate
the differences when it's expecting an operator.

Pm


Re: reduce metaoperator

2005-05-05 Thread Stuart Cook
On 5/6/05, Brent 'Dax' Royal-Gordon <[EMAIL PROTECTED]> wrote:
> I find this table very interesting, in that it shows the fundamental
> difference between reduce and the existing meta-ops.

Yep, that was basically the whole point of the table.

> The existing meta-operators alter the semantics of the opoerator, but
> don't really change its syntax; a unary operator is still unary, a
> binary operator is still binary, and so on.  Reduce is irreducibly
> (pardon the pun) different, in that it alters the syntax as well as
> the semantics.

I was thinking of restricting the ways in which meta-ops can alter the
syntax of an op, but now I think we're better off not letting it
happen at all. Meta-ops that redefine syntax would be very hairy for
the compiler (as I pointed out), and probably wouldn't buy us much
that you couldn't achieve with a macro anyway.

> That would result in the following syntaxes:
> 
> reduce { $^a / $^b } @foo;
> reduce [/] @foo;
> 
>$sum = reduce[+] @array;
>$fact = reduce[*] 1..$num;
>$firsttrue = reduce[||] @args;
>$firstdef = reduce[//] @args;
>@sumrows := reduce[+«] @rows;
>@foo[0..9; reduce[;](@dims); 0..9]

I personally like that, and it has the additional property of avoiding
the "[+] @foo" vs. "[+1, -2]" ambiguity I pointed out.

Furthermore, it makes it /much/ easier for newbies to figure out what
that code actually does (since they can just grep for 'reduce' in the
docs).


Stuart


Re: reduce metaoperator

2005-05-05 Thread Stuart Cook
On 5/6/05, Stuart Cook <[EMAIL PROTECTED]> wrote:
(B> (snip) As long as each meta-operator
(B> explicitly knows what type of regular operator it accepts (and
(B> produces), there shouldn't be any problems with ambiguity.
(B> 
(B
(BHaving posted that, I immediately thought of some problems:
(B
(BIf a meta-operator has
(B{meta-fixity => prefix|circumfix, result-fixity => prefix}
(Bthen it can be confused with a term, e.g.:
(B
(B$x = [+1, -2, +3]; # opening [ indicates a term
(B$y = [+] @stuff; # opening [ indicates a meta-op producing a prefix operator
(B
(BThis might confuse the parser, though I suppose you could always try
(Bboth possibilities and see which one works.
(B
(BThe second problem is if a meta-operator has
(B{meta-fixity => postfix, argument-fixity => x, result-fixity => y}
(Bwhere (x != y).
(B
(B# Imagine '$B!}(B' is a meta-postfix taking an infix and and returning a 
(Bprefix.
(B# The parser will reject (J\(B, because it doesn't know to expect
(B# an infix op until it reaches the $B!}(B.
(B@x = (J\(B$B!}(B @z;
(B# The parser might assume that + is prefix (since a term is expected),
(B# then have to go back and treat it as an infix instead.
(B$x = +$B!}(B $z;
(B
(BThis will /really/ confuse the parser, and should probably (IMO) be outlawed.
(B
(B
(BStuart

Re: reduce metaoperator

2005-05-05 Thread Brent 'Dax' Royal-Gordon
On 5/5/05, Stuart Cook <[EMAIL PROTECTED]> wrote:
> +-+---+-++
> | Meta-op | is| operates on | to produce |
> +-+---+-++
> | [ ] | circumfix | infix   | prefix |
> +-+---+-++
> | >> <<   | circumfix | infix   | infix  |
> +-+---+-++
> | =   | postfix   | infix   | infix  |
> +-+---+-++
> | >>  | prefix| postfix | postfix|
> +-+---+-++
> | <<  | postfix   | prefix  | prefix |
> +-+---+-++

I find this table very interesting, in that it shows the fundamental
difference between reduce and the existing meta-ops.

The existing meta-operators alter the semantics of the opoerator, but
don't really change its syntax; a unary operator is still unary, a
binary operator is still binary, and so on.  Reduce is irreducibly
(pardon the pun) different, in that it alters the syntax as well as
the semantics.

My suggestion is simple:

multi *reduce(&block, [EMAIL PROTECTED] is copy) {
my [EMAIL PROTECTED];
while(@list) {
$r = block($r, [EMAIL PROTECTED]( :elems(&block.arity - 1) );
}
return $r;
}
macro *reduce ($op, $expr) is parsed( / \[ () \] 
()/ ) {
# Would be reworked to produce a parse tree
return "reduce(&infix:<$op>, $expr)";
}

That would result in the following syntaxes:

reduce { $^a / $^b } @foo;
reduce [/] @foo;

   $sum = reduce[+] @array;
   $fact = reduce[*] 1..$num;
   $firsttrue = reduce[||] @args;
   $firstdef = reduce[//] @args;
   @sumrows := reduce[+«] @rows;
   @foo[0..9; reduce[;](@dims); 0..9]

Clearly we could squabble about the exact bracketing operators to use
(I chose square brackets because I thought they'd be less ambiguous
than parentheses or curlies), but I trust you get the idea.

I agree that reduce is very useful, and I even agree that it should be
in core, but it's not *so* useful that it needs to be invokable
without a keyword.  Summing a list--which, let's face it, is likely to
be the most common use for this--isn't common enough an operation to
need such a compact syntax; I can think of more useful meta-ops, like
one that tags each result with the operands that created it, allowing
junctions to be used for the stuff people currently complain they
can't be.

multi sub *infixmetaop:<[ ]> ( $lhs, $rhs ) {
return call but operands($lhs, $rhs);
}

-- 
Brent 'Dax' Royal-Gordon <[EMAIL PROTECTED]>
Perl and Parrot hacker


Re: reduce metaoperator

2005-05-05 Thread Stuart Cook
If I understand correctly, so far we have the following meta-operators:

[ ]
circumfix meta-operator on infix operator which produces a prefix operator

>> <<
circumfix meta-operator on infix operator which produces an infix operator

=
postfix meta-operator on infix operator which produces an infix operator

>>
prefix meta-operator on postfix operator which produces a postfix operator

<<
postfix meta-operator on prefix operator which produces a prefix operator

In other words:
+-+---+-++
| Meta-op | is| operates on | to produce |
+-+---+-++
| [ ] | circumfix | infix   | prefix |
+-+---+-++
| >> <<   | circumfix | infix   | infix  |
+-+---+-++
| =   | postfix   | infix   | infix  |
+-+---+-++
| >>  | prefix| postfix | postfix|
+-+---+-++
| <<  | postfix   | prefix  | prefix |
+-+---+-++

>From this table, we can see that [ ] is the only meta-operator that
produces a different 'type' of operator from that which it accepts,
which might be where the confusion lies. As long as each meta-operator
explicitly knows what type of regular operator it accepts (and
produces), there shouldn't be any problems with ambiguity.


Re: reduce metaoperator

2005-05-05 Thread John Williams
On Thu, 5 May 2005, John Williams wrote:
> or even
>
> @x -= @y;

Doh!  That should be C< $x -= $y; > of course.



Re: reduce metaoperator

2005-05-05 Thread John Williams
On Thu, 5 May 2005, David Wheeler wrote:

> > I can see how to ask for a binary (hence infix) operator, but how
> > do I ask
> > for a prefix or postfix operator specifically, which +<< and >>+ do?
> > Maybe there are Operator::Prefix, etc, roles defined so you can ask
> > for
> > them?
>
> Ask for them for what?

For negating all elements of an array:

 @negatives = -« @positives;

> They should write them [metaoperators] only for infix operators.

The above example is in S03, so that is not an option.

> Because [] applies only to infix operators, as I understand it.

You understand it.  I understand it.  But how does the parser know the
difference between

@x = -<< @y;

and

@x = [+] @y;

or even

@x -= @y;

which shows that the position of metaoperator is not the distinguishing
factor.




Re: reduce metaoperator

2005-05-05 Thread David Wheeler
On May 5, 2005, at 11:28 , John Williams wrote:
How does [+] know you mean
   reduce &infix:<+>, @array;
instead of
   reduce &prefix:<+>, @array;
which is nonsense, but the [+] is in a prefix position.
Because [] applies only to infix operators, as I understand it.
With the hyper metaoperator, the real operator is always in the place
where it would normally be parsed.  But this metaoperator pulls the  
real
operator out of its usual pre/in/post position.
Well, if it was in its place, you wouldn't need to reduce it, would you?
I suppose users will need to know the answer when they start trying to
write their own metaoperators.
They should write them only for infix operators.
I can see how to ask for a binary (hence infix) operator, but how  
do I ask
for a prefix or postfix operator specifically, which +<< and >>+ do?
Maybe there are Operator::Prefix, etc, roles defined so you can ask  
for
them?
Ask for them for what?
Regards,
David

smime.p7s
Description: S/MIME cryptographic signature


Re: reduce metaoperator

2005-05-05 Thread John Williams
On Wed, 4 May 2005, Larry Wall wrote:
> It would be nice to have an easy-to-access "What's this?" interface
> that could be stitched into your favorite editor to identify what's
> under the cursor, or at least a command like:
>
> p6explain '[+]'

That would make me extremely happy.

> :$sum = [+] @array;   # meta operator

Another random thought which came to me (right after "\\+" could be
mnemonic for "return a function ref for this operator") was this:

How does [+] know you mean

   reduce &infix:<+>, @array;

instead of

   reduce &prefix:<+>, @array;

which is nonsense, but the [+] is in a prefix position.

With the hyper metaoperator, the real operator is always in the place
where it would normally be parsed.  But this metaoperator pulls the real
operator out of its usual pre/in/post position.

I suppose users will need to know the answer when they start trying to
write their own metaoperators.

Maybe the metaoperator's function signature resolves that somehow?
But I haven't been following the function signature thread closely.

I can see how to ask for a binary (hence infix) operator, but how do I ask
for a prefix or postfix operator specifically, which +<< and >>+ do?
Maybe there are Operator::Prefix, etc, roles defined so you can ask for
them?

~ John Williams


A06 typo:

>infix:+( prefix:-($a), $b)
>
> [Update: That's now
>
>infix:<+>( prefix:-($a), $b)
>
> .]

The correction only corrected one of the errors:

   infix:<+>( prefix:<->($a), $b)







Re: reduce metaoperator

2005-05-05 Thread Leopold Toetsch
Larry Wall <[EMAIL PROTECTED]> wrote:

> It would be nice to have an easy-to-access "What's this?" interface
> that could be stitched into your favorite editor to identify what's
> under the cursor, or at least a command like:

> p6explain '[+]'

s:p5/nice to have/absolutely necessary/ unless $self ~~ @larry;

Could $EDITOR-p6explain use life information from the parser with the
current context of the requested token?

leo


Re: reduce metaoperator

2005-05-05 Thread Larry Wall
On Wed, May 04, 2005 at 11:58:59PM -0600, Luke Palmer wrote:
: On 5/4/05, Larry Wall <[EMAIL PROTECTED]> wrote:
: > [<] could mean "monotonically increasing".
: 
: Not unless we make boolean operators magic.  There are arguments for
: doing that, but I don't really want to think about how that would be
: done at the moment.  Reduce over a straight-up (or left) boolean
: operator doesn't make much sense...

It could be admitted under the rewrite rule as applied to chaining
comparison operators, such that

if [<](1,2,3) {...}

is the same as

if 1 < 2 < 3 {...}

Likewise, one could write [|] to mean "any" and [&] to mean "all",
but that'd be kind of silly.

On the other hand, I freely admit that those don't work under a recursive
binary view that artificially forces left-associativity.

Larry


Re: reduce metaoperator

2005-05-04 Thread Damian Conway
Luke Palmer wrote:
On 5/4/05, Larry Wall <[EMAIL PROTECTED]> wrote:
[<] could mean "monotonically increasing".
Not unless we make boolean operators magic.  There are arguments for
doing that, but I don't really want to think about how that would be
done at the moment.  Reduce over a straight-up (or left) boolean
operator doesn't make much sense...
But the comparators *are* magic in Perl 6. They're not binary, they're 
n-ary.
So, since:
[<] @vals
actually means:
@vals[0] < @vals[1] < @vals[2] < @vals[3]
we get the n-ary behaviour, which is true if those values *are* in that order.
Perhaps you're forgetting the difference between what "reduce" means 
mathematically, and how its semantics are approximated in Perl 5 (in 
List::Util). "Reduce" means "bung this operator in between each of the 
elements of this list". But there's no way[*] to do that directly in Perl 5, 
so we currently have to live with a pairwise binary approximation.

That's perhaps the nicest feature of Larry's proposed reduction operator: that 
it will finally allow us to implement the real semantics of "reduce" and so 
get all the handy metaoperators (sum, product, sum-of-squares, monotonicity, 
first-true, first-defined) we've been missing to date.

Damian
[*] Okay, that's not strictly true. Evil Damian is already contemplating how
to implement n-ary reduction in Perl 5. Bwah-ha-ha-ha!


Re: reduce metaoperator

2005-05-04 Thread Luke Palmer
On 5/4/05, Larry Wall <[EMAIL PROTECTED]> wrote:
> [<] could mean "monotonically increasing".

Not unless we make boolean operators magic.  There are arguments for
doing that, but I don't really want to think about how that would be
done at the moment.  Reduce over a straight-up (or left) boolean
operator doesn't make much sense...

Luke


Re: reduce metaoperator

2005-05-04 Thread Larry Wall
On Wed, May 04, 2005 at 09:55:31PM -0600, John Williams wrote:
:$sum = reduce(+) @array;   # macro

That one suffers the operator/term confusion I mentioned earlier.

:$sum = reduce &infix:<+> @array;   # regular sub

That one's complicated enough that you actually installed a syntax error.

:$sum = [+] @array; # meta operator

That's rather pretty.  :-)

:($sum = 0) >>+=<< @array;  # hyper tricks

That's rather ugly.

:use My::Cool::Reduce::Mixin;   # unless in core
:$sum = @array.reduce(+);   # macro-ey method

Macro methods are probably not going to be in anyone's Best Practices book.

: There can never be too many ways to do it, but as one who hasn't been able
: to keep very current with perl6l lately, I think a particularly relevant
: question we should be asking a lot is, "How long will it take someone
: reading that code to figure out what it means?"

It would be nice to have an easy-to-access "What's this?" interface
that could be stitched into your favorite editor to identify what's
under the cursor, or at least a command like:

p6explain '[+]'

: The nice thing about "reduce" is that it is easy to find in the index.
: "[+]" will not be in the index, although I'm sure it would be the first
: thing one would look for.  I'm not sure how many other things a newbie
: will try before looking up "metacircumfix:<[ ]>" or however that is
: spelled.

I think a p6explain would be a rather popular program.

: Also in the same light, I am not convinced that reduce is used often
: enough to deserve a shorter huffman encoding.  Sure it makes that fancy
: slice shorter, but how much headscratching is required for a human to
: parse that shortness?

That has to be balanced out against the probability that it will soon
be learned by the newbie, especially if it gets into popular idioms.
For instance, since [EMAIL PROTECTED] is going to install spaces between 
elements
just like "@foo", we might see frequently [EMAIL PROTECTED] to do join('',@foo).
Sum of squares is now [+](@foo »*« @foo) or [+](@foo »**« 2).
We'll probably see [//] and [||] now and then.  Lisp hackers will
probably like [=>] to turn a flat list into a car/cdr list.  [<]
could mean "monotonically increasing".

: Personally, I think this would be more readable, in part because the
: object paradigm is widely understood.
: 
: @foo[0..9; @array.reduce(&infix<;>) ; 0..9];
: @foo[0..9; @array.reduce(;) ; 0..9];

Well, we're also trying to give the mathematicians various kinds of
built-in syntactic relief where it doesn't greatly interfere with
one's sanity.  The verbose approach would really turn off the PDLers.

: I actually kinda like the idea, in spite of coming across as a naysayer
: here.  It just seems like an idea that should be in a module instead of in
: core, which seems like an awful strange thing to say to $Larry.

As I said in another message, I think this one is kind of a no-brainer
to teach to newbies, since like += it can be taught as a rewrite rule.
I would like it to be as much a part of core Perl as += is.

It also might be slightly easier to optimize something like [+] than
its less direct counterparts.

Larry


Re: reduce metaoperator

2005-05-04 Thread John Williams
   $sum = reduce(+) @array; # macro
   $sum = reduce &infix:<+> @array; # regular sub
   $sum = [+] @array;   # meta operator
   ($sum = 0) >>+=<< @array;# hyper tricks

   use My::Cool::Reduce::Mixin; # unless in core
   $sum = @array.reduce(+); # macro-ey method

There can never be too many ways to do it, but as one who hasn't been able
to keep very current with perl6l lately, I think a particularly relevant
question we should be asking a lot is, "How long will it take someone
reading that code to figure out what it means?"

The nice thing about "reduce" is that it is easy to find in the index.
"[+]" will not be in the index, although I'm sure it would be the first
thing one would look for.  I'm not sure how many other things a newbie
will try before looking up "metacircumfix:<[ ]>" or however that is
spelled.

Also in the same light, I am not convinced that reduce is used often
enough to deserve a shorter huffman encoding.  Sure it makes that fancy
slice shorter, but how much headscratching is required for a human to
parse that shortness?

Personally, I think this would be more readable, in part because the
object paradigm is widely understood.

@foo[0..9; @array.reduce(&infix<;>) ; 0..9];
@foo[0..9; @array.reduce(;) ; 0..9];

I actually kinda like the idea, in spite of coming across as a naysayer
here.  It just seems like an idea that should be in a module instead of in
core, which seems like an awful strange thing to say to $Larry.

~ John Williams

P.S.  I like [+] better than \\+ because I cannot figure out what \\ would
be mnemonic for.

P.P.S.  We can't use (R)+ ... it's already trademarked!  :)



Re: reduce metaoperator

2005-05-04 Thread Larry Wall
On Wed, May 04, 2005 at 09:55:57AM -0400, Aaron Sherman wrote:
: I don't think there's a perfect solution for what you want, but this is
: pretty darned close.

Yes, and I was always a little fond of the bracket solution since it
lets you visually distinguish

$x = [»+«] @foo;

$x = [+]« @foo;

In interests of simplification, it's vaguely possible we should
replace unary * with [,], which would let *x is always mean ::*x,
but probably not.

Larry


Re: reduce metaoperator

2005-05-04 Thread Aaron Sherman
On Wed, 2005-05-04 at 09:45, Larry Wall wrote:
> On Wed, May 04, 2005 at 09:34:28AM -0400, Aaron Sherman wrote:

> : Hmmm...
> : 
> : $sum = [+] @array
> : 
> : Nice.
> 
> I just thought that'd be visually confusing in a subscript:
> 
> @foo[0..9; [;[EMAIL PROTECTED]; 0..9]

Now, why did I think you wouldn't have already considered every
permutation? ;-)

> But maybe it's not so bad.

Yeah, it's confusing in some places, but I think they're mostly edges.

> Yes, but it is rather ambiguous for any unary that can take $_, like
> 
> [int]
> 
> but that's not an infix, and there isn't that much overlap, so it could
> probably be made to work, and not be too confusing, at least until
> someone adds an infix: operator...

And they could get a warning that tells them of the potential conflict
when they do

I don't think there's a perfect solution for what you want, but this is
pretty darned close.

-- 
Aaron Sherman <[EMAIL PROTECTED]>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback




  1   2   >