Pi is a programming (better a specification) language. It was developed in 1984 and is used at some German universities (for example at University of Potsdam).
It was made to develop specifications. Specifcations are provisional programs. They are not for making real programs which can be shipped, but to formulate a given problem into an algorithm, implement this algorithm, test it and show it to client to verify, that that is what he wanted. Then you can start making the real program basing on this specification.
The given Pi-Compiler (can be downloaded from http://www.cs.uni-potsdam.de/~owilhelm/Manuskripte/Pi/pi.zip ) translates the given specification into Haskell (in fact the compiler is buggy so there is a pre-compiler which translates the given code, so that the compiler understands it and a post-compiler, so that the Haskell-code is working).

How to write a Pi-specification (please make yourself familiar with specifications before reading the following):
As stated in specification it consists of the export, the import, the common parameters and the body. In the first three there are only the signatures of the operations and types ( in import and common parameters are these which are not in this module (specification) ). A signature is the first line of an operation (ex. in C int add (int x, int y) ).
To show you how this all works I show you a short specification of the natural numbers + 0 ({0,1,...}):

this is what is exported.

cem NAT
type view specification
type Nat
constructor null : -> Nat constructor successor: Nat -> Nat operation null : -> Nat operation successor: Nat -> Nat operation add : Nat,Nat -> Nat operation one : -> Nat operation two : -> Nat

The import is empty as we only import one specification, but this is also needed to be exported

Now follow the common parameters
common parameters
type Logic
operation true : -> Logic operation false : -> Logic constructor true : -> Logic constructor false : -> Logic

Now the body
construction of type Nat is internal
constructor null : -> Nat constructor successor: Nat -> Nat
operation add : Nat,Nat -> Nat variables x,y : Nat equations add(x,null) = x; add(x,successor(y)) = successor(add(x,y))
operation one : -> Nat equations one = successor(null)
operation two : -> Nat equations two = successor(one)

A constructor is the basis on which a type is constructed.

Please Note: Most of the modules are German so it can be hard for non-german speakers to understand