The curry Package

This section gives a high-level view of the curry package. The intent is to give readers some idea of where various bits of Sprite can be located.

Top-Level API

The curry module itself serves as a collection of classes and functions intended to carry out the most common tasks. Many of these are methods of a singleton Curry interpreter that is created when importing curry. For many common use cases, one can simply use these methods without ever thinking about an interpreter, let alone creating one.

The global interpreter can be obtained by calling curry.getInterpreter().

The top-level data and methods fall roughly into the following categories:

  • System Control

    These can be used to manipulate the global interpreter:

    curry.flags : The flags of the global interpreter, a dict; see Interpreter flags.

    curry.path : Configure or view the Curry search path.

    curry.reload() : Discard the global interpreter, then create a new one, with the flags given and those of the environment.

    curry.reset() : Soft-reset the global interpreter: unload every module but the Prelude and the packages, reset the path, clear the signature table.

    curry.stats() : Report the statistics of the run: time, steps, forks, collections, memory, compile time, collector time, the counts of tiered execution, and the counters of the collector.

    Also, see the curry.config module.

  • Symbols & Types

    These can be used to find Curry objects.

    curry.module() : Find a loaded module by name. A module of the Curry library of the installation is imported on demand; any other module must be imported first.

    curry.symbol() : Find a symbol by name.

    curry.type() : Find a type by name.

    curry.currytype() : Get the Curry type that corresponds to a Python type.

  • Curry Modules

    These can be used to create, transform, load, or save Curry code.

    curry.compile() : Create Curry modules (with mode ‘module’).

    curry.import_() : Import a Curry module by name.

    curry.load() : Load a compiled Curry module from its shared object.

    curry.save() : Write the generated code of a module to a file, a program with a goal or a module alone (module_main=False). The form is the one of the backend.

    curry.modules : Access imported modules.

  • Expressions & Evaluation

    These can be used to build and evaluate Curry expressions.

    curry.compile() : Create Curry expressions (with mode ‘expr’).

    curry.eval() : Evaluate a Curry goal; the arguments of curry.expr(), with the keyword converter.

    curry.expr() : Construct a Curry expression, typed (see Typed Expressions).

    curry.raw_expr() : Construct a Curry expression without types.

    curry.typeof() : The type of an expression or of a symbol.

    curry.describe() : Describe an expression, to be typed as a whole later.

    curry.topython() : Convert a Curry value to Python.

    curry.show_value() : The text of a converted value in Curry format.

  • Markers of expressions

    These objects stand for the parts of an expression that are no Python value (curry.expressions).

    curry.free : A free variable; one marker is one variable.

    curry.choice : A non-deterministic choice between two expressions.

    curry.typed : A part with its type stated in Curry syntax.

    curry.ref : A reference to a named subexpression (a keyword argument of curry.expr()).

    curry.cons, curry.nil : The cells of a cons-style list.

    curry.fail : A failure.

    curry.unboxed : The unboxed payload of an Int, Char or Float, as in [Prelude.Int, curry.unboxed(3)]. A payload that does not fit the primitive, and the marker anywhere else, is an error at construction; an item of an iterator is refused when the list is demanded.

The errors the package raises are in curry.exceptions. The errors of the typed boundary are subclasses of curry.exceptions.CurryTypeError, a TypeError, listed with an example each under the error catalogue. The errors of an evaluation are subclasses of curry.exceptions.EvaluationError. EvaluationError and curry.exceptions.CompileError derive from BaseException, not from Exception, so except Exception does not catch them; name the class in the except clause.

Interpreter flags

An interpreter has a dict of flags. curry.flags is the dict of the global interpreter; the environment variable SPRITE_INTERPRETER_FLAGS sets the flags of a process (interpret:off,rotation:steps:65536), and curry.reload() or Interpreter(flags={...}) sets them for a new interpreter, over the flags of the environment. A flag read at the start of an evaluation takes effect at the next one when it is changed in the dict. backend is read when the interpreter is made, so a change of it in the dict has no effect; curry.reload() or a new interpreter selects a backend. An assignment to curry.flags rebinds the name in the package and changes nothing. curry.interpreter.flags describes every flag at length; the table names them with their defaults.

Flag

Default

What it changes

backend

'cxx' [1]

The backend: 'cxx', the C++ backend.

interpret

'tiered'

How the C++ backend runs a module without a compiled object: 'tiered' interprets it at once and compiles it in the background; 'new' interprets it and never compiles it; 'all' interprets every module; 'off' compiles every module first.

rotation

'time:10ms'

How the C++ backend paces the rotation of its queue of alternatives: time mode (time:<N><unit>) or step mode (steps:<N>), in which the order of the values of a search reproduces. SPRITE_ROTATION sets it alone.

stack_limit

4194304

The bytes of C stack the C++ backend lets one evaluation use; None disables the guard.

typed_expr

True

Whether curry.expr() types the expression it builds. False makes it the untyped builder with the markers of expr.

inline_budget

4

The largest function body, in nodes built, that the optimizer inlines at a call; a call of a single-case function on a constructor becomes the branch. 0 turns both rules off.

defaultconverter

None

The converter of curry.eval() when the call names none: None or 'topython'.

checker

False

The checker mode of the Fair Scheme proofs program: the reference backend asserts the run-time invariants of the Fair Scheme at every fork, escape, pull-tab, instantiation and yield; the C++ backend ignores it.

debug

False

More consistency checks; the C++ backend compiles its modules in the debug flavor.

trace

False

Trace the computation.

telemetry_interval

None

Seconds between the event reports of the runtime in the log; None turns them off.

lazycompile

True

Materialize a function when it is first needed.

keep_temp_files

False

Keep the temporary files; a string names the directory for them.

postmortem

False

Copy the generated code of a failed compile from a string to the working directory.

Package Structure

The contents of the curry package are documented in detail in the API Reference. The major submodules are described briefly below.

curry.backends

The interface IBackend, its implementation, the C++ backend (curry.backends.cxx), and the generic code of the backends (curry.backends.generic).

curry.cache

Implements caching for Curry-to-ICurry and other conversions.

curry.common

Contains common definitions used throughout Sprite.

curry.config

Functions for interacting with Sprite’s system configuration.

curry.exceptions

Contains all non-built-in exceptions Sprite might raise.

curry.expressions

The builders curry.expr(), curry.raw_expr(), curry.typeof() and curry.describe(), and the markers of an expression.

curry.icurry

A Python implementation of ICurry, which serves as the Sprite IR.

curry.inspect

A module for inspecting Curry objects: the predicates on nodes, the types of a module, the ICurry and the generated code of a symbol.

curry.interpreter

Defines the Curry interpreter: the class Interpreter, the flags, and the modules that implement its methods.

curry.lib

A virtual package used as the base for importing Curry modules.

curry.objects

Defines the objects used to provide Python APIs to Curry objects. For instance, this defines curry.objects.CurryModule, which is the object created by importing a Curry module, and curry.objects.CurryNodeInfo, the object of a symbol.

curry.show

Code for converting Curry expressions to strings.

curry.toolchain

Contains code for manipulating the compilation pipeline. Driver functions for external programs used by Sprite can be found here, and the translation from FlatCurry to ICurry (curry.toolchain.flat2icurry).

curry.tools

Defines the command-line tools that come with Sprite. This is where the source for sprite-make and the REPL (curry.tools.icy) can be found. sprite-exec is defined in the __main__.py file for curry. This, incidentally, means that running python -m curry from a command prompt is a synonym for sprite-exec.

curry.typecheck

The typed boundary between Python and Curry. The signature table reads the type schemes of the loaded symbols from the FlatCurry interfaces (symbol.signature, symbol.scheme, interp.sigtable). The package also holds the defaulting table and the goals of curry.eval(), the engine and the builder that type the expressions of curry.expr(), and the error catalogue (curry.typecheck.errors).

curry.utility

General-purpose code.