Re: PDL-P: Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-05 Thread Ariel Scolnicov

Tuomas Lukka [EMAIL PROTECTED] writes:

 On 4 Aug 2000, Ariel Scolnicov wrote:
 
  Karl Glazebrook [EMAIL PROTECTED] writes:
  
   OK I will raise to the bait
   
   I think it's a bit unfair to say that PDL people have failed to 'bite',
   there was quite a bit of discussion on our list after your post. Also
   some concern about how much of perl6 is vapourware.
   
   I am game to take part in discussions. 
   
   It has always been apparent to me that Numerical Python is better integrated
   than PDL. Some language changes in core python WERE made to accomodate it,
   also Python had less syntax clutter to get around.
   
   I definitely support embedding many of the key PDL ideas into the language
   - they key one is a much easier syntax for a multi-dim slice. We are currently
   driven to
   
   $a-slice("10:100,30:200");
   
   compared to IDL AND NumPy: a[10:100,30:200]
  
  Perl doesn't have multi-dimensional arrays (yet, I hope), but it
  *does* spell `:' as "..", even today.  @x[7..9] is a 3-element list,
  which I don't see as any different from @x[7:9].  Does the slice share 
  the elements of @a in your example?
 
 Well, first of all, 
 
   10:100, 30:200
 
 is not the same: in Perl it comes out as
 
   10..100, 30..200
 
   10, 11, ... , 100, 30, 31, .., 200
 
 whereas what we want is
 
   Span(10, 100), Span(30, 200)
 
 where Span is some suitable object telling that this span is a parameter.
 There are also other syntaxes for slice we would like to have but these
 can probably be kludged.

I think we're confusing 2 separate issues here.  PDL seems to deal
with both, but let's keep them separate:

(1) Decent span objects for generating subarrays (e.g. 1:10:3 (which
should probably be 1..10:3, or whatever the iterator sequence
works out as).

(2) Multidimensional arrays.  Today Perl does *not* have these.  As
Tuomas points out, the `,' operator is already too overloaded to
separate indices.  Note: I say the Perl has no multidimensional
arrays.  A list-of-lists is *not* a multidimensional array.  A
multidimensional array can be *implemented* as a list-of-lists,
but not efficiently.

Naturally, there are interesting interactions between (1) and (2),
e.g. when slicing a multidimensional array (consider, for instance,
what an operator should look like that returns the diagonal of a
square matrix).

A third issue:

(3) An "rvalue" slice is a *copy* of the elements sliced from the
array; an "lvalue" slice consists of the elements themselves, with 
a different indexing scheme.  Naturally, Perl should have both...


[...]

  Regarding multi-dimensional arrays, the PDL porters are undoubtable
  champions; what is required?
 
 Well, the PDL distro is our answer to that ;) ;)

But Shirley Perl could make your job a little less horrible?  At the
very least, if `:' were a binary operator, you could overload it to
generate non-string slice indices.

-- 
Ariel Scolnicov|"GCAAGAATTGAACTGTAG"| [EMAIL PROTECTED]
Compugen Ltd.  |Tel: +972-2-6795059 (Jerusalem) \ We recycle all our Hz
72 Pinhas Rosen St.|Tel: +972-3-7658514 (Main office)`-
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555http://3w.compugen.co.il/~ariels



Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-04 Thread Martyn Pearce

On Fri, Aug 04, 2000 at 08:16:17AM +1000, Jeremy Howard wrote:
 Martyn J. Pearce wrote:
  ... what I would like to discuss adding to the language is
 
  1) a means to signal an early exit to the iterator,
  2) a means to tell we're at the end of a list without having to
  evaluate the list length as we start
  3) a much more lightweight, and language built-in, mechanism for
  currying these functions.
 
 Would the changes you're discussing support:
 - Infinite lists

I certainly hope so

 - Reducing to an array rather than a scalar?

Thinks Yes; the example of zip has previously been mentioned, and that
would.

 The first of these is pretty obvious--sometimes you want to define a mapping
 without restricting the domain.

Indeed.

 The second is about writing something like:
   @a = sumover(@b[$index::j]
 to get column sums. $index::j is in this case an iterator defined as
 operating over the second index of an array. Of course you can always do
 this with a loop, but to me the whole point of adding iterators, matrix ops,
 and reduce/fold is that you can write your code the way a mathematician
 writes a function. Having to put explicit loops in is a bit messy.

Yup.

 BTW, I'd like to see a more lightweight currying mechanism too. The
 challenge is to find a 'perlish' but not heavyweight approach...

Ah, good.  I assume that having established the challenge, you'll be
rising to it? :-)

Mx.

-- 
See, the stars are shining bright
Everything's all right tonight
-- (Martin L. Gore, Never Let Me Down Again)



Re: PDL-P: Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-04 Thread Karl Glazebrook


OK I will raise to the bait

I think it's a bit unfair to say that PDL people have failed to 'bite',
there was quite a bit of discussion on our list after your post. Also
some concern about how much of perl6 is vapourware.

I am game to take part in discussions. 

It has always been apparent to me that Numerical Python is better integrated
than PDL. Some language changes in core python WERE made to accomodate it,
also Python had less syntax clutter to get around.

I definitely support embedding many of the key PDL ideas into the language
- they key one is a much easier syntax for a multi-dim slice. We are currently
driven to

$a-slice("10:100,30:200");

compared to IDL AND NumPy: a[10:100,30:200]

I'd propose simply building the a:b syntax into the core of Perl6. It's
convenient and almost standard.

perl6 should provide simple arrays, but they should be allowed to be
replaced with objects with no change of syntax. So

@a[10:100,30:200];

Would work whether @a was a perl list of lists or a PDL compact array.

So would @a * @b

Loop unrolling sounds really good, their should be hooks for objects to
provide their own implementation. Proper overloading and ability to 
overload by arg type are required, i.e.

sub myfunc{ float x, complex y }
sub myfunc{ float x, float y }


Their should also be hooks for slices, for example if one is implementing
a complex objects (e.g. representing a map) - one might want a slice in
physical units instead of array indices.

I'd even propose getting rid of @a for arrays and $a for scalars and just
making the "a". I've never really liked that feature of perl - I am sure
some users agree and some disagree - might be worth taking a straw poll.
In this age where everything may (or may not) be an object are $ and @ really
required? There are too many objects types and not enough funny symbols..
even with Unicode.

Karl Glazebrook


Jeremy Howard wrote:
 
   BTW, I'd like to see a more lightweight currying mechanism too. The
   challenge is to find a 'perlish' but not heavyweight approach...
 
  Ah, good.  I assume that having established the challenge, you'll be
  rising to it? :-)
 
 Yes of course. But I want to first of all see the following RFCs from Damian
 he's promised:
 
  * Built-ins: min() and max() functions and acceptors
 
  * Built-ins: reduce() function
 
  * Data structures: Semi-finite (lazy) lists
 
  * Subroutines: higher order functions
 
  * Subroutines: lazy evaluation of argument lists
 
  * Superpositions: vector operations via superpositions
 
 Damian is likely to write these in a way that is nicely integrated together,
 based on past experience. What I'd then like to do is to see how these fit
 together to fill in the stuff I mentioned earlier today:
 quote
 - Matrix ops
 - Support for lazy evaluation
 - Compile time expression unrolling (e.g. so that $a = sum(@b*@c+@d) does
 just one loop and no memory copy, as would occur with expression templates
 in C++)
 - Ability to specify infinite lists (e.g. like in Haskell)
 - Generic programming (iterators, algorithms, etc, eg. like in the STL)
 /quote
 
 I think the way I'd like to do this is to try and implement a couple of
 interesting bits of code that I've found are good tests of numerical
 programming environments. Stuff that just looks beautiful in Mathematica
 (which supports functional, rule-based, and procedural programming), but is
 full of loops and control structures in most languages. That way any bits
 that are missing will be pretty obvious (at least bits that matter to me!)
 
 I've tried to get input from PDL porters by cross-posting a couple of times,
 but haven't got much of a bite yet. I'm nervous about finding that we either
 reinvent the wheel, or break useful stuff that they've done... Are there any
 PDL gurus here who are interested in getting involved in some of these
 perl6-language issues?



Re: PDL-P: Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-04 Thread Karl Glazebrook


Also on the issue of loop unrolling and efficient looping.

PDL has what we call 'threading'.

This allows a C-level function to specify the dimensionality of
the arguments it accepts. For example a function addtoline() which
hyptheticaly adds a constant to a row vector might
have a 'signature'

a(n); b(); [o]c(n);

So a(n) is a 1D input, b() is a scalar (0D) which addtoline might add
to all the elements of a(n) and c(n) is the output 1D.

What is really useful is that if you add extra dimensions they
get looped over automatically, at the C-level so really fast.

e.g. a(100,10), b(10), c(100,10)

- adds to all 10 rows of a.

ALSO they way it is implemented is the array pointers are calculated
by C macros in such a way as to support transpositions and slicing
with zero memory overhead. Thus if I want to add one to every *column*
of a, in a slice:

addtoline $a-xchg(0,1)-slice("10:20,20:40"), 10, $c

here xchg creates a virtual transposition of the first two dims, and slice
creates a virtual slice. This is all done by storing extra info in the
$a object.

I think these ideas would be of use in any discussion of perl6 numerical
efficiency - there are other ways I guess. The core idea is to try and stay
in compiled loops.

The other advantage of this 'threading' is that it then automatically parallelizes
the problem - we even have an experimental PDL implementation which can use
multiple CPUs to do 'threads'.

One problem we are continually faced in PDL is we do all this at the C-level
- but then we run into problems where if we have pure-perl PDL functions they
can't do these tricks. 

Another problem though is while one can usually write many complicated multi-dim
problems with threading tricks, and avoid loops, it is sometimes a bit taxing
on the brain! One often wishes one could just write it as C/fortran style
loops and have the language figure out how to do the loops efficiently.

Anyway some integration of concepts for handling large numerical computation
into the core would definitely be a good thing.

Karl Glazebrook



Re: PDL-P: Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-04 Thread Tim Jenness

On Fri, 4 Aug 2000, Tuomas Lukka wrote:

 On 4 Aug 2000, Ariel Scolnicov wrote:
 
 Well, first of all, 
 
   10:100, 30:200
 
 is not the same: in Perl it comes out as
 
   10..100, 30..200
 
   10, 11, ... , 100, 30, 31, .., 200
 

Additionally, generically it would not necessarily have to be a range of
integers. The range could be specified as floating point if we are
specifying a slice in physical coordinates.

-- 
Tim Jenness
JCMT software engineer/Support scientist
http://www.jach.hawaii.edu/~timj





Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-03 Thread Graham Barr

On Wed, Aug 02, 2000 at 07:36:09PM +0100, Tom Hughes wrote:
 In message [EMAIL PROTECTED]
   Gisle Aas [EMAIL PROTECTED] wrote:
 
  The upcoming Python (v2.0) introduces a builtin called zip() that does
  the same thing:
 
for a,b,c in zip(aa,bb,cc):
...
 
  There are also question on how long the resulting list should be if
  @a, @b, @c is not of the same length.  I think zip() was defined to
  stop when the first list runs out.
 
 I believe zip is quite a common name for this operation in
 functional languages. Certainly Miranda uses it to turn a
 tuple of lists into a list of tuples, stopping as soon as
 any of the lists runs out.

I was simply repeating a conversation. I was not implying any
name. If many other languages call it zip() then lets call it zip()

  Python also has a map function that can take multiple lists and iterate
  over them in sync.  E.g.
 
map(func, list1, list2, list3)
 
  where 'func' must be a function taking 3 arguments.  Can't see how to
  easily extend perl's map in that way.  Perhaps we could introduce
  map2, map3,... builtins? :-)
 
 This is what Miranda calls zipwith. Combined with reduce
 you can do things like scalar products very simply:
 
   reduce(plus, zipwith(multiply, list1, list2))

Maybe we should call it something like mapzip, zipmap, zmap, mapz ...
as it does seem to be a combination of both zip and map

 Note that Miranda actually calls reduce fold though - well
 actually foldl or foldr depending on which end of the list
 you start at.

Many other have brought up this. But I ask the question "do we need two
operators"

foldr can be done with  reduce reverse @list

where reverse could be inteligent and create an iterator which itterates
over the list backwards. But on the other hand having foldl and foldr
may be being consistent with other languages. I will leave that to
Larry to decide.

Graham.



Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-03 Thread Graham Barr

On Thu, Aug 03, 2000 at 06:31:38AM +, Martyn J. Pearce wrote:
 And I feel that by being able to iterate over lists with map, grep,
 fold[rl]/reduce{,_r}, whatever, _without pre-flattening the list_, we
 could drastically increase the applicability of these constructs.

Having iterators avaliable in the language and being able to say that
a sub takes an iterator could be a great advantage. Also being able
to create iterators.

ie being able say

sub reduce (+) { ...}

where + is an iterator and have an iterator context so

  reduce { ... } some_func()

and have some_func know it is being called in an iterator context
and be able to create it's own iterator. foldr could then be
done as

  reduce { ... } reverse some_func()

which could create a reverse iterator.

So there probably should be an RFC to add iterators to the language and
be avaliable from perl, not just C. But I have no idea how they
should look etc.

However, and I am makeing an assumption here, probably the most common
use of reduce is with one of the + - / * operators. So it would be nice
to be able to optimize these, maybe to a separate op. There is two ways
we can do that.

1) Allow a syntax for it

reduce (+) @list;

2) Detect and optimize like we do now for sort.

  reduce { $a + $b } @list;

But to be able to do either require reduce to be in the perl core
rather than a module as it requires either the lexer or optimizer
to know about reduce.

Graham.



Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-03 Thread Jeremy Howard

Graham Barr said:
 ...
 So there probably should be an RFC to add iterators to the language and
 be avaliable from perl, not just C. But I have no idea how they
 should look etc.

More generally, I wonder whether there should be an RFC on the changes
required to make perl a more friendly environment to numerical programming
(both in terms of speed and elegance)... Or at least close collabaration to
ensure that the end result creates a coherent whole. Some of the issues that
come to mind are:
- Matrix ops
- Support for lazy evaluation
- Compile time expression unrolling (e.g. so that $a = sum(@b*@c+@d) does
just one loop and no memory copy, as would occur with expression templates
in C++)
- Ability to specify infinite lists (e.g. like in Haskell)
- Generic programming (iterators, algorithms, etc, eg. like in the STL)

But I also don't know how this should look, or quite where to start tackling
it from. I suspect PDL provides a lot of useful ideas, but I haven't really
used it enough...

 However, and I am makeing an assumption here, probably the most common
 use of reduce is with one of the + - / * operators. So it would be nice
 to be able to optimize these, maybe to a separate op.

Well, maybe. But don't forget about min and max and everything in between,
which always seem to cause grief for reduce/fold implementations.





Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-03 Thread John Porter

Graham Barr wrote:
 
 I was simply repeating a conversation. I was not implying any
 name. If many other languages call it zip() then lets call it zip()

No, we can't call it zip, because that's what python calls it;
and that would make perl equivalent to python.*


[*being facetious. hopefully the other guy who made an argument like
this in seriousness earlier gets the point...]


-- 
John Porter




Re: Expanding the language primitives (was: Re: Reduce [was: Re: Random items (old p5p issues)])

2000-08-03 Thread Johan Vromans

Dan Sugalski [EMAIL PROTECTED] writes:

 More importantly, the more primitives that perl provides, the wilder
 and more useful things people will be able to do.

Not quite. Its the functions that are provided that matter, not
whether they are primitives or not[1]. A small set of primitives with a
large set of functions is more powerful than just a moderate set of
primitives.

Compare with Emacs: a relatively small set of powerful built-ins and a
plethora of lisp functions for everything else.

-- Johan

[1] Tentative terminology: 
   primitive: a function built directly into perl
   function:  a function loadable into perl
   module:a (collection of) functions written in Perl




Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread Graham Barr

On Tue, Aug 01, 2000 at 10:27:08PM +0300, Ariel Scolnicov wrote:
multimap operation list-of-lists # uurgh.

This made me think of something else that came up in a discussion with Larry
after the conference.

The discussion started off with the ability to do

  for ($a,$b) (@list) { ... }

and go through the list in steps of two, or whatever the number of vars were.

But then went onto interators and something like

  @list = interleave(@a,@b,@c);

which would interleave the lists given, and

  foreach ($a,$b,$c) (interleave(@a,@b,@c))

which would iterate around all lists at the same time, but without flattening
the list. Maybe through some kind of hierarchy of iterators or something

Graham.

I really should get all these ideas into an RFC.




Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread raptor

hi,

Why not some sort of functionality like LISP/Prolog i.e. working with lists.

("a",@x,"b",%y) - the list

head ("a",@x,"b",%y)   # "a"

head(tile("a",@x,"b",%y))   #@x

head(head(tile("a",@x,"b",%y)))   #$x[0]

head(tile(tile("a",@x,"b",%y)))   #"b"

if you like it then "splice" etc... can this be done in the moment ??
I think moto of the Perl6, should be "Steal with Style" :")

 On Tue, Aug 01, 2000 at 10:27:08PM +0300, Ariel Scolnicov wrote:
 multimap operation list-of-lists # uurgh.

 This made me think of something else that came up in a discussion with
Larry
 after the conference.

 The discussion started off with the ability to do

   for ($a,$b) (@list) { ... }

 and go through the list in steps of two, or whatever the number of vars
were.

 But then went onto interators and something like

   @list = interleave(@a,@b,@c);

 which would interleave the lists given, and

   foreach ($a,$b,$c) (interleave(@a,@b,@c))

 which would iterate around all lists at the same time, but without
flattening
 the list. Maybe through some kind of hierarchy of iterators or something

 Graham.

 I really should get all these ideas into an RFC.




Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread John Porter

Graham Barr wrote:
   But then went onto interators and something like
   
 @list = interleave(@a,@b,@c);
   
   which would interleave the lists given, and
   
 foreach ($a,$b,$c) (interleave(@a,@b,@c))

  sub interleave(\@;\@\@\@\@\@\@\@\@) {
my $m = -1;
for ( @_ ) { $m  $#{$_} and $m = $#{$_} }
map { my $i = $_; [ map { $_-[$i] } @_ ] } 0..$m;
  }

  for ( map { @$_ } interleave( @a, @b, @c ) )


 Gisle Aas wrote:
  Python also has a map function that can take multiple lists and iterate
  over them in sync.  E.g.
  
map(func, list1, list2, list3)
  
  where 'func' must be a function taking 3 arguments.  Can't see how to
  easily extend perl's map in that way.  Perhaps we could introduce
  map2, map3,... builtins? :-)

sub mapf(;\@\@\@\@\@\@\@\@\@) {
  my $cr = shift;
  my $m = -1;
  for ( @_ ) { $m  $#{$_} and $m = $#{$_} }
  map { my $i = $_; $cr-( map { $_-[$i] } @_ ) } 0..$m;
}


I guess my question is, why do these need to be builtins?

There is no limit to the funky algorithms one can come up with;
not everyting should go in the core.


-- 
John Porter

Aus tiefem Traum bin ich erwacht.




Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread Graham Barr

On Wed, Aug 02, 2000 at 10:43:37AM -0600, Tom Christiansen wrote:
 sub mapf(;\@\@\@\@\@\@\@\@\@) {
 
 Steal from lisp:
 
 map 
 maap
 maaap
 mapp
 mappp
 maappp
  dwim

:)

Graham.



Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread Hildo Biersma

Tom Christiansen wrote:
 
 sub mapf(;\@\@\@\@\@\@\@\@\@) {
 
 Steal from lisp:
 
 map
 maap
 maaap
 mapp
 mappp
 maappp
 ...

Should be feasible with an AUTOLOAD that takes a certain kind of regular
expression...

sub AUTOLOAD /^ma+p+$/ {
}

Some for the 'car' and 'cdr' variants, of course...

Hildo



Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread Glenn Linderman

Graham Barr wrote:

  The upcoming Python (v2.0) introduces a builtin called zip() that does
  the same thing:
 
for a,b,c in zip(aa,bb,cc):
...
 
  There are also question on how long the resulting list should be if
  @a, @b, @c is not of the same length.  I think zip() was defined to
  stop when the first list runs out.

 I am sure that will be a debate. My first thought was to continue for the
 longest and return undef's for the others. I am sure someone would suggest
 use aa other cc and many more.

 If this is implemented someone will just have to decide what make most sense
 and implement that.

stopping at the shortest doesn't permit useful operations on the remainder of the
longer list entries.

Stopping at the longest with undef's seems more general, and people who want the
shorter could

for $a, $b, $c in zip (@aa, @bb, @cc)
{
   last if ! defined $a  ||  ! defined $b  ||  ! defined $c;
}
--
Glenn
=
There  are two kinds of people, those
who finish  what they start,  and  so
on... -- Robert Byrne


___
Why pay for something you could get for free?
NetZero provides FREE Internet Access and Email
http://www.netzero.net/download/index.html



Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread Tom Hughes

In message [EMAIL PROTECTED]
  Gisle Aas [EMAIL PROTECTED] wrote:

 The upcoming Python (v2.0) introduces a builtin called zip() that does
 the same thing:

   for a,b,c in zip(aa,bb,cc):
   ...

 There are also question on how long the resulting list should be if
 @a, @b, @c is not of the same length.  I think zip() was defined to
 stop when the first list runs out.

I believe zip is quite a common name for this operation in
functional languages. Certainly Miranda uses it to turn a
tuple of lists into a list of tuples, stopping as soon as
any of the lists runs out.

 Python also has a map function that can take multiple lists and iterate
 over them in sync.  E.g.

   map(func, list1, list2, list3)

 where 'func' must be a function taking 3 arguments.  Can't see how to
 easily extend perl's map in that way.  Perhaps we could introduce
 map2, map3,... builtins? :-)

This is what Miranda calls zipwith. Combined with reduce
you can do things like scalar products very simply:

  reduce(plus, zipwith(multiply, list1, list2))

Note that Miranda actually calls reduce fold though - well
actually foldl or foldr depending on which end of the list
you start at.

Tom

-- 
Tom Hughes ([EMAIL PROTECTED])
http://www.compton.nu/
...Hacking's just another word for nothing left to kludge.




Re: Reduce [was: Re: Random items (old p5p issues)]

2000-08-02 Thread Simon Cozens

On Wed, Aug 02, 2000 at 12:22:10PM -0400, John Porter wrote:
   sub interleave(\@;\@\@\@\@\@\@\@\@) {
...
   }
 
 sub mapf(;\@\@\@\@\@\@\@\@\@) {
...
 }
 
 
 I guess my question is, why do these need to be builtins?

sub push (\@@) { @{$_[0]} = (@{$_[0]}, @_[1..@_]); }

-- 
Addi Just imagine we are meeting the aliens for the first time.
ton Most people would just shoot them to see how many points they are
worth.