Curry2Go: Compiling Curry to Go

Quick Linux install: more details   curl -sSL https://www-ps.informatik.uni-kiel.de/curry2go/download.sh | sh

Description

Curry2Go is a new implementation of the multi-paradigm declarative language Curry. As the name suggests, Curry2Go compiles Curry programs into Go programs. Similarly to many other implementations of Curry, the distribution contains an interactive environment (read/eval/print loop) to ease the development of Curry applications.

The current implementation includes all the essential features of Curry, like non-deterministic operations, logic variables and unification, encapsulated search, as well as advanced features like functional patterns and various search strategies. The default strategy is a fair search strategy which performs parallel evaluations in a multi-processor environment. In particular, the strategy is operationally complete, i.e., it always computes a value if it exists according to the declarative interpretation of the program. This contrasts Curry2Go with Prolog's backtracking search strategy and and other sequential Curry implementations, like PAKCS or KiCS2. For instance, Curry2Go computes a value to the following non-deterministic choice between three expressions, where the leftmost and rightmost are non-terminating:

    Curry2Go Interactive Environment Version...
    Prelude> length [1..] ? 42 ? length [1..]
    42

Libraries, packages, and tools

The Curry2Go distribution comes with a collection of base libraries that are useful for basic application programming. A short description of these libraries can be found here.

The distribution also contains the Curry Package Manager CPM that supports the easy installation of many further libraries and tools. There are more than 100 packages available for installation with Curry2Go.

Quick installation

Curry2Go requires an installation of Go (version 1.13 or newer), which can be downloaded from the Go website. The executable go must be accessible in the load path.

The Curry2Go compiler and REPL are implemented in Curry so that one needs an existing Curry system to compile from the source repository. In order to install Curry2Go without another Curry compiler, one can download and install a pre-compiled distribution of the system. To do so (in a Linux-based environment where a Go compiler is installed), execute the following command:

    > curl -sSL https://www-ps.informatik.uni-kiel.de/curry2go/download.sh | sh

This installs the Curry2Go system into the local directory Curry2Go which is created by the installation. Then add .../Curry2Go/bin to your path to start the Curry2Go REPL by the command

    > curry2go

If you do not use packages but only the base libraries, add the option -n or --nocypm for faster startup:

    > curry2go -n

In order to install into a (non-existing!) directory C2GDIR, add an argument:

    > curl -sSL https://www-ps.informatik.uni-kiel.de/curry2go/download.sh | sh -s - -d C2GDIR

If you already have another Curry system and the Curry Package Manager installed, you can also use it to install the Curry2Go system from the source repository. More information can be found in the more detailed installation instructions.

Usage

Curry2Go can be used similarly to other Curry systems, like PAKCS or KiCS2. After starting the Curry2Go interactive environment by the command

    > curry2go -n

the standard prelude is loaded so that one can evaluate expressions. For this purpose, Curry2Go compiles the current program together with the main expression into an executable and invokes it. Although this is silently done (unless you increase the verbosity to 2 or higher by :set v2), you will notice this process since it takes a few seconds. Actual timings for the compiler and expression evaluation can be shown by setting the timing flag with :set +time.

Programs, i.e., Curry modules, are compiled and loaded by the command

    Prelude> :load ModuleName

Note that the generated target Go programs are stored relative to the current directory in .curry/curry2go-xxx. This means that one needs read/write access to the current directory.

The interactive Curry2Go environment supports the direct evaluation of expressions:

    Prelude> 3*4.5
    13.5
    Prelude> "Hello " ++ "World!"
    "Hello World!"

In the default mode, only the result values of expressions are printed:

    Prelude> not b where b free
    True
    False

In order to show the bindings of variables occurring in initial expressions, one should turn on the option bindings:

    Prelude> :set +bindings

    Prelude> not b where b free
    (True, "b:", False)
    (False, "b:", True)

To print them more nicely, one can use the option show (note that in this case all free variables must or will be bound to ground data terms):

    Prelude> :set +show

    Prelude> not b where b free
    "{b = False} True"
    "{b = True} False"

    Prelude> const 42 (x::Bool) where x free
    "{x = False} 42"
    "{x = True} 42"
Why does it take so long to evaluate a simple expression?

You might wonder why it takes a few seconds to start the evaluation of a simple expression like 3*14. The reason is that the REPL is implemented on top of the Curry2Go compiler, i.e., each initial expression is written into a "main" module which is then transformed into Go code by the Curry2Go compiler (which also requires the reading of the prelude) and into a binary (executable) by the Go compiler. Then this binary is invoked to perform the actual evaluation. If you want to see what what is going on and where the time is spent, you can increase the verbosity and turn on the option to show the elapsed time during compilation:

    Prelude> :set +ctime
    Prelude> :set v2
    Prelude> 3*14
    ...