Pure is a dynamically typed, functional programming language based on term rewriting. It has facilities for user-defined syntax, macros, multiple-precision numbers, and compilation to native code through the LLVM.
Pure comes with an interpreter and debugger, provides automatic memory management, and has powerful functional and symbolic programming capabilities as well as interface to C libraries (e.g. for numerics, low-level protocols, and other such tasks). At the same time, Pure is a "small" language designed from scratch; its interpreter is not large, and the library modules are written in Pure itself. The syntax of Pure resembles that of Haskell.
The Pure language is a successor of the Q language created previously by the same author, Albert Gräf at the University of Mainz in Germany. Both languages are designed for applications in artificial intelligence, symbolic computation, and real-time multimedia processing.
Pure is free software distributed (mostly) under the GNU Lesser General Public License version 3 (or later).
Examples
The Fibonacci numbers (naive and inefficient algorithm):
fib 0 = 0; fib 1 = 1; fib n = fib (n-2) + fib (n-1) if n>1;
Better (tail-recursive and linear-time) version:
fib n = fibs (0,1) n with fibs (a,b) n = if n<=0 then a else fibs (b,a+b) (n-1); end;
Compute the first 20 Fibonacci numbers:
map fib (1..20);
A version of the sieve of Eratosthenes which computes the stream (lazy list) of all prime numbers:
primes = sieve (2..inf) with sieve (p:qs) = p : sieve [q | q = qs; q mod p] &; end;
Algorithm for the n queens problem which employs a list comprehension to organize the backtracking search:
queens n = search n 1 [] with search n i p = [reverse p] if i>n; = cat [search n (i+1) ((i,j):p) | j = 1..n; safe (i,j) p]; safe (i,j) p = ~any (check (i,j)) p; check (i1,j1) (i2,j2) = i1==i2 || j1==j2 || i1+j1==i2+j2 || i1-j1==i2-j2; end;
Gaussian elimination algorithm in Pure:
gauss_elimination x::matrix = p,x when n,m = dim x; p,_,x = foldl step (0..n-1,0,x) (0..m-1) end; step (p,i,x) j = if max_x==0 then p,i,x else // updated row permutation and index: transp i max_i p, i+1, {// the top rows of the matrix remain unchanged: x!!(0..i-1,0..m-1); // the pivot row, divided by the pivot element: {x!(i,l)/x!(i,j) | l=0..m-1}; // subtract suitable multiples of the pivot row: {x!(k,l)-x!(k,j)*x!(i,l)/x!(i,j) | k=i+1..n-1; l=0..m-1}} when n,m = dim x; max_i, max_x = pivot i (col x j); x = if max_x>0 then swap x i max_i else x; end with pivot i x = foldl max (0,0) [j,abs (x!j)|j=i..#x-1]; max (i,x) (j,y) = if x<y then j,y else i,x; end; /* Swap rows i and j of the matrix x. */ swap x i j = x!!(transp i j (0..n-1),0..m-1) when n,m = dim x end; /* Apply a transposition to a permutation. */ transp i j p = [p!tr k | k=0..#p-1] with tr k = if k==i then j else if k==j then i else k end; /* Example: */ let x = dmatrix {2,1,-1,8; -3,-1,2,-11; -2,1,2,-3}; x; gauss_elimination x;
Calling C from Pure is very easy. E.g., the following imports the puts
function from the C library and uses it to print the string "Hello, world!"
on the terminal:
extern int puts(char*); hello = puts "Hello, world!"; hello;