Re: Test Case: Complex Numbers

2005-11-18 Thread Flavio S. Glock
2005/11/11, Larry Wall [EMAIL PROTECTED]:

 While you're there, also think about the gray area between arrays and hashes,
 and whether .[...] subscripts are just a specialized form of .{...} 
 subscripts.

By the way, are lazy hash slices allowed?

  %h{1...}

I asked this in #perl6 when I was implementing lazy arrays (in the p5
backend), and most people found it was useless. But I thought I would
just ask again :)

- Flavio S. Glock


Re: Test Case: Complex Numbers

2005-11-18 Thread Larry Wall
On Fri, Nov 18, 2005 at 06:54:42PM -0200, Flavio S. Glock wrote:
: 2005/11/11, Larry Wall [EMAIL PROTECTED]:
: 
:  While you're there, also think about the gray area between arrays and 
hashes,
:  and whether .[...] subscripts are just a specialized form of .{...} 
subscripts.
: 
: By the way, are lazy hash slices allowed?
: 
:   %h{1...}

I don't see why not.  Why should people have to write

map { %h{$_} } 1...

to get the lazy behavior?  Plus we can do something intelligent with the
size of the dimension in the case of an array that we know the shape of.

: I asked this in #perl6 when I was implementing lazy arrays (in the p5
: backend), and most people found it was useless. But I thought I would
: just ask again :)

For any given feature, I don't care much about the people who find it
useless--I care more about the people who find it useful.  :-)

(That is, of course, as long as it doesn't get in the way of people
who aren't interested in the feature.)

Larry


Re: Test Case: Complex Numbers

2005-11-18 Thread Larry Wall
On Thu, Nov 17, 2005 at 10:18:19PM +0100, TSa wrote:
: Another idea is to model nums to have a directional bit where the
: polar complex have a full range angle.

This whole thing strikes me as a units problem.  Much like we
don't care if the internal representation is meters or furlongs,
so long as we can make 2.54`cm and 1`inch come out to the same thing.

Larry


Re: Test Case: Complex Numbers

2005-11-17 Thread TSa

HaloO,

Jonathan Lang wrote:

Complex numbers come in two representations: rectilinear coordinates
and polar coordinates:


I think there's also the Riemanian two angle form of the complex
number sphere with r = 0.5 around (0,0,0.5) touching the plane at
the origin (0,0) and reaching up to (0,0,1) in space. But admittedly
the resulting math is that of projective space.

Then there is the classic fact that you should make e.g. role Complex
an intentional supertype of Num while the class Complex needs a wider
extensional type with the added imaginary part in one form or another.

As Luke pointed out, a plain role/class pair might not be enough to
model the structural properties of the communalities and differences
of Num and Complex. We need to define a family of related types that
manage the different interpretations of a 2-tupel of Nums while sharing
the underlying data layout---not to mention to be compatible with more
generic vector stuff like the scalar product.

Another idea is to model nums to have a directional bit where the
polar complex have a full range angle.
--


Re: Test Case: Complex Numbers

2005-11-14 Thread Michele Dondi

On Fri, 11 Nov 2005, Jonathan Lang wrote:


That wasn't the intent; the intent was to define a
something-or-other Ccomplex that represents the fact that whatever
does this sometimes behaves like a complexRectilinear and other times
behaves like a complexPolar.  Even the underlying information (the
attributes involved) may vary from role to role, though what those
attributes represent ought to be the same regardless of which role is
in use.


I must say that I didn't follow the discussion very much. But this makes 
me think of this too: the two representations are handy for different 
calculations. It would be nice if they somehow declared what they can do 
better (or at all) and have the union take care of which one's methods 
to use.


In another situation, one may implement a system for doing integer 
arithmetics say in base twelve, and in this case one may have an union 
to decide to use its .division() method to perform division by three, 
possibly holding a flag telling that the most accurate status is that held 
in it.



Michele
--
Caro Bongo questa ? la civilt?: hai tutto quello che non vuoi,
quando non ti serve.
- Toto' Tarzan

Re: Test Case: Complex Numbers

2005-11-14 Thread Doug McNutt
At 15:59 +0100 11/14/05, Michele Dondi wrote:
I must say that I didn't follow the discussion (complex) very much. But this 
makes me think of this too: the two representations are handy for different 
calculations. It would be nice if they somehow declared what they can do 
better (or at all) and have the union take care of which one's methods to 
use.

In another situation, one may implement a system for doing integer arithmetics 
say in base twelve, and in this case one may have an union to decide to use 
its .division() method to perform division by three, possibly holding a flag 
telling that the most accurate status is that held in it.

Someday I may become competent to think in perl6 but if we're expanding on the 
topic. . .

Complex numbers are much like 2-D vectors, the real ones and not the ordered 
lists that are used with hyper operators. A union structure that allows for 3-D 
vectors some of which are pseudovectors would be interesting. It would also be 
possible to represent vectors in 3-D spherical coordinates.

Oh. . . A pseudovector differs from a vector in that it doesn't change 
direction when reflected in a plane mirror. The cross product of two ordinary 
vectors is a pseudovector. So is a magnetic field.

As for complex operations which have multiple results I think a principle value 
approach makes more sense than a list. It's well established for the inverse 
trigonometric functions. Leave RootOf( ) to Maple and Mathematica.

-- 

--  Halloween  == Oct 31 == Dec 25 == Christmas  --


Re: Test Case: Complex Numbers

2005-11-14 Thread Jonathan Lang
Doug McNutt wrote:
 As for complex operations which have multiple results I think a principle
 value approach makes more sense than a list. It's well established for the
 inverse trigonometric functions. Leave RootOf( ) to Maple and Mathematica.

In the hypothetical module that I'm describing, the principle value
approach _would_ be used - in scalar context.  The only time the list
of all possible results approach would be used would be if you use
list context.  If you have no need of the list feature, then you don't
have to use it.

I believe that what I have outlined is a reasonable approach to
handling complex numbers.  It may or may not be the best way to do so
(and I suspect that it isn't), but that isn't really the point.  The
point is that it _is_ reasonable, and I'd like to see how well Perl 6
handles it.

Michele Dondi wrote:
 I must say that I didn't follow the discussion very much. But this makes
 me think of this too: the two representations are handy for different
 calculations. It would be nice if they somehow declared what they can do
 better (or at all) and have the union take care of which one's methods
 to use.

That's one of the points I had in mind.  Rectilinear coordinates are
useful for addition and subtraction, while polar coordinates fare
better for multiplication, division, powers, logs, trigonometric
functions, and hyperbolic functions.  So define addition and
subtraction for the rectilinear coordinate system and define the
remaining operations for the polar coordinate system.

The problem is that the two coordinate systems don't just differ in
terms of which methods they make available; they also differ in terms
of how they represent the value that they represent.  So if you want
to multiply two complex numbers that were defined using rectilinear
coordinates, you'd need to transform them to polar coordinates first,
and then multiply those numbers.  Phrased in terms of roles, the
rectilinear role would have $.x and $.y attributes (which its methods
would use), while the polar role would have $.magnitude and
$.direction attributes (which _its_ methods would use).  That's two
sets of attributes which contain identical data in vastly different
formats; simply having one class or role do both of these roles would
result in extra memory usage (as both sets of attributes would need
storage allocated to them), not to mention the likelihood that the two
sets of attributes may end up getting out of synch with each other.

What I'm looking at is a way to declare that the two roles are
different representatives of the same thing.  Memory would be
allocated to exactly one set of attributes at a time, and
transformations between the different sets would be called whenever
you change the underlying representation of the data.  In the former
regard, this would be much like C's union; but it would differ from
them in that it would be designed to preserve the logical value (what
the data represents) rather than the physical value (the sequence of
bits in memory).

--
Jonathan Dataweaver Lang


Re: Test Case: Complex Numbers

2005-11-14 Thread Dave Whipp

Jonathan Lang wrote:


In the hypothetical module that I'm describing, the principle value
approach _would_ be used - in scalar context.  The only time the list
of all possible results approach would be used would be if you use
list context.  If you have no need of the list feature, then you don't
have to use it.


This might suprise people:

@a = (1,4,9);
@b = @a.map:{sqrt};

ok([EMAIL PROTECTED] == [EMAIL PROTECTED]); # fails because of list context



The problem is that the two coordinate systems don't just differ in
terms of which methods they make available; they also differ in terms
of how they represent the value that they represent


And they also differ in what values they can represent, assuming the 
underlying representation of real numbers uses a finite number of bits.



In the former
regard, this would be much like C's union; but it would differ from
them in that it would be designed to preserve the logical value (what
the data represents) rather than the physical value (the sequence of
bits in memory).


Which is not possible in the general case.

That probably doesn't mean that there isn't a good use for the concept, 
but I'd be wary of it for precision math stuff.


Re: Test Case: Complex Numbers

2005-11-11 Thread Larry Wall
On Fri, Nov 11, 2005 at 06:21:53AM +, Luke Palmer wrote:
: Just some initial thoughts and syntax issues.  I'll come back to it on
: the conceptual side a little later.
: 
: On 11/10/05, Jonathan Lang [EMAIL PROTECTED] wrote:
: 
:  class complexRectilinear {
:has $.x, $.y;
: 
: Hmm, that might need to be
: 
: has ($.x, $.y);
: 
: However, inlining hass isn't possible, so there's really no reason
: for that restriction.  But it might be good just for consistency with
: my.  But it also might not, because I'm always annoyed with those
: parentheses.

It's not about inlining in general, but particularly about the
relationship of precedence with assignment.  And you presumably
*can* say:

has ($.x, $.y) = (1, 2);

to mean the same as:

has $.x = 1;
has $.y = 2;

Likewise

state ($.x, $.y) = (1, 2);

means

state $.x = 1;
state $.y = 2;

:method infix:+ ($a is complexRectlinear, $b is complexRectilinear)
: 
: method infix:+ (complexRectilinear $a, complexRectilinear $b)
: 
:  returns complexRectilinear {
:  return new complexRectilinear($a.x + $b.x, $a.y + $b.y);
: 
: return new complexRectilinear: $a.x + $b.x, $a.y + $b.y;

rampantspeculation

Given the new relationship between

$obj.method(...)

and

$obj.method: ...,

I'm wondering if we can make the same relationship between

method $obj(...)
method $obj: ...
 
That is, : becomes more of a Haskellish $ operator.  I speculated this
earlier when I wanted to change

$obj.method :{...}

into

$obj.method: {...}

But foo $bar(...) is probably too ambiguous with a possible foo list
operator unless we were to require : on all calls to list operators:

print: 1,2,3

That's likely to inspire mutiny.  Though we could perhaps get away
with requiring the colon only on list operators that have more than
one argument, on the theory that

foo 1;

is always the same as

1.foo;

/rampantspeculation

: Hmm, that union looks like a backwards role.  That is, you're creating
: a role complex and saying that the interface of that role is
: whatever is common between these two classes.  Interesting idea... not
: sure how fruitful that is though.
: 
: The idea of several isomorphic implementations of the same thing has
: occurred to me several times, but I never figured out how it might
: work.  Let me think about that.

And what's the common role of a scalar that can have a string
implementation in several abstraction levels, plus any number of native
integer/float and bignum/bigfloat implementations hiding behind it?
Interesting question.

:  If $b's real component is
:  rational, it makes some sense to treat [-1] as the last element in the
:  list, [-2] as the second-to-last, and so on; but if $b's real
:  component is irrational, there _is_ no positive end to the list, and
:  it would make sense if [-1] referred to the first result that you
:  reach by rotating in the clockwise direction from the primary result.
:  Can an infinitely long list be set up so that [-1] still has
:  meaning?
: 
: Hmm.  I don't see why not.  Though we haven't established the array
: laws yet, you're probably not breaking any of them by doing that.  
: You can consider your array to be transfiniteish:
: 
: [ a[1], a[2], ..., a[-2], a[-1] ]
: 
: Understanding that no matter how long you iterate going forward,
: you'll never get to a[-1].

I believe we already said you could pop or refer to the end of an
infinite array in A6/Appendix B.

:  As an example,
:  let's say that $b = 0.5.  This means that the first result is rotated
:  zero radians counterclockwise from $a's direction, and corresponds to
:  [0].  [1] would correspond to being rotated pi radians, and the length
:  generator would say that there are only two elements in the list.
:  Could you set things up so that you could nonetheless access [2]
:  (which is rotated by 2*pi radians), [3] (rotated by 3*pi radians), or
:  possibly even have [-1] represent a rotation by -pi radians?
: 
: Well, it would certainly be okay to have an infinite list that had
: that property.   However, having the list report that its length is,
: say, finite $n, and then having @list[$n] be something besides undef
: may be breaking some law (but maybe not[1]).
: 
: What you're really doing is defining the indices mod $n.  Maybe
: there's some way to tell the compiler that your indices are defined
: that way to allow this sort of behavior.  Maybe you could make a
: subclass of Array called ModArray or something that allowed this. 
: Maybe you're simply not allowed to use square brackets in a case where
: the list is finite but defined for all indices.

All is fair if you predeclare.

: But that's all theoretical formality.  For the Perl practicioner, feel
: free to break the laws if it helps you get your job done. :-)
: 
: Luke
: 
: [1] I think I'm going to embark on writing down the laws for a few of
: our basic types so we can actually talk about this without 

Re: Test Case: Complex Numbers

2005-11-11 Thread Jonathan Lang
Luke Palmer wrote:
 Just some initial thoughts and syntax issues.  I'll come back to it on
 the conceptual side a little later.

I'm looking forward to it.

 Jonathan Lang wrote:
method coerce:complexPolar () returns complexPolar {
  return new complexPolar ($.x * $.x + $.y * $.y, atn($.y / $.x) *
  (sgn($.x) || sgn($.y)));
}

 Hmm. I don't know why you marked this with coerce:?

Neither do I; I was assuming that the purpose of coerce: is to allow
implicit type conversions - that is, if I feed a complexRectilinear
object into an argument slot that's looking for a complexPolar object,
this method would be called implicitly and the result would be used
instead.

...
  }
 
  ... and a similar definition for class polar.
 
  (Technically, coerce:complexPolar and infix:+ are generators in the
  sense that they create new instances of the class; but ISTR something
  about generators not being allowed in classes.)

 Ahh, you read that in theory.pod.  It's not clear that the factory
 and generator abstractions are all that useful (I'm still looking
 for a good use though).  I just included them for symmetry (like
 Maxwell :-).

FWIW, I didn't read theory.pod as thoroughly as I probably should
have, nor did I grasp it as well as I would like.  But when I looked
at the concept of virtual lists, the union/factory/generator triad
seemed to be, conceptually, a perfect fit: the virtual list is
actually a union, whose factory includes generators that produce
information about the list on demand.  More generally, a union would
be the appropriate tool for the magic behind what Perl 5 used ties
for.

 Don't think that you're not allowed to return instances of the class
 you are defining from methods.  You can.  Generators are more
 restrictive: they say that any subclass must return an instance of
 *itself* from that method; i.e. it probably wouldn't be able to use
 your implementation.  But that breaks subclassing laws, which is why
 they aren't allowed in classes.

I'm not sure I'm following this.

  You should then be able to say:
 
  union complex {
class complexRectilinear;
class complexPolar;
  }
 
  ...or something of the sort.  At this point, you have the ability to
  freely represent complex numbers in either coordinate system and to
  switch between them at will.  Am I right so far?

 Hmm, that union looks like a backwards role.  That is, you're creating
 a role complex and saying that the interface of that role is
 whatever is common between these two classes.  Interesting idea... not
 sure how fruitful that is though.

That wasn't the intent; the intent was to define a
something-or-other Ccomplex that represents the fact that whatever
does this sometimes behaves like a complexRectilinear and other times
behaves like a complexPolar.  Even the underlying information (the
attributes involved) may vary from role to role, though what those
attributes represent ought to be the same regardless of which role is
in use.

 The idea of several isomorphic implementations of the same thing has
 occurred to me several times, but I never figured out how it might
 work.  Let me think about that.

Cunion was probably a bad name for it, especially considering that
theory.pod already uses Cunion for a very specific purpose. 
Cchoice might have been a better name.

  However, if $b's real component isn't a rational number, you won't
  have a finite number of elements in the list.  Here's where I get a
  little fuzzy: IIRC, there's some means of defining a list by providing
  an element generator:
 
  generator element($index) returns complex { ... }
 
  Is there a way of setting things up so that an attempt to ascertain
  the list's length would call a separate generator for that purpose?
 
  generator length() returns complex { ... }
 
  At any point above, am I abusing the concept of theories, or failing
  to use them to their fullest extent?

 Well, you're not using generator correctly.

 You're really just trying to define a lazy list or an iterator, right?
  That most likely involves implementing some role:

 role ComplexPowers does Lazy {...}

 or:

 role ComplexPowers does Iterator {...}

 And then creating one of those objects from within your pow function.
 Nothing deeply type-theoretical going on here.

That's the most traditional way, yes; but is there anything wrong with
the concept of implementing it based on a factory instead of a role?

  If $b's real component is
  rational, it makes some sense to treat [-1] as the last element in the
  list, [-2] as the second-to-last, and so on; but if $b's real
  component is irrational, there _is_ no positive end to the list, and
  it would make sense if [-1] referred to the first result that you
  reach by rotating in the clockwise direction from the primary result.
  Can an infinitely long list be set up so that [-1] still has
  meaning?

 Hmm.  I don't see why not.  Though we haven't established the array
 laws yet, you're probably not 

Re: Test Case: Complex Numbers

2005-11-10 Thread Luke Palmer
Just some initial thoughts and syntax issues.  I'll come back to it on
the conceptual side a little later.

On 11/10/05, Jonathan Lang [EMAIL PROTECTED] wrote:

 class complexRectilinear {
   has $.x, $.y;

Hmm, that might need to be

has ($.x, $.y);

However, inlining hass isn't possible, so there's really no reason
for that restriction.  But it might be good just for consistency with
my.  But it also might not, because I'm always annoyed with those
parentheses.

   method infix:+ ($a is complexRectlinear, $b is complexRectilinear)

method infix:+ (complexRectilinear $a, complexRectilinear $b)

 returns complexRectilinear {
 return new complexRectilinear($a.x + $b.x, $a.y + $b.y);

return new complexRectilinear: $a.x + $b.x, $a.y + $b.y;

   }
   ...
   method coerce:complexPolar () returns complexPolar {
 return new complexPolar ($.x * $.x + $.y * $.y, atn($.y / $.x) *
 (sgn($.x) || sgn($.y)));
   }

Hmm. I don't know why you marked this with coerce:?  Maybe coerce:
marks a one-to-one correspondence; i.e. things that can be used
interchangably.  But for now, I think you either mean:

method asComplexPolar ()

Or:

method coerce:as (-- complexPolar)

(that might take an argument of some sort)

   ...
 }

 ... and a similar definition for class polar.

 (Technically, coerce:complexPolar and infix:+ are generators in the
 sense that they create new instances of the class; but ISTR something
 about generators not being allowed in classes.)

Ahh, you read that in theory.pod.  It's not clear that the factory
and generator abstractions are all that useful (I'm still looking
for a good use though).  I just included them for symmetry (like
Maxwell :-).

Don't think that you're not allowed to return instances of the class
you are defining from methods.  You can.  Generators are more
restrictive: they say that any subclass must return an instance of
*itself* from that method; i.e. it probably wouldn't be able to use
your implementation.  But that breaks subclassing laws, which is why
they aren't allowed in classes.

 You should then be able to say:

 union complex {
   class complexRectilinear;
   class complexPolar;
 }

 ...or something of the sort.  At this point, you have the ability to
 freely represent complex numbers in either coordinate system and to
 switch between them at will.  Am I right so far?

Hmm, that union looks like a backwards role.  That is, you're creating
a role complex and saying that the interface of that role is
whatever is common between these two classes.  Interesting idea... not
sure how fruitful that is though.

The idea of several isomorphic implementations of the same thing has
occurred to me several times, but I never figured out how it might
work.  Let me think about that.

 multi exp($a is complex, $b is complex) returns list of complex { ... }

multi exp(complex $a, complex $b) returns List of Complex {...}

 However, if $b's real component isn't a rational number, you won't
 have a finite number of elements in the list.  Here's where I get a
 little fuzzy: IIRC, there's some means of defining a list by providing
 an element generator:

 generator element($index) returns complex { ... }

 Is there a way of setting things up so that an attempt to ascertain
 the list's length would call a separate generator for that purpose?

 generator length() returns complex { ... }

 At any point above, am I abusing the concept of theories, or failing
 to use them to their fullest extent?

Well, you're not using generator correctly.

You're really just trying to define a lazy list or an iterator, right?
 That most likely involves implementing some role:

role ComplexPowers does Lazy {...}

or:

role ComplexPowers does Iterator {...}

And then creating one of those objects from within your pow function. 
Nothing deeply type-theoretical going on here.

 If $b's real component is
 rational, it makes some sense to treat [-1] as the last element in the
 list, [-2] as the second-to-last, and so on; but if $b's real
 component is irrational, there _is_ no positive end to the list, and
 it would make sense if [-1] referred to the first result that you
 reach by rotating in the clockwise direction from the primary result.
 Can an infinitely long list be set up so that [-1] still has
 meaning?

Hmm.  I don't see why not.  Though we haven't established the array
laws yet, you're probably not breaking any of them by doing that.  
You can consider your array to be transfiniteish:

[ a[1], a[2], ..., a[-2], a[-1] ]

Understanding that no matter how long you iterate going forward,
you'll never get to a[-1].

 As an example,
 let's say that $b = 0.5.  This means that the first result is rotated
 zero radians counterclockwise from $a's direction, and corresponds to
 [0].  [1] would correspond to being rotated pi radians, and the length
 generator would say that there are only two elements in the list.
 Could you set things up so that you could nonetheless access [2]
 

Test Case: Complex Numbers

2005-11-09 Thread Jonathan Lang
The following is an attempt to put a number of Perl6 concepts into
practice, in order to see how useful and intuitive they actually are.

Complex numbers come in two representations: rectilinear coordinates
and polar coordinates:

class complexRectilinear {
  has $.x, $.y;
  method infix:+ ($a is complexRectlinear, $b is complexRectilinear)
returns complexRectilinear {
return new complexRectilinear($a.x + $b.x, $a.y + $b.y);
  }
  ...
  method coerce:complexPolar () returns complexPolar {
return new complexPolar ($.x * $.x + $.y * $.y, atn($.y / $.x) *
(sgn($.x) || sgn($.y)));
  }
  ...
}

... and a similar definition for class polar.

(Technically, coerce:complexPolar and infix:+ are generators in the
sense that they create new instances of the class; but ISTR something
about generators not being allowed in classes.)

You should then be able to say:

union complex {
  class complexRectilinear;
  class complexPolar;
}

...or something of the sort.  At this point, you have the ability to
freely represent complex numbers in either coordinate system and to
switch between them at will.  Am I right so far?

Next:

multi exp($a is complex, $b is complex) returns complex { ... }

This defines a function that raises one complex number to the power of
another complex number and returns a third complex number.  One
problem is that if $b's real component isn't an integer, there's no
guarantee that there will be a unique answer.  To address this, we
could provide a second version of this function:

multi exp($a is complex, $b is complex) returns list of complex { ... }

However, if $b's real component isn't a rational number, you won't
have a finite number of elements in the list.  Here's where I get a
little fuzzy: IIRC, there's some means of defining a list by providing
an element generator:

generator element($index) returns complex { ... }

Is there a way of setting things up so that an attempt to ascertain
the list's length would call a separate generator for that purpose?

generator length() returns complex { ... }

At any point above, am I abusing the concept of theories, or failing
to use them to their fullest extent?

With this example, it would be useful if the list of results could
extend in both directions, so that one could advance through them in a
clockwise or counterclockwise direction.  If $b's real component is
rational, it makes some sense to treat [-1] as the last element in the
list, [-2] as the second-to-last, and so on; but if $b's real
component is irrational, there _is_ no positive end to the list, and
it would make sense if [-1] referred to the first result that you
reach by rotating in the clockwise direction from the primary result. 
Can an infinitely long list be set up so that [-1] still has
meaning?

Also, even if $b's real component is rational, there are times that
one might want to access a version of the result that is rotated some
multiple of 2*pi radians from one of the main results.  As an example,
let's say that $b = 0.5.  This means that the first result is rotated
zero radians counterclockwise from $a's direction, and corresponds to
[0].  [1] would correspond to being rotated pi radians, and the length
generator would say that there are only two elements in the list. 
Could you set things up so that you could nonetheless access [2]
(which is rotated by 2*pi radians), [3] (rotated by 3*pi radians), or
possibly even have [-1] represent a rotation by -pi radians?

--
Jonathan Dataweaver Lang