[pure-lang-svn] SF.net SVN: pure-lang:[695] pure/trunk/pure.1.in
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-09-04 01:18:03
|
Revision: 695 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=695&view=rev Author: agraef Date: 2008-09-04 01:18:14 +0000 (Thu, 04 Sep 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-04 00:45:30 UTC (rev 694) +++ pure/trunk/pure.1.in 2008-09-04 01:18:14 UTC (rev 695) @@ -411,7 +411,7 @@ lambdas, conditional expressions and ``catmaps'' (a list operation which combines list concatenation and mapping a function over a list, defined in the prelude), but they are often much easier to write. Some examples of list -comprehensions can be found below at the end of this section. +comprehensions can be found in the EXAMPLES section below. .TP .B Function applications: \fRfoo\ x\ y\ z As in other modern FPLs, these are written simply as juxtaposition (i.e., in @@ -520,9 +520,11 @@ .PP The & operator does .IR "lazy evaluation" . -More precisely, it turns its operand into a kind of parameterless anonymous -closure, deferring its evaluation. These kinds of objects are commonly known -as +This is the only postfix operator defined in the standard prelude, written as +`x&', where x is an arbitrary Pure expression. The & operator binds stronger +than any other operation except function application. It turns its operand +into a kind of parameterless anonymous closure, deferring its +evaluation. These kinds of objects are also commonly known as .I thunks or .IR futures . @@ -535,22 +537,9 @@ structures in Pure, in particular: lazy lists a.k.a. .IR streams . A stream is simply a list with a thunked tail, which allows it to be -infinite. E.g.: -.sp -.nf -> ints n = n : ints (n+1) &; let nats = ints 1; -> nats; -1:<<thunk 0xb6033528>> -> take 10 nats; -[1,2,3,4,5,6,7,8,9,10] -> nats; -1:2:3:4:5:6:7:8:9:10:11:<<thunk 0xb5fb1a08>> -> nats!9999; -10000 -.fi -.sp -Note that the prelude defines & as a postfix operator which binds stronger -than any other operation except function application. +infinite. The Pure prelude defines many functions for creating and +manipulating these kinds of objects; further details and examples can be found +in the EXAMPLES section below. .PP .B Toplevel. At the toplevel, a Pure program basically consists of rewriting rules (which @@ -699,8 +688,7 @@ symbols needed in an evaluation .I before entering the expression to be evaluated. -.PP -.B Examples. +.SH EXAMPLES Here are a few examples of simple Pure programs (see the following section for a closer discussion of the rule syntax). .PP @@ -756,7 +744,8 @@ 6.28318530717958 .fi .PP -A little list comprehension example (Erathosthenes' classical prime sieve): +.B List comprehensions. +Erathosthenes' classical prime sieve: .sp .nf primes n = sieve (2..n) \fBwith\fP @@ -796,6 +785,136 @@ = i1==i2 || j1==j2 || i1+j1==i2+j2 || i1-j1==i2-j2; \fBend\fP; .fi +.PP +.B Lazy evaluation and streams. +As already mentioned, lists can also be evaluated in a ``lazy'' fashion, by +just turning the tail of a list into a +.IR future . +This special kind of list is also called a +.IR stream . +Streams enable you to work with infinite lists (or finite lists which are so +huge that we would never want to keep them in memory). E.g., here's one way to +create the infinite list of all positive integers: +.sp +.nf +> ones = 1:ones&; +> integers = 1 : zipwith (+) ones integers&; +> \fBlet\fP ints = integers; ints; +1:<<thunk 0xb5fdd5b8>> +.fi +.PP +(Note that we use machine integers in this example, so in fact the list will +wrap around to the smallest negative integer at some point.) +.PP +Of course, care must be taken not to invoke ``eager'' operations such as `#' +(which computes the size of a list) on infinite streams, since this never +terminates. However, many list operations work with infinite streams just +fine, and return the appropriate stream results. E.g., the `take' function +(which retrieves a given number of elements from the front of a list) works +with streams just as well as with ``eager'' lists: +.sp +.nf +> take 10 ints; +1:<<thunk 0xb5fdd5e8>> +.fi +.PP +Hmm, not much progress there, but that's just how streams work (or rather +don't, they're lazy bums indeed!). But the stream computed with `take' is in +fact finite and we can readily convert it to an ordinary list, forcing its +evaluation: +.sp +.nf +> (list) (take 10 ints); +[1,2,3,4,5,6,7,8,9,10] +.fi +.PP +(Note that we typed `(list)' instead of just `list' here, so that the +interpreter does not mistake this for the interactive +.B list +command. This is only necessary at the interactive command prompt, see +INTERACTIVE USAGE.) +.PP +For interactive usage it's often convenient to define an eager variation of +`take' which combines `take' and `list'. Let's do this now, so that we can use +this operation in the following examples. +.sp +.nf +> takel n xs = list (take n xs); +> takel 10 ints; +[1,2,3,4,5,6,7,8,9,10] +.fi +.PP +Let's take another look at the `ints' stream now: +.sp +.nf +> ints; +1:2:3:4:5:6:7:8:9:10:<<thunk 0xb5fddcd8>> +.fi +.PP +As you can see, the invokation of `list' on the result of `take' forced the +corresponding prefix of the `ints' stream to be computed. The result of this +is memoized, so that this portion of the stream is now readily available in +case we need to have another look at it again later. By these means, possibly +costly reevaluations are avoided, trading memory for execution speed. +.PP +A number of convenience operations are available for generating stream values. +The prelude defines infinite arithmetic sequences, using +.B inf +or +.B -inf +to denote an upper (or lower) infinite bound for the sequence, e.g.: +.sp +.nf +> let u = 1..inf; let v = -1.0,-1.2..-inf; +> takel 10 u; takel 10 v; +[1,2,3,4,5,6,7,8,9,10] +[-1.0,-1.2,-1.4,-1.6,-1.8,-2.0,-2.2,-2.4,-2.6,-2.8] +.fi +.PP +Other useful stream generator functions are `iterate', `repeat' and `cycle', +which have been adopted from Haskell. Moreover, list comprehensions can draw +values from streams and return the appropriate stream result: +.sp +.nf +> \fBlet\fP pairs = [i,j; i=1..inf; j=1..i]; pairs; +(1,1):<<thunk 0xb5f28818>> +> takel 10 pairs; +[(1,1),(2,1),(2,2),(3,1),(3,2),(3,3),(4,1),(4,2),(4,3),(4,4)] +.fi +.PP +Finally, let's rewrite our prime sieve so that it generates the infinite +stream of +.I all +prime numbers: +.sp +.nf +all_primes = sieve (2..inf) \fBwith\fP + sieve [] = []; + sieve (p:qs) = p : sieve [q; q = qs; q mod p] &; +\fBend\fP; +.fi +.sp +Example: +.sp +.nf +> \fBlet\fP P = all_primes; +> takel 20 P; +[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71] +> P!299; +1987 +.fi +.PP +You can also just print the entire stream. This will run forever, so hit +Ctrl-C when you get bored. +.sp +.nf +> \fBusing\fP system; +> do (printf "%d\en") all_primes; +2 +3 +5 + ... +.fi .SH RULE SYNTAX Basically, the same rule syntax is used in all kinds of global and local definitions. However, some constructs (specifically, \fBwhen\fP, \fBlet\fP, @@ -1689,8 +1808,9 @@ See the DEFINITION LEVELS section below for details. .PP Note that these special commands are only recognized at the beginning of the -interactive command line. (Thus you can escape a symbol looking like a command -by prefixing it with a space.) +interactive command line. (Thus you can escape an identifier at the beginning +of the command line, which looks like a command, by prefixing it with a space +or by wrapping it up in parentheses.) .PP Some commands which are especially important for effective operation of the interpreter are discussed in more detail in the following sections. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |