How to restrict who may read my blog?
[svn:perl6-synopsis] r14586 - doc/trunk/design/syn
Hello Guest
  
  • Login
• Register…
• Start blog
  • Who, Where, When
• What can I do?
• What to Read?
  • Polls
• Avatars
• Interests
  • Cities and Countries
• Random blog
• Users search
  • Search
• Games
• Tests
• QAIX
  • Сообщества
• Talxy Chat
• Horoscope
• Online
 
Зарегистрируйся!

QAIX > Perl web-programming > [svn:perl6-synopsis]­ r14586 - doc/trunk/design/sy­n 7 October 2008 20:04:54

  Recent blog posts: 
  They have birthday today: 
  Forums:   
  Discuss: 
  Recent forum topics: 
  Recent forum comments:
  Moderators:

[svn:perl6-synopsis]­ r14586 - doc/trunk/design/sy­n

Guest 7 October 2008 20:04:54
 Author: larry
Date: Sun Oct 5 17:05:41 2008
New Revision: 14586

Modified:
doc/trunk/design/sy­n/S03.pod

Log:
Add missing series operator, mostly for readability.


Modified: doc/trunk/design/sy­n/S03.pod
===================­====================­====================­===================
--- doc/trunk/design/sy­n/S03.pod (original)
+++ doc/trunk/design/sy­n/S03.pod Sun Oct 5 17:05:41 2008
@@ -12,9 +12,9 @@

Maintainer: Larry Wall <larry@wall.org>
Date: 8 Mar 2004
- Last Modified: 1 Oct 2008
+ Last Modified: 5 Oct 2008
Number: 3
- Version: 140
+ Version: 141

=head1 Overview

@@ -49,7 +49,7 @@
R Item assignment = := ::= => += -= **= xx= .=
L Loose unary true not
X Comma operator , p5=>
- X List infix Z minmax X X~X X*X XeqvX
+ X List infix Z minmax X X~X X*X XeqvX ...
R List prefix : print push say die map substr ... [+] [*] any $ @
X Loose and and andthen
X Loose or or xor orelse
@@ -1584,6 +1584,75 @@

See L</Cross operators>.

+=item *
+
+C<< infix:<...> >>, the series operator.
+
+This operator takes a concrete list on its left and a function to be
+iterated on its right when the list must be extended.
+
+The value of the operator is the lazy list formed of the
+concrete list followed by the result of applying the function to the
+tail of the list as needed. The function indicates by its arity
+how many of the preceding values to pay attention to (and which the
+operator must track internally). Demonstration of this falls to the
+lot of the venerable Fibonacci sequence:
+
+ 1, 1 ... { $^y + $^z } # 1,1,2,3,5,8...
+ 1, 1 ... &infix:<+> # 1,1,2,3,5,8...
+
+More typically the function is unary, in which case any extra values
+in the list may be construed as human-readable documentation:
+
+ 0,2,4 ... { $_ + 2 } # same as 1..*:by(2)
+ <a b c> ... { .succ } # same as 'a'..*
+
+The function need not be monotonic, of course:
+
+ 1 ... { -$_ } # 1, -1, 1, -1, 1, -1...
+ False ... &prefix:<!> # False, True, False...
+
+The function can be 0-ary as well:
+
+ () ... &rand # list of random numbers
+
+If the right operand is C<*> (Whatever) and the sequence is obviously
+arithmetic or geometric, the appropriate function is deduced:
+
+ 1, 3, 5 ... * # odd numbers
+ 1. 2. 4 ... * # powers of 2
+
+Conjecture: other such patterns may be recognized in the future,
+depending on which unrealistic benchmark we want to run faster. C<:)>
+
+Note: the yada operator is recognized only where a term is expected.
+This operator may only be used where an infix is expected. If you
+put a comma before the C<...> it will be taken as a yada list operator
+expressing the desire to fail when the list reaches that point:
+
+ 1..20, ... "I only know up to 20 so far mister"
+
+If the yada operator finds a closure for its argument at compile time,
+it should probably whine about the fact that it's difficult to turn
+a closure into an error message. Alternately, we could treat
+an elipsis as special when it follows a comma to better support
+traditional math notation.
+
+The function may choose to terminate its list by returning ().
+Since this operator is list associative, an inner function may be
+followed by a C<...> and another function to continue the list,
+and so on. Hence,
+
+ 1 ... { $_ + 1 if $_ < 10 }
+ ... { $_ + 10 if $_ < 100 }
+ ... { $_ + 100 if $_ < 1000 }
+
+produces
+
+ 1,2,3,4,5,6,7,8,9,
+ 10,20,30,40,50,60,7­0,80,90,
+ 100,200,300,400,500­,600,700,800,900
+
=back

Many of these operators return a list of Captures, which depending on
Add comment
Geoffrey Broadwell 6 October 2008 06:02:27 permanent link ]
 On Sun, 2008-10-05 at 17:05 -0700, larry@cvs.perl.org wrote:
+C<< infix:<...> >>, the series operator.

Lovely, just lovely.

+ 1, 3, 5 ... * # odd numbers
+ 1. 2. 4 ... * # powers of 2

Did you mean to use commas on that second line?


-'f


Add comment
Larry Wall 6 October 2008 06:31:30 permanent link ]
 On Mon, Oct 06, 2008 at 09:16:27AM +0800, Xiao Yafeng wrote:
: +
: > +The function may choose to terminate its list by returning ().
: > +Since this operator is list associative, an inner function may be
: > +followed by a C<...> and another function to continue the list,
: > +and so on. Hence,
: > +
: > + 1 ... { $_ + 1 if $_ < 10 }
: > + ... { $_ + 10 if $_ < 100 }
: > + ... { $_ + 100 if $_ < 1000 }
: > +
: > +produces
: > +
: > + 1,2,3,4,5,6,7,8,9,
: > + 10,20,30,40,50,60,7­0,80,90,
: > + 100,200,300,400,500­,600,700,800,900
: > +
: > =back
:
:
: curious whether I can say:
: 1... {$_ + 1 if @_.elems <10}
:
: 1,2,3,4,5,6,7,8,9,

Good question. I think it ought to be okay, though it basically forces
the operator to keep track of the entire array in order to pass it in
as a slurpy on every iteration. But it seems like *-ary args should
be allowed as an extreme case. Here's the same thing more explicitly,
expressed in unary form:

@seq := 1 ... { $_ + 1 if @seq < 10 }

The thing is, the operator will still have to keep track of all the
values even if the list has already given away some of those value
via an iterator.

Here's a cute variant that doesn't have to store all the values just
to keep count:

1 ... { $_ + 1 if ++(state $) < 10 }

Hmm, I think *my* state's $ will soon be less than 10, at the rate
they're spending... :)­

Larry
Add comment
Larry Wall 6 October 2008 06:37:55 permanent link ]
 On Sun, Oct 05, 2008 at 07:31:30PM -0700, Larry Wall wrote:
: @seq := 1 ... { $_ + 1 if @seq < 10 }

Actually, that one might not work, since we can't find the length of
@seq without knowing how many value the closure will generate. The
implicit version would not have that problem.

Larry
Add comment
Jon Lang 6 October 2008 07:19:42 permanent link ]
 <larry@cvs.perl.org>­ wrote:
Log:
Add missing series operator, mostly for readability.

Is there a way for the continuing function to access its index as well
as, or instead of, the values of one or more preceding terms? And/or
to access elements by counting forward from the start rather than
backward from the end?

There is a mathematical technique whereby any series that takes the
form of "F(n) = A*F(n-1) + B*F(n-2) + C*F(n-3)" can be reformulated as
a function of n, A, B, C, F(0), F(1), and F(2). (And it is not
limited to three terms; it can be as few as one or as many as n-1 -
although it has to be the same number for every calculated term in the
series.) For the Fibonacci series, it's something like:

F(n) = (pow((sqrt(5) + 1)/2, n) + pow((sqrt(5) - 1)/2, n))/sqrt(5)

...or something to that effect. It would be nice if the programmer
were given the tools to do this sort of thing explicitly instead of
having to rely on the optimizer to know how to do this implicitly.

--
Jonathan "Dataweaver" Lang
Add comment
Larry Wall 6 October 2008 07:37:48 permanent link ]
 On Sun, Oct 05, 2008 at 08:19:42PM -0700, Jon Lang wrote:
: <larry@cvs.perl.org­> wrote:
: > Log:
: > Add missing series operator, mostly for readability.
:
: Is there a way for the continuing function to access its index as well
: as, or instead of, the values of one or more preceding terms? And/or
: to access elements by counting forward from the start rather than
: backward from the end?

That's what the other message was about. @_ represents the entire list
generated so far, so you can look at its length or index it from the
begining. Not guaranteed to be as efficient though.

: There is a mathematical technique whereby any series that takes the
: form of "F(n) = A*F(n-1) + B*F(n-2) + C*F(n-3)" can be reformulated as
: a function of n, A, B, C, F(0), F(1), and F(2). (And it is not
: limited to three terms; it can be as few as one or as many as n-1 -
: although it has to be the same number for every calculated term in the
: series.) For the Fibonacci series, it's something like:
:
: F(n) = (pow((sqrt(5) + 1)/2, n) + pow((sqrt(5) - 1)/2, n))/sqrt(5)
:
: ...or something to that effect. It would be nice if the programmer
: were given the tools to do this sort of thing explicitly instead of
: having to rely on the optimizer to know how to do this implicitly.

Um, I don't understand what you're asking for. Explicit solutions
are always available...

Larry
Add comment
Jon Lang 6 October 2008 20:09:55 permanent link ]
 Larry Wall wrote:
On Sun, Oct 05, 2008 at 08:19:42PM -0700, Jon Lang wrote:
: <larry@cvs.perl.org­> wrote:
: > Log:
: > Add missing series operator, mostly for readability.
:
: Is there a way for the continuing function to access its index as well
: as, or instead of, the values of one or more preceding terms? And/or
: to access elements by counting forward from the start rather than
: backward from the end?
That's what the other message was about. @_ represents the entire list
generated so far, so you can look at its length or index it from the
beginning. Not guaranteed to be as efficient though.

If I understand you correctly, an "All even numbers" list could be written as:

my @even = () ... { 2 * +@_ }

And the Fibonacci series could be written as:

my @fib = () ... { (pow((1 + sqrt(5))/2, +@_) - pow((1 - sqrt(5))/2,
+@_)) / sqrt(5)) }

Mind you, these are bulkier than the versions described in the patch.
And as presented, they don't have any advantage to offset their
bulkiness, because you still have to determine every intervening
element in sequential order. If I could somehow replace '+@_' in the
above code with an integer that identifies the element that's being
asked for, it would be possible to skip over the unnecessary elements,
leaving them undefined until they're directly requested. So:

say @fib[4];

would be able to calculate the fifth fibonacci number without first
calculating the prior four.

It's possible that the '...' series operator might not be the right
way to provide random access to elements. Perhaps there should be two
series operators, one for sequential access (i.e., 'infix:<...>') and
one for random access (e.g., 'infix:<...[]>'). This might clean
things up a lot: the sequential access series operator would feed the
last several elements into the generator:

0, 1 ... -> $a, $b { $a + $b }

while the random access series operator would feed the requested index
into the generator:

() ...[] -> $n { (pow((1 + sqrt(5))/2, $n) - pow((1 - sqrt(5))/2,
$n)) / sqrt(5)) }

I'd suggest that both feed the existing array into @_.
___________________­_______
: It would be nice if the programmer
: were given the tools to do this sort of thing explicitly instead of
: having to rely on the optimizer to know how to do this implicitly.
Um, I don't understand what you're asking for. Explicit solutions
are always available...

This was a reaction to something I (mis)read in the patch, concerning
what to do when the series operator is followed by a 'whatever'.
Please ignore.
___________________­_______
On an additional note: the above patch introduces some ambiguity into
the documentation. Specifically, compare the following three lines:

X List infix Z minmax X X~X X*X XeqvX ...
R List prefix : print push say die map substr ... [+] [*] any $ @

N Terminator ; <==, ==>, <<==, ==>>, {...}, unless, extra ), ], }

On the first line, '...' is the name of an operator; on the second and
third lines, '...' is documentation intended to mean "...and so on"
and "yadda-yadda", respectively. However, it is not immediately
apparent that this is so: a casual reader will be inclined to read the
first line as "...and so on" rather than 'infix:<...>', and will not
realize his error until he gets down to the point where the series
operator is defined.
___________________­_______
Another question: what would the following do?

0 ... { $_ + 2 } ... &infix:<+> ... *

If I'm reading it right, this would be the same as:

infix:<...> (0; { $_ + 2 }; &infix:<+>; *)

...but beyond that, I'm lost.
___________________­_______
Jonathan "Dataweaver" Lang
Add comment
Larry Wall 7 October 2008 05:11:38 permanent link ]
 On Mon, Oct 06, 2008 at 09:09:55AM -0700, Jon Lang wrote:
: Larry Wall wrote:
: > On Sun, Oct 05, 2008 at 08:19:42PM -0700, Jon Lang wrote:
: > : <larry@cvs.perl.org­> wrote:
: > : > Log:
: > : > Add missing series operator, mostly for readability.
: > :
: > : Is there a way for the continuing function to access its index as well
: > : as, or instead of, the values of one or more preceding terms? And/or
: > : to access elements by counting forward from the start rather than
: > : backward from the end?
: >
: > That's what the other message was about. @_ represents the entire list
: > generated so far, so you can look at its length or index it from the
: > beginning. Not guaranteed to be as efficient though.
:
: If I understand you correctly, an "All even numbers" list could be written as:
:
: my @even = () ... { 2 * +@_ }
:
: And the Fibonacci series could be written as:
:
: my @fib = () ... { (pow((1 + sqrt(5))/2, +@_) - pow((1 - sqrt(5))/2,
: +@_)) / sqrt(5)) }
:
: Mind you, these are bulkier than the versions described in the patch.
: And as presented, they don't have any advantage to offset their
: bulkiness, because you still have to determine every intervening
: element in sequential order. If I could somehow replace '+@_' in the
: above code with an integer that identifies the element that's being
: asked for, it would be possible to skip over the unnecessary elements,
: leaving them undefined until they're directly requested. So:
:
: say @fib[4];
:
: would be able to calculate the fifth fibonacci number without first
: calculating the prior four.
:
: It's possible that the '...' series operator might not be the right
: way to provide random access to elements. Perhaps there should be two
: series operators, one for sequential access (i.e., 'infix:<...>') and
: one for random access (e.g., 'infix:<...[]>'). This might clean
: things up a lot: the sequential access series operator would feed the
: last several elements into the generator:
:
: 0, 1 ... -> $a, $b { $a + $b }
:
: while the random access series operator would feed the requested index
: into the generator:
:
: () ...[] -> $n { (pow((1 + sqrt(5))/2, $n) - pow((1 - sqrt(5))/2,
: $n)) / sqrt(5)) }
:
: I'd suggest that both feed the existing array into @_.

That's what the ++(state $) example was about in the other message.
The only downside is that it's assuming only one element is feed in
on the left. Otherwise you need to initialize the anonymous state
variable to some larger number. Maybe it's an idiom where you just
always initialize $n to the number of elements on the left:

0,1,2 ... { state $n = 3; $n++ }

I don't see much need for additional relief, especially since
it's normally trivial to write such lists other ways:

map { func($^n) } 0..*
func($_) for 0..*
for 0..* { .func }

: On an additional note: the above patch introduces some ambiguity into
: the documentation. Specifically, compare the following three lines:
:
: X List infix Z minmax X X~X X*X XeqvX ...
: R List prefix : print push say die map substr ... [+] [*] any $ @
:
: N Terminator ; <==, ==>, <<==, ==>>, {...}, unless, extra ), ], }
:
: On the first line, '...' is the name of an operator; on the second and
: third lines, '...' is documentation intended to mean "...and so on"
: and "yadda-yadda", respectively. However, it is not immediately
: apparent that this is so: a casual reader will be inclined to read the
: first line as "...and so on" rather than 'infix:<...>', and will not
: realize his error until he gets down to the point where the series
: operator is defined.

No, the second one not metasyntactic--it's­ the prefix:<...>, also known
as yada. It's essentially a synonym for fail, and so takes a list
argument. The third one is not yada--it's metasyntactic to represent
any "expect infix" block that stops the current expression such as in

if $x { say "yup" }

Admittedly the table is rather terse.

: ___________________­_______
: Another question: what would the following do?
:
: 0 ... { $_ + 2 } ... &infix:<+> ... *
:
: If I'm reading it right, this would be the same as:
:
: infix:<...> (0; { $_ + 2 }; &infix:<+>; *)
:
: ...but beyond that, I'm lost.

It would never get to the + or the * because $_ + 2 is never ().
The operator iterates each function until the function fails to
produce any list elements. Note you can go the other way too: the
function can actually return multiple list elements at once, so you
can interleave two (or more) independent lists:

0,1 ... { $^even + 2, $^odd + 2 }

Interestingly, since the returned list is a capture, such a list
in slice context would turn into [0,1],[2,3],[4,5]..., In list
context it's just 0,1,2,3,4,5...

I think that's just wicked cool.

Larry
Add comment
TSa 7 October 2008 19:57:28 permanent link ]
 HaloO,

Larry Wall wrote:
The operator iterates each function until the function fails to
produce any list elements....

What is the list type these days? It used to be List for writeable
lists and Seq for readonly ones. But isn't the latter superseded by
Capture? I would think it handy to have a type like Range that allows
to introspect the list e.g. to get the routine that calculates the
next item when given a previous one or the routine that calculates
the nth item in a random access fashion. Random access for a numeric
Range is particularly easy:

multi method postcircumfix:<[ ]> ( Range[Num] $range, Int $index )
{
my $ret = $range.from + $index * $range.by;
return $ret <= $range.to ?? $ret !! undef;
}

How would the corresponding method look like for List?

multi method postcircumfix:<[ ]> ( List $list, Int $index )
{
my &nth = $list.nth; # get nth item generator

if &nth
{
return nth($index);
}
else
{
# use iterator interface
}
}

Note that every function that takes an Int as first parameter could then
be wrapped up as a list with random access.

Note you can go the other way too: the
function can actually return multiple list elements at once, so you
can interleave two (or more) independent lists:
0,1 ... { $^even + 2, $^odd + 2 }
Interestingly, since the returned list is a capture, such a list
in slice context would turn into [0,1],[2,3],[4,5]..., In list
context it's just 0,1,2,3,4,5
I think that's just wicked cool.

Very subtle it is. And I wonder how exactly this is implemented.
I mean the pairs returned from the generator are captured into
what, protoarrays that auto-flatten into a list and become real
arrays in a slice?


Regards, TSa.
--

"The unavoidable price of reliability is simplicity" -- C.A.R. Hoare
"Simplicity does not precede complexity, but follows it." -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Add comment
Moritz Lenz 7 October 2008 20:04:54 permanent link ]
 TSa wrote:
HaloO,
Larry Wall wrote:
The operator iterates each function until the function fails to
produce any list elements....
What is the list type these days? It used to be List for writeable
lists and Seq for readonly ones.

Array = mutable
List = immutable, lazy
Seq = immutable, eager

Moritz
--
Moritz Lenz
http://perlgeek.de/­ | http://perl-6.de/ | http://sudokugarden­.de/
Add comment
 

Add new comment

As:
Login:  Password:  
 
 
  
 
Пожалуйста, относитесь к собеседникам уважительно, не используйте нецензурные слова, не злоупотребляйте заглавными буквами, не публикуйте рекламу и объявления о купле/продаже, а также материалы нарушающие сетевой этикет или УК РФ.


QAIX > Perl web-programming > [svn:perl6-synopsis]­ r14586 - doc/trunk/design/sy­n 7 October 2008 20:04:54

see also:
Cannot form email hyperlink correctly…
The Core of the Matter (was "Re…
пройди тесты:
Do you know women?
see also:
Hi People!
Popup window in AJAX
LG Flatron L1750SQ

  Copyright © 2001—2008 QAIX
Idea: Miсhael Monashev
Помощь и задать вопросы можно в сообществе support.qaix.com.
Сообщения об ошибках оставляем в сообществе bugs.qaix.com.
Предложения и комментарии пишем в сообществе suggest.qaix.com.
Информация для родителей.
Write us at:
If you would like to report an abuse of our service, such as a spam message, please .