Re: Hyper operator corner case?

2005-04-18 Thread Thomas Sandlaß
Roger Hale wrote:
One set of cases that doesn't seem to have come up in discussion:
(1, 3, 2) - (83, 84, 81, 80, 85)
Should this give
(-82, -81, -79, -80, -85)
From an arithmetic point of view it should be exactly that. The
implementation might need to morph the code though, see below.

as by hallucinating $neutral - $x == $x?  This latter $neutral in fact 
doesn't exist among ordinary numbers, and I would call it algebraically 
unnatural:  for all (other) $n,

$n - ($a + $b) == ($n - $a) - $b
or, as you increase $a by $b, $n - $a decreases by $b (a sort of 
contravariance), but

$neutral - ($a + $b) == $a + $b == ($neutral - $a) + $b
!  This violates algebraic relations I would prefer to rely on, both in 
my own reasoning and that of the compiler and other program-handling 
programs.
Me too! The thing is that the field of the real numbers is build on the
operators + and * which are associative and commutative. The neutral
elements are 0 and 1 respectively. The non-associative operators - and /
are defined in terms of the inverse elements. Thus $a - $b == $a + (-$b)
and $a / $b == $a * (1/$b) if $b != 0. We could also bring in $b**-1 as
another way to find the multiplicative inverse. But that just pulls in
yet another operator and the question which axioms apply to it and how
it is hyperated.
For user-defined numerical types---that is ones that provide +, *, -, /,
**, etc---I would hope that these axioms hold. Actually I hope that
there is a set of roles that define the standard numerics and enforce
sanity as far as that is possible via the class composition mechanics.
So coming back to your example, operator - would call - on the RHS
and call + with the result. But I've no idea to which extent operator
  is a special runtime operator versus a term re-writing at compile
time.
--
TSa (Thomas Sandla)



Re: Hyper operator corner case?

2005-04-17 Thread Roger Hale
Thomas Sandla wrote:
John Williams wrote:
Good point.  Another one is: how does the meta_operator determine the
identity value for user-defined operators?

Does it have to? The definition of the identity value---BTW, I like
the term neutral value better because identity also is a relation
between two values---is that $x my_infix_op $neutral == $x.
One set of cases that doesn't seem to have come up in discussion:
(1, 3, 2) - (83, 84, 81, 80, 85)
Should this give
(-82, -81, -79, -80, -85)
as it would by hallucinating 0 (neither a left-identity nor left-neutral 
element for subtraction strictly, but at least a natural left pivot 
element), or

(-82, -81, -79, 80, 85)
as by hallucinating $neutral - $x == $x?  This latter $neutral in fact 
doesn't exist among ordinary numbers, and I would call it algebraically 
unnatural:  for all (other) $n,

$n - ($a + $b) == ($n - $a) - $b
or, as you increase $a by $b, $n - $a decreases by $b (a sort of 
contravariance), but

$neutral - ($a + $b) == $a + $b == ($neutral - $a) + $b
!  This violates algebraic relations I would prefer to rely on, both in 
my own reasoning and that of the compiler and other program-handling 
programs.

Best regards
 Roger


Re: Hyper operator corner case?

2005-04-15 Thread Thomas Sandlaß
John Williams wrote:
Good point.  Another one is: how does the meta_operator determine the
identity value for user-defined operators?
Does it have to? The definition of the identity value---BTW, I like
the term neutral value better because identity also is a relation
between two values---is that $x my_infix_op $neutral == $x.
So the generic implementation that copies surplus elements is correct
with respect to the resulting value. You shouldn't expect the operator
beeing called as many times as there are elements in the bigger data
structure, though. It's called only for positions where both structures
have actual values. But that is the same as short-circuiting  and ||.
And somewhat the reverse of authreading from junctive values.

I believe the fine points fall out like this:
   @a + 1# replicate
   @a + (1)  # replicate: (1) is still scalar
   @a + [1]  # extend: [1] is an array (and will auto-deref)
I think they fall out naturally from typing and dispatch. But note
that the » « operator has three args. I haven't made the op a dispatch
selector. If the my_infix_op from above needs to handle neutral elements
by itself just tell the dispatcher by defining
infix_circumfix_meta_operator:{'»','«'}:(List,List,my_infix_op:) and
construct the neutral elements when one of the list runs out of elements.
I hope the syntax I used does what I want to express. Note that in
:(List,List,my_infix_op:) the first two elements are types while
my_infix_op is a sub value. In that sense my op was actually wrong
but it was nice for wording my sentence. So the generic name should read
infix_circumfix_meta_operator:{'»','«'}:(List,List:Code) or perhaps
infix_circumfix_meta_operator:{'»','«'}:(List,List:) if  is considered
as the code sigil. Hmm, then we could also have :(@,@:) meaning the
same type spec?
BTW, starting from these type specs I come (back) to the suggestion of using
» « for hypering function calls and/or their arguments. Has that been decided?
I'm not sure if specialisation on values is covered by the :() syntax.
E.g. one could implement infix:*:(0,Any) to return 0 without evaluating
the Any term at all! But this needs either lazy evaluation in the functional
paradigma or code morphing 'x() * y()' to '(($t = x()) != 0) ?? $t * y() :: 0'
or some such. On assembler level this morphing reduces to an additional
check of a register for zero. But I'm not sure if the type system and the
optimizer will be *that* strong in the near future ;)
Regards
--
TSa (Thomas Sandlaß)


Re: Hyper operator corner case?

2005-04-14 Thread John Williams
I found where Damain explains the rule as basically replicate dimensions,
extend lengths, using an identity value when extending the length.
http://www.mail-archive.com/perl6-language@perl.org/msg08304.html

On Wed, 13 Apr 2005, Thomas Sandlaß wrote:

 Brent 'Dax' Royal-Gordon wrote:
  IIRC, it's f) (1,2,3,4,5) + (1,2,$identity,$identity,$identity),
  where $identity's value is determined by a table something like this:

 In the case of  infix_circumfix_meta_operator:{'»','«'}:(List,List:op)
 there's no upgrade---to use the S03 term.  A simple apply op where
 the lists overlap and keep the rest of the longer one suffices.
 That is (1,2,3,4,5) + (1,2) becomes (1+1, 2+2, 3, 4, 5). For
 infix_circumfix_meta_operator:{'»','«'}:(List,Scalar:op) the upgrade
 works by applying the operator with the scalar to all entries:
 (1,2,3,4,5) + 1 becomes (1+1, 2+1, 3+1, 4+1, 5+1).

Good point.  Another one is: how does the meta_operator determine the
identity value for user-defined operators?

(1,2,3,4,5) my_infix_op (3,2,4)

Maybe we should say that the excess length is simply copied unchanged.
But some might argue that not calling the op for each element would be
cheating somehow.  That's not my position, but I cannot think how to
refute it right now, if you want the side-effects.

 What I ask myself is wether (1,2,3) »+ 1 should be a syntax error or just
 a different form to express the :(List,Scalar:) case. BTW, I know that
 infix_prefix_meta_operator:{'»'} isn't mentioned in A12.

  I could be wrong, though; I can't find any support for it in the design 
  docs.

Replicate dimensions is specified in the first version of A3.

The length issue was resolved on the mailing lists.
Could someone add the ruling to S3 to answer this FAQ?

I believe the fine points fall out like this:

   @a + 1# replicate
   @a + (1)  # replicate: (1) is still scalar
   @a + [1]  # extend: [1] is an array (and will auto-deref)

~ John Williams



Re: Hyper operator corner case?

2005-04-14 Thread Larry Wall
On Thu, Apr 14, 2005 at 11:08:21AM -0600, John Williams wrote:
: Good point.  Another one is: how does the meta_operator determine the
: identity value for user-defined operators?
: 
: (1,2,3,4,5) my_infix_op (3,2,4)
: 
: Maybe we should say that the excess length is simply copied unchanged.
: But some might argue that not calling the op for each element would be
: cheating somehow.  That's not my position, but I cannot think how to
: refute it right now, if you want the side-effects.

One naive possibility is to supply one identity value per precedence level.
Then you could get 0 for addition and 1 for multiplication.  Doesn't
really work though, given there are so many different kinds of addition
and multiplication lumped together.  Arguably the identity value for %
is Inf.

Another approach to get the side effects would be to assume that
whatever meta code is actually calling the scalar operator is
smart enough to coerce ordinary undefs into undef but identity
or some such that each individual operator would know how to deal
with rather than generating an exception/undef.

:  What I ask myself is wether (1,2,3) »+ 1 should be a syntax error or just
:  a different form to express the :(List,Scalar:) case. BTW, I know that
:  infix_prefix_meta_operator:{'»'} isn't mentioned in A12.
: 
:   I could be wrong, though; I can't find any support for it in the design 
docs.

We decided that binary ops should always just have »« on both sides,
since it's essentially just a single dwim this bit of information.

Basically, »« is just a flagrant value of 1.

: Replicate dimensions is specified in the first version of A3.
: 
: The length issue was resolved on the mailing lists.
: Could someone add the ruling to S3 to answer this FAQ?
: 
: I believe the fine points fall out like this:
: 
:@a + 1# replicate
:@a + (1)  # replicate: (1) is still scalar
:@a + [1]  # extend: [1] is an array (and will auto-deref)

Yes.  Parens in scalar context do not automagically produce a list.
Comma is another matter, so

   @a + (1,)

turns out to be the same as

   @a + [1]

since there is no scalar comma operator in Perl 6.

All that being said, it's almost certainly the case that (1) is
a mistake.  and should perhaps produce a warning: Useless use of
parentheses or some such.  Not that we frown on useless use of
parentheses in general, since they're often clarifying precedence.
But nobody should be confused about the precedence of a simple term.

Larry


Re: Hyper operator corner case?

2005-04-13 Thread Brent 'Dax' Royal-Gordon
David Christensen [EMAIL PROTECTED] wrote:
 Example:
(1,2,3,4,5) + (1,2)
 
 Is this equivalent to:
 
 a) (1,2,3,4,5) + (1,2,undef,undef,undef) (undef padding)
 b) (1,2,3,4,5) + (1,2,1,2,1) (repetition)
 c) (1,2,3,4,5) + (1,2,2,2,2) (stretching)
 d) (1,2) + (1,2) (truncation)
 e) something else, ie, warnings about mismatched dimension, die(),
 segfault, kill -9 1 (whatever your sadism level is).

IIRC, it's f) (1,2,3,4,5) + (1,2,$identity,$identity,$identity),
where $identity's value is determined by a table something like this:

infix:+0
infix:-0
infix:~''
infix:*1
infix:/1
infix:%mumble
infix:x1

I could be wrong, though; I can't find any support for it in the design docs.

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

I used to have a life, but I liked mail-reading so much better.


Re: Hyper operator corner case?

2005-04-13 Thread Thomas Sandlaß
Brent 'Dax' Royal-Gordon wrote:
IIRC, it's f) (1,2,3,4,5) + (1,2,$identity,$identity,$identity),
where $identity's value is determined by a table something like this:
In the case of  infix_circumfix_meta_operator:{'»','«'}:(List,List:op)
there's no upgrade---to use the S03 term.  A simple apply op where
the lists overlap and keep the rest of the longer one suffices.
That is (1,2,3,4,5) + (1,2) becomes (1+1, 2+2, 3, 4, 5). For
infix_circumfix_meta_operator:{'»','«'}:(List,Scalar:op) the upgrade
works by applying the operator with the scalar to all entries:
(1,2,3,4,5) + 1 becomes (1+1, 2+1, 3+1, 4+1, 5+1).
What I ask myself is wether (1,2,3) »+ 1 should be a syntax error or just
a different form to express the :(List,Scalar:) case. BTW, I know that
infix_prefix_meta_operator:{'»'} isn't mentioned in A12.

I could be wrong, though; I can't find any support for it in the design docs.
Indeed, upgrade is a bit fuzzy ;)
--
TSa (Thomas Sandlaß)


Hyper operator corner case?

2005-04-12 Thread David Christensen
Hey folks,
I wanted to delurk and address an issue that may need clarification in 
regards to hyper operators.

Quoting S03:
If one argument is insufficiently dimensioned, Perl upgrades it:
 (3,8,2,9,3,8) - 1;  # (2,7,1,8,2,7)
Now in this example case, it's pretty clear that the scalar 1 gets 
turned into a list of 1s with the length of the lhs.  What about the 
case of a larger-dimensioned or single-dimensioned array?

Example:
  (1,2,3,4,5) + (1,2)
Is this equivalent to:
a) (1,2,3,4,5) + (1,2,undef,undef,undef) (undef padding)
b) (1,2,3,4,5) + (1,2,1,2,1) (repetition)
c) (1,2,3,4,5) + (1,2,2,2,2) (stretching)
d) (1,2) + (1,2) (truncation)
e) something else, ie, warnings about mismatched dimension, die(), 
segfault, kill -9 1 (whatever your sadism level is).

Additionally, I was wondering if there was a difference between:
(3,8,2,9,3,8) - 1
and
(3,8,2,9,3,8) - (1)
I suppose the answer to that depends on the answer to the above 
question.

If the answer is the a) case as above and undef resolves to 0 
numerically, then we run into another issue to consider.  In the case 
of addition and subtraction, 0 is the identity element, and so:

(1,2,3,4,5) + (1,2) yields (2,4,3,4,5).
But the intuitiveness goes away with multiplication, and completely 
blows up with division:

(1,2,3,4,5) * (1,2) yields (1,4,0,0,0), probably not what we wanted.
(1,2,3,4,5) / (1,2) yields (1,1,NaN,NaN,NaN), and probably die()s 
with division by zero errors.

If in the addition and subtraction cases we want to preserve the 
identity cases for the slots not accounted for, undef is fine because 
it resolves to 0; to provide the same features for multiplication and 
division, the identity element would have to be 1.  But that would 
suppose that the potential hyper-operators would know what their 
appropriate identity elements were (and that such a thing is meaningful 
to them).

Additionally, if there is a difference between the automatic scalar 
promotion and list promotion, we could run into errors where people 
would expect an expression to be a scalar which would be promoted in 
the documented fashion, but would really be promoted in one of a)-e), 
breaking what they expected:

(1..5) + ($a-$b) # list context for the expression?  Promotes like 
what?
(1..5) + +($a-$b) # forced scalar context -- promotes like 
documented.
(1..5) + (1) # promotes like what?

Thoughts?
David Christensen