Re: Synopsis 9 draft 1

2004-09-21 Thread Jonadab the Unsightly One
John Macdonald [EMAIL PROTECTED] writes:

 If a int1 (or int2 or nybble or other sub-addressable sized value)
 is being referred to, a similar issue arises since most machines
 these days have byte addressing, but do not have bit addressing.  If
 you can't refer directly to it, the value will have to be extracted
 and re-inserted to provide is rw access.

I surely must be misunderstanding what you're saying...  the way I
read that, you're suggesting that it will matter to Perl -- not only
to the compiler but even to user code -- how the underlying hardware
addresses its memory.  I really hope that's not the case.

I thought Parrot would take care of all that fiddly platform-dependent
stuff so that Perl doesn't have to know or care about it.  Perl6 code
shouldn't have to even *know* whether it's running on a big or little
(or middle) endian system, how many bits wide the BUS is, how many
bits are in an integer, whether there's a math coprocessor, whether
the instruction set is RISC or CISC, how many CPUs there are, what
kind of filesystem the underlying OS has, or whether the underlying
GUI is Win32 or Aqua or GTK or Qt.  Perl6 code shouldn't have to know
that stuff *even* to call libraries written in another language; even
the compiler shouldn't have to know about it.  Parrot should have a
wrapper API thingydo that makes it Just Work.

That's the point of having a VM, or such was my understanding.

I don't think I'm dreaming the impossible here, because Inform seems
to manage this stuff just fine, with either of the VMs it compiles to
(except for the parts about calling libraries written in other
languages, and having a GUI; Inform doesn't support those things).
You can write the code and compile it on a DOS system, stick the
binary on an ftp server, and J. Random Nerd can download it, and
assuming he has the appropriate version of the VM for his system, it
will run your code -- whether his system is SPARC/Solaris or Nintendo
Gameboy, your code will never know the difference; as far as your code
is concerned, it's running on the z-machine.  Parrot should be like
that (except that Parrot's minimum requirements for the underlying
system will have to be a little higher, because we want to support
things like disk I/O and allocating more RAM after the program starts
running).

So if the underlying hardware doesn't know how to write a single byte,
then Parrot should have workaround code for that.  Perl shouldn't even
need to know about it.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: Synopsis 9 draft 1

2004-09-21 Thread Ovid
--- Jonadab the Unsightly One [EMAIL PROTECTED] wrote:
 I surely must be misunderstanding what you're saying...  the way I
 read that, you're suggesting that it will matter to Perl -- not only
 to the compiler but even to user code -- how the underlying hardware
 addresses its memory.  I really hope that's not the case.

Perhaps I'm misunderstanding things, but I thought that Perl6 should be able to 
*optionally* allow
such things if platform specific fine-grained code tuning is necessary.  Most of the 
time it
shouldn't be, but if it's required that .01% of the time why force someone to reach 
for another
language, regardless of how easy the languages are to integrate?

Cheers,
Ovid

=
Silence is Evilhttp://users.easystreet.com/ovid/philosophy/indexdecency.htm
Ovid   http://www.perlmonks.org/index.pl?node_id=17000
Web Programming with Perl  http://users.easystreet.com/ovid/cgi_course/


Re: Synopsis 9 draft 1

2004-09-21 Thread Jonadab the Unsightly One
Aaron Sherman [EMAIL PROTECTED] writes:

 It took us some time discussing this... we weren't sure what tense
 you were using. At first we thought it might be the past subjective,
 but after a while, we decided to coin a new tense: the vapor tense. ;-)

Actually, it's not new at all; there's already a quite established
terminology for that tense.  It's called the prophetic past.

HTH.HAND.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: Synopsis 9 draft 1

2004-09-21 Thread Jonadab the Unsightly One
Larry Wall [EMAIL PROTECTED] writes:

 int1, int2, int4, int8, int16, int32, int64, uint1, uint2, uint4,
 uint8, uint16, uint32, uint64, num32, num64, num128, complex32,
 complex64, complex128, ...

Well, all that is harmless enough, as long as I don't ever have the
misfortune to inherit maintenance of any code that *uses* those
lowlevel types.

We are also getting a holds whatever size number you put in it, up to
the limits of available system resources type, right?  Good.

 say @x = @x[];  # prints @x = 1 2 3

Nice.  Until now I wasn't sure I liked the new interpolation rules,
but this looks good.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: Synopsis 9 draft 1

2004-09-09 Thread Michele Dondi
On Thu, 2 Sep 2004, Larry Wall wrote:

 To declare a multidimensional array, you add a shape parameter:
 
 my num @nums is shape(3);   # one dimension, @nums[0..2]
 my int @ints is shape(4;2); # two dimensions, @ints[0..3; 0..1]

Just a random thought, and probably a minor point: I know that there 
already so many keywords, but if not already taken, could Chas be 
introduced as a synonim for Cis to be freely used where it would fit 
better? Especially in constructs like

  my num @data is Stuff has shape(4;2);


Michele
-- 
 I was wondering if there is someone who knows a good perl spam filter.
That's funny. Most of my spam is for v1agr4 and p3nis [EMAIL PROTECTED], not Perl.
- John J. Trammell in clpmisc, Re: Perl Spam Filter (slightly edited)


Re: Synopsis 9 draft 1

2004-09-09 Thread Matthew Walton
Michele Dondi wrote:
On Thu, 2 Sep 2004, Larry Wall wrote:

To declare a multidimensional array, you add a shape parameter:
   my num @nums is shape(3);   # one dimension, @nums[0..2]
   my int @ints is shape(4;2); # two dimensions, @ints[0..3; 0..1]

Just a random thought, and probably a minor point: I know that there 
already so many keywords, but if not already taken, could Chas be 
introduced as a synonim for Cis to be freely used where it would fit 
better? Especially in constructs like

  my num @data is Stuff has shape(4;2);
Chas is already used to give classes attributes...
class Thing {
  has @.fingers;
  has $.mysteriousness;
}
I wouldn't be surprised if it does run-time attribute addition to 
objects as well, but I can't recall seeing that anywhere and haven't got 
time to look right now. Even if it doesn't, it would, I think, be a 
mistake to overload it in this way.



Re: Synopsis 9 draft 1

2004-09-09 Thread John Macdonald
On Thu, Sep 09, 2004 at 03:09:47PM +0200, Michele Dondi wrote:
 On Thu, 2 Sep 2004, Larry Wall wrote:
 
  And yes, an Cint1 can store only -1 or 0.  I'm sure someone'll think of
  a use for it...
 
 Probably OT, but I've needed something like that badly today: working on
 a japh that turned out to require mostly golfing skills (and not that I
 have many, I must admit)... well, it would have been useful to have, say,
 a pack template for 2-bits unsigned integers...

As an array index -1 and 0 give you the 2 ends.  The perl5
code to alternately extract elements from the two eds of an
array can be something like:

my $end = 0;# -1 to start with right end

while( @array ) {
my $next = splice( @array, $end, 1 );
# use the $next element
$end = -1 - $end;
}

Using int1 for $end, that last line can be changed in a variety
of ways, such as:

$end ^= 1;

(except that the p5 ^= operator is written differently in p6)

This is not a *good* use of int1 though. :-)

-- 


Re: Synopsis 9 draft 1

2004-09-09 Thread Luke Palmer
John Macdonald writes:
 As an array index -1 and 0 give you the 2 ends.  The perl5
 code to alternately extract elements from the two eds of an
 array can be something like:
 
 my $end = 0;  # -1 to start with right end
 
 while( @array ) {
   my $next = splice( @array, $end, 1 );
   # use the $next element
   $end = -1 - $end;
 }
 
 Using int1 for $end, that last line can be changed in a variety
 of ways, such as:
 
   $end ^= 1;

Well, if you're golfing:

$end++;

If the low level types wrap around rather than promote;

Luke


Re: Synopsis 9 draft 1

2004-09-09 Thread Smylers
Michele Dondi writes:

 On Thu, 2 Sep 2004, Larry Wall wrote:
 
  To declare a multidimensional array, you add a shape parameter:
  
  my num @nums is shape(3);   # one dimension, @nums[0..2]
  my int @ints is shape(4;2); # two dimensions, @ints[0..3; 0..1]
 
 Just a random thought, and probably a minor point: I know that there 
 already so many keywords, but if not already taken, could Chas be 
 introduced as a synonim for Cis to be freely used where it would fit 
 better? Especially in constructs like
 
   my num @data is Stuff has shape(4;2);

I also think Cis shape reads awkwardly.  Would making it Cis shaped
be any better?

  my num @data is Stuff is shaped(4;2);

Smylers



Re: Synopsis 9 draft 1

2004-09-07 Thread Aaron Sherman
On Fri, 2004-09-03 at 20:08, Larry Wall wrote:

 Arrays with explicit ranges don't use the
 minus notation to count from the end.  We probably need to come up
 with some other notation for the beginning and end indexes.  But it'd
 be nice if that were a little shorter than:
 
 @ints.shape[0].beg
 @ints.shape[0].end
 
 Suggestions?  Maybe we just need integers with whence properties... :-)

Actually, what you had in Perl 5, was essentially:

$x[-1] == reverse(@x)[0]

In Perl 6, this is actually workable because of the lazy evaluation of
reverse, so if you simply re-name reverse to rev as a list method for
brevity:

my int @ints is shape(-10..10);
@ints.rev[-10]; # assuming that @x.rev retains shape

And as someone pointed out:

@ints.abs.rev[0]

if you had an abs that strips away shape.

All that being said, I think that this (shape) is a dangerous idea at
best. If used, it should probably specify a length ONLY:

my int @ints is shape(10)

and in that light, I think it would best be renamed to length or
extent.

Specifying the origin should be left to $[... that is, left out.

-- 
 781-324-3772
 [EMAIL PROTECTED]
 http://www.ajs.com/~ajs



Re: Synopsis 9 draft 1

2004-09-07 Thread Larry Wall
On Tue, Sep 07, 2004 at 10:34:33PM -0400, John Macdonald wrote:
: If a int1 (or int2 or nybble or other sub-addressable sized
: value) is being referred to, a similar issue arises since most
: machines these days have byte addressing, but do not have bit
: addressing.  If you can't refer directly to it, the value will
: have to be extracted and re-inserted to provide is rw access.

Well, sure.  Is this any more of a problem than vec() in Perl 5?

Larry


Re: Synopsis 9 draft 1

2004-09-06 Thread Leopold Toetsch
Larry Wall [EMAIL PROTECTED] wrote:
 On Sat, Sep 04, 2004 at 09:47:29AM +0200, Leopold Toetsch wrote:

: Honestly I don't see the point why all normal array usage should be
: slowed down just for the sake of some rare usage patterns.

 Does it have to?  Couldn't it have a different vtable?  (Which argues
 that such a shape ought to be considered an parameterization of the
 implementation type.  (Which argues that it should be of shape
 rather than is shape...).)

A different vtable implies some kind of a derived class. The question
is, if an of shape or is shape already causes a new class of
arrayish objects.
The question probably is: how much of this class code is done directly
by Parrot. But given that shapes can be fully dynamic too my gut feeling
is that some glue code will be in the Perl6 library.

 Larry

leo


Re: Synopsis 9 draft 1

2004-09-06 Thread Larry Wall
On Mon, Sep 06, 2004 at 10:13:56AM +0200, Leopold Toetsch wrote:
: A different vtable implies some kind of a derived class. The question
: is, if an of shape or is shape already causes a new class of
: arrayish objects.
: The question probably is: how much of this class code is done directly
: by Parrot. But given that shapes can be fully dynamic too my gut feeling
: is that some glue code will be in the Perl6 library.

Okay, I'll try to make it clear in S9 that non-0-based arrays are not
to be implemented in such a way that the base array class is slowed.
If that means they're not in 6.0.0 at all, that's okay.  I'm mostly
just trying to keep the syntactic space open for them by allowing ranges
in shape parameters, which implies that the parameters are lists rather
than scalars, which implies they have to be separated by semicolons
rather than commas.

Larry


Re: Synopsis 9 draft 1

2004-09-06 Thread Larry Wall
On Sat, Sep 04, 2004 at 09:47:29AM +0200, Leopold Toetsch wrote:
: Honestly I don't see the point why all normal array usage should be
: slowed down just for the sake of some rare usage patterns.

Another possibility is that .[] always forces the normal view of an
array as 0-based, and if you want non-0-based arrays you have to use
the .{} interface instead, on the assumption that strange subscripts
are more like hash keys than ranges of integers.  Certainly if
you have a sparse array with keys like 1,2,4,8,16,32... you have a
situation that's more like a hash than an array.  A sparse array
might not even give you the .[] interace.  The presence of a .[]
interface might signal the ability to process contigous ranges,
even if those ranges are offset from the .{} range.

Such an approach would have the benefit that a module could simply
treat all its arrays as 0-based .[] arrays, and if you happened to
pass a non-0-based .{} array in, it would still work, albeit with
0-based indexes instead of whatever shape the .{} interface uses.

Anyway, it's an idea that might or might not make sense.  It seems
to me, though, that either you're interested in treating all the
dimensions of a subscript as non-0-based, or none of them.  I think
people will rarely want to mix those in the same subscript.

On the other hand, it opens up the possibility of mixing up .[] with .{}
and getting off-by-n errors, unless a declared shape of non-0-based
turns off the .[] interface entirely.

Larry


Re: Synopsis 9 draft 1

2004-09-05 Thread Aaron Sherman
On Thu, 2004-09-02 at 19:47, Larry Wall wrote:

 This synopsis summarizes the non-existent Apocalypse 9, which
 discussed in detail the design of Perl 6 data structures.  It was
 primarily a discussion of how the existing features of Perl 6 combine
 to make it easier for the PDL folks to write numeric Perl.

It took us some time discussing this... we weren't sure what tense you
were using. At first we thought it might be the past subjective, but
after a while, we decided to coin a new tense: the vapor tense. ;-)

Working my way through... thanks Larry!

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




Re: Synopsis 9 draft 1

2004-09-04 Thread Juerd
Larry Wall skribis 2004-09-03 17:08 (-0700):
 The element with index -1.  Arrays with explicit ranges don't use the
 minus notation to count from the end.  We probably need to come up
 with some other notation for the beginning and end indexes. 

@array.abs[0];
@array.abs[-1];

.abs would be an alternative interface for the array, where 0 is always
the first element.

The real index is then 

( $abs_index = 0 ?? @array.first :: @array.last + 1 ) + $abs_index


Juerd


Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-04 Thread Juerd
John Williams skribis 2004-09-03 23:06 (-0600):
  (A and Z)
 I think I'd prefer alpha and omega.

Why not use Cyrillic or Korean or the secret code alphabet we used in
school?

I don't like using letters for array indexes, but if they're used,
please keep it ascii :)


Juerd


Re: Synopsis 9 draft 1

2004-09-04 Thread Leopold Toetsch
John Williams [EMAIL PROTECTED] wrote:

 What happens when the Pascal programmer declares

 my int @ints is shape(-10..10);

Should that really all be in core? Why not let the user create his own
derived array that does what she wants?

Honestly I don't see the point why all normal array usage should be
slowed down just for the sake of some rare usage patterns.

 ~ John Williams

leo


Re: Synopsis 9 draft 1

2004-09-04 Thread Leopold Toetsch
Larry Wall [EMAIL PROTECTED] wrote:
 On Fri, Sep 03, 2004 at 11:41:05AM +0100, Tim Bunce wrote:

: (I'm not (yet) familiar with Parrot's ManagedStruct and UnManagedStruct
: types but there's probably valuable experience there.)

 Quite likely.

Well, *ManagedStruct is already working pretty well. It is used to
interface with C code that returns or takes structures of some natural
types. It supports nested structures and pointers to these as well as
arrays of items and a limited set of callback functions.

See e.g. runtime/parrot/library/SDL* for a lot of such usage.

Constructing such a struct takes a list of triples:
- data type
- optional array count of item
- optional offset

Alignment is calculated automatically, if offset is zero. Access to
structure items is by index or by name, if the initializer list
provides named items.

Under the hood an exact image of the C structure is created.

 Larry

leo


Re: Synopsis 9 draft 1

2004-09-04 Thread Eirik Berg Hanssen
Larry Wall [EMAIL PROTECTED] writes:

 On Fri, Sep 03, 2004 at 05:45:12PM -0600, John Williams wrote:

 : What happens when the Pascal programmer declares
 : 
 : my int @ints is shape(-10..10);
 : 
 : Does it blow up?

 No.

 : If not, does  @ints[-1]  mean the element with index -1 or the last element?

 The element with index -1.  Arrays with explicit ranges don't use the
 minus notation to count from the end.

  If '*' is already going to be a special term when expecting an array
index, I could imagine using it also as a term for the end of the
array -- which end depending on whether it is used in addition or
subtraction.

my int @ints is shape(-10..10;0..3);

@ints[*+0;*-0] =:= @ints[-10;3];

  (Though I cannot see any reason why I would want to use something
like that, I am sure someone somewhere would find it useful ...)

 We probably need to come up with some other notation for the
 beginning and end indexes.  But it'd be nice if that were a little
 shorter than:

 @ints.shape[0].beg
 @ints.shape[0].end

 Suggestions?  Maybe we just need integers with whence properties... :-)

  A _little_ shorter, okay?  If @ints.shape[0] is a range, then:

my int @ints is shape(-10..10;0..3);
@ints.shape[0;0] == -10;
@ints.shape[0;-1] == 10;

  Assuming shape has the proper shape, that is.  :-)

  And, in scalar context, it would still return the size.

my int @ints is shape(-10..10;0..3);
@ints.shape[0] == 21;

  ... now, I don't know if I mean that seriously.  You be the judge.  :-)


Eirik
-- 
 Rule of Feline Frustration: ---* I bet you never noticed that
When your cat has fallen asleep on your lap | homeowner has the word
and looks utterly content and adorable, you | meow in the middle of it. 
will suddenly have to go to the bathroom.   *-  P. McGraw 


Re: Synopsis 9 draft 1

2004-09-04 Thread Sean O'Rourke
At Fri, 3 Sep 2004 17:08:00 -0700,
[EMAIL PROTECTED] (Larry Wall) wrote:
 
 On Fri, Sep 03, 2004 at 05:45:12PM -0600, John Williams wrote:
 : If not, does  @ints[-1]  mean the element with index -1 or the last element?
 
 The element with index -1.  Arrays with explicit ranges don't use the
 minus notation to count from the end.  We probably need to come up
 with some other notation for the beginning and end indexes.  But it'd
 be nice if that were a little shorter than:
 
 @ints.shape[0].beg
 @ints.shape[0].end
 
 Suggestions?  Maybe we just need integers with whence properties... :-)

I think @ints[-11] is the obvious choice!

Also, it might be a decent default to have array parameters (or any
bindings) automatically readjust their indices to [0..$#array] unless
explicitly declared otherwise:

sub f1(@a) { @a[0] }
sub f2(@a is shape(:natural))  { @a[0] }
sub f3(@a is shape(-2..(-2 + @a.len))) { @a[0] }

my @array is shape(-1..1) = 1..3;

f1(@a);  # == 1
f2(@a);  # == 2
f3(@a);  # == 3

That way, any code using non-zero-based indices would be clearly
marked as such, which seems prudent -- I know I don't use $[ where
appropriate, and usually assume that $#x + 1 == @x.

/s


The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread David Green
In article [EMAIL PROTECTED], 
 [EMAIL PROTECTED] (Larry Wall) wrote:
I'm still thinking A is the first one and Z is the last one.  Someone
talk me out of it quick.

Just think of all the trouble it would cause in the summaries:
'Meanwhile, in perl6-language, there was much discussion about Z.  
Actually, most of the discussion was about Z, but there's no chance I'm 
using the American pronunciation.  I was born pronouncing it Z, and 
I'll die pronouncing it Z, Z be damned.'

Besides, this is Perl, and there should be a classical solution, a 
literary solution, a solution that makes other languages look on 
uncomfortably because they can't quite decide whether it's too crazy for 
words or whether they've been left in the dust once again.

The actual issue is how to distinguish cardinal numbers from ordinals, 
right?  So if we want ordinal numbers, why not use ordinals?

 say From the home office in Moose Jaw, Saskatchewan:;
 say @top_AZ_alternatives[1st .. 10th];

So the first element is 1st (or 1th), and the last is -1st.  Or maybe 0th 
is the first? No, that's silly, 1st should be first.  0th could be the 
element before the first, and I suppose -0th means after the last.  (If 
you read from the 0th/-0th element of an array you presumably get undef, 
and you could write to it to unshift/push.)

We already have ordinals for grammars, so I'm sure we could make 'em work 
here.  (Maybe nth() is an operator that constructs ordinal-objects?   
(I kind of want a th suffix operator so I can do ($n)th.  Although that 
doesn't really lend itself to counting from the end, like the supposed 
-nth operator, unless you can do something like ($n)th but backwards 
... eh, which may not be worth it.))

I actually found things I liked in pretty much all the suggested 
alternatives, but none of them reached out and grabbed me by the throat 
the way nth did.  It just seems more Perlish.


   - David just reali[sz]ed that in England @floor[1st] is 
 the second, but is hoping nobody else notices Green


Re: Synopsis 9 draft 1

2004-09-04 Thread Larry Wall
On Sat, Sep 04, 2004 at 09:47:29AM +0200, Leopold Toetsch wrote:
: John Williams [EMAIL PROTECTED] wrote:
: 
:  What happens when the Pascal programmer declares
: 
:  my int @ints is shape(-10..10);
: 
: Should that really all be in core? Why not let the user create his own
: derived array that does what she wants?

That's sort of what we're doing here.  Normal arrays have no shape
and are 0-based.

: Honestly I don't see the point why all normal array usage should be
: slowed down just for the sake of some rare usage patterns.

Does it have to?  Couldn't it have a different vtable?  (Which argues
that such a shape ought to be considered an parameterization of the
implementation type.  (Which argues that it should be of shape
rather than is shape...).)

Larry


Re: The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread Larry Wall
On Sat, Sep 04, 2004 at 08:30:27AM -0600, David Green wrote:
: I actually found things I liked in pretty much all the suggested 
: alternatives, but none of them reached out and grabbed me by the throat 
: the way nth did.  It just seems more Perlish.

Yow.  Presumably nth without an argument would mean the last.  So

@ints[1st..nth]

means

@ints[*]

And if it's a unary with an optional arg, we can write

@ints[nth+1..nth-1]

Hmm, that's not quite right.  My wife looks over my shoulder and
says What about zth?  Not knowing the history of A..Z already...

But yeah, nth is pretty grabby.

Larry


Re: Synopsis 9 draft 1

2004-09-04 Thread Nigel Sandever
On Fri, 3 Sep 2004 17:08:00 -0700, [EMAIL PROTECTED] (Larry Wall) wrote:
 On Fri, Sep 03, 2004 at 05:45:12PM -0600, John Williams wrote:
 : On Thu, 2 Sep 2004, Larry Wall wrote:
 : 
 :  The argument to a shape specification is a semicolon list, just like
 :  the inside of a multidimensional subscript.  Ranges are also allowed,
 :  so you can pretend you're programming in Fortran, or awk:
 : 
 :  my int @ints is shape(1..4;1..2); # two dimensions, @ints[1..4; 1..2]
 : 
 : What happens when the Pascal programmer declares
 : 
 : my int @ints is shape(-10..10);
 : 
 : Does it blow up?
 
 No.
 
 : If not, does  @ints[-1]  mean the element with index -1 or the last element?
 
 The element with index -1.  Arrays with explicit ranges don't use the
 minus notation to count from the end.  We probably need to come up
 with some other notation for the beginning and end indexes.  But it'd
 be nice if that were a little shorter than:
 
 @ints.shape[0].beg
 @ints.shape[0].end
 
 Suggestions?  Maybe we just need integers with whence properties... :-)

How about keywords clo and chi?

 
 Larry





Re: The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread Adam D. Lopresto
On Sat, 4 Sep 2004, David Green wrote:

 In article [EMAIL PROTECTED],
  [EMAIL PROTECTED] (Larry Wall) wrote:
 I'm still thinking A is the first one and Z is the last one.  Someone
 talk me out of it quick.

 The actual issue is how to distinguish cardinal numbers from ordinals,
 right?  So if we want ordinal numbers, why not use ordinals?

  say From the home office in Moose Jaw, Saskatchewan:;
  say @top_AZ_alternatives[1st .. 10th];

 So the first element is 1st (or 1th), and the last is -1st.  Or maybe 0th
 is the first? No, that's silly, 1st should be first.  0th could be the
 element before the first, and I suppose -0th means after the last.  (If
 you read from the 0th/-0th element of an array you presumably get undef,
 and you could write to it to unshift/push.)

Very close.  I really like counting from the front using a postfix operator
th (you'd also want st and nd to be synonymous, and maybe a special
first) but it seems to me trying to count backwards in that scheme just
doesn't quite work.  That last element isn't -1st, that's (or at least
(-1)st, depending on precedence) the one before the 0th, which is the one
before the 1st.  If you want to count from the end, why not go all the way and
use last, last-1, last-2, etc.  last+1 would be the first element past
the current bounds, so push @foo, $bar would be the same as
@foo[last+1]=$bar.  Of course, getting any of this to actually work seems
tricky, but doesn't seem any harder than A or Z, and would read extremely well.

 We already have ordinals for grammars, so I'm sure we could make 'em work
 here.  (Maybe nth() is an operator that constructs ordinal-objects?
 (I kind of want a th suffix operator so I can do ($n)th.  Although that
 doesn't really lend itself to counting from the end, like the supposed
 -nth operator, unless you can do something like ($n)th but backwards
 ... eh, which may not be worth it.))

I don't see any reason why st, nd, and th couldn't be postfix operators
instead of prefix.
-- 
Adam Lopresto
http://cec.wustl.edu/~adam/

The prince wants your daughter for his wife.
Well, tell him his wife can't have her.
- Blackadder III


Re: Synopsis 9 draft 1

2004-09-04 Thread Larry Wall
: On Sat, Sep 04, 2004 at 09:47:29AM +0200, Leopold Toetsch wrote:
: : Honestly I don't see the point why all normal array usage should be
: : slowed down just for the sake of some rare usage patterns.

On Sat, Sep 04, 2004 at 08:48:54AM -0700, Larry Wall wrote:
: Does it have to?  Couldn't it have a different vtable?

Though I can see where it might slow down some optimizations.

Larry


Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-04 Thread John Williams
On Sat, 4 Sep 2004, Juerd wrote:
 John Williams skribis 2004-09-03 23:06 (-0600):
   (A and Z)
  I think I'd prefer alpha and omega.

 Why not use Cyrillic or Korean or the secret code alphabet we used in
 school?

I meant the actual words alpha and omega, because they're like A and Z
but with some extra religious connotation of first and last.


st (nd, rd) as a cardinal postfix operator sounds good.

To keep 1st+$n a Cardinal, we could define

  multi operator:+ (Cardinal $a, Int $b) is commutative {...}

Is nth a magic function that returns the cardinal size of the
dimension it is in?

~ John Williams




Re: The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread Luke Palmer
David Green writes:
 The actual issue is how to distinguish cardinal numbers from ordinals, 
 right?  So if we want ordinal numbers, why not use ordinals?

While we're here, I think perl should understand ordinals
(http://mathworld.wolfram.com/OrdinalNumber.html), too.  The syntax is
quite ready for it:

$w = +0...;
$w1 = $w + 1;
assert($w1  $w);

sub wn($n) { $n ?? wn($n-1)+1 :: $w }
$w2 = 0... + wn0...;
assert($w2 == $w*2);

Just think of the possibilities!  :-)

Seriously though, putting 1st, 2nd, nth, etc. in the language is somehow
very appealing.  It makes my heartburn about m:1st// settle down quite a
bit, too.

Luke



Re: The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread David Green
On 2004/9/04, [EMAIL PROTECTED] (Larry Wall) wrote:
Yow.  Presumably nth without an argument would mean the last.  So
@ints[1st..nth]
means
@ints[*]

Yeah, I was thinking something like that.  And if the arg is an actual 
array, maybe it returns the max dimension(s)?  I think you'd get that 
anyway for one dimension...  in scalar context it would just be the same 
as using the array itself, since it returns the number of elements:

 @degree=('a'..'f');
 nth @degree == nth(@degree) == nth([EMAIL PROTECTED]) == nth(6) == 6th
 nth @degree == @degree.nth == 6

Hm, some ambiguity there, since 6 isn't quite the same as 6th (although 
of course it only makes sense for 6th to evaluate to 6 in numeric 
context).  So the .nth method needs to return an ordinal?

But with multiple dimensions, nth would return the max for each one:
 @degree is shape (5;6;7);
 nth @degree != nth ([EMAIL PROTECTED])
 nth @degree == @degree.nth == (5, 6, 7)  # or is that (5;6;7)?  
  # or (5th;6th;7th)?

So @degree[nth @degree] == @degree[nth; nth; nth];

Something like that

And if it's a unary with an optional arg, we can write

@ints[nth+1..nth-1]

Hmm, that's not quite right.  My wife looks over my shoulder and 
says What about zth?  Not knowing the history of A..Z already...

=)  Was that supposed to be first to last again, or second to second 
last?  1st, 2nd, nth could all take an arg; but I think no arg should 
mean the same as an argument of zero.  Then nth+1 = 1st+0 = 2nd-1, etc.

 @int[1st+0 .. nth-0] # first to last
 @int[1st+1 .. nth-1] # second to second last
 @int[1st+2 .. nth-2] # third to third last

 @int[1st+$offset .. nth-$offset] #whateverth to whateverth last
 @int[nth(1+$offset)..nth(-$offset)]  #same thing

Using nth(1) to mean first looks better with the brackets, I guess.  
(Psychologically it reads more like the nth position is 1 than the 
nth position plus 1 more.)  There's still that problem of whether 0th 
should be at the beginning or the end (or both (or neither)).  Having 
both +0th and -0th is a nice symmetry, but it's more suited to humans 
than programmers; one reason for wanting to make -1 the last position is 
so that you can wrap around simply by decrementing your counter.

Whichever way we try to go, Murphy's Law predicts you'll always wish the 
zero were at the other end.  I think it makes more sense to start 
counting with the first==nth(1) and go up to the last=nth(0)=nth: 
because counting from the front is likely to happen more often than 
counting from the end; and because 1st(0) gives us a symmetrical 
counterpart to nth(0).


-David nth degrees of exasperation Green


Re: The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread David Green
In article [EMAIL PROTECTED],
 [EMAIL PROTECTED] (Luke Palmer) wrote:

sub wn($n) { $n ?? wn($n-1)+1 :: $w }
$w2 = 0... + wn«0...;
assert($w2 == $w*2);
Just think of the possibilities!  :-)

Hm.  Needs more Unicode.  =)

Seriously though, putting 1st, 2nd, nth, etc. in the language is somehow
very appealing.  It makes my heartburn about m:1st// settle down quite a
bit, too.

It is kind of comfortable.  Which is why I think I'd like to keep the 
redundant nth (if we have first and last), aka 'th (where nth($i) 
and $i'th are just pre- and postfixed versions of each other).

When you're referring to an element in the middle of a list,
 $four'th
just feels cleaner than first+$four or something.


Re: The first shall be first (was Re: parameter contexts (was: Synopsis 9 draft 1))

2004-09-04 Thread Jonathan Lang
David Green wrote:
 It is kind of comfortable.  Which is why I think I'd like to keep the 
 redundant nth (if we have first and last), aka 'th (where nth($i) 
 and $i'th are just pre- and postfixed versions of each other).

Especially important since there's a potential ambiguity problem between
the C$n'th notation and the C'' notation, whereas no such ambiguity
exists for Cnth($n).  

 When you're referring to an element in the middle of a list,
  $four'th
 just feels cleaner than first+$four or something.

or something (namely, last+$four, or 0th+$four).  :)  In this case,
C0th would probably be clearer than Clast.  

And whenever the ambiguity isn't an issue, I'd prefer $four'th to
nth($four) as well.  

=
Jonathan Dataweaver Lang



__
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail


Re: Synopsis 9 draft 1

2004-09-03 Thread Tim Bunce
On Thu, Sep 02, 2004 at 04:47:40PM -0700, Larry Wall wrote:
 
 =head1 Compact structs
 
 A class whose attributes are all low-level types can behave as
 a struct.

all low-level types or all low-level *sized* types?
(I'm wondering about char arrays, string and pointers.)

I presume a char[n] array within a structure could be represented
as an array of int8. That might be uncomfortable to work with.

And that a pointer would be... what? Some platforms has odd
sizing issues for pointers. Perhaps a voidp type is needed?
(Which would just be an intN where N is sizeof(void*)*8.)

If a class whose attributes are all low-level types can behave as
a struct, is that class then also considered a low-level type?
(So other structs can be composed from it.)

I think that's important because it allows you to avoid having
to build too much into the base perl6 language. Semantics like
turning an array of int8 with a string with or without paying
attention to an embedded null, can be provided by classes that
implement specific behaviours for low level types but can still
be considered low level types themselves.

 (Access from outside the class is still only through
 accessors, though.)  Whether such a class is actually stored compactly
 is up to the implementation, but it ought to behave that way,
 at least to the extent that it's trivially easy (from the user's
 perspective) to read and write to the equivalent C structure.

Is there some syntax to express if the struct is packed or
needs alignment? (Perhaps that would be needed per element.)

Certainly there's a need to be able match whatever packing
and alignment the compiler would use.

(I'm not (yet) familiar with Parrot's ManagedStruct and UnManagedStruct
types but there's probably valuable experience there.)

 That is, when byte-stringified, it should look like the C struct,
 even if that's not how it's actually represented inside the class.
 (This is to be construed as a substitute for at least some of the
 current uses of Cpack/Cunpack.)

Whether elements are packed or not for byte stringification is,
perhaps, orthognal to whether they're packed internally.

Network i/o would prefer packed elements and structure interfacing
would need aligned elements.

Tim.


Re: Synopsis 9 draft 1

2004-09-03 Thread Rafael Garcia-Suarez
On Fri, 3 Sep 2004 11:41:05 +0100, Tim Bunce [EMAIL PROTECTED] wrote:
 Is there some syntax to express if the struct is packed or
 needs alignment? (Perhaps that would be needed per element.)

Why am I suddenly thinking about unions ?


Re: Synopsis 9 draft 1

2004-09-03 Thread Jonathan Scott Duff
On Thu, Sep 02, 2004 at 04:47:40PM -0700, Larry Wall wrote:
 my ref[Array] @ragged2d;

What is a ref type exactly? Is it like a pointer in C? If so, and
based on the parameterization above, I assume that there will also be
the appropriate pointer arithmetic such that if $fido is declared as a
ref[Dog] and pointed at an array of Dogs, then $fido++ will move to the
next Dog in the array. Something like this:

my Dog @pound;
my ref[Dog] $fido;
# after we've populated the @pound with Dogs ...
loop ($fido = @pound[0]; ?$fido; $fido++) {
   $fido.bark();
}

Is there some other syntax to get a compact array of things?  Do I
need an attribute on the array?

 the presence of a low-level type tells Perl that it is free to
 implement the array with compact storage, that is, with a chunk
 of memory containing contiguous (or as contiguous as practical)
 elements of the specified type without any fancy object boxing that
 typically applies to undifferentiated scalars.  (Perl tries really
 hard to make these elements look like objects when you treat them
 like objects--this is called autoboxing.)

Will it also try really hard to use compact storage or are the
low-level types just compiler hints?  (As a first approximation, could
all of the int types be implemented as Ints with appropriate
serialization?)

 To declare a multidimensional array, you add a shape parameter:
 
 my num @nums is shape(3);   # one dimension, @nums[0..2]
 my int @ints is shape(4;2); # two dimensions, @ints[0..3; 0..1]

Maybe it's just my BASIC upbringing, but shape doesn't seem like the
right word.  Words like dimension and cardinal fit better in my
head, but I'd want them shorter and dim and card don't quite work
either ;-)

But shape makes me want to do something like this:

my num @a is shape('triangle');
my num @b is shape('octagon');
my num @c is shape('square');

That might make sense for triangles, but not the others (unless
I'm just suffering a failure of imagination)

size could even work though it's vague. Maybe even basis though
that's not quite right either.  Or perhaps extent?

Anyway ...my two cents.  If shape is carved in stone, I'll live with
it :)

 If you wanted that C0..2 range to mean
 
 @nums[0;1;2]
 
 instead, then you need to use that Csemi we keep mentioning:
 
 @nums[semi 0..2]

If I had 

@a = (0,undef,2); 

would 

@nums[semi @a] 

be the same as

@nums[0;*;2]

?

 XXX It's not clear whether C[EMAIL PROTECTED] should return the size of the entire
 array or the size of the first dimension (or the scalar value of the
 entire array if it's really a zero-dimensional array!).  I've put
 C[EMAIL PROTECTED] above just in case.

hmm

my int @a is shape(3;4;5);

[EMAIL PROTECTED];;] == 3   (same as [EMAIL PROTECTED], right?)
[EMAIL PROTECTED];*;] == 4   (same as [EMAIL PROTECTED];*])
[EMAIL PROTECTED];;*] == 5   

BTW, could these also be made to work (or something similar)?

my int @b;
my int @a is shape(10;5;7);
@b = @a[*:by(2);;]  # @b is now shape(5;5;7)
@b = @a[;1,4;]  # @b is now shape(10;2;7)
@b = @a[;(*);]  # @b is now shape(10;7)
@b = @a[;;;*]   # @b is now shape(10;5;7;1)
@b = @a[;;;*5]  # @b is now shape(10;5;7;5)

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Synopsis 9 draft 1

2004-09-03 Thread Gregory P. Keeney
Jonathan Scott Duff wrote:
Maybe it's just my BASIC upbringing, but shape doesn't seem like the
right word.  Words like dimension and cardinal fit better in my
head, but I'd want them shorter and dim and card don't quite work
either ;-)
But shape makes me want to do something like this:
my num @a is shape('triangle');
my num @b is shape('octagon');
my num @c is shape('square');
That might make sense for triangles, but not the others (unless
I'm just suffering a failure of imagination)
I think 'shape' fits better than 'cardinal' or 'dimension'; these things 
have a 'dimension' that is distinct from their shape (e.g., Cmy int @a 
is shape(3;4;5); has three dimensions). 'shape' implies the topology of 
the array; though I can see how it would be easy to assume 'shape' means 
'polygon'.

Think of it more like the shape of ships, the shape of ships, the shape 
of water when it drips (_The Shape of Me and Other Things_ , Dr. 
Suess). A teapot and a mobius strip both have very different shapes with 
very different features, as do a sparse array and a quaternion.

Forgive me if I come across pedantic; I'm just trying to provide some 
examples of thinking in terms of 'shape' as Perl 6 defines it.

Gregory Keeney
Anyway ...my two cents.  If shape is carved in stone, I'll live with
it :)
See, a stone has another shape! grin


Re: Synopsis 9 draft 1

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 10:00:24AM -0500, Jonathan Scott Duff wrote:
: On Thu, Sep 02, 2004 at 04:47:40PM -0700, Larry Wall wrote:
:  my ref[Array] @ragged2d;
: 
: What is a ref type exactly? Is it like a pointer in C?

It's exactly like a reference in Perl 5.  Declaring a compact array of
ref is merely declaring that the array will only hold references
to Perl 6 data structures, and doesn't have to worry about holding
value types like int or num.  It may come out to the same thing as an
ordinary array, depending on how Parrot ends up defining references
internally.

: If so, and
: based on the parameterization above, I assume that there will also be
: the appropriate pointer arithmetic such that if $fido is declared as a
: ref[Dog] and pointed at an array of Dogs, then $fido++ will move to the
: next Dog in the array. Something like this:
: 
:   my Dog @pound;
:   my ref[Dog] $fido;
:   # after we've populated the @pound with Dogs ...
:   loop ($fido = @pound[0]; ?$fido; $fido++) {
:  $fido.bark();
:   }

I don't see any more reason to allow that in Perl 6 than in Perl 5.

: Is there some other syntax to get a compact array of things?  Do I
: need an attribute on the array?

I don't know what you mean by of things.

:  the presence of a low-level type tells Perl that it is free to
:  implement the array with compact storage, that is, with a chunk
:  of memory containing contiguous (or as contiguous as practical)
:  elements of the specified type without any fancy object boxing that
:  typically applies to undifferentiated scalars.  (Perl tries really
:  hard to make these elements look like objects when you treat them
:  like objects--this is called autoboxing.)
: 
: Will it also try really hard to use compact storage or are the
: low-level types just compiler hints?  (As a first approximation, could
: all of the int types be implemented as Ints with appropriate
: serialization?)

I suspect the compiler will try harder for composite types than for
scalars, but certain algorithms will run much faster if they can use
Parrot integer registers rather than PMCs, so int and num scalars
are also likely to be implemented by the Perl 6 compiler directly.

:  To declare a multidimensional array, you add a shape parameter:
:  
:  my num @nums is shape(3);   # one dimension, @nums[0..2]
:  my int @ints is shape(4;2); # two dimensions, @ints[0..3; 0..1]
: 
: Maybe it's just my BASIC upbringing, but shape doesn't seem like the
: right word.  Words like dimension and cardinal fit better in my
: head, but I'd want them shorter and dim and card don't quite work
: either ;-)
: 
: But shape makes me want to do something like this:
: 
:   my num @a is shape('triangle');
:   my num @b is shape('octagon');
:   my num @c is shape('square');
: 
: That might make sense for triangles, but not the others (unless
: I'm just suffering a failure of imagination)
: 
: size could even work though it's vague. Maybe even basis though
: that's not quite right either.  Or perhaps extent?
: 
: Anyway ...my two cents.  If shape is carved in stone, I'll live with
: it :)

I picked it only because that's what the PDL folks came up with
in their series of RFCs after their own round of discussions.
That doesn't mean we can't change it if we do come up with something
better.  But I rather like shape.  It's short, and not easily confused
with other Perl 6 concepts.

:  If you wanted that C0..2 range to mean
:  
:  @nums[0;1;2]
:  
:  instead, then you need to use that Csemi we keep mentioning:
:  
:  @nums[semi 0..2]
: 
: If I had 
: 
:   @a = (0,undef,2); 
: 
: would 
: 
:   @nums[semi @a] 
: 
: be the same as
: 
:   @nums[0;*;2]
: 
: ?

Dunno.  I suspect we can allow

@a = (0,*,2);

in the indirect form in any event.  But the '*' is also still negotiable.
As is the semi, for that matter.

:  XXX It's not clear whether C[EMAIL PROTECTED] should return the size of the 
entire
:  array or the size of the first dimension (or the scalar value of the
:  entire array if it's really a zero-dimensional array!).  I've put
:  C[EMAIL PROTECTED] above just in case.
: 
: hmm
: 
: my int @a is shape(3;4;5);
: 
: [EMAIL PROTECTED];;] == 3   (same as [EMAIL PROTECTED], right?)
: [EMAIL PROTECTED];*;] == 4   (same as [EMAIL PROTECTED];*])
: [EMAIL PROTECTED];;*] == 5   
: 
: BTW, could these also be made to work (or something similar)?

That seems rather opaque to me.  Better is

@a.shape[0] == 3
@a.shape[1] == 4
@a.shape[2] == 5

: my int @b;
: my int @a is shape(10;5;7);
: @b = @a[*:by(2);;]# @b is now shape(5;5;7)
: @b = @a[;1,4;]# @b is now shape(10;2;7)
: @b = @a[;(*);]# @b is now shape(10;7)
: @b = @a[;;;*] # @b is now shape(10;5;7;1)
: @b = @a[;;;*5]# @b is now shape(10;5;7;5)

I don't like notation that uses null slices to mean everything,
because, as you 

Re: Synopsis 9 draft 1

2004-09-03 Thread Jonathan Scott Duff
On Fri, Sep 03, 2004 at 09:29:36AM -0700, Larry Wall wrote:
 : If so, and
 : based on the parameterization above, I assume that there will also be
 : the appropriate pointer arithmetic such that if $fido is declared as a
 : ref[Dog] and pointed at an array of Dogs, then $fido++ will move to the
 : next Dog in the array. Something like this:
 : 
 : my Dog @pound;
 : my ref[Dog] $fido;
 : # after we've populated the @pound with Dogs ...
 : loop ($fido = @pound[0]; ?$fido; $fido++) {
 :$fido.bark();
 : }
 
 I don't see any more reason to allow that in Perl 6 than in Perl 5.

heh, that answers that then. I was trying to put on a I'm a C coder and
I want to write perl as C hat, but I guess the answer is learn perl!

 : Is there some other syntax to get a compact array of things?  Do I
 : need an attribute on the array?
 
 I don't know what you mean by of things.

If my int @foo makes a compact array of ints, is there a way to make a
compact array of Dog? (Does it even make sense?) And if so, does it look
like my Dog @foo or must there be some other syntax to declare it?

 I picked it only because that's what the PDL folks came up with
 in their series of RFCs after their own round of discussions.
 That doesn't mean we can't change it if we do come up with something
 better.  But I rather like shape.  It's short, and not easily confused
 with other Perl 6 concepts.

Works for me.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Synopsis 9 draft 1

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 12:25:37PM -0500, Jonathan Scott Duff wrote:
: If my int @foo makes a compact array of ints, is there a way to make a
: compact array of Dog? (Does it even make sense?) And if so, does it look
: like my Dog @foo or must there be some other syntax to declare it?

It's just my Dog @foo, which can be stored exactly like my
ref @foo.  Maybe my ref @foo is redundant with my Any @foo,
if Any is always a reference type.  (Which would imply that a mere
value passed to an Any parameter would be autoboxed, which sounds
about right.  When viewed as an Any, int turns into Int, num into Num,
str into Str, ref into Ref, dog into Dog, etc. :-)

Larry


Re: Synopsis 9 draft 1

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 11:41:05AM +0100, Tim Bunce wrote:
: On Thu, Sep 02, 2004 at 04:47:40PM -0700, Larry Wall wrote:
:  
:  =head1 Compact structs
:  
:  A class whose attributes are all low-level types can behave as
:  a struct.
: 
: all low-level types or all low-level *sized* types?
: (I'm wondering about char arrays, string and pointers.)

I'm not intending to run this all the way into C madness.  :-)

The problem with arrays, even arrays that are of fixed shape, is
that someone has to remember that shape, and in the case of a dynamic
language, that's not always going to be the compiler.  So either we
have to find someplace related to the object to tuck an invisible array
header, or we force the programmer to keep track of lengths as C does.
I am presuming the former is the better approach.  I really only care
if it's efficient to serialize to and from C structs, not whether the
in-memory representation is identical.

: I presume a char[n] array within a structure could be represented
: as an array of int8. That might be uncomfortable to work with.

Not a lot more uncomfortable to work with than in C.  :-)

But I'm guessing the low-level Cstr type is a buffer of bytes.  Probably
means we say

has str $s is bytes($n)

or

has str[n] $s

or some such.

: And that a pointer would be... what? Some platforms has odd
: sizing issues for pointers. Perhaps a voidp type is needed?
: (Which would just be an intN where N is sizeof(void*)*8.)

Eh, pointer?  I don't see any pointers around here...but then I
haven't looked very hard on purpose...

: If a class whose attributes are all low-level types can behave as
: a struct, is that class then also considered a low-level type?
: (So other structs can be composed from it.)

It should be easy to serialize.

: I think that's important because it allows you to avoid having
: to build too much into the base perl6 language. Semantics like
: turning an array of int8 with a string with or without paying
: attention to an embedded null, can be provided by classes that
: implement specific behaviours for low level types but can still
: be considered low level types themselves.

That's fine, but you have to expect the objects to keep extra info
around to manage some of the low-level types according to the desired
semantics.  What this probably means is that objects might have extra
parameters that aren't expected to officially serialize/deserialize.
I don't profess to be an expert on that subject.  I just want it to
be fairly efficient to interface to C and C++ libraries that return
structures.  But only to the extent that it doesn't warp Perl into C.
I'm just trying to tell the implementors that they are allowed to
go as far as they reasonably can in that direction, as long as they
don't feel like they have to go unreasonably far.  :-)

:  (Access from outside the class is still only through
:  accessors, though.)  Whether such a class is actually stored compactly
:  is up to the implementation, but it ought to behave that way,
:  at least to the extent that it's trivially easy (from the user's
:  perspective) to read and write to the equivalent C structure.
: 
: Is there some syntax to express if the struct is packed or
: needs alignment? (Perhaps that would be needed per element.)

Would be easy to specify with traits.

: Certainly there's a need to be able match whatever packing
: and alignment the compiler would use.

It only has to look like that.  :-)

: (I'm not (yet) familiar with Parrot's ManagedStruct and UnManagedStruct
: types but there's probably valuable experience there.)

Quite likely.

:  That is, when byte-stringified, it should look like the C struct,
:  even if that's not how it's actually represented inside the class.
:  (This is to be construed as a substitute for at least some of the
:  current uses of Cpack/Cunpack.)
: 
: Whether elements are packed or not for byte stringification is,
: perhaps, orthognal to whether they're packed internally.

Well, I don't know if it's 90° in practice because of efficiency concerns,
but in the abstract that's about right.

: Network i/o would prefer packed elements and structure interfacing
: would need aligned elements.

Presumably.  I expect the default would be aligned.

Larry


Re: Synopsis 9 draft 1

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 05:45:12PM -0600, John Williams wrote:
: On Thu, 2 Sep 2004, Larry Wall wrote:
: 
:  The argument to a shape specification is a semicolon list, just like
:  the inside of a multidimensional subscript.  Ranges are also allowed,
:  so you can pretend you're programming in Fortran, or awk:
: 
:  my int @ints is shape(1..4;1..2); # two dimensions, @ints[1..4; 1..2]
: 
: What happens when the Pascal programmer declares
: 
: my int @ints is shape(-10..10);
: 
: Does it blow up?

No.

: If not, does  @ints[-1]  mean the element with index -1 or the last element?

The element with index -1.  Arrays with explicit ranges don't use the
minus notation to count from the end.  We probably need to come up
with some other notation for the beginning and end indexes.  But it'd
be nice if that were a little shorter than:

@ints.shape[0].beg
@ints.shape[0].end

Suggestions?  Maybe we just need integers with whence properties... :-)

Larry


Re: Synopsis 9 draft 1

2004-09-03 Thread John Williams
On Thu, 2 Sep 2004, Larry Wall wrote:
 A multidimensional array is indexed by a semicolon list, which is really
 a list of lists in disguise.  Each sublist is a slice of one particular
 dimension.  So

 @array[0..10; 42; @x]

 is really short for

 @array.postcircumfix:[]( == [0..10], [42], [EMAIL PROTECTED] );

I'm a bit surprised.

If I declare

   method postcircumfix:[] ($self: [EMAIL PROTECTED]);

Is $object[$yada] the same as

   $object.postcircumfix:[]( $yada );  # which I would expect

or

   $object.postcircumfix:[]( == [ $yada ] );  # which surprises me

If the latter, Why?
If the former, where did the extra magic for arrays come from?


Tangential trivial thoughts:

Can I declare an alphabetic postcircumfix operator?

   sub postcircumfix:ipso...facto ( $left, $inside ) {...}

Is that even usable, given that no space is allowed before the
postcircumfix operator?  Or does this work:

   $foo.ipso 'bar' facto;

Or maybe it has to be declared multi instead of sub for that?

~ John Williams



Re: Synopsis 9 draft 1

2004-09-03 Thread Rod Adams
Larry Wall wrote:
On Fri, Sep 03, 2004 at 05:45:12PM -0600, John Williams wrote:
: What happens when the Pascal programmer declares
: 
: my int @ints is shape(-10..10);
: 
: Does it blow up?

No.
: If not, does  @ints[-1]  mean the element with index -1 or the last element?
The element with index -1.  Arrays with explicit ranges don't use the
minus notation to count from the end.  We probably need to come up
with some other notation for the beginning and end indexes.  But it'd
be nice if that were a little shorter than:
   @ints.shape[0].beg
   @ints.shape[0].end
Suggestions?  Maybe we just need integers with whence properties... :-)
Larry
What jumps to my mind is that inside an array subscript could be 
(sub)?context of it's own. Then one could do:

@ints[.beg .. .end ; .beg + 3 .. .end];
Where the .beg and .end would relate to @ints.shape[0] or @ints.shape[1] 
depending on which position it's in.

My only issue with this, and why I refered to it as a possible 
subcontext, is that it's easy to concieve of somewanting to use the 
prior context to generate the subscripts for an array.

The other idea which jumps to mind was to create an operator which tell 
the compiler to treat the the following number as if it referred to a 
0-based (sub)array, and negatives count off the end. What springs to my 
mind is that we are saying this is the relative to start / end of the 
range, so I will call it  (capital delta).

@ints[ 0 .. -1 ; 3 .. -1 ];
It at least looks nice.
-- Rod


Re: Synopsis 9 draft 1

2004-09-03 Thread Luke Palmer
John Williams writes:
 On Thu, 2 Sep 2004, Larry Wall wrote:
  A multidimensional array is indexed by a semicolon list, which is really
  a list of lists in disguise.  Each sublist is a slice of one particular
  dimension.  So
 
  @array[0..10; 42; @x]
 
  is really short for
 
  @array.postcircumfix:[]( == [0..10], [42], [EMAIL PROTECTED] );
 
 I'm a bit surprised.
 
 If I declare
 
method postcircumfix:[] ($self: [EMAIL PROTECTED]);
 
 Is $object[$yada] the same as
 
$object.postcircumfix:[]( $yada );  # which I would expect
 
 or
 
$object.postcircumfix:[]( == [ $yada ] );  # which surprises me
 
 If the latter, Why?
 If the former, where did the extra magic for arrays come from?

Well, that's just postcircumfix operators are defined.  We have to pick
some way for the arguments to come in for any operator type we define,
and this is just how those work.  

Defining postcircumfix operators this way allows us to use semicolon
slices in hashes and even sub-like calls:

method postcircumfix:() ($self: [EMAIL PROTECTED]) {...}

$object($foo ; $bar);

For multiple argument lists.  Coderefs don't do this by default (they
don't accept that notation), but other forms of $object() might.

BTW, the latter is the same as:

$object.postcircumfix:[]( [$yada] );

Since it has no positional section.

 Tangential trivial thoughts:
 
 Can I declare an alphabetic postcircumfix operator?
 
sub postcircumfix:ipso...facto ( $left, $inside ) {...}
 
 Is that even usable, given that no space is allowed before the
 postcircumfix operator?  Or does this work:
 
$foo.ipso 'bar' facto;

Yep, that's fine, if very weird looking.

Luke


parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread Jonathan Lang
Larry Wall wrote:
 Arrays with explicit ranges don't use the minus notation to count from 
 the end.  We probably need to come up with some other notation for the 
 beginning and end indexes.  But it'd be nice if that were a little 
 shorter than:
 
 @ints.shape[0].beg
 @ints.shape[0].end
 
 Suggestions?  Maybe we just need integers with whence properties...
 :-)

Actually, I'd go for something a little bit longer in the first case:

   @ints.shape[0].begin

'beg' is what you do when you're down on your luck; it oughtn't be how you
start out.  

As for shortening things, a bit of dwimmery might be in order: if the
array in question only has one dimension, the [0] might be made optional;
and when you're using the postcircumfix:[] index operator, you might have
each expression evaluated in the context of the appropriate dimension:

   @ints[.begin + 2, .end - 3]

would be equivalent to

   @[EMAIL PROTECTED] + 2, @ints.shape[1].end - 3]

I wonder if this notion of contextualizing a method's signature could be
generalized... I could see a case for treating most methods as if the
expressions in each parameter were being evaluated within the caller's
class:

   scratch $jack: .back

would be equivalent to

   $jack.scratch($jack.back)

This isn't quite the same thing as the index operator given above:

   @ints[.begin + 2, .end - 3]

would be equivalent to

   @[EMAIL PROTECTED] + 2, @ints.end - 3]

by this logic, which isn't what we want.  We'd either have to make this a
special case or say:

   @ints[.shape[0].begin + 2, .shape[1].end - 3]

...which would be unneccessarily bulky.  OTOH, it would be annoying if we
had to say

   @[EMAIL PROTECTED], @ints.shape[0].begin]

if we wanted to access the index whose first dimension corresponds to the
lowest bound of the second dimension and vice versa - though why you'd
ever want to do something like that is beyond me.  Perhaps this is
appropriate Huffman coding after all...

How to declare this?  Perhaps you could do something like:

   method postcircumfix:[] 
 ($object: [EMAIL PROTECTED] is context($object.shape[$_])) {...}

where the context trait normally has a value of $object in a method. 
The above is an example of how the thing would be applied to the list
parameter, with the context being applied to each element in turn and $_
being set to the list's index for that element; similarly, an anonymous
named parameter might work the same way, with $_ being set to the
parameter's key.  Any function that has exactly one invocant would have a
default context of that invocant for every parameter, while any function
that has anything _but_ one invocant would have _no_ default parameter
context - which wouldn't stop programmers from explicitly adding contexts
where appropriate.  

=
Jonathan Dataweaver Lang



___
Do you Yahoo!?
Win 1 of 4,000 free domain names from Yahoo! Enter now.
http://promotions.yahoo.com/goldrush


Re: Synopsis 9 draft 1

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 07:42:53PM -0500, Rod Adams wrote:
(B: What jumps to my mind is that inside an array subscript could be 
(B: (sub)?context of it's own. Then one could do:
(B: 
(B: @ints[.beg .. .end ; .beg + 3 .. .end];
(B
(BAwful dotty...
(B
(B: Where the .beg and .end would relate to @ints.shape[0] or @ints.shape[1] 
(B: depending on which position it's in.
(B: 
(B: My only issue with this, and why I refered to it as a possible 
(B: subcontext, is that it's easy to concieve of somewanting to use the 
(B: prior context to generate the subscripts for an array.
(B
(BThat too...
(B
(B: The other idea which jumps to mind was to create an operator which tell 
(B: the compiler to treat the the following number as if it referred to a 
(B: 0-based (sub)array, and negatives count off the end. What springs to my 
(B: mind is that we are saying this is the "relative to start / end" of the 
(B: range, so I will call it $B&$(B (capital delta).
(B: 
(B: @ints[ $B&$(B0 .. $B&$(B-1 ; $B&$(B3 .. $B&$(B-1 ];
(B: 
(B: It at least looks nice.
(B
(BI'd prefer to keep things in the Latin-1 range though.
(B
(BHere's some other screwy ideas:
(B
(B@ints[A..Z]
(B@ints[=+0..=-1]
(B@ints[|+0..|-1]
(B@ints[\+0..\-1]
(B@ints[{0}..{-1}]
(B
(BThere's something to be said for the last one.  Those are actually
(Bclosures, so it'd be perfectly natural for the subscript to delay
(Bevaluation of those numbers until it know the current bounds of the
(Bcurrent dimension.  The other syntaxes would have to be recognized
(Band translated to @ints.shape[$dim].beg and .end.  Which would
(Bpreclude them from being used outside a subscript:
(B
(B@allbutone = (A..Z-1);
(Breturn @[EMAIL PROTECTED];
(B
(BI suppose we could always get around that with special endpoint objects.
(BBut closures are already special.  On the other hand, that's a real
(Bminus in the closure, so it's sort of making the same mistake as Perl 5.
(B
(BThough if we went with A and Z, I suppose for consistency the
(Bcorresponding methods would want to be:
(B
(B@ints.shape[$dim].A
(B@ints.shape[$dim].Z
(B
(BAnd that A..Z notation has the benefit of *not* relying on the -1 hack.
(B(Though presumably the \+ and \- style thingies are two-character
(Bunary operators, not real numeric operators.  In which case \-0 means
(Bthe first unused entry after the array.  Poor-man's push:
(B
(B@ints[\-0] = $x;
(B
(BCould even do the same chicanery with {+0} and {-1}, I suppose, but that
(Bfeels tacky.
(B
(BI guess I still have a soft spot for the A to Z approach:
(B
(B@ints[Z+1] = $x;
(B
(BI wonder if that means that @ints.shape[n].AZ returns a range.
(B
(BThe fun thing would be getting A..Z to work for enumerated ranges of
(Bhash keys.  I thought it was kind of fun that Perl 5's restricted
(Bhashes naturally fell out of shape("Foo", "Bar", "Baz").  I guess
(Bthat means the .. operator has to be sensitive to which subscript
(Bit's being expanded in, though.  And A+1..Z-1 would presumably be
(Bsmart enough to give you only a "Bar"...which some folks might be
(Bhappy enough with.
(B
(BLarry

Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 06:31:49PM -0700, Jonathan Lang wrote:
: I wonder if this notion of contextualizing a method's signature could be
: generalized... I could see a case for treating most methods as if the
: expressions in each parameter were being evaluated within the caller's
: class:
: 
:scratch $jack: .back
: 
: would be equivalent to
: 
:$jack.scratch($jack.back)

But wouldn't that mean Jack scratching my back instead of his?
I think we'd have people losing track of the current topic all the
time if we did something like that.

: This isn't quite the same thing as the index operator given above:
: 
:@ints[.begin + 2, .end - 3]
: 
: would be equivalent to
: 
:@[EMAIL PROTECTED] + 2, @ints.end - 3]
: 
: by this logic, which isn't what we want.  We'd either have to make this a
: special case or say:
: 
:@ints[.shape[0].begin + 2, .shape[1].end - 3]
: 
: ...which would be unneccessarily bulky.  OTOH, it would be annoying if we
: had to say
: 
:@[EMAIL PROTECTED], @ints.shape[0].begin]
: 
: if we wanted to access the index whose first dimension corresponds to the
: lowest bound of the second dimension and vice versa - though why you'd
: ever want to do something like that is beyond me.  Perhaps this is
: appropriate Huffman coding after all...
: 
: How to declare this?  Perhaps you could do something like:
: 
:method postcircumfix:[] 
:  ($object: [EMAIL PROTECTED] is context($object.shape[$_])) {...}
: 
: where the context trait normally has a value of $object in a method. 
: The above is an example of how the thing would be applied to the list
: parameter, with the context being applied to each element in turn and $_
: being set to the list's index for that element; similarly, an anonymous
: named parameter might work the same way, with $_ being set to the
: parameter's key.  Any function that has exactly one invocant would have a
: default context of that invocant for every parameter, while any function
: that has anything _but_ one invocant would have _no_ default parameter
: context - which wouldn't stop programmers from explicitly adding contexts
: where appropriate.  

I think we just need something really short and unconfusing for the
commonest cases, and let people write it out longhand for the others.
Somebody needs to talk me out of using A..Z for the simple cases.

Larry


Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread John Williams
 I think we just need something really short and unconfusing for the
 commonest cases,

   @a[ 42 ; -1 but last ]

That reads pretty well, no?

Maybe the other end isn't quite as good:

  @a[ 1 but first .. -2 but last ]

Hmm.  Should -1 but last or 0 but last be the last element?

~ John Williams




Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread Larry Wall
On Fri, Sep 03, 2004 at 08:19:11PM -0600, John Williams wrote:
:  I think we just need something really short and unconfusing for the
:  commonest cases,
: 
:@a[ 42 ; -1 but last ]
: 
: That reads pretty well, no?
: 
: Maybe the other end isn't quite as good:
: 
:   @a[ 1 but first .. -2 but last ]
: 
: Hmm.  Should -1 but last or 0 but last be the last element?

Well, hey, it almost makes sense to go with:

@a[0 but true .. -1 but false]

:-)

I'm still thinking A is the first one and Z is the last one.  Someone
talk me out of it quick.

Larry


Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread Jonathan Lang
Larry Wall wrote:
 On Fri, Sep 03, 2004 at 06:31:49PM -0700, Jonathan Lang wrote:
 : I wonder if this notion of contextualizing a method's signature could
 : be generalized... I could see a case for treating most methods as if 
 : the expressions in each parameter were being evaluated within the 
 : caller's class:
 : 
 :scratch $jack: .back
 : 
 : would be equivalent to
 : 
 :$jack.scratch($jack.back)
 
 But wouldn't that mean Jack scratching my back instead of his?
 I think we'd have people losing track of the current topic all the
 time if we did something like that.

Would we?  It seems obvious to me that once you specify a subject, all
possessive objects that follow are considered to be possessed by that
subject; read the dot in the shorthand as his, her, its, their, or
your, as appropriate:

   $spot.chase .tail;

would be

   Spot: chase your tail.

This is the same way that dots operate within a method's body.  

 I think we just need something really short and unconfusing for the
 commonest cases, and let people write it out longhand for the others.
 Somebody needs to talk me out of using A..Z for the simple cases.

How is A..Z different from
(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)?  

=
Jonathan Dataweaver Lang



___
Do you Yahoo!?
Win 1 of 4,000 free domain names from Yahoo! Enter now.
http://promotions.yahoo.com/goldrush


Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread Rod Adams
Larry Wall wrote:
I'm still thinking A is the first one and Z is the last one.  Someone
talk me out of it quick.
I had thought about A and Z before my previous post. I dismissed it for 
two reasons:

1) Using Alphas as an index for something that should be numeric can be 
very confusing. Especially when one sees:

@Int[4 .. Z];
2) If A = first and Z = last, DWIM (but maybe not DWYM) would dictate 
that I should be able to say:

@Int[C .. Y];
instead of:
@Int[A+2 .. Z-1];

That's why I liked the concept of an operator to modify the number 
afterwards. Okay,  might not have been the best choice, but there are 
other options. Looking at your preferred Latin-1 table, we have:

 (sect;) Use this Section of the array
 (reg;) The R means Relative to base
Or if we want to get silly, use  instead of .., and just use the 
numbers as is.

If you insist on using A and Z, at least make them \A and \Z, to give a 
stronger visual cue that something different is happening.

-- Rod



Re: parameter contexts (was: Synopsis 9 draft 1)

2004-09-03 Thread John Williams
 If you insist on using A and Z, at least make them \A and \Z, to give a
 stronger visual cue that something different is happening.

I think I'd prefer alpha and omega.

Or maybe turn my previous suggestion around and make first and last
special constants.  Then say:

  @a[ first .. last but 1 ]

Or does it have to be   last but int(1) ?

~ John Williams



Synopsis 9 draft 1

2004-09-02 Thread Larry Wall
=head1 Overview

This synopsis summarizes the non-existent Apocalypse 9, which
discussed in detail the design of Perl 6 data structures.  It was
primarily a discussion of how the existing features of Perl 6 combine
to make it easier for the PDL folks to write numeric Perl.

=head1 Lazy lists

All list contexts are lazy by default.  They still flatten eventually,
but only when forced to.  You have to use unary C** to get a non-lazy
flattening list context (that is, to flatten immediately like Perl 5).

=head1 Sized types

Sized low-level types are named most generally by appending the number
of bits to a generic low-level type name:

int1
int2
int4
int8
int16
int32   (aka int on 32-bit machines)
int64   (aka int on 64-bit machines)

uint1   (aka bit)
uint2
uint4
uint8   (aka byte)
uint16
uint32
uint64

num32
num64   (aka num on most architectures)
num128

complex32
complex64   (aka complex on most architectures)
complex128

Complex sizes indicate the size of each Cnum component rather than
the total.  This would extend to tensor typenames as well if they're
built-in types.  Of course, the typical tensor structure is just
reflected in the dimensions of the array--but the principle still holds
that the name is based on the number of bits of the simple base type.

The unsized types Cint and Cnum are based on the architecture's
normal size for Cint and Cdouble in whatever version of C the
run-time system (presumably Parrot) is compiled in.  So Cint
typically means Cint32 or Cint64, while Cnum usually means
Cnum64, and Ccomplex means two of whatever Cnum turns out to be.

You are, of course, free to use macros or type declarations to
associate additional names, such as short or single.  These are
not provided by default.  An implementation of Perl is not required
to support 64-bit integer types or 128-bit floating-point types unless
the underlying architecture supports them.

And yes, an Cint1 can store only -1 or 0.  I'm sure someone'll think of
a use for it...

XXX Alternately we could go with a byte count rather than a bit count.
But people seem to know whether they have a 32-bit or 64-bit processor.
If you ask whether they have a 4-byte or 8-byte processor, they have
to think about it a long time...

XXX Plus this opens the door for types like uint5.  Arguably, these should
be declared as int[:range(0..31)] or some such, a là Ada.

=head1 Compact structs

A class whose attributes are all low-level types can behave as
a struct.  (Access from outside the class is still only through
accessors, though.)  Whether such a class is actually stored compactly
is up to the implementation, but it ought to behave that way,
at least to the extent that it's trivially easy (from the user's
perspective) to read and write to the equivalent C structure.
That is, when byte-stringified, it should look like the C struct,
even if that's not how it's actually represented inside the class.
(This is to be construed as a substitute for at least some of the
current uses of Cpack/Cunpack.)

=head1 Compact arrays

In declarations of the form:

my bit @bits;
my int @ints;
my num @nums;
my int4 @nybbles;
my str @buffers;
my ref[Array] @ragged2d;
my complex128 @longdoublecomplex;

the presence of a low-level type tells Perl that it is free to
implement the array with compact storage, that is, with a chunk
of memory containing contiguous (or as contiguous as practical)
elements of the specified type without any fancy object boxing that
typically applies to undifferentiated scalars.  (Perl tries really
hard to make these elements look like objects when you treat them
like objects--this is called autoboxing.)

The declarations above declare one-dimensional arrays of indeterminate
length.  Such arrays are autoextending just like ordinary Perl
arrays (at the price of occasionally copying the block of data to
another memory location).  For many purposes, though, it's useful to
define array types of a particular size and shape that, instead of
autoextending, throw an exception if you try to access outside their
declared dimensionality.  Such arrays tend to be faster to allocate and
access as well.

A multidimensional array is indexed by a semicolon list, which is really
a list of lists in disguise.  Each sublist is a slice of one particular
dimension.  So

@array[0..10; 42; @x]

is really short for

@array.postcircumfix:[]( == [0..10], [42], [EMAIL PROTECTED] );

though in the list of lists form, a bare number is interpreted as if
it were a list of one element, so you can also say:

@array.postcircumfix:[]( == [0..10], 42, [EMAIL PROTECTED] );

Note that at the comma level, a list such as:

@[EMAIL PROTECTED],@y]

is always interpreted as a one-dimensional slice in the outermost
dimension, which is the same as:

@[EMAIL PROTECTED],@y;]

or more verbosely:

@array.postcircumfix:[]( == [EMAIL 

Re: Synopsis 9 draft 1

2004-09-02 Thread Uri Guttman
 LW == Larry Wall [EMAIL PROTECTED] writes:

  LW =head1 Compact structs

  LW A class whose attributes are all low-level types can behave as
  LW a struct.  (Access from outside the class is still only through
  LW accessors, though.)  Whether such a class is actually stored compactly
  LW is up to the implementation, but it ought to behave that way,
  LW at least to the extent that it's trivially easy (from the user's
  LW perspective) to read and write to the equivalent C structure.
  LW That is, when byte-stringified, it should look like the C struct,
  LW even if that's not how it's actually represented inside the class.
  LW (This is to be construed as a substitute for at least some of the
  LW current uses of Cpack/Cunpack.)

and vec. hard to get pack/unpack to access single bits with offsets or
classic c bit fields.

from inside the class (no accessor needed) will bit sized attributes be
direct access to the field (ala c)? that would mean you could use a
class to map to complex structures and in particular to i/o registers
and not have to jump through shift/mask hoops.

the rest of S9 hurt my brane

uri

-- 
Uri Guttman  --  [EMAIL PROTECTED]   http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs    http://jobs.perl.org