Re: Overloading Roles

2009-10-07 Thread David Green

On 2009-Oct-5, at 3:41 pm, Jon Lang wrote:
Concerning that last one: would it be reasonable to have a Discrete  
role

that provides a .succ method, and then overload the Range role?


I think a type needs to be Discrete and Ordered for successors to make  
sense (e.g. consider a discrete unordered type like Complex ints).


I'm still thinking a Discrete type is the same as a Set; so perhaps  
Discrete  Ordered means Positional?  But that doesn't feel right --  
although any ordered set can be represented as an array, that seems to  
confuse the idea of order that is intended.


(And perhaps Discrete should be a different type from Set even if  
they do work out the same, simply to better document one's intent.)




-David



Re: Overloading Roles

2009-10-06 Thread Jonathan Worthington

Jon Lang wrote:

Concerning that last one: would it be reasonable to have a Discrete role
that provides a .succ method, and then overload the Range role?  E.g.:

role Range[Ordered ::T] { ... }

role Range[Ordered Discrete ::T] {
...
method iterator ( - RangeIterator ) { ... }
}

If so, then this approach might also be used to handle the special behavior
that comes with Numeric types:

role Range[Ordered Numeric ::T] { ... }

  
If the question is can you define multiple roles with the same name, 
but taking different signatures, then the answer is yes, and that it 
goes by the same rules as multiple dispatch (and it's even been 
implemented :-)). What you pasted won't quite work, however, as you 
can't write multiple types before a parameter (at least in 6.0.0). So 
you'd want something more like:


role Range[::T where Ordered  Numeric] { ... }

Hope this helps,

Jonathan


Overloading Roles

2009-10-05 Thread Jon Lang
Consider a Range role that is parameterized (i.e., Range of T is a
perfectly valid thing to do).  According to the spec, the definition of
Range depends on the nature of T:

* If the lower bound is Numeric, certain coercion rules are attempted on the
upper bound; otherwise, the two boundaries must have the same type.
** Speculation: if the lower bound is a Whatever, the boundary type should
be determined by the upper bound; if both are Whatever, treat it as Numeric?
* if the boundary type has a .succ method, then the Range can provide a
RangeIterator; otherwise, it can't.

Concerning that last one: would it be reasonable to have a Discrete role
that provides a .succ method, and then overload the Range role?  E.g.:

role Range[Ordered ::T] { ... }

role Range[Ordered Discrete ::T] {
...
method iterator ( - RangeIterator ) { ... }
}

If so, then this approach might also be used to handle the special behavior
that comes with Numeric types:

role Range[Ordered Numeric ::T] { ... }

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-28 Thread TSa

HaloO,

Larry Wall wrote:

As it stands the .() forms are a great way to stack ops after
a term. Together with knowing about the ops on the symbolic unary
level you can easily read expressions from the terms outwards.


I'm not actually parsing expressions. Or as you point out below
with respect to look-ahead I'm bad at it as a human. But as a
human I've got a 2D vision and mathematical expressions are inherently
2D on paper. So they are more like a drawing than a writing.

The poor equivalent in a programming language is whitespace markup.
Consider the triangle inequality:

|$x+$y| = |$x| + |$y|

This nicely breaks apart into five clusters of characters. I recognize
the two infix ops = and + and bring my precedence knowledge to
bear or look it up. After that I analyze the remaining three
clusters. I see all of them having | as first and last character.
So I know that three absolute values are linked by two operators.
And only then do I start to analyze the things inside the | |s which
gives me the sum of $x and $y and the same values separately.

The version with more spaces is different

   |$x + $y| = |$x| + |$y|

because now I tend to perceive the two +s on equal footing and
converge visually on |$x using prefix | and $y| postfix. To avoid
that an ASCII equivalent of a typesetting system gives

   | $x + $y |   =   | $x |   +   | $y |

to guide my visual distance parsing or however that might be called.



Good practice would then be to join these extended terms by an
obvious set of infix ops---usually one. The only twists to learn in
this scheme would be ++, -- and **.


I don't follow that.  Example?


The twist of ++, -- and ** is that they lay between method and symbolic
unary precedence and that ** is the only binary operator with tighter
precedence then the symbolic unarys.

By operator stacking I mean something like

  !+-~?|+^~^$x.a.b.c + [EMAIL PROTECTED]

which splits into two blobs left and right of + each of which has a
sigiled term as nucleus. From there I would work outwards in operator
precedence. In other words, writing the former example as

   $x ** $y!

visually attaches ! to $y and deters from the precedence issue.
So it should be something like

   $x**$y\ !

to highlight it. But parens aren't that bad here either

   ($x ** $y)!

But the tight precedence of infix ** should be made obvious by
not surrounding it with whitespace. Which gives

   ($x**$y)!

as the best option.


I would make more infix ops list like. We already have

  ,  associative, non-commutative

 |  ^   associative, commutative

and could add ~ into the first group and *, +, +, +|, ~, ~, +^
and ~^ into the second one. The code generator and the optimizer would
use these features and give erroneous results when overloads don't
respect them.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-28 Thread Doug McNutt
At 09:46 -0400 3/27/08, Mark J. Reed wrote:
Is it just me, or is all this talk about precedence and functions vs operators 
vs methods creating a niggling sensation in anyone else's head? It feels like 
we're in the vicinity of another one of them Big Simplifying Idea things. 
Unfortunately, I don't have the actual Big Idea, so it could just be a false 
alarm.

At 16:24 +0100 3/26/08, TSa wrote:
I agree. But let me explain how I arrive at that. To me there is no binary 
minus! -f(x) - g(x) = -f(x) + -g(x) = -g(x) + -f(x). I.e. plus is commutative. 
In other words overloading unary minus gives you the binary version for free. 
Or even better is to deeply overload unary plus to do the Ring role. 
Additionally implementing unary / or 1/ or so would yield the Field role.

At 17:06 +0100 3/20/08, TSa wrote:
BTW, do we have a unary multiplikative inversion operator? That is 1/ as 
prefix or **-1 as postfix? Perhaps .inv as method? Do we have .neg for 
additive inversion?

This is becoming a night time habit. I really need to spend a whole lot of time 
learning the new operator syntax and Perl 6 Essentials 1st edition isn't 
going to cut it. Following Mark's line of thought, that bothers me.

Thomas' idea that there is no such thing as a binary minus operator and his 
question about inversion operators intrigue me. Perhaps there is a way to a 
breakthrough that would be acceptable to long-time users of the chalkboard and 
still be mathematically pure and and easily parsed.

A while back there was a flurry of new math being taught in US elementary 
schools. The idea was to introduce set theory early and avoid the re-learning 
necessary when groups and fields are introduced later. It was a failure mostly 
because the teachers couldn't understand it.

A group is a set with a single binary operator defined, the result of that 
operator is a member of the group, there is a null member of the group that 
returns the value of the other operand, and every member of the group has an 
inverse for which the operation returns the null. Note that those axioms say 
nothing about an inversion operator. For numbers the operator is either 
addition, +, or multiplication, *. Subtraction and division are notably missing.

A field is a set which looks like two kinds of group with two operators. One 
operator has higher precedence than the other and the existence of the inverse 
for one operator requires some modification for the null of the other operator.

Matrices and vectors are reasonably comfortable in fields. Note that 
commutativity is not a group requirement. The vector cross product is a bit 
strange but some folks claim that a cross product is really an antisymmetric 
tensor that isn't really a vector because it doesn't transform, under 
reflection, as the coordinate differentials. That kind of thinking would fit 
right in and might be beneficial. Overloading code would be required for * and 
+ only but inversions would replace that bit of simplification. Note that the 
term class acquires a close relationship with the term field.

I think it is possible to insist that users of perl 6 for math think in terms 
of fields while writing expressions. Just remove the / and - operators from 
the language. They're not present in the field axioms so why have them? Just 
announce that perl 6 will be different. The rest of the world now listens when 
we say a perl regular expression. Why not the same for perl math expression 
?.

NIST now likes people to avoid the term per when writing about dimensions of 
physical quantities. A watt is a kg*m**2*s**-2 when translated to perl 5 but it 
looks a lot better in print with superscripts and no explicit * operator. 
Calling it a kilogram meter squared per second per second has been deprecated 
for years. Engineers and physicists known to me have no problem with it.

There was once a mnemonic, PEMDAS, that was taught in algebra classes. 
Parentheses, exponentiation, multiplication, division, addition, subtraction 
was the order to use when working with algebraic expressions. Restricting that 
to fields would change it to PFMA by which I mean parentheses, functions, 
multiplication, addition. Functions would include exponentiation along with 
other things like inversion and more complicated library functions.. Users 
would have to learn that division and subtraction would be called out by an 
inversion followed by a multiply or add operation.

Terms on the right side of the replacement operator would be separated by + 
signs only.

Needed would be a really simple syntax for the two types of inversion. 
Something like a distinct sigl would be nice from a user's point of view. 
$xxx[$n] is closely associated with @xxx and it seems possible to come up with 
something like Nxxx for the additive inversion of $xxx and Dxxx for its 
multiplicative equivalent. Variables starting with I through N was not a bad 
way to indicate an integer.

I haven't any idea how one would request that a function

Re: Musings on operator overloading

2008-03-27 Thread Thom Boyer

Thom Boyer wrote:

Now, I think that

$x.foo

is a method call, even if there's a postfix:foo declaration in scope. 
And that's a problem, because, no matter what precedence postfix:foo 
was given,


1,2,3.foo

is still going to mean

1, 2, (3.foo)

instead of the desired

postfix:foo(1,2,3)



The way I wrote that, it sounds like I think postfix:foo isn't a 
method call, but of course it is.


What I really meant to say is that, in

1,2,3.foo

the precedence of foo gets changed to the precedence of dot. I don't 
actually know that that is true. Is it?


And does dot always do that? If it does, then something odd happens. 
Consider infix:* and postfix:!, where infix:* binds tighter than 
postfix:+, and both bind more loosely than dot. Then


1 * 2!  # means (1 * 2)!
1 * 2.! # means 1 * (2!)

Methinks one or more of my assumptions is erroneous, 'cuz that's just 
too ugly to live.

=thom


Re: Musings on operator overloading

2008-03-27 Thread Thom Boyer

Thom Boyer wrote:
And does dot always do that? If it does, then something odd happens. 
Consider infix:* and postfix:!, where infix:* binds tighter than 
postfix:+, and both bind more loosely than dot. Then


I meant ... tighter than postfix:!, ...



1 * 2!  # means (1 * 2)!
1 * 2.! # means 1 * (2!)

Methinks one or more of my assumptions is erroneous, 'cuz that's just 
too ugly to live.

=thom




Re: Musings on operator overloading

2008-03-27 Thread TSa

HaloO,

Larry Wall wrote:

I deem that to be an unlikely failure mode, however.  So maybe .++
is just gone now, and you have to write \++ instead.  Any objections?


Please keep .++ as outlined below. Does the degenerate unspace not
collide with prefix:\? That is does foo\bar() not mean to capture
the result from bar() and call foo with it unflattened?



I'm not sure that's a great loss.  It does suggest an alternate
approach, though, which is to keep the .() forms with forced method
precedence, and only require \x form for alpha postfixes that want
to keep their own precedence.  Not sure if I like that entirely,
but it could fall out naturally from the definition of unspace in
the current scheme of things, so maybe it's a non-issue.


As it stands the .() forms are a great way to stack ops after
a term. Together with knowing about the ops on the symbolic unary
level you can easily read expressions from the terms outwards.
Good practice would then be to join these extended terms by an
obvious set of infix ops---usually one. The only twists to learn in
this scheme would be ++, -- and **.

Another good use of the dot forms is to get a single character
form to tighten precedence: $x**3! != $x**3.! == $x**(3!). This
is kind of reverse visually, though. So one might be tempted to
make ! tighter than ** and get the looser meaning with $x**2\!
which wouldn't be a degenerate unspace but a special form to
unbind a tight op as in $x**$y\++ == ($x**$y)++ disregarding the
fact that $x**$y is no lvalue.

BTW, are there still the * and ** prefix ops for list flattening?
Or are these superseded by prefix |?



and maybe even

circumfix:| | ::= prefix:abs;
|$x|

except for the fact that that would collide with prefix:|...


So no whitespace dwimmery here? I.e. one would need |$x | to
force the second | into infix? But eventually the parser has
to give up when the same symbol is overloaded as prefix, postfix,
infix and symmetric circumfix anyway.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-27 Thread TSa

HaloO,

TSa wrote:

Another good use of the dot forms is to get a single character
form to tighten precedence: $x**3! != $x**3.! == $x**(3!).


BTW, is the dot form only available for postfix or for infix
as well? I.e. 3 * 2 == 3.*(2)?


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-27 Thread TSa

HaloO,

Jon Lang wrote:

TSa wrote:

 Note that I see ** more as a parametric postscript then a real binary.
 That is $x**$y sort of means $x(**$y).


That's where we differ, then.  I'm having trouble seeing the benefit
of that perspective, and I can clearly see a drawback to it - namely,
you have to think of infix:** as being a different kind of thing
than infix:.«+ - * /, despite having equivalent forms.


I see no drawback but a necessity because of the following asymmetry:

  3 * 2 == 3 + 3 == 2 + 2 + 2;
  3 **2 == 3 * 3 != 2 * 2 * 2;

So ** more behaves like 3.pow(2) and overloading ** with
non-numeric types on the right is questionable. Certain
overloads of the left side might even require the right
side to be (unsigned) integer. And of course

 $any ** $int === [*]($any xx $int)

should hold.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-27 Thread Thom Boyer

Jon Lang wrote:

Thom Boyer wrote:

 That seems better to me than saying that there's no tab character in

 say blah $x\t blah


Whoever said that?


Oops. I thought Larry did. But he didn't; I misread it. Whew.

Somehow I managed to read Larry's words and get exactly the *opposite* 
meaning from what he actually wrote:


Larry Wall wrote:
 This may also simplify the parsing rules inside double quoted
 strings if we don't have to figure out whether to include postfix
 operators like .++ in the interpolation.  It does risk a visual
 clash if someone defines postfix:t:

 $x\t   # means ($x)t
 $x\t   # means $x ~ \t

How embarrassing. Thanks for asking Whoever said that?, because it 
forced me to go reread it.


I think I'd better go reread the whole thing. More carefully this time.


 Thom Boyer wrote:
  when (if I understand correctly) you could write that as simply as

  1,2,3 say

 Nope.  This is the same situation as the aforementioned '++' example,
 in that you'd get into trouble if anyone were to define an infix:say
 operator.

OK. Let me see if I get this. First, let me state my understanding of 
the issue with ++ (where ++ is actually a stand-in for *any* operator 
that is both postfix and infix):


$x++ # postfix operator, because there's no whitespace
$x.++# postfix (the dot is optional)

$x ++# infix operator, because there's whitespace

$x\   ++ # postfix: space isn't allowed, but unspace is
$x\  .++ # postfix (the dot is still optional)


Question: given

($x)++   # no whitespace, so postfix?

is ++ postfix, or infix?


Now, I think that

$x.foo

is a method call, even if there's a postfix:foo declaration in scope. 
And that's a problem, because, no matter what precedence postfix:foo 
was given,


1,2,3.foo

is still going to mean

1, 2, (3.foo)

instead of the desired

postfix:foo(1,2,3)

so Larry has proposed

1,2,3\foo   # means: postfix:foo(1, 2, 3)

as a way to get the desired meaning without having to resort to parentheses.

So the point is that a nospace unspace acts like dot, in that it turns 
the following operator into a postfix operator. But it doesn't have the 
undesired characteristic that it turns an intended postfix operator into 
a method dispatch. Have I got that right, or am I still wandering in a 
wilderness that is completely disconnected from Larry's proposal?


Final question: I think these are all equivalent. Are they?

1,2,3\foo
(1,2,3)foo
(1,2,3).foo
postfix:foo(1,2,3)

=thom


Re: Musings on operator overloading

2008-03-27 Thread Mark J. Reed
Is it just me, or is all this talk about precedence and functions vs
operators vs methods creating a niggling sensation in anyone else's
head?  It feels like we're in the vicinity of another one of them Big
Simplifying Idea things.  Unfortunately, I don't have the actual Big
Idea, so it could just be a false alarm.

On the one hand, I'm worried that Perl6 is going to turn into the
computer equivalent of Quenya, which was never completed because its
creator couldn't stop tinkering.  (No offense to Larry intended..)  On
the other, given how much design thought has gone into it thus far,
much of it radical, it would be terrible to miss an opportunity to do
something great in the rush to git 'er done.


Re: Musings on operator overloading

2008-03-27 Thread Larry Wall
On Wed, Mar 26, 2008 at 07:32:23PM -0600, Thom Boyer wrote:
 Question: given

 ($x)++   # no whitespace, so postfix?

 is ++ postfix, or infix?

That is postfix.  Any infix that could be confused with a postfix
requires intervening whitespace.

 Now, I think that

 $x.foo

 is a method call, even if there's a postfix:foo declaration in scope. And 
 that's a problem, because, no matter what precedence postfix:foo was 
 given,

 1,2,3.foo

 is still going to mean

 1, 2, (3.foo)

 instead of the desired

 postfix:foo(1,2,3)

 so Larry has proposed

 1,2,3\foo   # means: postfix:foo(1, 2, 3)

 as a way to get the desired meaning without having to resort to parentheses.

 So the point is that a nospace unspace acts like dot, in that it turns the 
 following operator into a postfix operator. But it doesn't have the 
 undesired characteristic that it turns an intended postfix operator into a 
 method dispatch. Have I got that right, or am I still wandering in a 
 wilderness that is completely disconnected from Larry's proposal?

The .++ form is still not a method (single) dispatch, just an alternate
form of the postfix, which is a multi dispatch.  The basic problem
is that .i is ambiguous, and by the current standard grammar is
not resolved by LTM because it's a tie.  We could maybe fix that by
changing it so the meth part of .meth isn't counted as part of the
same token, but right now it is.  Or we could bias .meth forms toward
single dispatch (which might work the same, depending on whether there's
an equivalent method definition, which often there is, especially if
the multi is defined as just an exported method).

 Final question: I think these are all equivalent. Are they?

 1,2,3\foo
 (1,2,3)foo
 (1,2,3).foo
 postfix:foo(1,2,3)

At the moment, the .foo form is officially ambiguous, so might end up
going through single dispatch instead of multi dispatch.  To the casual
reader it looks like it should be single dispatch.  That's what
is bugging me.  Well, one of the things...

The current tie-breaker on longest token matching is to use rule
ordering, but that's not terribly robust.

Larry


Re: Musings on operator overloading

2008-03-27 Thread Larry Wall
On Thu, Mar 27, 2008 at 01:01:27PM +0100, TSa wrote:
 HaloO,

 Larry Wall wrote:
 I deem that to be an unlikely failure mode, however.  So maybe .++
 is just gone now, and you have to write \++ instead.  Any objections?

 Please keep .++ as outlined below. Does the degenerate unspace not
 collide with prefix:\? That is does foo\bar() not mean to capture
 the result from bar() and call foo with it unflattened?

No, listops require a space after if there are any arguments.

 I'm not sure that's a great loss.  It does suggest an alternate
 approach, though, which is to keep the .() forms with forced method
 precedence, and only require \x form for alpha postfixes that want
 to keep their own precedence.  Not sure if I like that entirely,
 but it could fall out naturally from the definition of unspace in
 the current scheme of things, so maybe it's a non-issue.

 As it stands the .() forms are a great way to stack ops after
 a term. Together with knowing about the ops on the symbolic unary
 level you can easily read expressions from the terms outwards.
 Good practice would then be to join these extended terms by an
 obvious set of infix ops---usually one. The only twists to learn in
 this scheme would be ++, -- and **.

I don't follow that.  Example?

 Another good use of the dot forms is to get a single character
 form to tighten precedence: $x**3! != $x**3.! == $x**(3!). This
 is kind of reverse visually, though.

Unless you count precedence forcing as more work in some sense.  :)

 So one might be tempted to
 make ! tighter than ** and get the looser meaning with $x**2\!
 which wouldn't be a degenerate unspace but a special form to
 unbind a tight op as in $x**$y\++ == ($x**$y)++ disregarding the
 fact that $x**$y is no lvalue.

That seems unnecessarily convoluted for a rarely used item.

 BTW, are there still the * and ** prefix ops for list flattening?
 Or are these superseded by prefix |?

The * and ** prefixes are gone.  We have * and ** as bare terms
now, which precludes their being used as a prefix.  Lists may be
dereferenced into capture context with |, or into list context with
@ or @@.

 and maybe even

 circumfix:| | ::= prefix:abs;
 |$x|

 except for the fact that that would collide with prefix:|...

 So no whitespace dwimmery here? I.e. one would need |$x | to
 force the second | into infix? But eventually the parser has
 to give up when the same symbol is overloaded as prefix, postfix,
 infix and symmetric circumfix anyway.

We don't do that kind of lookahead, nor should we force the reader to
do it.  Circumfixes are recognized only by their initial token, and
therefore live in the same slot as prefixes.  The final token is used
only to validate the termination of the inner expression.  Any other
approach is likely to confuse both the compiler and the user.

Note that the human brain is not well wired to do lookahead in
linguistic processing, since you'd have to know what was not yet
uttered by the speaker.  N-token lookahead schemes are good for
academic papers but not so good for users.  You can cheat a bit
visually, but it's not terribly efficient to have to glance ahead in
any case.

Larry


Re: Musings on operator overloading

2008-03-27 Thread Larry Wall
On Thu, Mar 27, 2008 at 01:08:43PM +0100, TSa wrote:
 HaloO,

 TSa wrote:
 Another good use of the dot forms is to get a single character
 form to tighten precedence: $x**3! != $x**3.! == $x**(3!).

 BTW, is the dot form only available for postfix or for infix
 as well? I.e. 3 * 2 == 3.*(2)?

Only postfix.  (And we already use .* for something else.)  You can
probably get away with 3.infix:*(2) though.

However, note also that operators are intended to be dispatch
using multiple dispatch, not single.  Multiple dispatch allows the
language to defined the operator without getting the object involved.
Single dispatch has to rely on the semantics of the object itself to
determine the meaning of a method.  This becomes important when we
have objects from outside of Perl.  $a + $b is always addition under
multiple dispatch, but $a.infix:+($b) might do concatenation if $a
is a foreign object from a language that (mis)treats + that way.

Larry


Re: Musings on operator overloading

2008-03-27 Thread Larry Wall
On Thu, Mar 27, 2008 at 09:46:29AM -0400, Mark J. Reed wrote:
: Is it just me, or is all this talk about precedence and functions vs
: operators vs methods creating a niggling sensation in anyone else's
: head?  It feels like we're in the vicinity of another one of them Big
: Simplifying Idea things.  Unfortunately, I don't have the actual Big
: Idea, so it could just be a false alarm.

We're in the vicinity of a lot of big ideas here, but most of them are
already thunk of and documented in one of the synopses.  I think any
additional Big Simplifying Ideas at this point would only simplify
things for us, not for the user (which is the usual failure mode of
Big Simplifying Ideas).

: On the one hand, I'm worried that Perl6 is going to turn into the
: computer equivalent of Quenya, which was never completed because its
: creator couldn't stop tinkering.  (No offense to Larry intended..)  On
: the other, given how much design thought has gone into it thus far,
: much of it radical, it would be terrible to miss an opportunity to do
: something great in the rush to git 'er done.

Um, you're missing something basic here; most of the radical design we
have so far is there *precisely* because it will allow us to publish
snapshots of the language without ever finishing the language.  :)

If you can't fix it, feature it...

Larry


Re: Musings on operator overloading

2008-03-27 Thread Thom Boyer

Larry Wall wrote:

The .++ form is still not a method (single) dispatch, just an alternate
form of the postfix, which is a multi dispatch.  


But the postfix is a unary operator, right? So that'd be multi dispatch 
on one argument.


How does single dispatch differ from multi dispatch on a single argument?
=thom


Re: Musings on operator overloading

2008-03-27 Thread Larry Wall
On Thu, Mar 27, 2008 at 09:02:37AM -0600, Thom Boyer wrote:
 Larry Wall wrote:
 The .++ form is still not a method (single) dispatch, just an alternate
 form of the postfix, which is a multi dispatch.  

 But the postfix is a unary operator, right? So that'd be multi dispatch on 
 one argument.

Correct.

 How does single dispatch differ from multi dispatch on a single argument?

The question is, who's to be master, that's all.  :)

Single dispatch asks the object's MOP (meta-object protocol) to
dispatch through its .HOW interface, so it depends on which metaobject
system the object was born under.

Multiple dispatch, in contrast, pays attention only to the type
information that comes from the .WHAT interface, and doesn't ask
the MOP to do the dispatch.  It is external to any MOP, except
insofar as the MOP gets involved to help define how .WHAT returns
type information.  But types are considered largely declarative,
not procedural.

(This view of single dispatch is slightly oversimplified, insofar
as the MOP typically sets up an efficient responder interface that
handles the actual dispatch without having to redecide every time.)

Practically speaking, the main difference is foo $x looks for
a function with one argument, while $x.foo looks for a method
with no arguments.

multi sub foo ($x) { say I am a function }
vs.
method foo () { say I am a method }

The candidate list for multis is constructed from all longnames visible
in the current lexical scope, and there is no inheritance involved,
only importation of function names (which, for so-called built-in
functions, is done by the Prelude from the various modules those
functions are defined in).

The candidate list for methods is determined by the MOP, but generally
follows class hierarchy for class-based OO.

A routine can be visible via both routes, but only by some form of
aliasing.  The close method/function is defined something like:

class IO;
...
method close () is export {...}

and when the Prelude does use IO it imports the close method not
as method, but as a function, as if you'd said:

multi close (IO $self) {...}

or some such.

And since mutlis are lexically scoped, and operators are just macros
that translate to function calls, and longnames from different scopes
are interleaved, it means we have lexically-scoped overloading if
you want it.

The other ramification is that we get to define our operators
independently of what the object might think the operator means,
even if it comes from another language.  These may mean two entirely
different things if $a comes from, say, Python or Java or Perl 5:

$a + $b # always addition in Perl 6
$a.'+'($b)  # depends on language of $a

More subtly, the same distinction happens with unaries:

+$a # always numification in Perl 6
$a.prefix+# depends on language of $a

Larry


Re: Musings on operator overloading

2008-03-26 Thread Doug McNutt
At 21:40 +0100 3/25/08, TSa wrote:
Doug McNutt wrote:
Don't allow it ( = - f($x);  )to become

= f(-$x);   ## wrong!

Unless of course f does Linear, then you can factor out or in the
multiplication with -1 at will. So linearity of operators and
functions is a very interesting property for optimizers.

Well. . . I was going to let it pass but I had trouble sleeping this morning 
because of it.

f($x) = constant + $x

would certainly be considered a linear function with constant derivative but 
for that definition -f($x) is not the same as f(-$x). I think the appropriate 
term is antisymmetric to indicate -f(x) = f(-x). Examples would be sin(x), 
pow(x,3), 1/x, x**3.

What worried me in the night is a comment in the Camel book that says the ** 
operator has a higher precedence than the unary minus with the clear 
implication, unfortunately true, that other languages declare the opposite.

If that structure will persist into perl 6 there is a real danger that new 
postfix operators that are being talked about, multiplicative or additive 
inversion for example, may well need to be declared either symmetric or 
antisymmetric to keep an ambitious parser or optimizer under control.

What is really needed is a more careful detection of the unary minus. In 
chalkboard algebra there is no such thing as a unary minus in an equation. A 
leading minus, one that follows an = sign or a left parenthesis, is interpreted 
as an implied subtraction from zero or perhaps an implied multiplication by 
negative unity. The unary minus only shows up in things like a list of numbers, 
the components of a vector (-1,2,-3) or numeric values arriving over a teletype 
link..

I think, but can't prove, that the discrepancy began with compiler compilers - 
yacc - where GUI programmers - Excel - saw an easy way to put formulas on a 
video tube. All they had to do was provide operator definitions and precedence 
rules.

One possibility is to decide that unary minus does not exist in a replacement 
expression. Perform a clear and subtract assembly instruction. That would not 
matter for a common programming technique that defines a constant $negpi =  
-3.1416; instead of a real unary minus using *NEGPI = \-3.1416; or use constant 
NEGPI = -3.1416;.

It's needs some updating but http://macnauchtan.com/pub/precedence.html is 
still on the net.

The statements:

= - f($x) - g($x);
= - g($x) - f($x);

should always return the same result regardless of whether f or g is 
implemented as a function, a method, or a postfix operator; and that should be 
true even if the - operator is overloaded.

-- 
-- If you are presented a number as a percentage, and you do not clearly 
understand the numerator and the denominator involved, you are surely being 
lied to. --


Re: Musings on operator overloading

2008-03-26 Thread TSa

HaloO,

Doug McNutt wrote:

Well. . . I was going to let it pass but I had trouble sleeping this

 morning because of it.

Sorry.



f($x) = constant + $x



would certainly be considered a linear function


No, I was talking about the other linear ;)



with constant
derivative but for that definition -f($x) is not the same as f(-$x).
I think the appropriate term is antisymmetric to indicate -f(x) =
f(-x). Examples would be sin(x), pow(x,3), 1/x, x**3.


That's a weaker property known also as even and odd functions
because their power series contain only even or odd powers.
Linearity means $a*f($x) == f($a*$x)  f($x+$y) == f($x)+f($y).



The statements:

= - f($x) - g($x);
= - g($x) - f($x);

should always return the same result regardless of whether f or g is
implemented as a function, a method, or a postfix operator; and that
should be true even if the - operator is overloaded.


I agree. But let me explain how I arrive at that. To me there is no
binary minus! -f(x) - g(x) = -f(x) + -g(x) = -g(x) + -f(x). I.e. plus
is commutative. In other words overloading unary minus gives you the
binary version for free. Or even better is to deeply overload unary
plus to do the Ring role. Additionally implementing unary / or 1/ or so
would yield the Field role.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-26 Thread Mark J. Reed
On Wed, Mar 26, 2008 at 11:24 AM, TSa [EMAIL PROTECTED] wrote:
  I agree. But let me explain how I arrive at that. To me there is no
  binary minus!

I must agree with that one.  In chalkboard mathematics, - is a unary
negation operator, and its use as a binary op in x - y is just
shorthand for x + -y.

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-26 Thread Larry Wall
On Wed, Mar 26, 2008 at 12:04:43PM -0400, Mark J. Reed wrote:
: On Wed, Mar 26, 2008 at 11:24 AM, TSa [EMAIL PROTECTED] wrote:
:   I agree. But let me explain how I arrive at that. To me there is no
:   binary minus!
: 
: I must agree with that one.  In chalkboard mathematics, - is a unary
: negation operator, and its use as a binary op in x - y is just
: shorthand for x + -y.

That interpretation doesn't help me solve my generic parsing problems,
which is about the relationship of op1 to op2 and op3 in

op1 a() op2 b() op3 c()

and presumably the same thing for postfixes in the other order.

So here's another question in the same vein.  How would mathematicians
read these (assuming Perl has a factorial postfix operator):

1 + a(x)**2!
1 + a(x)²!

Larry


Re: Musings on operator overloading

2008-03-26 Thread TSa

HaloO,

Larry Wall wrote:

That interpretation doesn't help me solve my generic parsing problems,
which is about the relationship of op1 to op2 and op3 in

op1 a() op2 b() op3 c()

and presumably the same thing for postfixes in the other order.


My idea is to have a term re-writing stage before the precedence
parser does its job. I assume that chalkboard mathematics means
term re-writing. Which sort of means that infix:-($x,$y) is a macro
that expands to infix:+($x,prefix:-($y)).



So here's another question in the same vein.  How would mathematicians
read these (assuming Perl has a factorial postfix operator):


Without implying to actually being a mathematician I'll
give my thoughts on the subject.



1 + a(x)**2!


That is a poor version the the version below and obviously
depends on the precedence that ! has relative to **.


1 + a(x)²!


This means to me to square the return value of a(x), then
take the factorial and then add 1. Getting a(x) raised to
2! would require the ! to be superscripted as well. Its ASCII
version would explicitly require a(x)**(2!). So a(x)**2! is
either ambiguous or requires lower precedence for !. My actual
reading of the ASCII version picks a(x) as the operation with
highest precedence and going from there outwards encountering
+ to the left and ** to the right with ** being of higher
precedence. Then I'm left with + to the left and ! to the right
with precedence of ! higher than +.

I hope that helps, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-26 Thread Mark J. Reed
On Wed, Mar 26, 2008 at 1:06 PM, TSa [EMAIL PROTECTED] wrote:
   1 + a(x)²!

Seems like a mathematician would be inclined to write that one as this instead:

1 + a²(x)!

But I'm not suggesting that you try to make (a**2)(x) work for
(a(x))**2 in Perl. :)

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-26 Thread Larry Wall
On Wed, Mar 26, 2008 at 06:06:29PM +0100, TSa wrote:
 HaloO,

 Larry Wall wrote:
 That interpretation doesn't help me solve my generic parsing problems,
 which is about the relationship of op1 to op2 and op3 in

 op1 a() op2 b() op3 c()

 and presumably the same thing for postfixes in the other order.

 My idea is to have a term re-writing stage before the precedence
 parser does its job. I assume that chalkboard mathematics means
 term re-writing. Which sort of means that infix:-($x,$y) is a macro
 that expands to infix:+($x,prefix:-($y)).

Alas, you can't figure out which terms to rewrite until you've parsed them.

 So here's another question in the same vein.  How would mathematicians
 read these (assuming Perl has a factorial postfix operator):

 Without implying to actually being a mathematician I'll
 give my thoughts on the subject.


 1 + a(x)**2!

 That is a poor version the the version below and obviously
 depends on the precedence that ! has relative to **.

 1 + a(x)²!

 This means to me to square the return value of a(x), then
 take the factorial and then add 1. Getting a(x) raised to
 2! would require the ! to be superscripted as well. Its ASCII
 version would explicitly require a(x)**(2!). So a(x)**2! is
 either ambiguous or requires lower precedence for !. My actual
 reading of the ASCII version picks a(x) as the operation with
 highest precedence and going from there outwards encountering
 + to the left and ** to the right with ** being of higher
 precedence. Then I'm left with + to the left and ! to the right
 with precedence of ! higher than +.

That's what I thought.  Now note that ! can't easily be rewritten
as a simple binary operator (unless you do something recursive, and
then it's not simple).

Now, I think I know how to make the parser use precedence on either
a prefix or a postfix to get the desired effect (but perhaps not going
both directions simulatenously).  But that leads me to a slightly
different parsing question, which comes from the asymmetry of postfix
operators.  If we make postfix:! do the precedence trick above with
respect to infix:** in order to emulate the superscript notation,
then the next question is, are these equivalent:

1 + a(x)**2!
1 + a(x)**2.!

likewise, should these be parsed the same?

$a**2i
$a**2.i

and if so, how to we rationalize a class of postfix operators that
*look* like ordinary method calls but don't parse the same.  In the
limit, suppose some defines a postfix say looser than comma:

(1,2,3)say
1,2,3say
1,2,3.say

Would those all do the same thing?  Or should we maybe split postfix
dot notation into two different characters depending on whether
we mean normal method call or a postfix operator that needs to be
syntactically distinguished because we can't write $a.i as $ai?

I suppose, if we allow an unspace without any space as a degenerate
case, we could write $a\i instead, and it would be equivalent to ($a)i.
And it resolves the hypothetical postfix:say above:

1,2,3.say   # always a method, means 1, 2, (3.say)
1,2,3\ say  # the normal unspace, means (1, 2, 3)say
1,2,3\say   # degenerate unspace, means (1, 2, 3)say

This may also simplify the parsing rules inside double quoted
strings if we don't have to figure out whether to include postfix
operators like .++ in the interpolation.  It does risk a visual
clash if someone defines postfix:t:

$x\t# means ($x)t
$x\t  # means $x ~ \t

I deem that to be an unlikely failure mode, however.  So maybe .++
is just gone now, and you have to write \++ instead.  Any objections?

I suppose that means that .(), .[], and .{} would also be gone, in favor
of \(), \[], and \{}.  We'd given a different meaning to foo\() at one
point, but I think that went away.  And since these postfixes aren't
alphanumeric, you don't need the degenerate unspace to separate them
from a variable name.  So you generally wouldn't see them unless you
wanted $a\ () with extra whitespace.

Another possible downside: getting rid of the .postop form also
has the side effect of getting rid of these bare forms

.++ # meaning ($_)++
.() # meaning ($_)()
.[] # meaning ($_)[]
.{} # meaning ($_.{}
. # meaning ($_)
.i  # meaning ($_)i   :)

I'm not sure that's a great loss.  It does suggest an alternate
approach, though, which is to keep the .() forms with forced method
precedence, and only require \x form for alpha postfixes that want
to keep their own precedence.  Not sure if I like that entirely,
but it could fall out naturally from the definition of unspace in
the current scheme of things, so maybe it's a non-issue.

And it makes it really easy to define postfixes equivalent to
prefixes:

postfix:- ::= prefix:-;
$x\-

postfix:abs ::= prefix:abs;
$x\abs

and maybe even

circumfix:| | ::= prefix:abs;
|$x|

except for the fact that that 

Re: Musings on operator overloading

2008-03-26 Thread Jon Lang
Larry Wall wrote:
  So here's another question in the same vein.  How would mathematicians
  read these (assuming Perl has a factorial postfix operator):

 1 + a(x)**2!
 1 + a(x)²!

The 1 + ... portion is not in dispute: in both cases, everything to
the right of the addition sign gets evaluated before the addition
does.  As such, I'll now concentrate on the right term.

As TsA pointed out, mathematicians wouldn't write the former case at
all; they'd use a superscript, and you'd be able to distinguish
between a(x) to the two-factorial power and (a(x) squared)
factorial based on whether or not the factorial is superscripted.  So
the latter would be (a(x) squared) factorial.

OTOH, you didn't ask how mathematicians would write this; you asked
how they'd read it.  As an amateur mathematician (my formal education
includes linear algebra and basic differential equations), I read the
former as a(x) to the two-factorial power: all unary operators, be
they prefix or postfix, should be evaluated before any binary operator
is.

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-26 Thread Larry Wall
On Wed, Mar 26, 2008 at 11:00:09AM -0700, Jon Lang wrote:
: OTOH, you didn't ask how mathematicians would write this; you asked
: how they'd read it.  As an amateur mathematician (my formal education
: includes linear algebra and basic differential equations), I read the
: former as a(x) to the two-factorial power: all unary operators, be
: they prefix or postfix, should be evaluated before any binary operator
: is.

Could we please get all the mathematicians in the world together to
vote on this?  :)

I also wouldn't mind a straw vote from all the future mathematicians...

Larry


Re: Musings on operator overloading

2008-03-26 Thread Jon Lang
Larry Wall wrote:
  Now, I think I know how to make the parser use precedence on either
  a prefix or a postfix to get the desired effect (but perhaps not going
  both directions simulatenously).  But that leads me to a slightly
  different parsing question, which comes from the asymmetry of postfix
  operators.  If we make postfix:! do the precedence trick above with
  respect to infix:** in order to emulate the superscript notation,
  then the next question is, are these equivalent:

 1 + a(x)**2!
 1 + a(x)**2.!

To me, both of these should raise a(x) to the 2-factorial power; so
yes, they should be equivalent.

  likewise, should these be parsed the same?

 $a**2i
 $a**2.i

In terms of form, or function?  Aesthetically, my gut reaction is to
see these parse the same way, as raise $a to the power of 2i; in
practice, though, 2i on a chalkboard means 2 times i, where i is
unitary.  Hmm...

Again, though, this isn't a particularly fair example, as mathematical
notation generally uses superscripting rather than ** to denote
exponents, allowing the presence or absence of superscripting on the
i to determine when it gets evaluated.  That is, the mathematical
notation for exponents includes an implicit grouping mechanism.

  and if so, how to we rationalize a class of postfix operators that
  *look* like ordinary method calls but don't parse the same.  In the
  limit, suppose some defines a postfix say looser than comma:

 (1,2,3)say
 1,2,3say
 1,2,3.say

  Would those all do the same thing?

Gut reaction: the first applies say to the list 1, 2, 3; the
second and third apply say to 3.

  Or should we maybe split postfix
  dot notation into two different characters depending on whether
  we mean normal method call or a postfix operator that needs to be
  syntactically distinguished because we can't write $a.i as $ai?

  I suppose, if we allow an unspace without any space as a degenerate
  case, we could write $a\i instead, and it would be equivalent to ($a)i.
  And it resolves the hypothetical postfix:say above:

 1,2,3.say   # always a method, means 1, 2, (3.say)
 1,2,3\ say  # the normal unspace, means (1, 2, 3)say
 1,2,3\say   # degenerate unspace, means (1, 2, 3)say

  This may also simplify the parsing rules inside double quoted
  strings if we don't have to figure out whether to include postfix
  operators like .++ in the interpolation.

I'm in favor of the minimalist unspace concept, independent of the
current concerns.  In effect, it lets you insert the equivalent of
whitespace anywhere you want (except in the middle of tokens), even if
whitespace would normally be forbidden; and it does so in a way that
takes up as little space as possible.

  It does risk a visual
  clash if someone defines postfix:t:

 $x\t# means ($x)t
 $x\t  # means $x ~ \t

  I deem that to be an unlikely failure mode, however.

:nod: Alphanumeric postfixes ought to be rare compared to symbolic postfixes.

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-26 Thread TSa

HaloO,

Mark J. Reed wrote:

On Wed, Mar 26, 2008 at 1:06 PM, TSa [EMAIL PROTECTED] wrote:

  1 + a(x)²!


Seems like a mathematician would be inclined to write that one as this instead:

1 + a²(x)!


That one is ambiguous because it could mean a(a(x)) or a(x)*a(x)
with the latter case being used for the trigonometric functions
as exceptions to the former rule.



But I'm not suggesting that you try to make (a**2)(x) work for
(a(x))**2 in Perl. :)


That might actually be written a**2($x) which is visually unpleasing
because ** separates a and 2 while 2 and ($x) don't even have
something in between.

I'm tempted for quite a while now to start a thread called operator
arithmetic discussing first class code value arithmetic. But I don't
know if that is too far off this list.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-26 Thread TSa

HaloO,

Larry Wall wrote:

That's what I thought.  Now note that ! can't easily be rewritten
as a simple binary operator (unless you do something recursive, and
then it's not simple).


Would $x! == [*]1..$x constitute simple parserwise? Admittedly
it's not a single but two ops and one of them a meta.



Now, I think I know how to make the parser use precedence on either
a prefix or a postfix to get the desired effect (but perhaps not going
both directions simulatenously).




 But that leads me to a slightly
different parsing question, which comes from the asymmetry of postfix
operators.


How are postfix operators asymmetric?


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-26 Thread Larry Wall
On Wed, Mar 26, 2008 at 11:00:09AM -0700, Jon Lang wrote:
: all unary operators, be they prefix or postfix, should be evaluated 
: before any binary operator is.

And leaving the pool of voting mathematicians out of it for the moment,
how would you parse these:

sleep $then - $now
not $a eq $b
say $a ~ $b
abs $x**3

These all work only because unaries can be looser than binaries.
And Perl 5 programmers will all expect them to work, in addition to
-$a**2 returning a negative value.  And we have to deal with unary
precedence anyway, or !%seen{$key}++ doesn't work right...

Larry


Re: Musings on operator overloading

2008-03-26 Thread Jon Lang
TSa wrote:
  Jon Lang wrote:
   all unary operators, be
   they prefix or postfix, should be evaluated before any binary operator
   is.

  Note that I see ** more as a parametric postscript then a real binary.
  That is $x**$y sort of means $x(**$y).

That's where we differ, then.  I'm having trouble seeing the benefit
of that perspective, and I can clearly see a drawback to it - namely,
you have to think of infix:** as being a different kind of thing
than infix:.«+ - * /, despite having equivalent forms.

  Note also that for certain
  operations only integer values for $y make sense. E.g. there's no
  square root of a function.

...as opposed to a square root of a function's range value.  That is,
you're talking in terms of linear algebra here, where D²(x) means
D(D(x)), as opposed to basic algebra, where f²(x) means (f(x))².
 This is similar to your earlier the other Linear comment.

This is a case where the meaning of an operator will depend on the
system that you're dealing with.  Math is full of these, especially
when it comes to superscripts and subscripts.  I'd recommend sticking
to the basic algebraic terminology for the most part (e.g., f²(x) :=
(f(x))²), and apply all's fair if you predeclare if you intend to
use a more esoteric paradigm.  So if you want:

  D²(x) + 2D(x) + x

to mean:

  (D(D(x)) + 2 * D(x) + x

You should say:

  use linearAlgebra;
  D²(x) + 2D(x) + x

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-26 Thread TSa

HaloO,

Larry Wall wrote:

likewise, should these be parsed the same?

$a**2i
$a**2.i

and if so, how to we rationalize a class of postfix operators that
*look* like ordinary method calls but don't parse the same. 


This is a conceptual problem that .blahh is visually nailed down on
the top precedence by the dot whereas it actually comes in as additional
information about i. There's the same problem with

   foo 1 + 3;  #  (foo 1) + 3  or  foo (1 + 3)

which can only be decided by information about foo.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-26 Thread Larry Wall
On Wed, Mar 26, 2008 at 07:43:16PM +0100, TSa wrote:
 HaloO,

 Larry Wall wrote:
 That's what I thought.  Now note that ! can't easily be rewritten
 as a simple binary operator (unless you do something recursive, and
 then it's not simple).

 Would $x! == [*]1..$x constitute simple parserwise? Admittedly
 it's not a single but two ops and one of them a meta.

I meant there's no $x!0 corresponding to 0-$x in the prefix:- rewrite.

 Now, I think I know how to make the parser use precedence on either
 a prefix or a postfix to get the desired effect (but perhaps not going
 both directions simulatenously).


  But that leads me to a slightly
 different parsing question, which comes from the asymmetry of postfix
 operators.

 How are postfix operators asymmetric?

Prefix ops can be followed by whitespace, while postfix may not
be preceded by whitespace.  Also, the presence of sigils makes
it less likely to need space on the front unless you use an
alphabetic prefix operator on something starting alphanumeric:

abs 1-$x

The asymmetry is essentially that we can't just write

1-$x abs

without parsing abs as an infix rather than a postfix.  (And please
don't suggest parsing infixes with optional nullterms on the right;
we tried that once, and it screws up the term/infix expectations
rather badly.)

Larry


Re: Musings on operator overloading

2008-03-26 Thread Jon Lang
On Wed, Mar 26, 2008 at 12:03 PM, Larry Wall [EMAIL PROTECTED] wrote:
 On Wed, Mar 26, 2008 at 11:00:09AM -0700, Jon Lang wrote:

 : all unary operators, be they prefix or postfix, should be evaluated
  : before any binary operator is.

  And leaving the pool of voting mathematicians out of it for the moment,
  how would you parse these:

 sleep $then - $now
 not $a eq $b
 say $a ~ $b
 abs $x**3

Those don't strike me as being unary operators; they strike me as
being function calls that have left out the parentheses.  Probably
because they're alphanumeric rather than symbolic in form.

  These all work only because unaries can be looser than binaries.
  And Perl 5 programmers will all expect them to work, in addition to
  -$a**2 returning a negative value.

True enough.  Perhaps I should have said as a rule of thumb...

  And we have to deal with unary
  precedence anyway, or !%seen{$key}++ doesn't work right...

  Larry




-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-26 Thread Mark J. Reed
On Wed, Mar 26, 2008 at 3:18 PM, Jon Lang [EMAIL PROTECTED] wrote:
  Those don't strike me as being unary operators; they strike me as
  being function calls that have left out the parentheses.

At least through Perl5, 'tain't no difference between those two in Perl land.

As for binary !, you could say posit that the second operand is the
degree of multifactorialhood, defaulting to 1; e.g. x!2 for what
mathematicians would write as x‼, which definitely does not mean
(x!)!.

Dadgum mathematicians, always messing things up. Can't y'all go back
to APL and leave the rest of us alone? :)

Oh, and I've always mentally filed -x as shorthand for (-1*x); of
course, that's an infinitely recursive definition unless -1 is its own
token rather than '-' applied to '1'.  Maybe I should have adopted
dc(1)ese and spelled it _1.

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-26 Thread Jon Lang
Mark J. Reed wrote:
 Jon Lang wrote:
Those don't strike me as being unary operators; they strike me as
being function calls that have left out the parentheses.

  At least through Perl5, 'tain't no difference between those two in Perl land.

True enough - though the question at hand includes whether or not
there should be.

Perhaps a distinction should be made between prefix and postfix.
After all, postfix already forbids whitespace.  True, the original
reason for doing so was to distinguish between infix and postfix; but
it tends to carry the implication that postfix operators are kind of
like method calls, while prefix operators arekind of like function
calls.

Personally, I'd like to keep that parallel as much as possible.
Unless it can be shown to be unreasonable to do so. :)

  As for binary !, you could say posit that the second operand is the
  degree of multifactorialhood, defaulting to 1; e.g. x!2 for what
  mathematicians would write as x‼, which definitely does not mean
  (x!)!.

Wouldn't that be x ! 2?  Mandatory whitespace (last I checked),
since infix:! had better not replace postfix:!.

  Oh, and I've always mentally filed -x as shorthand for (-1*x); of
  course, that's an infinitely recursive definition unless -1 is its own
  token rather than '-' applied to '1'.

It's also only guaranteed to work if x is numeric; even in math,
that's not certain to be the case. :)

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-26 Thread Thom Boyer

Larry Wall wrote:

On Wed, Mar 26, 2008 at 12:56:08PM -0600, Thom Boyer wrote:

Larry Wall wrote:

... In the
limit, suppose some defines a postfix say looser than comma:

(1,2,3)say
1,2,3say
1,2,3.say


I must be missing something. Wouldn't it be easier to write

  1,2,3 say

since say was defined to bind looser than comma? Then you wouldn't need a 
nospace unspace.


The part of Perl 6 that bothers me most is the whitespace dwimmery that 
required unspace in the first place. I'd hate to see more of it.


Not that I have a better solution than the proposed whitespace dwimmery, 
mind you.


How would you keep infix operators in a separate namespace from postfix
then?  As soon as someone defines infix:++ you're hosed, or we have
to throw out all term/infix distinctions that Perl has always had.  How
would you parse

$x ++ /foo/;

It also completely destroys the current absolute distinction between

say(1 + 2), 3
say (1 + 2), 3

Larry


Yup. You gotta have some way to resolve those problems, and the 
whitespace distinction does the job. And, as I said, I don't have a 
better solution.


But that doesn't obviate my unease with whitespace being so very 
significant to the meaning of a program. Perhaps it comes from exposure 
to Fortran IV at an impressionable age -- a language in which nothing 
changes if you remove ALL whitespace (outside of Hollerith constants, 
that is). It might be fair to liken that exposure to the effects of 
Thalidomide: perhaps my brain's been deformed.


But it's only an unease, and I recognize that it's a bias I acquired by 
programming in so many different languages in which whitespace is 
insignificant. I further recognize that Perl offers a lot of way-cool 
stuff that wouldn't be possible with out whitespace dwimmery.


I *love* list operators. Being able to write, in Perl 5,

  foreach_vertex $polygon, sub {
# executed once for each vertex, with the vertex in $a
print point #, $n++, : $a\n;
  };

instead of

foreach_vertex($polygon, sub {
  # executed once for each vertex, with the vertex in $a
  print point #, $n++, : $a\n;
});

makes a world of difference to readability. And I'd be *tempted* to 
resolve the the ambiguity in


say (1 + 2), 3

by treating that as

say(1+2), 3

and requiring (function-call, not list-operator) syntax like

say((1+2), 3)

if you want the other. But that would have a horrible effect. If I 
started with


say $x*2, 3

and then realized I needed to add one to $x before doubling, I'd be 
surprised by the resulting treatment of


say ($x+1)*2, 3

So you made the right call there, in my opinion. The whitespace makes 
clear the programmer's intent, once you're used to list operators.



As for:

 $x ++ /foo/;

well, for that case, I can't even think of a BAD suggestion to make, so 
whitespace dwimmery is again the best solution I know.



And yet that whitespace-is-insignificant meme keeps tickling my brain. 
And what really cranked it up to poison-ivy level was the unspace. I 
can't even explain why. I don't even *understand* why, myself, so I can 
hardly speak on the subject in a cogent manner.


I suspect it's an emotional, irrational, reaction. I probably just need 
to just scratch the inside of my skull with a wire brush until the itch 
is gone. And quit bothering the list with my idiosyncrasy. After all, 
it's an entirely artificial idea in the first place -- because,

to humans,
whitespace
really
   DOES
 matter;
   it's
 only
those
stupid
 compilers
   that feel
  otherwise.


-

But the main point I was trying to make is just that I didn't see the 
necessity of positing


1,2,3\say

when (if I understand correctly) you could write that as simply as

1,2,3 say


And if someone really wants to apply a Ct postfix operator in a string 
interpolation, then let them say


say blah {$x t} blah

That seems better to me than saying that there's no tab character in

say blah $x\t blah

Backslashes in double-quotish contexts are already complicated enough!
=thom



Re: Musings on operator overloading

2008-03-26 Thread Jon Lang
Thom Boyer wrote:
  But the main point I was trying to make is just that I didn't see the
  necessity of positing

  1,2,3\say

  when (if I understand correctly) you could write that as simply as

  1,2,3 say

Nope.  This is the same situation as the aforementioned '++' example,
in that you'd get into trouble if anyone were to define an infix:say
operator.

  That seems better to me than saying that there's no tab character in

  say blah $x\t blah

Whoever said that?

  Backslashes in double-quotish contexts are already complicated enough!

...and they'd remain precisely as complicated as they are now, because
backslashes in interpolating quotes and in patterns would continue to
behave precisely as they do now.  Backslash-as-unspace would remain
unique to code context, as it is now, changing only in that it gets
followed by \s* instead of \s+.  In particular, if you were to define
a postfix:t operator, you'd embed it in a string as:

say blah {$x\t} blah

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading

2008-03-25 Thread TSa

HaloO,

Larry Wall wrote:

Another minor psychological factor is comes into play is that, besides
being too hard to type, ÷  is visually a symmetrical operator,
while division is inherently an asymmetric operation.  You'll notice
that other asymmetric operators invented by mathematicians tend to
convey that asymmetry visually.


OK, with symmetric equal to commutative. But you don't have this
concern with - which is as asymmetric as /. Also x and xx are
asymmetric without visual indication. These are not even symmetric
in the types of their operants.



:  Second,  a path is much more like a string than a number.
: 
: Right.  Which means there's no room for confusion with division,

: 'cause you can't divide strings!  Ambiguity gone, problem solved, no
: worries.

Er, except for hordes of Perl 5 programmers who think you can...  :)


Yeah! We could actually invent x/ for a inverse operation of x
in the sense that you factor a string. E.g. 'aaa' x/ 3 eq 'a' but
'abc' x/ 3 eq ''. That is a non-repetitive string is kind of primal.
Hmm, or x/ behaves more like % and 'abc' x/ 3 eq 'abc' and 'aaa' x/ 2
eq 'a' and of course 'aaa' x/ 3 eq ''. But that might better be spelled
x%, I think.

Speaking of x actually makes me wonder about two things in its
definition: (1) why is it non-associative and (2) why is it not
on the multiplicative precedence but below addition? It could be
made left associative: 'ab' x 3 x 2 eq 'abababababab' which implies
that 3 x 2 == 6. So we would get a multiplication operator that the 
optimizer wouldn't touch commutatively. Hence it would be a good

candidate for the vector cross product and quaternion multiplication
and such.

Or we could use it for the scalar multiplication of vectors. That would
require it to be commutative, though. Note that this is no problem if we
define infix:x:(::T,::T) to be a type error whilst infix:x:(::T,
Num | Num, ::T) allows 3 x 'a' eq 'a' x 3 eq 'aaa' when ::T === Str.
Actually we could make x commutatively list associative and define that
at most one operant can be of a type different from Num or better a
type that is a Field, e.g. Complex. This automatically gives
(1,2,3) x 3 === 3 x (1,2,3) === (2,6,9). Uhh, and ~~ might check linear
dependence of vectors or so. BTW, how would the signature of x look
like if you want to enforce the presence of at most one argument of
type Field? The problem is you can't have the variadic array at the
front or the middle to get

  multi *listfix:x (   none(Field) ::T $v, Field [EMAIL PROTECTED] |
  Field [EMAIL PROTECTED], none(Field) ::T $v|
  Field [EMAIL PROTECTED], none(Field) ::T $v, Field [EMAIL 
PROTECTED]
  -- T)
  {...}

perhaps

  multi *listfix:x ( [EMAIL PROTECTED] where { one(@scalars) does none(Field) 
or
   all(@scalars) does Field } )
  {...}

but that makes capturing the non-field type impossible.


An additional idea of mine is to also introduce a generic multiplication
operator infix:o as ASCII equivalent of U+2218. An exponentiation in
terms of o would be written oo. That somewhat makes xx oddly overloaded
with list replication where one could expect it to be exponentiation in
terms of x. Then again scalar multiplication has no exponential form.

For geometric algebra one would introduce _| (U+2A3C) and |_ (U+2A3D)
for left and right contraction and /\ for the wedge. And then choose x
for the geometric product if it had multiplicative precedence. Or if we 
follow the scalar multiplication approach outlined above,

infix:*:(::T, T -- T) would become a generic list associative
non-commutative product operator. Note that a proper product is
homogeneous in ::T whereas multiplicative x is generally not.


Sorry if this is off-topic, but this is the outcome if I'm musing about
operator overloading. My driving idea is to abstractly define the
properties of operators that should hold when overloaded. E.g. + for
string concatenation is bad because I would expect $a + $b eqv $b + $a.
From the commutativity point of view it could be argued to overload -
which isn't commutative like ~. But I've never seen - being overloaded
with string concatenation ;)


In the last section of S03 good names for the three groups of operators
are asked for. I would call the group with guaranteed sequence points
just that: sequential operators. They come in two types: left and right
sequential. Basically this replaces the wrong usage of associativity
of an operator. Then associativity could retain its mathematical meaning
and allow the optimizer/parallizer to group at will. E.g + would be
associative but - left-sequential or forcing associative addition with
prior unary -. Same thing with * and / if we have e.g. prefix:1/
applied before associating the factors.

Commutativity would be an even better property of an operator because it
doesn't have to assemble values returned from multiple threads in the
order prescribed

Re: Musings on operator overloading

2008-03-25 Thread TSa

HaloO,

Doug McNutt wrote:

Don't allow it to become

= f(-$x);   ## wrong!


Unless of course f does Linear, then you can factor out or in the
multiplication with -1 at will. So linearity of operators and
functions is a very interesting property for optimizers.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-21 Thread Aristotle Pagaltzis
* TSa [EMAIL PROTECTED] [2008-03-19 16:00]:
 Aristotle Pagaltzis wrote:
 Something like

 path { $app_base_dir / $conf_dir / $foo_cfg . $cfg_ext }

 where the operators in that scope are overloaded irrespective of
 the types of the variables (be they plain scalar strings,
 instances of a certain class, or whatever).

 Assuming there are Path, Extension, Directory and File types,
 the better approach would be in my eyes to overload string
 concatenation.

That presumes you will never want non-path concatenation
semantics on filesystem path values. Then how do I write
`die Couldn't open $abspath: $!\n`?

 When you leave the broader domain of mathematical and “para-”
 mathematical abstractions behind and start to define things
 like division on arbitrary object types that model aspects of
 domains which have nothing even resembling such concepts,
 you’re rapidly moving into the territory of obfuscation.

 Indeed mathematics is all about distilling abstract properties
 from problem domains and then proving abstract theorems. That
 means when applying mathematics you only have to meet the
 preconditions and get all consequences for free. But
 overloading a symbol that means product with something that
 does not adhere to the algebraic properties of products is a
 bad choice.

Which was my point.

 Note that even with mathematical abstractions, there are cases
 where scope-bound overloading is a win over type-bound
 overloading. Consider a hypothetical Math::Symbolic that lets
 you do something like this:

 my $x = Math::Symbolic-new();
 print +( $x**2 + 4 * $x + 3 )-derivative( $x );

 I hope it’s obvious how such a thing would me implemented.

 No, I find that far from obvious.

Time to read up on operator overloading then. :-)  When I say
“hypothetical” I mean merely in the sense that “it doesn’t exist
on the CPAN in this form” – I did not imply that this would
require anything outside the currently available semantics.
Kragen Sitaker wrote that precise library in Python 2.x; it
could easily be recreated in Perl 5.

 Your derivative method should have type :(Code -- Code)

No. There are no code blocks or parse trees anywhere in sight,
only an expression representation built up the Math::Symbolic
object internally as its methods for the various overloaded
operations were called.

 Now, if you used type-bound overloading, then the following
 two expressions cannot yield the same result:

 ( 2 / 3 ) * $x
 2 * $x / 3

 But if overloading was scope-bound, they would!

 First of all I would allow the optimizer to convert the latter
 into the former unconditionally. […] Hmm, thinking twice, the
 above optimization is admissible only if multiplication is
 commutative irrespective of the type of $x.

Exactly.

 I think your statement makes only sense when the polymorphism
 on the type of $x is dropped in scope-bound overloading.

That’s what I was talking about all along: a way to overload
operators monomorphically for the duration of a scope. Operators
in Perl are monomorphic, as a rule of thumb. String concatenation
requires that you use the string concatenation operator, not the
addition operator overloaded by the string type to mean
concatenation. So I’d like directory-scope path qualification to
have its own operator; what the `path {}` syntax does is override
the operator bound to the slash and dot symbols for the duration
of the block, regardless of the type of operands they operate on.

 In other words $x is then always converted into the suitable
 form.

Yes. That’s exactly how Perl already works. You say `$x + $y`, it
converts $x and $y into numbers somehow. You say `$foo eq $bar`,
it stringifies $foo and $bar in whichever way it can. You say
`if ( $quux )` and it boolifies $quux in whatever way it knows to
do so.

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.org/


Re: Musings on operator overloading

2008-03-21 Thread Aristotle Pagaltzis
* Mark J. Reed [EMAIL PROTECTED] [2008-03-19 20:45]:
 Maybe it's just 'cause I cut my teeth on BASIC, but + for
 string concatenation has always felt pretty natural. Obviously
 it won't work in Perl where you are using the operator to
 determine how to treat the operands. At first blush I find it
 more readily readable than  or ||, or even ..

Personally, after getting thoroughly used to Perl, I always have
a vague feeling of unease in languages where I need to use + to
concatenate. It makes the meaning of the statement dependent on
the types of any variables, which is information that a reader
won’t necessarily find in close vicinity of the statement. And
that’s exactly what led me to the idea I proposed in the initial
mail in this thread – changing the meaning of an operator from
one monomorphic operation to another within a lexical scope.

 Hopefully, the new meaning is somewhat related to the original
 - a sort of operator metonymy - but if the context is
 sufficiently different, that's not a requirement. Again,
 nobody's going to think you're dividing pathnames.

Strongly disagree. If context was sufficient to help the reader,
how did operator overloading get such a bad rep in C++? That’s
exactly what my proposal was all about: if you’re completely
changing the meaning of an operator, the reader should have
nearby indication of what is really going on.

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.org/


Re: Musings on operator overloading

2008-03-21 Thread Mark J. Reed
On Fri, Mar 21, 2008 at 4:25 PM, Aristotle Pagaltzis [EMAIL PROTECTED] wrote:
 It makes the meaning of the statement dependent on
  the types of any variables, which is information that a reader
  won't necessarily find in close vicinity of the statement.

[...]

  if you're completely changing the meaning of an operator, the reader should 
 have
  nearby indication of what is really going on.

Ah, so you want the types of typed vars to be apparent where those
vars are used.  Well, there's an easy solution there: Hungarian
notation!

(ducks under barrage of rotten fruit)

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-21 Thread Aristotle Pagaltzis
* Mark J. Reed [EMAIL PROTECTED] [2008-03-21 21:35]:
 On Fri, Mar 21, 2008 at 4:25 PM, Aristotle Pagaltzis [EMAIL PROTECTED] 
 wrote:
  It makes the meaning of the statement dependent on the types
  of any variables, which is information that a reader won't
  necessarily find in close vicinity of the statement.
 
 [...]
 
   if you're completely changing the meaning of an operator,
   the reader should have nearby indication of what is really
   going on.
 
 Ah, so you want the types of typed vars to be apparent where
 those vars are used.  Well, there's an easy solution there:
 Hungarian notation!
 
 (ducks under barrage of rotten fruit)

The other easy solution is monomorphism, wherein the types of the
variables are irrelevant. It so happens that this is what Perl
does and what my proposal was about.

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.org/


Re: Musings on operator overloading

2008-03-20 Thread David Green

On 2008-Mar-19, at 1:40 pm, Mark J. Reed wrote:

On Wed, Mar 19, 2008 at 1:01 PM, Larry Wall [EMAIL PROTECTED] wrote:

The use of + in Python or  in C++ is, I think, primarily the
violation of a *linguistic* principle, not a mathematical principle.


Maybe it's just 'cause I cut my teeth on BASIC, but + for string  
concatenation has always felt pretty natural.


That's because it is natural.  Kids don't have to be very old to get  
the joke in 1+1=11.  People just naturally think of plus or a plus- 
sign as a synonym for and.  In a non-technical context, I bet we all  
scribble down '+'s on notes and grocery lists, etc. to stand for any  
of Perl's: + ~ , ;  .  It's not that there isn't ambiguity, but  
it's an ambiguity that we're used to dealing with in everyday life, so  
it maps easily onto a programming language.


Not that I'm saying separate operators are a bad thing.  When  
programming, we do often have to mix numbers and strings in all sorts  
of ways, so Perl's + and ~ are often a better match for the problem- 
space.  It may require marginally more effort to get used to than  
BASIC's dual-purpose +, but I'm not sure even that's true, since we  
really are used to distinguishing addition from concatenation, even in  
grocery lists -- it's just that we humans are a lot better about  
understanding context than machines are, so we implicitly translate  
plus signs into one or the other on the fly.


(Actually, Perl6 allows for context in a way that earlier Perls  
didn't: you can declare something to be a Num or a Str, and then a  
single overloaded + would work; in the old days when scalars had  
split personalities, you needed to specify the type some other way --  
in the operator.  Interestingly, BASIC has gone the other direction --  
at least, Visual BASIC uses + for addition and  for concatenation;  
I'm guessing this happened when VB got variant types that could hold  
either numbers or strings.)



While I agree with the sentiment of not arbitrarily restricting
people from doing ugly things unless they ask for such restrictions,
Agreed... though I disagree that the sort of overloading under  
discussion (/ for separating paths) falls into the ugly things  
category.


It's not ideal, but it's a fact of life.  Slashes for path separators  
are such a widespread custom that it would make as much sense to give  
up slashes for division.  (Actually, it would make more sense to keep  
slashes for paths and switch to ÷ (U+00F7) because the real division  
sign is at least as widespread for division, and isn't ambiguous in  
all the other ways slashes are, such as random separators on grocery  
lists.)


Whereas it is common to find addition and concatenation in the same  
expression, it's very uncommon to find division and path-building  
going on at the same time.  Path-building plus string-concat'ing *is*  
a likely and reasonable combination, though, so I would be against  
using ~ for joining paths.


(It is tempting to want a leading / to start an absolute path, and  
./ to introduce a relative path, but those are ambiguous with regex  
delimiters and a $_ method.  (Although ./ could probably work by the  
longest-token rule?)  However, it's not a hardship to do something  
like: io $foo/$bar, or io /$foo/$bar, where io() is an IO-object  
constructor -- those example thus being: io($foo) / $bar, or io() /  
$foo / $bar.)


The typical user already has a good notion of what the common  
operators

are, and what they mean.  So while drastically changing the meaning
of one of those operators may not be a disservice to the writer of
the code, it may well be a disservice to the reader.


Which is why I hope P6 defines standard symbols in the standard  
way.  (Where by standard I mean symbols that have a well-defined  
popular meaning, e.g. ÷, ≤, ∈, ±, ¬.  Well, and a meaning that's  
useful to Perl... ♂ and ♀ are well-defined, but I don't know how  
you'd use them in P6.  (I guess they could be enums!))


I agree *changing* the meaning is bad.  But the Good Kind of  
operator overloading doesn't do that; it just adds a new meaning.   
It really is overloading.


Yup, again because overloading is natural to human communication.   
And of course being so flexible about how to balance mapping onto the  
way humans think vs. mapping onto the problem space is what makes P6  
so delightful.


Which is why I like it so much more than certain of its brethren  
with their Orthogonality Ueber Alles attitude.  I just don't want to  
see that sort of prescriptivity creep in to Perl.



(Unless it's predeclared, of course!!)


-David



Re: Musings on operator overloading

2008-03-20 Thread Mark J. Reed
On Thu, Mar 20, 2008 at 2:24 AM, David Green [EMAIL PROTECTED] wrote:
  Interestingly, BASIC has gone the other direction --
  at least, Visual BASIC uses + for addition and  for concatenation;
  I'm guessing this happened when VB got variant types that could hold
  either numbers or strings.

Actually, VisualBASIC (at least as of VB.NET/2008) still has + for
concatenation, too.   is preferred because of the complex set of
rules that determine when + does conversions and when it doesn't (for
instance, adding a stringish Object to a numeric Object wll in some
cases convert the string to a number and add instead of
concatenating!), but + still works.


-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-20 Thread TSa

HaloO,

Mark J. Reed wrote:

For the record, I am opposed to any restriction on operator
overloading that requires mathematical properties to hold.  ANYTHING
is fair if you predeclare.


Hmm, my idea is more about defining interfaces that allow to detach
implementation of (numerical) algorithms from datatypes. E.g. the
Euclidean algorithm to find the gcd requires division and a remainder
that decreases in absolute value. This is like sorting objects that
do the Ordered role.



Besides, there is nothing that inherently
associates the / symbol with division - it's only an ASCII
approximation of fraction notation.


We all know that ASCII is a rather limited char set but one
that has the widest support. Unicode has got U+2215 and U+2044
for division and fraction composition.


 I want to be able to define / as
a path constructor and not give a flying flip that (path 2) * (path 3)
/ (path 5) - whatever the heck * might mean on paths - is not the same
as (path 2) / (path 5) * (path 3).


We need to distinguish two fundamentally different things here.
Symbol overloading which is a parser feature and operator overloading
that is runtime dispatch unless the compiler has enough information
to avoid it. Using / for paths has several drawbacks. First, it is not
the universal directory separator, \ is in widespread use also. Second,
a path is much more like a string than a number. Third, you have to
make sure that at least one of the concatenated types is a Path so that
you are dispatching to the intended implementation.

Instead of overloading ~ for paths I think inventing ~/ or ~\ as
path concatenating operators is well in line with the Perl 6 operator
set. And ~. could be the extension concatenator. And I also feel that
overloading ~ for file concatenation or photo stitching is good
practice.

BTW, operator overloading does not allow to change the precedence,
associativity and commutativity of the operator because these are
parser features.


We already had the issue of overloading / with div for Int operants.
And IIRC the conclusion then was that / is a Num operator and thus
2/3 != 0 but 2/3 == 0..



The P in Perl stands for Practical, not Pedantic.


I consider well designed interfaces as practical not pedantic ;)


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-20 Thread Mark J. Reed
On Thu, Mar 20, 2008 at 10:01 AM, TSa [EMAIL PROTECTED] wrote:
  Hmm, my idea is more about defining interfaces that allow to detach
  implementation of (numerical) algorithms from datatypes. E.g. the
  Euclidean algorithm to find the gcd requires division and a remainder
  that decreases in absolute value. This is like sorting objects that
  do the Ordered role.

Sure.  But that's different from saying Ok, you can only define an /
operator for numberish things.


   Besides, there is nothing that inherently
   associates the / symbol with division - it's only an ASCII
   approximation of fraction notation.

  We all know that ASCII is a rather limited char set but one
  that has the widest support. Unicode has got U+2215 and U+2044
  for division and fraction composition.

Not to mention good old ÷, which is even in Latin-1.

  Using / for paths has several drawbacks. First, it is not
  the universal directory separator, \ is in widespread use also.

Meh.  Even on Windows you can use / everywhere in the API, and Windows
folks are used to seeing the forward slash used this way in URLs if
nothing else.  Mac OS X uses POSIX paths under the covers, and we sure
aren't going to get the colon for this anyway...

 Second,  a path is much more like a string than a number.

Right.  Which means there's no room for confusion with division,
'cause you can't divide strings!  Ambiguity gone, problem solved, no
worries.

 Third, you have to make sure that at least one of the concatenated types is a 
 Path so that
  you are dispatching to the intended implementation.

Yes, I was sort of assuming there'd be a simple constructor for that.
Maybe even a lexically-enablable path literal syntax.  #P... anyone?
:)

  Instead of overloading ~ for paths I think inventing ~/ or ~\ as
  path concatenating operators is well in line with the Perl 6 operator
  set. And ~. could be the extension concatenator.

I would be pretty happy with ~/ and ~.  Especially if we also got
unary ~/ for making absolute paths in a natural fashion.

  And I also feel that  overloading ~ for file concatenation or photo 
 stitching is good  practice.

File concatenation, maybe; photo stitching is inherently a more
complex operation than concatenation.  Overloading ~ for that would
be, in my mind, analogous to overloading * for vectors: there's more
than one way to do that, so which operation does it mean?

  BTW, operator overloading does not allow to change the precedence,
  associativity and commutativity of the operator because these are
  parser features.

That depends on the degree to which you can munge the parser, though.
And I got the impression that in Perl6 the parser is pretty mungible.
You just have to get to it early enough...

  We already had the issue of overloading / with div for Int operants.
  And IIRC the conclusion then was that / is a Num operator and thus
  2/3 != 0 but 2/3 == 0..

What I'd really like  (blue skies, smiling at me...) to see come back
from / is a sort of abstract result-of-division object, which you can
then extract what you want out of it: quotient as float, quotient as
integer, modulus, list containing the latter two, rational fraction,
whatever.  Of course, it should automatically Numify to some default,
probably the floating point quotient, and be optimized to yield that
directly when the parser can figure out that it can do that...

   The P in Perl stands for Practical, not Pedantic.

  I consider well designed interfaces as practical not pedantic ;)

Of course, good design is extremely practical.  Just not necessarily
objectively measurable. :)

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-20 Thread TSa

HaloO,

Mark J. Reed wrote:

Sure.  But that's different from saying Ok, you can only define an /
operator for numberish things.


Well, if you adhere to the ring, field or whatever interface the
overloaded / sort of ends up being numberish anyway.

BTW, do we have a unary multiplikative inversion operator?
That is 1/ as prefix or **-1 as postfix? Perhaps .inv as method?
Do we have .neg for additive inversion?



Right.  Which means there's no room for confusion with division,
'cause you can't divide strings!  Ambiguity gone, problem solved, no
worries.


But without contextual information about the type of $x and $y an
expression $x/$y doesn't look particularly stringish to me.



 BTW, operator overloading does not allow to change the precedence,
 associativity and commutativity of the operator because these are
 parser features.


That depends on the degree to which you can munge the parser, though.
And I got the impression that in Perl6 the parser is pretty mungible.
You just have to get to it early enough...


But you can't mix the two concepts! Consider

  sub foo ($x)
  {
 return $x + $x * $x;
  }

and imagine a type Blahh that behaves like Num but swaps precedence
of + and *:

  my Blahh $y = 3;

  say foo($y);  # == 18
  say foo(3);   # == 12

How should the dispatcher know to dispatch to + first for $y?

Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-20 Thread Larry Wall
On Thu, Mar 20, 2008 at 11:03:11AM -0400, Mark J. Reed wrote:
:Besides, there is nothing that inherently
:associates the / symbol with division - it's only an ASCII
:approximation of fraction notation.
: 
:   We all know that ASCII is a rather limited char set but one
:   that has the widest support. Unicode has got U+2215 and U+2044
:   for division and fraction composition.
: 
: Not to mention good old ÷, which is even in Latin-1.

At this point in our history, slash for division is so ingrained
into the culture that it would be very difficult to change without
widespread grumbling.  People have a hard enough time accepting things
the extra typing of «+», and I suspect we get away with that only
because the user feels the construct is very powerful, and hence
worth the agony.  Huffman coding can be tweaked in several ways,
and power / cost might be one of them.  Division is perceived as a
very basic operation, so not worth much cost to type.

Another minor psychological factor is comes into play is that, besides
being too hard to type, ÷  is visually a symmetrical operator,
while division is inherently an asymmetric operation.  You'll notice
that other asymmetric operators invented by mathematicians tend to
convey that asymmetry visually.  And even with division, the notion
of over is asymmetrical, which / is of course proxying for.

But perhaps the overriding reason to avoid ÷ is that it's perceived
as something that's only used in grade school that you grow out of.

:   Using / for paths has several drawbacks. First, it is not
:   the universal directory separator, \ is in widespread use also.
: 
: Meh.  Even on Windows you can use / everywhere in the API, and Windows
: folks are used to seeing the forward slash used this way in URLs if
: nothing else.  Mac OS X uses POSIX paths under the covers, and we sure
: aren't going to get the colon for this anyway...

Well, then there's VMS...  :)

:  Second,  a path is much more like a string than a number.
: 
: Right.  Which means there's no room for confusion with division,
: 'cause you can't divide strings!  Ambiguity gone, problem solved, no
: worries.

Er, except for hordes of Perl 5 programmers who think you can...  :)

:  Third, you have to make sure that at least one of the concatenated types is 
a Path so that
:   you are dispatching to the intended implementation.
: 
: Yes, I was sort of assuming there'd be a simple constructor for that.
: Maybe even a lexically-enablable path literal syntax.  #P... anyone?
: :)

Been trying to avoid tokens that start with # to keep the parsing rules
simple...er, less complex...  We don't even allow # for user-defined
quotes any more, since it's legal to have whitespace (and hence, a
comment) between the q and the quote char.

But I'd suggest that path() would be much more readable, and Path()
is already a built-in coercion if you have a Path type.  And how
often do you really type path literals?  And maybe it would better
be handled by some kind of url-ish string that gets mapped to the
local conditions transparently.  Or just use arrays, which are much
more convenent for directory tree traversals, and convert to path
at the last moment.

:   Instead of overloading ~ for paths I think inventing ~/ or ~\ as
:   path concatenating operators is well in line with the Perl 6 operator
:   set. And ~. could be the extension concatenator.
: 
: I would be pretty happy with ~/ and ~.  Especially if we also got
: unary ~/ for making absolute paths in a natural fashion.

Those would work, though I wouldn't exactly call 'em pretty...  Nice
visual correspondence though.  I'd even let you have ~: for the drive.  :)

:   And I also feel that  overloading ~ for file concatenation or photo 
stitching is good  practice.
: 
: File concatenation, maybe; photo stitching is inherently a more
: complex operation than concatenation.  Overloading ~ for that would
: be, in my mind, analogous to overloading * for vectors: there's more
: than one way to do that, so which operation does it mean?

At some point it becomes silly to define an operator when you can just
say mystitch(@pix).

:   BTW, operator overloading does not allow to change the precedence,
:   associativity and commutativity of the operator because these are
:   parser features.
: 
: That depends on the degree to which you can munge the parser, though.
: And I got the impression that in Perl6 the parser is pretty mungible.
: You just have to get to it early enough...

Not disagreeing with either of you, but more in the way of an
explication...

You can add or change operator syntax in Perl 6, but such changes are
mandatorily lexically scoped, as are all macros and grammatical tweaks.
It's quite possible for a given operator parser to adjust its own
precedence and associativity on the fly.  Indeed, the assignment
operator has to decide at parse-time, based on its left argument,
whether its precedence is that of an item assignment or a list
assignment.

What you guys

Re: Musings on operator overloading

2008-03-20 Thread Larry Wall
On Thu, Mar 20, 2008 at 05:06:00PM +0100, TSa wrote:
 BTW, do we have a unary multiplikative inversion operator?
 That is 1/ as prefix or **-1 as postfix?

Well, 1/ looks like a pretty good prefix. :)

Except it's not really first class.  This ain't Haskell...

As for **-1, I'd suspect that of being more approximative
than the corresponding division on some architectures.

 Perhaps .inv as method?

I imagine most non-mathematicians would go more for .recip or some
such.

 Do we have .neg for additive inversion?

We currently have $num.prefix:- which is admittedly a bit unwieldy.

But it's difficult to extend that syntax to reciprocal, since

$num.infix:/(1)

doesn't work because the args are in the wrong order.  If someone *did*
define prefix:1/ then you could say:

$num.prefix1/

though that probably screws up precedence somehow.

 But you can't mix the two concepts!

Indeed, to the first approximation, the parser pays no attention to
the types, and multiple dispatch pays no attention to the syntax.

Larry


Re: Musings on operator overloading

2008-03-20 Thread Doug McNutt
At 17:06 +0100 3/20/08, TSa wrote:
BTW, do we have a unary multiplikative inversion operator?
That is 1/ as prefix or **-1 as postfix? Perhaps .inv as method?
Do we have .neg for additive inversion?

There certainly is the unary minus even though it is badly interpreted in some 
languages, thankfully NOT including perl 5.

Don't even think about parsing  = -$x**2; so that it returns a positive result.

Perl 5 handles it by assigning a higher precedence to ** than to addition. The 
real fact is that the minus sign in the above formula just isn't a unary minus 
in chalkboard algebra.

= $a - $b - f($x);  when $a is known to by identically equal to $b should be 
the same as
= 0 -  f($x); or just
= - f($x);  which happens easily with pencil and paper.

Don't allow it to become

= f(-$x);   ## wrong!

even if the f() is really written as $x**2 or has some other postfix operation 
- inversion -  that's considered a function by a mathematician.

*

At 15:01 +0100 3/20/08, TSa wrote:
BTW, operator overloading does not allow to change the precedence,
associativity and commutativity of the operator because these are
parser features.

A vector on the chalkboard can be a row or a column but in a computer it's an 
ordered list with the vertical or horizontal order of the components residing 
only in the mind of the programmer.

Multiplying a vector by a matrix implicitly indicates that the vector is a row. 
Multiplying a matrix by a vector implies a column vector and the results are 
quite different.

=$vector * $matrix;

is probably well handled in a overloading method because the order implies the 
rowness or columnness of the vector but it could get confused by a parser that 
has its own ideas about precedence and commutativity.

-- 

-- From the U S of A, the only socialist country that refuses to admit it. --


Re: Musings on operator overloading

2008-03-20 Thread Mark J. Reed
On Thu, Mar 20, 2008 at 1:09 PM, Doug McNutt [EMAIL PROTECTED] wrote:
  Don't even think about parsing  = -$x**2; so that it returns a positive 
 result.

Okay, going way off on a tangent here, but  I don't think the Perl
interpretation is quite as obviously correct as you think it is;
there's a reason the perlsyn page describes it as possibly surprising.
 Especially if you use a literal instead of a variable, in which case
the '-' might be considered part of the literal token in some
languages and preempt operator precedence altogether.

In any case, the decision is far from unanimous.  Fortran, the
original source of the ** operator, agrees with Perl on this front;
but COBOL, if asked to COMPUTE the same expression, returns a positive
result.  ( I know, what do you expect from a business-oriented
language...)

Ada, AWK, Groovy, Haskell, LSL, Lua, Pascal, Python, Ruby, Scala, and
Simula all agree that the result is negative.

APL also agrees, and it's arguably the ultimate mathematician's
language, but it also just evaluates right to left with no precedence
levels.  There are also languages like M[UMPS] that similarly lack
precedence and just plow through left to right, which yields a
positive answer here.

Precedenceful languages that return a positive result include
ALGOL-68, AppleScript, bash/ksh/zsh (let-arithmetic), bc(1), Eiffel,
and SNOBOL.

SmallTalk has no unary -, but 0 - x raisedTo: 2 yields a positive answer.

The various Basic implementations disagree with each other; Visual
Basic (including VB.NET) and LibertyBASIC say it's positive, while
Chipmunk says negative.  Going back in time to 8-bit days, the BASICs
on  Commodore, TI, Sinclair, and TRS-80 (model 1 level 2) machines
return a negative result, while Apple and Atari return a positive one.

I find it particularly interesting that not even all of the BASICs
from the same codebase (Microsoft's original Altair release) agree
with each other...

We now return you to your regularly scheduled Perl 6 mailing list,
already in progress.

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading (was: File-Fu overloading)

2008-03-20 Thread Aristotle Pagaltzis
Hi Jonathan,

* Jonathan Lang [EMAIL PROTECTED] [2008-02-24 22:30]:
 So if I'm understanding you correctly, the following would be
 an example of what you're talking about:
 
   { use text; if $a  49 { say $a } }
 
 ...with the result being the same as Perl5's 'if $a gt 49 {
 say $a }' (so if $a equals '5', it says '5'). Am I following
 you? If so, I'm not seeing what's so exciting about the
 concept; all it is is a package that redefines a set of
 operators for whatever scopes use it. If I'm not following you,
 I'm totally lost.

you’re indeed following me. And it’s indeed not very exciting.

And that’s exactly the point. I find that regular, type-based
overloading is *very* exciting… but not in a good way. An
approach that makes operator overloading an unexciting business
therefore seems very useful to me.

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.org/


Re: Musings on operator overloading

2008-03-19 Thread TSa

HaloO,

Aristotle Pagaltzis wrote:

Something like

path { $app_base_dir / $conf_dir / $foo_cfg . $cfg_ext }

where the operators in that scope are overloaded irrespective of
the types of the variables (be they plain scalar strings,
instances of a certain class, or whatever).


Assuming there are Path, Extension, Directory and File types,
the better approach would be in my eyes to overload string
concatenation. The only drawback is that one of the operants
of ~ has to be e.g. a Path to dispatch to infix:~:(Path, Str
-- Path). Subsequent concatenations will continue to dispatch
to path concatenation because of the return type. With path and
ext being unary casts to Path and Extension we get:

  path $app_base_dir ~ $conf_dir ~ $foo_cfg ~ ext $cfg_ext;



I suspect though that having the object carry the semantics
around with it is still going to be preferred.


No, the semantics should come from a set of operations that
blend together. The object type should be used only to dispatch
to specific implementations of these semantics.



When you leave the broader domain of mathematical and “para-”
mathematical abstractions behind and start to define things like
division on arbitrary object types that model aspects of domains
which have nothing even resembling such concepts, you’re rapidly
moving into the territory of obfuscation.


Indeed mathematics is all about distilling abstract properties
from problem domains and then proving abstract theorems. That
means when applying mathematics you only have to meet the
preconditions and get all consequences for free. But overloading
a symbol that means product with something that does not adhere
to the algebraic properties of products is a bad choice.

OTOH, overloading ~ with an operation that behaves like a monoid
is a bad idea too when the new operation doesn't feel like
concatenation. Actually I would argue that ~ could be overloaded
for ints in the sense that 1 ~ 2 == 12 numerically, but I'm unsure
how that would be implemented without an intermediate string.


A lot of C++ programmers could sing a song about that.


Oh yes, not being able to invent new symbols for new
operations is a pain.

But math itself is not free of such things. E.g. there's no
commonly accepted notation for conjugation. Some use an overbar,
others a dagger or asterisk postsuperscript. The latter might
ask for a unary postscript * which I think is technically possible
in Perl 6. But * as a symbol is already heavily overloaded.



Note that even with mathematical abstractions, there are cases
where scope-bound overloading is a win over type-bound
overloading. Consider a hypothetical Math::Symbolic that lets you
do something like this:

my $x = Math::Symbolic-new();
print +( $x**2 + 4 * $x + 3 )-derivative( $x );

I hope it’s obvious how such a thing would me implemented.


No, I find that far from obvious. Your derivative method
should have type :(Code -- Code) i.e. it returns {2*$^x + 4}
when given {$^x**2 + 4 * $^x + 3}. But I fail to see how
the type Math::Symbolic of your $x should instruct the parser
to hand over the parse tree to .derivative or some such.



Now,
if you used type-bound overloading, then the following two
expressions cannot yield the same result:

( 2 / 3 ) * $x
2 * $x / 3

But if overloading was scope-bound, they would!


First of all I would allow the optimizer to convert the latter
into the former unconditionally. Then I think your statement makes
only sense when the polymorphism on the type of $x is dropped in
scope-bound overloading. In other words $x is then always converted
into the suitable form. But how is that performed in general? IIRC,
the only generically available form is stringification.

Hmm, thinking twice, the above optimization is admissible only if
multiplication is commutative irrespective of the type of $x.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Re: Musings on operator overloading

2008-03-19 Thread Mark J. Reed
For the record, I am opposed to any restriction on operator
overloading that requires mathematical properties to hold.  ANYTHING
is fair if you predeclare. Besides, there is nothing that inherently
associates the / symbol with division - it's only an ASCII
approximation of fraction notation.  I want to be able to define / as
a path constructor and not give a flying flip that (path 2) * (path 3)
/ (path 5) - whatever the heck * might mean on paths - is not the same
as (path 2) / (path 5) * (path 3).

The P in Perl stands for Practical, not Pedantic.


On 3/19/08, TSa [EMAIL PROTECTED] wrote:
 HaloO,

 Aristotle Pagaltzis wrote:
  Something like
 
  path { $app_base_dir / $conf_dir / $foo_cfg . $cfg_ext }
 
  where the operators in that scope are overloaded irrespective of
  the types of the variables (be they plain scalar strings,
  instances of a certain class, or whatever).

 Assuming there are Path, Extension, Directory and File types,
 the better approach would be in my eyes to overload string
 concatenation. The only drawback is that one of the operants
 of ~ has to be e.g. a Path to dispatch to infix:~:(Path, Str
 -- Path). Subsequent concatenations will continue to dispatch
 to path concatenation because of the return type. With path and
 ext being unary casts to Path and Extension we get:

path $app_base_dir ~ $conf_dir ~ $foo_cfg ~ ext $cfg_ext;


  I suspect though that having the object carry the semantics
  around with it is still going to be preferred.

 No, the semantics should come from a set of operations that
 blend together. The object type should be used only to dispatch
 to specific implementations of these semantics.


  When you leave the broader domain of mathematical and para-
  mathematical abstractions behind and start to define things like
  division on arbitrary object types that model aspects of domains
  which have nothing even resembling such concepts, you're rapidly
  moving into the territory of obfuscation.

 Indeed mathematics is all about distilling abstract properties
 from problem domains and then proving abstract theorems. That
 means when applying mathematics you only have to meet the
 preconditions and get all consequences for free. But overloading
 a symbol that means product with something that does not adhere
 to the algebraic properties of products is a bad choice.

 OTOH, overloading ~ with an operation that behaves like a monoid
 is a bad idea too when the new operation doesn't feel like
 concatenation. Actually I would argue that ~ could be overloaded
 for ints in the sense that 1 ~ 2 == 12 numerically, but I'm unsure
 how that would be implemented without an intermediate string.

  A lot of C++ programmers could sing a song about that.

 Oh yes, not being able to invent new symbols for new
 operations is a pain.

 But math itself is not free of such things. E.g. there's no
 commonly accepted notation for conjugation. Some use an overbar,
 others a dagger or asterisk postsuperscript. The latter might
 ask for a unary postscript * which I think is technically possible
 in Perl 6. But * as a symbol is already heavily overloaded.


  Note that even with mathematical abstractions, there are cases
  where scope-bound overloading is a win over type-bound
  overloading. Consider a hypothetical Math::Symbolic that lets you
  do something like this:
 
  my $x = Math::Symbolic-new();
  print +( $x**2 + 4 * $x + 3 )-derivative( $x );
 
  I hope it's obvious how such a thing would me implemented.

 No, I find that far from obvious. Your derivative method
 should have type :(Code -- Code) i.e. it returns {2*$^x + 4}
 when given {$^x**2 + 4 * $^x + 3}. But I fail to see how
 the type Math::Symbolic of your $x should instruct the parser
 to hand over the parse tree to .derivative or some such.


  Now,
  if you used type-bound overloading, then the following two
  expressions cannot yield the same result:
 
  ( 2 / 3 ) * $x
  2 * $x / 3
 
  But if overloading was scope-bound, they would!

 First of all I would allow the optimizer to convert the latter
 into the former unconditionally. Then I think your statement makes
 only sense when the polymorphism on the type of $x is dropped in
 scope-bound overloading. In other words $x is then always converted
 into the suitable form. But how is that performed in general? IIRC,
 the only generically available form is stringification.

 Hmm, thinking twice, the above optimization is admissible only if
 multiplication is commutative irrespective of the type of $x.


 Regards, TSa.
 --

 The Angel of Geometry and the Devil of Algebra fight for the soul
 of any mathematical being.   -- Attributed to Hermann Weyl



-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-19 Thread Larry Wall
On Wed, Mar 19, 2008 at 12:38:48PM -0400, Mark J. Reed wrote:
: For the record, I am opposed to any restriction on operator
: overloading that requires mathematical properties to hold.  ANYTHING
: is fair if you predeclare. Besides, there is nothing that inherently
: associates the / symbol with division - it's only an ASCII
: approximation of fraction notation.  I want to be able to define / as
: a path constructor and not give a flying flip that (path 2) * (path 3)
: / (path 5) - whatever the heck * might mean on paths - is not the same
: as (path 2) / (path 5) * (path 3).
: 
: The P in Perl stands for Practical, not Pedantic.

While I agree with the sentiment of not arbitrarily restricting
people from doing ugly things unless they ask for such restrictions,
I'd also like to point out that the desire to maintain consistent
symbolic distinctions is not limited to mathematicians.

The use of + in Python or  in C++ is, I think, primarily the
violation of a *linguistic* principle, not a mathematical principle.
The typical user already has a good notion of what the common operators
are, and what they mean.  So while drastically changing the meaning
of one of those operators may not be a disservice to the writer of
the code, it may well be a disservice to the reader.

Perl is about linguistics, and hence is more concerned with successful
communication than with pure mathematical platonics.

Larry


Re: Musings on operator overloading

2008-03-19 Thread Mark J. Reed
On Wed, Mar 19, 2008 at 1:01 PM, Larry Wall [EMAIL PROTECTED] wrote:
  While I agree with the sentiment of not arbitrarily restricting
  people from doing ugly things unless they ask for such restrictions,

Agreed... though I disagree that the sort of overloading under
discussion (/ for separating paths) falls into the ugly things
category.

  I'd also like to point out that the desire to maintain consistent
  symbolic distinctions is not limited to mathematicians.

Absolutely.   Or rather, not absolutely. I think absolute consistency
is in the same category as absolute orthogonality... too much of a
good thing.

  The use of + in Python or  in C++ is, I think, primarily the
  violation of a *linguistic* principle, not a mathematical principle.

Maybe it's just 'cause I cut my teeth on BASIC, but + for string
concatenation has always felt pretty natural.  Obviously it won't work
in Perl where you are using the operator to determine how to treat the
operands.   At first blush I find it more readily readable than  or
||, or even ..

And  makes sense for the various kinds of appending it is used for
in C++, Ruby, etc, but only if you don't look at it and think bit
shift. Fortuantely, bit shift isn't a fundamental arithmetic
operation in the traditional sense, and the set of people who think
that is proportionally smaller.

  The typical user already has a good notion of what the common operators
  are, and what they mean.  So while drastically changing the meaning
  of one of those operators may not be a disservice to the writer of
  the code, it may well be a disservice to the reader.

I agree *changing* the meaning is bad.  But the Good Kind of operator
overloading doesn't do that; it just adds a new meaning.  It really is
overloading.  Hopefully, the new meaning is somewhat related to the
original - a sort of operator metonymy - but if the context is
sufficiently different, that's not a requirement.  Again, nobody's
going to think you're dividing pathnames.

  Perl is about linguistics, and hence is more concerned with successful
  communication than with pure mathematical platonics.

Which is why I like it so much more than certain of its brethren with
their Orthogonality Ueber Alles attitude.  I just don't want to see
that sort of prescriptivity creep in to Perl.

-- 
Mark J. Reed [EMAIL PROTECTED]


Re: Musings on operator overloading

2008-03-18 Thread TSa

HaloO,

Doug McNutt wrote:

I really want to use complex numbers, vectors, matrices, and
sometimes quarternions. I really want to be able to define or use
previously defined operators in a way that I learned in the 50's. I
want my compiler to understand when I use vectors in which the
components are complex numbers. I want dot and cross product to work.
I want to be able to multiply a matrix by a vector and get a polite
error message if I try that with impossible arguments.


This is all possible with Perl 6 and its type system, I hope. The
concept of a vector as an element of a vector space e.g. should
be instanciable with complex numbers as coordinates. That is
the dot product has type :(Vector[::T], Vector[::T] -- ::T). The
type ::T has to do the Num role to be viable for instanciating
Vector. E.g. Vector[Str] should give a compile time type error.



What I think I learned from those two messages is that it's damnably
difficult for a parser to figure out what I'm doing. Perhaps it just
isn't worth while.


If you mean that the parser understands the semantics of your code,
building a parser is indeed in the realm of AI. But for reasonable
operator overloading only two things are needed. Firstly a definition
what exactly constitutes the type Num algebraically. And Secondly a
syntax to make that information machine readable.

The definition of Num should be as minimal as possible. E.g. it should
not contain the requirement to be totally ordered. Well, Num will
actually be ordered and there's a type that does not require it. This
could be called Field. That is it defines the presence of +, -, * and /
as binary operations and unary -. Interestingly there's no unary /.

Other functions like sqrt make use of these operators to iteratively
calculate their result. The only additional requirement for a numerical
type is thus to provide an absolute value function. So as long as a user
defined type Foo provides these five operations the sqrt function should
automatically be callable with it! Note further that a template
implementation of sqrt should automatically yield the result undef for
negative real numbers by detecting diverging absolute value or
occurrence of division by zero while iterating. And of course there can
be optimized implementations for certain types.



I really don't mind informing my compiler in advance about what I
want a variable to be treated as. Typedef {}, Dimension () and the
like are no problem at all. I don't mind. And I think that would also
apply to my scientifically oriented friends.


Yes, type annotation allows the compiler to detect errors that would
otherwise occur at runtime. Not to mention the fact that no optimization
is possible. Well, with the above algebraic approach you can generically
optimize 2*$x/3 from the cost of two multiplications to (2/3)*$x which
costs one runtime multiplication irrespective of the type of $x.



Wouldn't it make life easier for the parser to overload the *
operator into a dot product whenever both arguments have been defined
as vectors or been returned as vectors by a previous operation?


Yes, that is easy doing for the compiler. It simply creates code for
a dynamically dispatched operator. But the algebraically pleasing
approach needs tensor calculus or Clifford algebras to properly define
products of vectors.



One
could even use ** for a cross product since raising to a vector power
is unreasonable.


This is a particularly bad idea that plays in the same league as
using + for string concatenation. Powering is defined through
multiplication. So without a proper product there can hardly be
a power operator. Without that you don't have power series either
and therefore no higher functions like sine or cosine etc. One could
also overload the string replicating x operator to mean cross product
when called with two three or seven dimensional vectors. Much better
than overloading * for the inner product it might be possible to dwell
on the customs to write it as a,b if one can avoid the clash with
the non-interpolating string list creator. OTOH the scalar product is
just [+](@a »*« @b). A nice idea is to abbreviate that as *+ or +* akin
to Einstein's summation convention.


Regards, TSa.
--

The Angel of Geometry and the Devil of Algebra fight for the soul
of any mathematical being.   -- Attributed to Hermann Weyl


Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Aristotle Pagaltzis
[Cc to perl6-language as I think this is of interest]

[Oh, and please read the entire thing before responding to any
one particular point. There are a number of arguments flowing
from one another here. (I am guilty of being too quick with the
Reply button myself, hence this friendly reminder.)]

* Eric Wilhelm [EMAIL PROTECTED] [2008-02-24 02:05]:
 # from Aristotle Pagaltzis
 # on Saturday 23 February 2008 14:48:
 I find the basic File::Fu interface interesting… but operator
 overloading always makes me just ever so slightly queasy, and
 this example is no exception. 
 
 Is that because of the syntax, the concepts, or the fact that
 perl5 doesn't quite get it right?

It’s a matter of readability. It’s the old argument about, if
not to say against, operator overloading: you’re giving `*` a
completely arbitrary meaning that has nothing in common in any
way with what `*` means in contexts that the reader of the code
had previously encountered.

 Does it help to know that error messages will be plentiful and
 informative?  (Not to mention the aforementioned disambiguation
 between mutations and stringifications.)

It has nothing to do with any of these factors.

 I get the desire for syntactic sugar, I really do… but looking
 at this, I think the sane way to accommodate that desire is to
 attach overloaded semantics to a specially denoted scope
 rather than hang them off the type of an object.
 
 I can't picture that without an example.

Something like

path { $app_base_dir / $conf_dir / $foo_cfg . $cfg_ext }

where the operators in that scope are overloaded irrespective of
the types of the variables (be they plain scalar strings,
instances of a certain class, or whatever).

Note that I’m not proposing this as something for File::Fu to
implement. It would be rather difficult, if at all possible, to
provide such an interface in Perl 5. You need macros or access to
the grammar or something like that in order to implement this at
all. Although I think that even if you have those, you wouldn’t
want to use them directly, but rather as a substrate to implement
scope-attached operator overloading as an abstraction over them.

But I think it’s desirable to use this abstraction instead of
using grammar modifications or macros directly, since it vastly
more limited power than the former and still much less power than
the latter. It should therefore be easier both in use by the
programmer who designs the overloading scope and in readability
for the maintenance programmer who reads code that uses overload
scopes.

It would particularly help the latter, of course, because the
code’s behaviour does not vary based on the types that happen to
pass through; the source code is explicit and direct about its
meaning.

 I suspect though that having the object carry the semantics
 around with it is still going to be preferred.

There are cases where it would be.

When the object is a mathematical abstraction in some broad
sense, e.g. it’s a complex number class, or it implements some
kind of container such as a set, then being able to overload
operators based on the type of that object would be useful.

But note that in all of these examples, it is very much
self-evident what the meaning of an overloaded `+` would be: that
meaning comes from the problem domain – a problem domain that has
the rare property of having concepts such as operators and
operands.

When you leave the broader domain of mathematical and “para-”
mathematical abstractions behind and start to define things like
division on arbitrary object types that model aspects of domains
which have nothing even resembling such concepts, you’re rapidly
moving into the territory of obfuscation.

A lot of C++ programmers could sing a song about that.

However, I think the way that Java reacted to this (“only the
language designer gets to overload operators!!”) is completely
wrong. I agree fully with the underlying desire you express:

 The essential motivation is that if I can't make this
 interface work, I'm just going to slap strings together and be
 done with it.  The converse is that if I can make this
 interface work then cross-platform pathname compatibility
 becomes far less tedious.

Absolutely it is very, very useful to be able to define syntactic
sugar that makes it as easy and pleasant to do the right thing
(manipulate pathnames as pathnames) as it is to do the wrong
thing (use string operations to deal with pathnames). That is
precisely why I said that I do get why you’d want to overload
operators.

And this contradiction – that being able to declare sugar is
good, but the way that languages have permitted that so far leads
to insanity – is what sent me thinking along the lines that there
has to be some way to make overloading sane. And we all know that
all is fair if you predeclare. And that led me to the flash of
inspiration: why not make overloading a property of the source
(lexical, early-bound) rather than of the values (temporal, late-
bound)? And what

Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Andy Armstrong

On 24 Feb 2008, at 15:00, Aristotle Pagaltzis wrote:

Something like

   path { $app_base_dir / $conf_dir / $foo_cfg . $cfg_ext }



I've wanted this often. I've also wanted a clean way to lexically  
supply a default target object. For example with HTML::Tiny you often  
write


 my $h = HTML::Tiny-new();
 $h-body($h-head($h-title('FooPage')), $h-body(...));

I'd love to be able to drop the '$h-' everywhere. Like this:

 $h-body( head( title( 'FooPage' ) ), body( ... ) );

I guess that would/could be a related mechanism.

--
Andy Armstrong, Hexten






Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Luke Palmer
On Sun, Feb 24, 2008 at 3:00 PM, Aristotle Pagaltzis [EMAIL PROTECTED] wrote:
  Something like

 path { $app_base_dir / $conf_dir / $foo_cfg . $cfg_ext }

  where the operators in that scope are overloaded irrespective of
  the types of the variables (be they plain scalar strings,
  instances of a certain class, or whatever).

This is excellent.  I've long supported the one symbol-one meaning
idea.  There are some trade-offs, though, which I'll describe.  I'll
use Haskell as my object language, since it does this sort of operator
defining rather than operator overloading (only for infix binary
operators though, not full syntactic constructs).

Recently I implemented a Vector class in Haskell.  Vectors have
addition and multiplication, of a sort, so it makes sense to use the +
and * operators.   In Haskell overloading comes in type classes, where
the operators you overload need to have specific types and you also
have an implicit contract to obey some laws about them when you
overload.  In the context of Perl, types don't mean squat, but the
implicit laws are still important, so this argument still applies.
The Num class for these operators looks like this:

  class Num a where
(+) :: a - a - a   -- take 2 arguments of type a and return 1 of type a
(*) :: a - a - a
...

Which means that if I wanted to overload (+) to work on vectors, my
(+) would have to have type Vector - Vector - Vector.  That's fine,
it is that type.  And it's associative and commutative as the class
expects.

The trouble is with (*).  There are three types of multiplication on
vectors, with these types:

Double - Vector - Vector
Vector - Double - Vector
Vector - Vector - Double  -- inner product

None of which is Vector - Vector - Vector as Num is expecting.

Now, not letting me overload (*) was a good idea on Num's part.
Normally if you have some v in Num, you can say (v*v) + v and it will
be legal.  But if v were a vector, then this wouldn't work, you'd end
up trying to add a scalar and a vector.  It's very simple, Vectors are
not Nums in the sense that the class requires

The way I solved this was to create my own class with special vector
operations, so the user of the module had to differentiate between
vector operations and scalar operations.

  class Vector v where
(^+^) :: v - v - v
(*^)  :: Double - v - v
(^*^) :: v - v - Double

  x ^* y  = y *^ x
  x ^-^ y = x ^+^ (-1) *^ y

Which could be construed as annoying.

This problem could have been ameliorated in another way, namely to
have designed Num differently.  If Num separated the notions of
addition and multiplication, or even had been designed as a Vector
space in the first place, then I could have used + and * like I wanted
to.  But it wasn't, so I couldn't.  More below.

  I hope it's obvious how such a thing would me implemented. Now,
  if you used type-bound overloading, then the following two
  expressions cannot yield the same result:

 ( 2 / 3 ) * $x
 2 * $x / 3

  But if overloading was scope-bound, they would!

And here is why you need ad-hoc overloading in addition to scope-based
overloading.  There are times when I mean 2/3  4 to mean the symbolic
data structure representing that condition, and there are other times
when I just want to check whether 2/3 is less than 4!  Here's a
contrived example:

  my $expr = 1;
  my $count = 1;
  while ($count  10) {
print $count $expr\n;
$expr = $expr + $expr;
$count = $count + 1;
  }

With the intention of printing something like:

  1 1
  2 1 + 1
  3 (1 + 1) + (1 + 1)
  ...

Which is, of course, broken.  I would have to do something crazy with scopes:

  while ($count  10) {
print $count $expr\n;
$expr = do { use Math::Symbolic; $expr + $expr };
$count = $count + 1;
  }

Which could also be construed as annoying.

However, here $count + 1 and $expr + $expr are the same +.  They both
mean add.  Why should I have to play with scopes for this.  Contrast
this with Java, where 3 + 4 and hello  + world are different +s
(unless you're used to thinking about monoids).  Getting those two to
coexist is the thing that should require playing with scopes (or
better yet, using diffrent symbols for the two of them).

I do think the best solution is a combination of overloading and
scoping.  That is, allow operator overloading, but not overloading the
name +, rather overloading a specific +, such as Math::infix:+.

This still allows poor usage as we've commonly seen with operator
overloading.  But it also allows well-behaved usage, which was
previously forbidden.

Luke


Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Larry Wall
On Sun, Feb 24, 2008 at 04:23:54PM +, Andy Armstrong wrote:
 I've wanted this often. I've also wanted a clean way to lexically supply a 
 default target object. For example with HTML::Tiny you often write

  my $h = HTML::Tiny-new();
  $h-body($h-head($h-title('FooPage')), $h-body(...));

 I'd love to be able to drop the '$h-' everywhere. Like this:

  $h-body( head( title( 'FooPage' ) ), body( ... ) );

 I guess that would/could be a related mechanism.

In Perl 6 you can at least get it down the minimalistic indication
of a method vs function:

given $h {
  .body( .head( .title( 'FooPage' ) ), .body( ... ) );
}

That can be construed as clean in a way that a functional interface
with an implicit object could not.  P6 is big on distinguishing
method calls from function calls *because* of wanting to distinguish
object-centric single dispatch from function-based multiple dispatch
(including all operator dispatch) which, by the way, is generally
controlled lexically in P6, as the OP suggests.  (It's also used in
the global (or more like super-lexical) Prelude scope by the compiler
to define the base language each compilation unit starts in.)
So we're ahead of you there...  :)

Basically anything that could be construed as language mutation is
limited lexically in P6, and mixing in user-defined multimethods can
be construed as at least semantic mutation, and is also syntactic
mutation if you define new operators rather than merely overloading
existing ones.  (We have a bias toward new operators for different
semantics, also suggested in the OP.  There's lots of Unicode operators
available, I hear...)

But back to .body etc.  To go further than that without the cooperation
of the class, you'd have to curry the invocant on a class, currently
described as something like:

(use HTML::Tiny).assuming(:self(HTML::Tiny.new()));

which would presumably import all the methods as functions, give
or take the fact that that syntax would not intrinsically indicate
the desire to import anything, which is a problem.  It is probably
a common enough operation to give a shortcut to:

use HTML::Tiny :singleton;

or some such, which would automatically run new, curry all the methods
on the invocant, install those resulting functions under the singleton tag
as marked for export, then import them as you would any other tag.  Then
your call reduces to:

body( head( title( 'FooPage' ) ), body( ... ) );

But as I just described it, if you wanted to use another singleton in
a different scope, you'd end up clobbering singleton tag, so really
you want to treat that as an anonymous tag somehow.  (Import tags
are really just subpackages in P6, so an anonymous temporary subpackage
is likely not a problem.)  Then you wouldn't have colliding curries,
and the exporting module doesn't have to be aware of who is importing
from it, which is pretty bogus when you think about it.

Presumably the HTML::Tiny protoobject can then be queried for its
singleton object if you really need to have $h for some reason.

Larry


Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Doug McNutt
At 17:30 + 2/24/08, Luke Palmer wrote:
On Sun, Feb 24, 2008 at 3:00 PM, Aristotle Pagaltzis [EMAIL PROTECTED] wrote:

And I read both very carefully and failed to understand most of it.

I use perl for physics and engineering mostly because I forgot most of my 
FORTRAN long ago and perl works everywhere.

I really want to use complex numbers, vectors, matrices, and sometimes 
quarternions. I really want to be able to define or use previously defined 
operators in a way that I learned in the 50's. I want my compiler to understand 
when I use vectors in which the components are complex numbers. I want dot and 
cross product to work. I want to be able to multiply a matrix by a vector and 
get a polite error message if I try that with impossible arguments.

What I think I learned from those two messages is that it's damnably difficult 
for a parser to figure out what I'm doing. Perhaps it just isn't worth while.

But. . .

I really don't mind informing my compiler in advance about what I want a 
variable to be treated as. Typedef {}, Dimension () and the like are no problem 
at all. I don't mind. And I think that would also apply to my scientifically 
oriented friends.

Wouldn't it make life easier for the parser to overload the * operator into a 
dot product whenever both arguments have been defined as vectors or been 
returned as vectors by a previous operation? One could even use ** for a cross 
product since raising to a vector power is unreasonable. Just recognizing the 
special use declared and passing the operation off to a required subroutine 
would be adequate. Yes. It can all be expressed in simple object-oriented 
language but all of the File::Fu stuff is unduly complicating the use in 
mathematics.

Practical Extraction and Reporting are what perl is about and I know I'm 
stretching the plan but just a bit of code that will allow, but not require, 
typedefs - er classes - of special things that cause operators to be passed to 
subroutines - er class methods - to be written could make a big difference.

Even translating ^ to pow($x,$y) would be useful to some, but I remember that 
much FORTRAN. And -2^2 is -4 (correctly?) in C on a two's complement machine.

-- 

-- Life begins at ovulation. Ladies should endeavor to get every young life 
fertilized. --


Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Jonathan Lang
Aristotle Pagaltzis wrote:
  And this contradiction – that being able to declare sugar is
  good, but the way that languages have permitted that so far leads
  to insanity – is what sent me thinking along the lines that there
  has to be some way to make overloading sane. And we all know that
  all is fair if you predeclare. And that led me to the flash of
  inspiration: why not make overloading a property of the source
  (lexical, early-bound) rather than of the values (temporal, late-
  bound)? And what we need to do that is a way to say this scope
  is special in that the operators herein follow rules that differ
  from the normal semantics. There you have it.

So if I'm understanding you correctly, the following would be an
example of what you're talking about:

  { use text; if $a  49 { say $a } }

...with the result being the same as Perl5's 'if $a gt 49 { say $a
}' (so if $a equals '5', it says '5').  Am I following you?  If so,
I'm not seeing what's so exciting about the concept; all it is is a
package that redefines a set of operators for whatever scopes use it.
If I'm not following you, I'm totally lost.

-- 
Jonathan Dataweaver Lang


Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread David Green

On 2008-Feb-24, at 2:28 pm, Jonathan Lang wrote:

 { use text; if $a  49 { say $a } }
...with the result being the same as Perl5's 'if $a gt 49 { say  
$a }' (so if $a equals '5', it says '5').  Am I following you?  If  
so, I'm not seeing what's so exciting about the concept;


The whole point is to be not exciting: instead of being kept on the  
edge of your seat wondering what possible meaning  has this time,  
it's right there explicitly, boringly in front on you.  As indicated,  
that has advantages and disadvantages.  In general, I tend towards  
solutions that do what human beings would do (as opposed to  
programmers, although of course that isn't always feasible).


One thing humans do, when faced with a dot product, say, is to use a  
dot; and happily, Perl 6 makes it easy to define Unicode operators so  
we don't have to overload operators that mean something else.


Something else humans do, however, is to overload symbols: e.g. /  
for a filepath separator and for division.  I'm not convinced that  
scope-based overloading is the way to go in this particular case,  
though.  It is the way to go for regexes, which overload all sorts of  
symbols that have other meanings, because regexes come in self- 
contained lumps anyway.  (Although similar overloadings are used in  
Signatures, which are another limited scope, come to think of it).


Of course, using a slash for division is a slightly ugly hack anyway,  
because typewriters didn't have the proper symbol (U+00F7).  P6 could  
use ÷ for division, and / for portable path-separation.  (Which is  
kind of tempting, at least to me; I must admit I've been pondering the  
use of / for filenames for some time.)


On the other hand, I think that in real code, it should be fairly  
obvious whether you're doing arithmetic or working with files, so  
perhaps the solution is to add unambiguous alternatives for those  
exceptional cases when you want to make it absolutely explicit:  
open($dir fs ($filename ~ $total div $count)).


(I also expect that files will be treated more consistently in P6,  
without as many issues about whether a file is a string or a handle  
or an object...)



-David



Re: overloading the variable declaration process

2006-02-14 Thread Stevan Little
On 2/12/06, Thomas Sandlass [EMAIL PROTECTED] wrote:
   IIRC, you can always create a new method for a class, even outside of
   its definition, simply by ensuring that the first parameter to be
   passed in will be an object of that type:
  
 method bark (Dog $_) { ... }
 
  I don't think this is true unless it is a multi method, in which case
  it is not actually a method of the of the class, but instead just
  DWIMs because of MMD and the fact we allow an invocant calling style
  freely.

 Yes, the question of ownership of methods is still
 somewhat unresolved. I think we need to distinguish
 something I've called slots in an object from free
 (multi) methods that are defined outside of the class
 definition block. BTW, do the outsiders have access
 to the private data slots with the $! twigil?

I think that multimethods defined outside of the scope of the class
should not have access to the classes data slots, it should use the
accessors. And those multimethods should live in the package in which
they are defined. The class implementation can stash refs to
multimethods which apply to it for optimization reasons, but this has
nothing to do with the language design itself.

As far as method name disambiguation, we should use the calling style
(invocant vs. normal function call) to determine which method to call.

I am sure there are other edge cases to be uncovered here as well, but
I can't think of them at the moment.

Stevan


RE: overloading the variable declaration process

2006-02-12 Thread Thomas Sandlass
Stevan Little wrote:

 ^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the
 class (actually it's a prototypical instance of the class which the
 metaclass ^Dog describes, but you dont really need to know that to use
 it).
 
  ^Dog.can(bark) # false
   Dog.can(bark) # true

Wasn't the ^ sigil dropped in favor of a 0..^n list creation op?
So the first line is spelled

  ::Dog.can(bark) # false

instead?

 Of course you have a conceptual circulatiry issue now because well,..
 what is a MetaClass? Well it could be an instance of a MetaMetaClass,
 but what is that an instance of? This could go on forever (turtles all
 the way down as it is sometimes called).
 
 But in practice you either just stop and say this is as far as it
 goes,  or you bootstrap your class model somehow and tie the knot.
 I prefer the boostrapping as it is much more elegant and tends to
 allow for much more flexibility.

I agree. Your cicularity is basically an a-priori infinity conceptually
one level outside of the meta system.

And there will be an orthogonal type/kind system.


  IIRC, you can always create a new method for a class, even outside of
  its definition, simply by ensuring that the first parameter to be
  passed in will be an object of that type:
 
method bark (Dog $_) { ... }
 
 I don't think this is true unless it is a multi method, in which case
 it is not actually a method of the of the class, but instead just
 DWIMs because of MMD and the fact we allow an invocant calling style
 freely.

Yes, the question of ownership of methods is still
somewhat unresolved. I think we need to distinguish
something I've called slots in an object from free
(multi) methods that are defined outside of the class
definition block. BTW, do the outsiders have access
to the private data slots with the $! twigil?


  or maybe
 
method Dog.bark () { ... }
 
 Yes that works too.

Shouldn't that read Dog::bark? Why the dot?
-- 
$TSa.greeting := HaloO;  # mind the echo!









Re: overloading the variable declaration process

2006-02-12 Thread Jonathan Lang
Thomas Sandlass wrote:
   or maybe
  
 method Dog.bark () { ... }
 
  Yes that works too.

 Shouldn't that read Dog::bark? Why the dot?

Because I'm not 100% with the proper syntax of things.  The intent was
to add a bark() method to Dog during runtime.

--
Jonathan Dataweaver Lang


Re: overloading the variable declaration process

2006-02-09 Thread Stevan Little
On 2/8/06, Jonathan Lang [EMAIL PROTECTED] wrote:
 Stevan Little wrote:
  Yes, that is correct, because:
 
  Dog.isa(Dog)  # true
  $spot.isa(Dog)  # true
  ^Dog.isa(Dog)  # false
 
  In fact ^Dog isa MetaClass (or Class whatever you want to call it).
 
  At least that is how I see/understand it.

 OK.  To help me get a better idea about what's going on here, what
 sorts of attributes and methods would ^Dog have?

Well, a metaclass describes the behaviors and attributes of a class,
and ^Dog is an *instance* of the metaclass. So actually ^Dog would not
actually have attributes and methods since it is an instance. That
said, I think ^Dog would probably respond to methods like these (some
of which are described in S12):

  ^Dog.name # Dog
  ^Dog.version # 0.0.1 (or something similiar of course)
  ^Dog.authority  # cpan:LWALL or email:[EMAIL PROTECTED]

  ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL

I would like to see some methods like this:

  # dynamically add a method that
  # Dog and $spot would respond to
  ^Dog.add_method(bark = method () { ... });

Which would be like doing this in Perl 5:

  no strict 'refs';
  *{'Dog::bark'} = sub { ... };

And of course if you can add a method, you will need to be able to
fetch and delete them as well, so a get_method and remove_method
would be in order as well.

And if you can add methods, surely you can add attributes, so
(add|get|remove)_attribute would be needed.

  ^Dog.add_attribute(:label$fur, :accessrw);

Would be equivalent to saying this:

  class Dog is reopened {
  has $fur is rw;
  }

And ^Dog would also provide access to infromation about super and
subclasses as well. So superclasses and subclasses methods would
make sense too. We would also need methods to deal with Role
relationships as well.

So, given the above items, the class MetaClass might look something like this:

  class MetaClass {
  has $name is rw;
  has $version is rw;
  has $authority is rw;

  has @superclasses;
  has @subclasses;

  has %methods;
  has %attributes;

  method identifier { ... }

  method superclasses { ... }
  method subclasses { ... }

  method add_method { ... }
  method get_method { ... }
  method remove_method { ... }

  method add_attribute { ... }
  method get_attribute { ... }
  method remove_attribute { ... }
  }

So given this, you could almost look at this code:

  class Foo-0.0.1-cpan:JRANDOM {
  has $bar is rw;

  method baz (Foo $self:) { ... }
  }

As being roughly equivalent to the following code:

  ^Foo := MetaClass.new();
  ^Foo.name('Foo');
  ^Foo.version(0.0.1);
  ^Foo.authority(:cpanJRANDOM);

  ^Foo.add_attribute(:label$bar, :accessrw);
  ^Foo.add_method(baz = method (Foo $self) { ... });

Of course this is mostly unspecced, and it is still unclear exactly
how much of this meta-level API will be accessible in Perl 6 itself.
And as far the the Pugs work on this goes, we plan to have something
similar to the above available in the next release (6.28.0).

Hope this helps.

Stevan


Re: overloading the variable declaration process

2006-02-09 Thread Jonathan Lang
Stevan Little wrote:
 Jonathan Lang wrote:
  OK.  To help me get a better idea about what's going on here, what
  sorts of attributes and methods would ^Dog have?

 Well, a metaclass describes the behaviors and attributes of a class,
 and ^Dog is an *instance* of the metaclass. So actually ^Dog would not
 actually have attributes and methods since it is an instance.

Huh?  A dog can bark; so the Dog class should have a method called
'bark'.  Or does 'can' not mean what it seems to mean?

 That said, I think ^Dog would probably respond to methods like
 these (some of which are described in S12):

OK; apparently, what I meant when I asked what methods and attributes
does ^Dog have? is what you're talking about when you speak of which
methods ^Dog will respond to.  To me, an object has whatever methods
that it responds to.

   ^Dog.name # Dog
   ^Dog.version # 0.0.1 (or something similiar of course)
   ^Dog.authority  # cpan:LWALL or email:[EMAIL PROTECTED]

   ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL

Would it be valid to speak of ^$spot?  If so, what would ^$spot.name be?

 I would like to see some methods like this:

   # dynamically add a method that
   # Dog and $spot would respond to
   ^Dog.add_method(bark = method () { ... });

 Which would be like doing this in Perl 5:

   no strict 'refs';
   *{'Dog::bark'} = sub { ... };

IIRC, you can always create a new method for a class, even outside of
its definition, simply by ensuring that the first parameter to be
passed in will be an object of that type:

  method bark (Dog $_) { ... }

or maybe

  method Dog.bark () { ... }

 And of course if you can add a method, you will need to be able to
 fetch and delete them as well, so a get_method and remove_method
 would be in order as well.

To fetch a method, why not have .can() return a reference to the
method upon success?  I might even go so far as to treat can() as an
lvalue, using the assignment of a coderef as an alternate way of
adding or changing the object's behavior on the fly:

  method bark (Dog $_:) { ... };
  Dog.can(bark) = method () { ... }; # Teach the dog a new trick
  Dog.can(bark) = true; # inform the dog that it ought to know how
to bark, without telling it how, yet; equivalent to a literal =
method { ... }.
  Dog.can(bark) = false; # tell the dog to forget how to bark.
  Dog.can(bark) = undef; # Ditto.

(Doing this to Dog DWIMs to modifying the behavior of all dogs at once
- you're declaring that dogs can bark or this is how dogs bark,
whereas doing it to $spot DWIMs to modifying the behavior of $spot
only: $brutus.can('bark') = false: my best friend's pet dog seems to
have lost the capacity to bark in its old age; that doesn't mean that
dogs in general can't bark.)

Similar things might be done with .has (for attributes), .isa (for
superclasses), and .does (for roles).

--
Jonathan Dataweaver Lang


Re: overloading the variable declaration process

2006-02-09 Thread Stevan Little
On 2/9/06, Jonathan Lang [EMAIL PROTECTED] wrote:
 Stevan Little wrote:
  Jonathan Lang wrote:
   OK.  To help me get a better idea about what's going on here, what
   sorts of attributes and methods would ^Dog have?
 
  Well, a metaclass describes the behaviors and attributes of a class,
  and ^Dog is an *instance* of the metaclass. So actually ^Dog would not
  actually have attributes and methods since it is an instance.

 Huh?  A dog can bark; so the Dog class should have a method called
 'bark'.  Or does 'can' not mean what it seems to mean?

^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the
class (actually it's a prototypical instance of the class which the
metaclass ^Dog describes, but you dont really need to know that to use
it).

  ^Dog.can(bark) # false
  Dog.can(bark) # true

This is a very important distinction. Saying Dog class has a method
called 'bark', implies the following statements are true

- Dog will respond to the method called bark.

- Given my Dog $spot, $spot will respond to the method called bark.

- ^Dog (the metaclass instance which describes a class called Dog)
does *not* respond to the method called bark.

- ^Dog (since it describes the class called Dog) manages all of the
methods which Dog and $spot will respond too, one of which is called
bark.

There is a clear line between the meta-level (where ^Dog lives) and
the user-level (where Dog and $spot) live. This is a line which is
heavily blurred in Perl 5, and in many OO languages (aside from
Smalltalk, CLOS and a few others) the meta-level is just not
accessible at all from user-land.

  That said, I think ^Dog would probably respond to methods like
  these (some of which are described in S12):

 OK; apparently, what I meant when I asked what methods and attributes
 does ^Dog have? is what you're talking about when you speak of which
 methods ^Dog will respond to.  To me, an object has whatever methods
 that it responds to.

I disagree, an object is an instance of a class. A class has the
methods that the object will respond too. You would not want to store
all the methods in each instance, it would not make sense. Each
instance needs to share a set of methods, and those methods are stored
in the class.

Well what is a class?

In Perl 5 a class is simply a package, and the subs in that package
are methods. In Perl 6 however, a class will be an instance of another
class, the MetaClass. These two things are really not that different
when you think about it.

- A Perl 5 package holds methods for you by storing them in the symbol
table. You can add, get, remove these methods from the symbol table
using the symbol table API.

- A Perl 6 class holds methods for you by storing them inside an
instance variable in an instance of the MetaClass, and you can add,
get, remove these methods by using the methods of MetaClass.

Of course you have a conceptual circulatiry issue now because well,..
what is a MetaClass? Well it could be an instance of a MetaMetaClass,
but what is that an instance of? This could go on forever (turtles all
the way down as it is sometimes called).

But in practice you either just stop and say this is as far as it
goes,  or you bootstrap your class model somehow and tie the knot.
I prefer the boostrapping as it is much more elegant and tends to
allow for much more flexibility.

^Dog.name # Dog
^Dog.version # 0.0.1 (or something similiar of course)
^Dog.authority  # cpan:LWALL or email:[EMAIL PROTECTED]
 
^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL

 Would it be valid to speak of ^$spot?  If so, what would ^$spot.name be?

There is no such thing as a ^$spot. The ^ is the class sigil, and
will hold metaclass instances only, just as variables with  % will
only holds hashes, and variables with @ will only holds arrays, etc.

  I would like to see some methods like this:
 
# dynamically add a method that
# Dog and $spot would respond to
^Dog.add_method(bark = method () { ... });
 
  Which would be like doing this in Perl 5:
 
no strict 'refs';
*{'Dog::bark'} = sub { ... };

 IIRC, you can always create a new method for a class, even outside of
 its definition, simply by ensuring that the first parameter to be
 passed in will be an object of that type:

   method bark (Dog $_) { ... }

I don't think this is true unless it is a multi method, in which case
it is not actually a method of the of the class, but instead just
DWIMs because of MMD and the fact we allow an invocant calling style
freely.

 or maybe

   method Dog.bark () { ... }

Yes that works too. But TIMTOWTDI, and each has it's own benefits.
Your above approach works fine while you are writing the code, but is
not as useful for dynamically adding a method at runtime (unless you
use eval(), but that gets ugly). Using the metaclass API dynamically
adding a method to a class at runtime is trivial, again, think of it
as being no different that doing this in Perl 5:

# deep within a function 

Re: overloading the variable declaration process

2006-02-09 Thread Jonathan Lang
Stevan Little wrote:
 Jonathan Lang wrote:
  OK; apparently, what I meant when I asked what methods and attributes
  does ^Dog have? is what you're talking about when you speak of which
  methods ^Dog will respond to.  To me, an object has whatever methods
  that it responds to.

 I disagree, an object is an instance of a class. A class has the
 methods that the object will respond too. You would not want to store
 all the methods in each instance, it would not make sense. Each
 instance needs to share a set of methods, and those methods are stored
 in the class.

I think that we're talking past each other: you're trying to educate
me on how a programmer should think about objects and classes; I'm
trying to figure out how a non-programmer thinks of them.

To non-programmers (and amateur programmers), objects aren't instances
of classes; classes are categories of related objects.  Objects have
behaviors and characteristics; classes are a convenient shorthand for
describing behaviors and characteristics common to a set.  Objects
come first, while classes are thought of in the context of objects. 
The same implementation can be used for both perspectives: dogs can
bark; Spot is a dog; therefore, Spot can bark is a form of reasoning
that underlies using the class-and-instance model for the back-end
implementation of the object-and-category paradigm.

classes have methods; objects respond to them is part of the
classes-and-instances paradigm; but that isn't really how people
think.

In terms of practical differences: under the classes-and-instances
paradigm, if you want to create an object whose behavior differs
slightly from a given class, you need to create a subclass that has
the desired behavior and to create the object as an instance of that
subclass.  With the object-and-category paradigm, there's nothing that
insists that every object's behavior must conform precisely to the
behaviors described by its classes; the latter are merely rules of
thumb to apply to the former until you learn differently, and
behaviors can be added, removed, or tweaked on an individual basis. 
This is why (last I checked) but creates a behind-the-scenes
'singleton' subclass for the new object instead of demanding that a
new subclass be explicitly created, and why I suggested the
possibility of adding, replacing, or removing methods for individual
objects as well as for classes (which, presumably, would also be
implemented under the hood by replacing the object's class by a
'singleton' subclass).

 ^Dog.name # Dog
 ^Dog.version # 0.0.1 (or something similiar of course)
 ^Dog.authority  # cpan:LWALL or email:[EMAIL PROTECTED]
  
 ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL
 
  Would it be valid to speak of ^$spot?  If so, what would ^$spot.name be?

 There is no such thing as a ^$spot.

OK.  The only reason I was thinking in those terms was because of the
possibility that $spot might be based on one of those
behind-the-scenes customized subclasses that I mentioned earlier: if

  my Dog $brutus but cannot(bark);

How do you access the subclass of Dog that $brutus is the instance of?

  IIRC, you can always create a new method for a class, even outside of
  its definition, simply by ensuring that the first parameter to be
  passed in will be an object of that type:
 
method bark (Dog $_) { ... }

 I don't think this is true unless it is a multi method, in which case
 it is not actually a method of the of the class, but instead just
 DWIMs because of MMD and the fact we allow an invocant calling style
 freely.

I was under the impression that the distinction between a method and a
multi-method was how many of the parameters get used to dispatch:
methods aren't really owned by classes, any more than class
definition is a declarative process; it just looks that way on the
surface.  Am I wrong about this?

  or maybe
 
method Dog.bark () { ... }

 Yes that works too. But TIMTOWTDI, and each has it's own benefits.

I'm aware of that, and was proposing this as Another Way.

 Your above approach works fine while you are writing the code, but is
 not as useful for dynamically adding a method at runtime (unless you
 use eval(), but that gets ugly).

I was under the impression that class definition was fundamentally a
functional process dressed up as a declarative process.  method
Dog.bark () { ... } would seem to me to be a means of continuing that
process after the fact - that is, adding a method to a class after
you've left the class definition block.  It seems to serve exactly the
same purpose as using the metaclass API.  That is, I see it as being
alternate syntax for ^Dog.add_method(bark = method () { ... }).

  To fetch a method, why not have .can() return a reference to the
  method upon success? I might even go so far as to treat can() as an
  lvalue, using the assignment of a coderef as an alternate way of
  adding or changing the object's behavior on the fly:
 
method bark (Dog $_:) { ... 

Re: overloading the variable declaration process

2006-02-08 Thread Matt Fowles
Stevan~

On 2/7/06, Stevan Little [EMAIL PROTECTED] wrote:

  After all Foo is just a specific instance of the class Class.

 Shhh... class objects don't exist ... I was never here,... I will I
 count to three and when I snap my fingers you will awaken and will
 have forgotten all about class Class.

 1 ... 2 ... 3 ... *snap*

... What!?!?  Where was I?  Oh, yeah.  As I was saying, I think we
just take C++'s object system exactly.

Matt
--
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


Re: overloading the variable declaration process

2006-02-08 Thread Larry Wall
On Tue, Feb 07, 2006 at 07:32:18PM -0500, Stevan Little wrote:
: On 2/7/06, Matt Fowles [EMAIL PROTECTED] wrote:
:  Stevan~
: 
:  I am going to assume that you intended to reply to perl 6 language,
:  and thus will include your post in its entirety in my response.
: 
: Yes, sorry... I missed the reply to all button on the gmail UI by a
: few pixels I guess. Thank you for forwarding.
: 
:  Now that everyone is on the same page, I will go about responding
: 
: 
: # snip some code 
: 
:  
:   class Pipe::Stem {
:  has $composed_of;
:  has $color;
:  has $length;
:  has $filter = bool::false;
:   }
: 
:  so far I am mostly with you, except one question.  Does has $filter =
:  bool::false; just provide a default?
: 
: Yes, that is a default value. I assume that most Pipe smokers don't
: like filters in their pipes, I might be wrong on that one because I am
: not a pipe smoker :)
: 
:   You would then model the different pipes you sell;
:  
:   class MagrittePipe {
:   has $stem = Pipe::Stem.new(
::composed_ofebony,
::colorblack,
::lengthshort
:);
:   has $bowl = Pipe::Bowl.new(
::composed_ofmahogany,
::colorbrown,
::sizemedium
:);
:   }
:  
:   Now, you might say, why not make the MagrittePipe an instance of Pipe,
:   and give the Pipe class a few more attributes, like a name. Well, if
:   you did that then you couldn't subclass it of course.
: 
:  Actually, I was going to ask why not make MagrittePipe inherit from Pipe.
: 
: Ooops, forgot that part it should infact inherit from Pipe. And of
: course you can do that dynamically with the metamodel ;)
: 
:   Well, using introspection, it becomes very simple to discover various
:   qualities about your inventory, enough to probably even autogenerate
:   the HTML pages for your online-web store (powered by Perl 6 of
:   course). And lets not forget the uber-cool Perl 6 Object Database
:   which you are using to store your real-time inventory in (all
:   metamodel powered of course). And of course if you want, you can use
:   the DistributedObjectProxy metaclass which will automatically make
:   your objects distributed so that your door-to-door Pipe saleforce can
:   update your inventory in real time from their cellphones. And your RD
:   department can use the built-in (but as yet unspeced) logic
:   programming features of Perl 6 to mine your customer information from
:   your (previously mentioend) object database and genetically grow
:   new, more desireable Pipe products (which is easy to do since your
:   metaclasses are programatically composable (and no I don't mean eval
:   $code)).
: 
:  I think you mis-understand me.  I do not question the value of a
:  powerful meta-model.  Quite the contrary I want to see Perl 6 have a
:  meta-model more powerful and accessible then CLOS.  I see it as a
:  necessity for a language that plans to truely scale in the future.
: 
:  What I do question is the usefullness of having bare class names
:  represent these prototype objects.  I just don't really understand
:  what they are for or do.
: 
: Well, to be totally honest, I think only Larry truely understands
: their usage, but to the best of my understanding they are intented to
: serve a number of roles;
: 
: (Larry, please correct me if I am wrong here)
: 
: - to allow for introspection of the class.
: 
: After all ^Foo.can() is really just a series of method calls to the
: Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to
: type!!
: 
: - provide an invocant for class methods.
: 
: Larry does not like the class-method/instance-method distinction (in
: fact it seems he doesn't even like the class/instance distinction
: either), and has declared that a class method is really just a
: method of the class which does not access any instance attributes.
: Well, this complicates the type signature of the invocant, and we need
: an invocant that the type-checker can check.
: 
: In Perl 5, classes were just package names which were just strings.
: This will not work in Perl 6 in the presence of a reasonably decent
: type checker, the class needs to be *something*. Now Larry has also
: declared  that he does not like the idea of a class object, I think
: this is because that means that a properly typed method signature for
: a class method would look like this:
: 
: class Foo {
: method foo (Class $class:) {
: say I am a class method, and proud of it;
: }
: }
: 
: According to the signature, this method takes any Class instance as an
: invocant. Well
: thats just not right because it should only accept the Class instance
: which represents the Foo class. But we can't (at least I dont think we
: can) be that specific, at least not easily enough to also allow this
: method 

Re: overloading the variable declaration process

2006-02-08 Thread Jonathan Lang
Consider my Dog $spot.  From the Perl6-to-English Dictionary:
  Dog: a dog.
  $spot: the dog that is named Spot.
  ^Dog: the concept of a dog.

Am I understanding things correctly?

If so, here's what I'd expect: a dog can bark, or Spot can bark; but
the concept of a dog cannot bark:
  can Dog bark; # answer: yes
  can $spot bark; # answer: yes
  can ^Dog bark; # answer: no

--
Jonathan Dataweaver Lang


Re: overloading the variable declaration process

2006-02-08 Thread Stevan Little
On 2/8/06, Jonathan Lang [EMAIL PROTECTED] wrote:
 Consider my Dog $spot.  From the Perl6-to-English Dictionary:
   Dog: a dog.
   $spot: the dog that is named Spot.
   ^Dog: the concept of a dog.

 Am I understanding things correctly?

 If so, here's what I'd expect: a dog can bark, or Spot can bark; but
 the concept of a dog cannot bark:
   can Dog bark; # answer: yes
   can $spot bark; # answer: yes
   can ^Dog bark; # answer: no

Yes, that is correct, because:

Dog.isa(Dog)  # true
$spot.isa(Dog)  # true
^Dog.isa(Dog)  # false

In fact ^Dog isa MetaClass (or Class whatever you want to call it).

At least that is how I see/understand it.

Stevan


Re: overloading the variable declaration process

2006-02-08 Thread Jonathan Lang
Stevan Little wrote:
 Yes, that is correct, because:

 Dog.isa(Dog)  # true
 $spot.isa(Dog)  # true
 ^Dog.isa(Dog)  # false

 In fact ^Dog isa MetaClass (or Class whatever you want to call it).

 At least that is how I see/understand it.

OK.  To help me get a better idea about what's going on here, what
sorts of attributes and methods would ^Dog have?

--
Jonathan Dataweaver Lang


Re: overloading the variable declaration process

2006-02-07 Thread Ashley Winters
On 2/6/06, Larry Wall [EMAIL PROTECTED] wrote:
 So the basic answer to you question is, I think, yes.  If Dog chooses
 to always return true for .defined, then (in Haskell terms) it's more
 like a Just type than a Maybe type.  Perl 6's objects like to be Maybe
 types by default, but you can override it.  (I'm using the Haskell
 terms loosely here, of course.)  But the very concept of definedness
 is getting mushy in Perl 6.  What we need is more concepts of the
 form Is this *sufficiently* defined for what I want to do with it?
 That's why I proposed defined according to a particular role as
 one way to ask that sort of question.

So, if ^Dog describes a Dog which defines a $dog, do we need an
undescribed() function?

Just kidding... kinda.

Ashley Winters


Re: overloading the variable declaration process

2006-02-07 Thread Larry Wall
On Mon, Feb 06, 2006 at 10:41:02PM -0500, Matt Fowles wrote:
: Larry~
: 
: On 2/6/06, Larry Wall [EMAIL PROTECTED] wrote:
:  This is mostly motivated by linguistics rather than computer science,
:  insofar as types/classes/roles in natural language are normally
:  represented by generic objects rather than meta objects.  When I
:  ask in English:
: 
:  Can a dog bark?
: 
:  that's equivalent to asking in Perl 6:
: 
:  Dog.can('bark')
: 
: Or you might think of it more as a question like Can the ideal of a
: dog bark?  the answer to which is of course No, it doesn't exist..

As soon as you say the ideal you've chosen Platonism over
Aristotelianism.  :-)

: Perhaps, I am just too firmly rooted in old paradigms but I think it
: is very important not to conflate the representation of a thing with
: the thing.
: 
: http://en.wikipedia.org/wiki/Image:MagrittePipe.jpg

Indeed, and the modeling point of view is that $pipe is *also* just
a representation of the Pipe.  Neither Pipe nor $pipe is the thing
itself.  Most computer programs are about Something Else, so computer
languages should be optimized for talking about other things rather
than talking about themselves.  The answer to

Pipe.can(Smoke)
$pipe.can(Smoke)

should be the same, not different.  On the other hand,

^Pipe.can(Smoke)

is a different matter, insofar as you're asking a question about a Class
object rather than a Pipe object.  And now you get your Platonism back.
You just have to be explicit about it.

Larry


Re: overloading the variable declaration process

2006-02-07 Thread Matt Fowles
Larry~

On 2/7/06, Larry Wall [EMAIL PROTECTED] wrote:

 Indeed, and the modeling point of view is that $pipe is *also* just
 a representation of the Pipe.  Neither Pipe nor $pipe is the thing
 itself.  Most computer programs are about Something Else, so computer
 languages should be optimized for talking about other things rather
 than talking about themselves.  The answer to

 Pipe.can(Smoke)
 $pipe.can(Smoke)

 should be the same, not different.  On the other hand,

 ^Pipe.can(Smoke)

 is a different matter, insofar as you're asking a question about a Class
 object rather than a Pipe object.  And now you get your Platonism back.
 You just have to be explicit about it.

I see the value of ^Pipe and $pipe as seperate objects which can be
manipulated programmatically.  What I don't really understand is what
exactly Pipe is and where it would be useful.

They way you have described Pipe feels a little muddy to me and I am
unsure about its purpose and semantics.  Is it just an object I ask
`.can()` or does it have some deeper usefulness?

Matt
--
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


Re: overloading the variable declaration process

2006-02-07 Thread Matt Fowles
Stevan~

I am going to assume that you intended to reply to perl 6 language,
and thus will include your post in its entirety in my response.

On 2/7/06, Stevan Little [EMAIL PROTECTED] wrote:
 On 2/7/06, Matt Fowles [EMAIL PROTECTED] wrote:
  Larry~
 
  On 2/7/06, Larry Wall [EMAIL PROTECTED] wrote:
  
   Indeed, and the modeling point of view is that $pipe is *also* just
   a representation of the Pipe.  Neither Pipe nor $pipe is the thing
   itself.  Most computer programs are about Something Else, so computer
   languages should be optimized for talking about other things rather
   than talking about themselves.  The answer to
  
   Pipe.can(Smoke)
   $pipe.can(Smoke)
  
   should be the same, not different.  On the other hand,
  
   ^Pipe.can(Smoke)
  
   is a different matter, insofar as you're asking a question about a Class
   object rather than a Pipe object.  And now you get your Platonism back.
   You just have to be explicit about it.
 
  I see the value of ^Pipe and $pipe as seperate objects which can be
  manipulated programmatically.  What I don't really understand is what
  exactly Pipe is and where it would be useful.
 
  They way you have described Pipe feels a little muddy to me and I am
  unsure about its purpose and semantics.  Is it just an object I ask
  `.can()` or does it have some deeper usefulness?

 Well since ^Pipe will really just be the same value as Pipe.meta, then
 you can do many things with it (if I get my metamodel wishes that is).
  Now, in keeping with the examples of useful things for people other
 than programmers and computers spirit of this discussion, here is one
 possible approach to using metaclasses in a constructive way.

 Okay, so lets assume you own a tobacco shop, and you have modeled a
 Pipe hierarchy to represent all the pipes you sell. Your base classes
 might look something like this:

 class Pipe {
 has $stem;
 has $bowl;
 }

 class Pipe::Bowl {
has $composed_of;
has $color;
has $size;
 }

 class Pipe::Stem {
has $composed_of;
has $color;
has $length;
has $filter = bool::false;
 }

 You would then model the different pipes you sell;

 class MagrittePipe {
 has $stem = Pipe::Stem.new(
  :composed_ofebony,
  :colorblack,
  :lengthshort
  );
 has $bowl = Pipe::Bowl.new(
  :composed_ofmahogany,
  :colorbrown,
  :sizemedium
  );
 }

 Now, you might say, why not make the MagrittePipe an instance of Pipe,
 and give the Pipe class a few more attributes, like a name. Well, if
 you did that then you couldn't subclass it of course.

 class MagrittePipe::SpecialEngravedAnniversayEdition {
  is MagrittePipe;
  does Engraved[$engraving_text = Ceci n'est pas une pipe];
  does SpecialEdition[$typeAnniversay];
 }

 Now, what does all this have to do with metamodel?

 Well, using introspection, it becomes very simple to discover various
 qualities about your inventory, enough to probably even autogenerate
 the HTML pages for your online-web store (powered by Perl 6 of
 course). And lets not forget the uber-cool Perl 6 Object Database
 which you are using to store your real-time inventory in (all
 metamodel powered of course). And of course if you want, you can use
 the DistributedObjectProxy metaclass which will automatically make
 your objects distributed so that your door-to-door Pipe saleforce can
 update your inventory in real time from their cellphones. And your RD
 department can use the built-in (but as yet unspeced) logic
 programming features of Perl 6 to mine your customer information from
 your (previously mentioend) object database and genetically grow
 new, more desireable Pipe products (which is easy to do since your
 metaclasses are programatically composable (and no I don't mean eval
 $code)).

 Of course, I am just dreaming here, but  maybe I am not! Most of
 this is already possible using CLOS (see the Franz's AllegroCL 8.0
 it's bad*ss IMO), so why can't we have it?

 Anyway, I hope that doesn't make your head hurt too much Matt ;)

Now that everyone is on the same page, I will go about responding

 class Pipe {
 has $stem;
 has $bowl;
 }

 class Pipe::Bowl {
has $composed_of;
has $color;
has $size;
 }

 class Pipe::Stem {
has $composed_of;
has $color;
has $length;
has $filter = bool::false;
 }

so far I am mostly with you, except one question.  Does has $filter =
bool::false; just provide a default?


 You would then model the different pipes you sell;

 class MagrittePipe {
 has $stem = Pipe::Stem.new(
  :composed_ofebony,
  :colorblack,
  :lengthshort
  );
 has $bowl = Pipe::Bowl.new(
  

Re: overloading the variable declaration process

2006-02-07 Thread Stevan Little
On 2/7/06, Matt Fowles [EMAIL PROTECTED] wrote:
 Stevan~

 I am going to assume that you intended to reply to perl 6 language,
 and thus will include your post in its entirety in my response.

Yes, sorry... I missed the reply to all button on the gmail UI by a
few pixels I guess. Thank you for forwarding.

 Now that everyone is on the same page, I will go about responding


# snip some code 

 
  class Pipe::Stem {
 has $composed_of;
 has $color;
 has $length;
 has $filter = bool::false;
  }

 so far I am mostly with you, except one question.  Does has $filter =
 bool::false; just provide a default?

Yes, that is a default value. I assume that most Pipe smokers don't
like filters in their pipes, I might be wrong on that one because I am
not a pipe smoker :)

  You would then model the different pipes you sell;
 
  class MagrittePipe {
  has $stem = Pipe::Stem.new(
   :composed_ofebony,
   :colorblack,
   :lengthshort
   );
  has $bowl = Pipe::Bowl.new(
   :composed_ofmahogany,
   :colorbrown,
   :sizemedium
   );
  }
 
  Now, you might say, why not make the MagrittePipe an instance of Pipe,
  and give the Pipe class a few more attributes, like a name. Well, if
  you did that then you couldn't subclass it of course.

 Actually, I was going to ask why not make MagrittePipe inherit from Pipe.

Ooops, forgot that part it should infact inherit from Pipe. And of
course you can do that dynamically with the metamodel ;)

  Well, using introspection, it becomes very simple to discover various
  qualities about your inventory, enough to probably even autogenerate
  the HTML pages for your online-web store (powered by Perl 6 of
  course). And lets not forget the uber-cool Perl 6 Object Database
  which you are using to store your real-time inventory in (all
  metamodel powered of course). And of course if you want, you can use
  the DistributedObjectProxy metaclass which will automatically make
  your objects distributed so that your door-to-door Pipe saleforce can
  update your inventory in real time from their cellphones. And your RD
  department can use the built-in (but as yet unspeced) logic
  programming features of Perl 6 to mine your customer information from
  your (previously mentioend) object database and genetically grow
  new, more desireable Pipe products (which is easy to do since your
  metaclasses are programatically composable (and no I don't mean eval
  $code)).

 I think you mis-understand me.  I do not question the value of a
 powerful meta-model.  Quite the contrary I want to see Perl 6 have a
 meta-model more powerful and accessible then CLOS.  I see it as a
 necessity for a language that plans to truely scale in the future.

 What I do question is the usefullness of having bare class names
 represent these prototype objects.  I just don't really understand
 what they are for or do.

Well, to be totally honest, I think only Larry truely understands
their usage, but to the best of my understanding they are intented to
serve a number of roles;

(Larry, please correct me if I am wrong here)

- to allow for introspection of the class.

After all ^Foo.can() is really just a series of method calls to the
Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to
type!!

- provide an invocant for class methods.

Larry does not like the class-method/instance-method distinction (in
fact it seems he doesn't even like the class/instance distinction
either), and has declared that a class method is really just a
method of the class which does not access any instance attributes.
Well, this complicates the type signature of the invocant, and we need
an invocant that the type-checker can check.

In Perl 5, classes were just package names which were just strings.
This will not work in Perl 6 in the presence of a reasonably decent
type checker, the class needs to be *something*. Now Larry has also
declared  that he does not like the idea of a class object, I think
this is because that means that a properly typed method signature for
a class method would look like this:

class Foo {
method foo (Class $class:) {
say I am a class method, and proud of it;
}
}

According to the signature, this method takes any Class instance as an
invocant. Well
thats just not right because it should only accept the Class instance
which represents the Foo class. But we can't (at least I dont think we
can) be that specific, at least not easily enough to also allow this
method to be called by an instance of Foo as well.

So, the solution,  use prototype instances for class objects. So
now we can properly type our class method for both Foo and $foo like
this:

class Foo {
method foo (Foo $class:) {
say I am a class method, and proud of it;
}
}

And whalla, 

Re: overloading the variable declaration process

2006-02-07 Thread Matt Fowles
Stevan~

On 2/7/06, Stevan Little [EMAIL PROTECTED] wrote:

 Well, to be totally honest, I think only Larry truely understands
 their usage, but to the best of my understanding they are intented to
 serve a number of roles;

I agree with you about that, which is part of what bothers me.


 (Larry, please correct me if I am wrong here)

 - to allow for introspection of the class.

 After all ^Foo.can() is really just a series of method calls to the
 Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to
 type!!

 - provide an invocant for class methods.

 Larry does not like the class-method/instance-method distinction (in
 fact it seems he doesn't even like the class/instance distinction
 either), and has declared that a class method is really just a
 method of the class which does not access any instance attributes.
 Well, this complicates the type signature of the invocant, and we need
 an invocant that the type-checker can check.

 In Perl 5, classes were just package names which were just strings.
 This will not work in Perl 6 in the presence of a reasonably decent
 type checker, the class needs to be *something*. Now Larry has also
 declared  that he does not like the idea of a class object, I think
 this is because that means that a properly typed method signature for
 a class method would look like this:

 class Foo {
 method foo (Class $class:) {
 say I am a class method, and proud of it;
 }
 }

 According to the signature, this method takes any Class instance as an
 invocant. Well
 thats just not right because it should only accept the Class instance
 which represents the Foo class. But we can't (at least I dont think we
 can) be that specific, at least not easily enough to also allow this
 method to be called by an instance of Foo as well.

 So, the solution,  use prototype instances for class objects. So
 now we can properly type our class method for both Foo and $foo like
 this:

 class Foo {
 method foo (Foo $class:) {
 say I am a class method, and proud of it;
 }
 }

 And whalla, we have a class/instance method ala Perl 5 and it is
 properly type checkable too.

 Of course I might be totally wrong here, but this is my best grasp on
 the subject.

Perl 6 allows dispatch on value (if I am not mistaken).  Thus, just as we have a

sub fact( Int 0 ) { return 0; }
sub fact( Int $n ) { return $n * fact($n-1); }

Why not have class methods take the form

class Foo {
method foo (Class Foo) {
say I am a class method, and proud of it;
}
}

They are still well types (I think), and properly restricts the types
allowed for foo.  After all Foo is just a specific instance of the
class Class.

Matt
--
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


Re: overloading the variable declaration process

2006-02-06 Thread Larry Wall
On Sun, Feb 05, 2006 at 07:26:09PM -0800, Darren Duncan wrote:
: Part way through writing this, I had a brief chat on #perl6 with 
: stevan (and apparently the meta-model is still quite in flux) and he 
: said my question was related to Larry's class but undef idea, and 
: that Larry should talk more about the subject.

Aside from the fact that it's not a class, and not necessarily undef,
class but undef is a good name for it.  :-)

I've been calling them prototype objects lately for lack of a
better word.  To me, the Real Class is the object instance hiding
behind .meta.  But when you say bare Foo you actually naming a
generic object of the type ^Foo, which I see currently as shorthand
for Foo.meta, and which any object that does Foo can get at if it
needs metadata, including the Foo object itself.  In short,

Foo.does('Foo')

This is mostly motivated by linguistics rather than computer science,
insofar as types/classes/roles in natural language are normally
represented by generic objects rather than meta objects.  When I
ask in English:

Can a dog bark?

that's equivalent to asking in Perl 6:

Dog.can('bark')

The Dog there is in the same type category as $dog, and specifically
is *not* in the same type category as the class that is managing
the logic behind the scenes.  As a user, I'm thinking about doggy
objects, not classy objects.  It's the very same kind of linguistic
reasoning that gives us given rather than switch, and when rather
than case.  People want to think about their problem's objects,
not the language implementor's representations of those objects.

Now in the case of .can, we do eventually end up asking the metaobject
whether this objects supports the .bark method, but the point is that
the user doesn't have to keep track of how many metas there are.
Or looking at it the other way, any object can stand in for all its
meta objects.  This is how we think (I think).

Psycholinguistially, every dog object in your brain is really a
kind of partially instantiated object that is slowly being filled in
with knowledge about the real world counterpart to your mental model.
Your mental model is never perfect.

The trend in the world today is away from monolithic computers that
either know everything or nothing, and toward programs that have
to work with imperfect knowledge that is generated or downloaded on
the fly.  So I think the modeling view of reality is the sweet spot
for the future, and languages that have to know everything before
they think they know anything are doomed to fail.  Well, not fail,
but have restricted ecological niches, such as rocket science.
(And maybe not even there, as machines get more autonomous.)

So the basic answer to you question is, I think, yes.  If Dog chooses
to always return true for .defined, then (in Haskell terms) it's more
like a Just type than a Maybe type.  Perl 6's objects like to be Maybe
types by default, but you can override it.  (I'm using the Haskell
terms loosely here, of course.)  But the very concept of definedness
is getting mushy in Perl 6.  What we need is more concepts of the
form Is this *sufficiently* defined for what I want to do with it?
That's why I proposed defined according to a particular role as
one way to ask that sort of question.

Hope this helps.

Larry


Re: overloading the variable declaration process

2006-02-06 Thread Darren Duncan

At 3:02 PM +0800 2/6/06, Audrey Tang wrote:

On 2/6/06, Darren Duncan [EMAIL PROTECTED] wrote:

 Speaking briefly, I would like it if Perl 6 provided a way for a
 class (or role, or meta-class, etc) to declare that all variables
 declared to be of that type are automatically/implicitly set to a
 particular value at declaration time, so that they are not undefined

  if the programmer using them doesn't explicitly set a value.

If so, your use case can be satisfied by declaring that ::NumType (the
class object)
numifies to 0, and ::StrType stringifies to , via the coerceas form.


That could be fine for some situations, but I was looking for a more 
generic solution for:


  my FooType $foo; # acts like we said .= new()
  $foo.do_action();

Essentially, that $foo is like or is a fully instantiated object on 
which you can call arbitrary FooType object methods as if someone set 
it with new(), but where in fact the user never did this.


The coercing solution won't work if the types of use are not 
coersions to simple data types like strings or numbers.


Thank you. -- Darren Duncan


Re: overloading the variable declaration process

2006-02-06 Thread Luke Palmer
On 2/6/06, Larry Wall [EMAIL PROTECTED] wrote:
 This is mostly motivated by linguistics rather than computer science,
 insofar as types/classes/roles in natural language are normally
 represented by generic objects rather than meta objects.  When I
 ask in English:

 Can a dog bark?

 that's equivalent to asking in Perl 6:

 Dog.can('bark')

That sentence is ambiguous.  You can interpret it as:

Can some dog bark?

Or as:

Can every dog bark?

I think you meant the latter, however the sentence is leaning toward
the former.  Can dogs bark? would be less ambiguous in that respect.

And while I'm starting to see the linguistic rationale behind this
decision, I still can't find anything concrete that this buys us. 
Call me an American, but I like instant gratification.

Luke


Re: overloading the variable declaration process

2006-02-06 Thread Matt Fowles
Larry~

On 2/6/06, Larry Wall [EMAIL PROTECTED] wrote:
 This is mostly motivated by linguistics rather than computer science,
 insofar as types/classes/roles in natural language are normally
 represented by generic objects rather than meta objects.  When I
 ask in English:

 Can a dog bark?

 that's equivalent to asking in Perl 6:

 Dog.can('bark')

Or you might think of it more as a question like Can the ideal of a
dog bark?  the answer to which is of course No, it doesn't exist..

Perhaps, I am just too firmly rooted in old paradigms but I think it
is very important not to conflate the representation of a thing with
the thing.

http://en.wikipedia.org/wiki/Image:MagrittePipe.jpg

Matt
--
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


overloading the variable declaration process

2006-02-05 Thread Darren Duncan

All,

Speaking briefly, I would like it if Perl 6 provided a way for a 
class (or role, or meta-class, etc) to declare that all variables 
declared to be of that type are automatically/implicitly set to a 
particular value at declaration time, so that they are not undefined 
if the programmer using them doesn't explicitly set a value.


Here are usage examples:

  my NumType $foo; # implicitly contains a defined NumType of value 0
  my StrType $bar; # implicitly contains a defined StrType of value ''

Sure, the user could say .= new() or such, but I wanted a fallback 
if they didn't do that.


Then when they come to just use that not explicitly set variable, it 
contains some type-defined reasonable default value.


Presumably, the object meta-model would have an appropriate function 
defined for use at that time, which returns undef by default, and 
this function is what individual classes can override.


Part way through writing this, I had a brief chat on #perl6 with 
stevan (and apparently the meta-model is still quite in flux) and he 
said my question was related to Larry's class but undef idea, and 
that Larry should talk more about the subject.


Thank you. -- Darren Duncan


Re: overloading the variable declaration process

2006-02-05 Thread Audrey Tang
On 2/6/06, Darren Duncan [EMAIL PROTECTED] wrote:
 Speaking briefly, I would like it if Perl 6 provided a way for a
 class (or role, or meta-class, etc) to declare that all variables
 declared to be of that type are automatically/implicitly set to a
 particular value at declaration time, so that they are not undefined
 if the programmer using them doesn't explicitly set a value.

In a somewhat related note, Perl 6 allows this form:

my Dog $fido .= new;

which may be treated as a special form (as is currently the case with Pugs).
However if it's not, it would desugar to:

my Dog $fido;
$fido = $fido.new;

which seem to imply that $fido is set to ::Dog (the dog class) as its
initial value.
However, that would potentially make this a no-op:

my Dog $fido = Dog;

which may make sense except that defined($fido) may need to be regulated
as true even for the my Dog $fido case.

If so, your use case can be satisfied by declaring that ::NumType (the
class object)
numifies to 0, and ::StrType stringifies to , via the coerceas form.

Audrey


Method overloading, MMD/SMD

2005-05-27 Thread Yuval Kogman
In Synopsis 13 MMD is discussed as the mechanism for overloading an
operator.

Many a times I would like to overload a method of a class.

I just played around with this:

http://svn.openfoundry.org/pugs/modules/Class-Events/lib/Class/Events.pm

Notice how the Named event variation appends the role, adding some
more specific signatures to familiar functions, to increase
dwimmery.

How do i get this to behave?

Do I need to say all the methods that can ever be overloaded are
multi? Or do I say that only the overloading ones are multi? If the
first - how do I get a delegation to be multi? Does that rely on the
delegation handler method?

Also, is SMD not possibly representable in MMD? Is SMD a subset of
MMD or a completely different system?

Also on a side note, say I have two roles, both of which define the
private attribute $.:horse. Do these attributes conflict, or does
each role get it's own slot? What about MI/mixins?

Grazie

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me tips over a cow: neeyah!!



pgpY3osGEiO6Z.pgp
Description: PGP signature


Re: A6: overloading multis on constness of parameters

2003-03-14 Thread Larry Wall
On Fri, Mar 14, 2003 at 01:45:56PM +1100, Damian Conway wrote:
: Oh, and I was wrong to originally write: Cmulti *isa ...

Sorry, you're not even wrong.  :-)

: Multimethods live in their own namespace. No * required.

Alternately, we require the C* in order to accurately document
their scope.  And I do think they live in C*.  Otherwise we need to
come up with yet another name for the global scope that happens to
contain multimethods.  An argument can also be made that we should
do that anyway on the grounds that we might someday have scoped
multi-methods of some kind or other.

I suppose can allow a Csub * in the same scope as Cmulti * for
the case that you want a global override of all the multimethods.
It just looks for the sub first.  If that sub then wants to redispatch
to the multimethods, it'd have to use some special multimethod syntax
that doesn't look like a sub invocation, such as the notional

($a,$b,$c) forwhich foo() 

we talked about in Sebastopol, however we end up spelling forwhich.
It's really a kind of postpositional topicalizer for the following
predicate.  English doesn't really have any good ones of those.
If I were Japanese, I'd spell it wa or ga or no.

Well, okay, I'd actually spell it  or  or  if I were
*really* Japanese.  :-)

Larry


Re: A6: Assignment Overloading

2003-03-14 Thread Larry Wall
On Fri, Mar 14, 2003 at 01:20:28PM +1100, Damian Conway wrote:
: Luke Palmer wrote:
: 
: So, now that we have binding, is it possible to overload the
: assignment operator?  
: 
: Not really. The problem is that Cinfix:= is really an operator on 
: *containers*, not on *values*. So, in order to overload C=, you'll still 
: need to define an appropriate CSTORE method on the appropriate 
: implementation class for the container. Whether CSTORE can also be 
: spelled Cinfix:= is another question.
: 
: 
: Does the assignment operator mean value copy
: instead of reference copy?
: 
: The assignment operator means copy rhs's value into lhs's container.
: The binding operator means copy (reference to) rhs's container into lhs's 
: symbol table entry.

Note that assignment is a very shallow copy in any event.  Intrinsic types
are copied by default, plus any objects with a .copy method.  In other words,
Scalar has a .copy method by default, and anything else is your own doing.
Int, Num, Str, and Ref inherit the .copy interface from Scalar.  In particular,
a Ref only copies itself unless it refers to something with a .copy method.

In other words, the .copy method defines it as an intrinsic scalar type.

That's exactly how it works, bearing in mind that any or all of the
details might be wrong.

Larry


A6: Assignment Overloading

2003-03-13 Thread Luke Palmer
So, now that we have binding, is it possible to overload the
assignment operator?  Does the assignment operator mean value copy
instead of reference copy?

Luke


Re: A6: overloading multis on constness of parameters

2003-03-13 Thread Damian Conway
Piers Cawley wrote:

Speaking of multis and constants, Greg McCarroll wondered on IRC if
this would work:
multi factorial (Int 0) { 1 }
multi factorial (Int $n) { $n * factorial($n-1) }
Probably not. We did discuss whether multimethods should be able to be 
overloaded by value, but concluded (for that week, at least ;-) that this
might prove syntactically excessive.

Besides which, since multimethod dispatch will have to use Cisa to determine 
type compatibility on parameters anyway, it's trivial to implement this form 
of value-based dispatch yourself:

 class Zero {
 multi *isa ($obj, Zero $class) { $obj ~~ 0 }
 }
 # and then...

 multi factorial (IntZero $g) { 1 }

or, supposing we have some form of parameterized types, you could create 
something more generic like:

 class Val($N) {
multi *isa ($obj, Val($N) $class) { $obj ~~ $N }
 }
 # and then...

 multi factorial (IntVal(0) $g) { 1 }

;-)

Damian



Re: A6: Assignment Overloading

2003-03-13 Thread Damian Conway
Luke Palmer wrote:

So, now that we have binding, is it possible to overload the
assignment operator?  
Not really. The problem is that Cinfix:= is really an operator on 
*containers*, not on *values*. So, in order to overload C=, you'll still 
need to define an appropriate CSTORE method on the appropriate 
implementation class for the container. Whether CSTORE can also be spelled 
Cinfix:= is another question.


Does the assignment operator mean value copy
instead of reference copy?
The assignment operator means copy rhs's value into lhs's container.
The binding operator means copy (reference to) rhs's container into lhs's 
symbol table entry.

Damian




Re: A6: overloading multis on constness of parameters

2003-03-13 Thread Luke Palmer
 or, supposing we have some form of parameterized types, you could create 
 something more generic like:
 
   class Val($N) {
  multi *isa ($obj, Val($N) $class) { $obj ~~ $N }
   }
 
   # and then...
 
   multi factorial (IntVal(0) $g) { 1 }

Yes, YES!  Marvelous!

Not that that couldn't be done with a closure anyway...

{
  my Class %valClasses;

  sub Val($N) returns Class {
my Class $rclass = %valClasses{$N} //= class {
  multi *isa ($obj, $rclass $class) { $obj ~~ $N }
} 
  }
}

multi factorial (Int  Val(0) $g) { 1 }

Hmm, would Val(0) be evaluated at compile-time in that case... or must
I mark it with some sort of trait, or do some other kind of trick.

Cool, anyhow.

Luke


Re: A6: overloading multis on constness of parameters

2003-03-13 Thread Damian Conway
Luke Palmer wrote:

Not that that couldn't be done with a closure anyway...

{
  my Class %valClasses;
  sub Val($N) returns Class {
my Class $rclass = %valClasses{$N} //= class {
  multi *isa ($obj, $rclass $class) { $obj ~~ $N }
} 
  }
}

multi factorial (Int  Val(0) $g) { 1 }
I don't think so. I seriously doubt you can put a run-time-evaluated sub call 
in a type specification visions of Dan fainting in horror ;-)
A Cmacro might do the trick though.

Oh, and I was wrong to originally write: Cmulti *isa ...
Multimethods live in their own namespace. No * required.
Damian



Re: A6: overloading multis on constness of parameters

2003-03-12 Thread Larry Wall
On Wed, Mar 12, 2003 at 01:35:08PM +1100, Damian Conway wrote:
: Joe Gottman wrote:
: 
:Will it be possible in perl6 to overload multis on the const-ness of a
: parameter, like C++ does?  For instance,
: 
:multi getX(Foo $self:) returns Int {...} #const version
:multi getX(Foo $self: is rw) returns Int is rw {...} #non-const version
: 
: That second one would have to be:
: 
:  multi getX(Foo $self is rw:) returns Int is rw {...}
: 
: 
: Then we have the issue that Perl 6 objects can't really be constant,
: since Cis constant is a compile-time trait of *containers*...really just
: a don't assign to this container marker.
: 
: However, within those limitations, I guess it's possible. After all, we 
: have to check for lvaluability of Cis rw parameters anyway.

Might be one of those things that is taken as a tie-breaker, all other
things being equal.  I'm thinking return types fall into the same category.

Larry


  1   2   3   >