curry package
The Sprite Curry system.
This package contains everything one needs to compile and execute Curry code. The topmost module provides an instance of the Curry system and an API to interact with it.
To perform a soft reset call reset(). This returns the system to its
original state, with no definitions and no modules imported. The configuration
is taken from environment variable SPRITE_INTERPRETER_FLAGS. To change that at
runtime, call reload() and specify new flags.
Use import_() to import Curry modules, compile() to compile Curry
code, expr() to build Curry expressions, and eval() to evaluate
them. path determines where Sprite searches for Curry code. Loaded
modules can be found under modules. Use topython() to convert
Curry values to Python objects. stats() reports the statistics of the
run: time, rewrite steps, forks, collections, memory, compile time, and
collector time.
Example
>>> mymodule = curry.compile("""
... data Item = A | B
... rotate A = B
... rotate B = A
... main :: Item
... main = rotate A ? rotate B
... """)
>>> for value in curry.eval(mymodule.main):
... print(value)
B
A
- class curry.choice(cid, lhs, rhs=None)[source]
Bases:
objectUsed with
expr()to place a choice into a Curry expression.Through
expr, the choice is a call ofPrelude.?, whose rewrite step draws a fresh id from the interpreter;cidis not used. Throughraw_expr, it is aChoicenode with the idcid, 0 by default.
- curry.compile(mode='module', imports=None, exprtype=None, modulename=None)[source]
Compile a string containing Curry code. In mode ‘module’, the string is interpreted as a Curry module. In mode ‘expr’, the string is interpreted as a Curry expression.
- Parameters:
string – A string containing Curry code.
mode – Indicates how to interpret the string (see above).
imports – A list specifying additional modules to import. The elements can be strings or
CurryModuleobjects. Import statements will be prepended to the code string and CURRYPATH will be adjusted accordingly. This can be useful when importing dynamically-compiled modules whose names and locations are difficult to obtain.exprtype – A string specifying the expression type. This is what would appear to the right of
::in a Curry type annotation for the expression. Used only in ‘expr’ mode. Without it, the class constraints of the expression are defaulted with the table of the PAKCS REPL:NumtoInt,FractionaltoFloat,MonadtoIO, a loneDatatoBool; seecurry.typecheck.defaulting.modulename – Specifies the module name. Used only in ‘module’ mode. The module is placed in
curry.interpreter:Interpreter.modulesunder that name. By default, a unique name is chosen, which no later compile reuses.
- Returns:
In ‘module’ mode, a
CurryModule. In ‘expr’ mode, a Curry expression. A text that ends inwhere x, y freedeclares free variables, as in the REPL. A variable whose type is absent from the result type of the expression cannot show in a value, socurry.evalyields each value of such an expression with its binding (Bindings); a variable whose type occurs in the result type is left in the value. The REPL of PAKCS prints the binding of every declared variable. Withexprtype, or with a comment afterfree, the clause stays a local declaration and no binding is reported.- Raises:
CompileError – The front end rejects the text, or, in ‘expr’ mode without
exprtype, the table cannot default a class constraint.
- class curry.cons(head, tail0, *tail)[source]
Bases:
objectUsed with
expr()to place one or more list constructors into a Curry expression.
- curry.currytype(ty)[source]
Gets the Curry type corresponding to a Python type. For instance, for the Python
booltype, this returns the type object forPrelude.Bool.
- curry.describe(*args, **kwds)[source]
The description of an expression: the arguments of
expr()as a tree, typed only when a consumer asks for its node. The DSL builds descriptions at every operator and types them once at the boundary, so that an outer context fixes the types of the inner parts. A description is an argument ofexpr()and ofeval;strprints it in Curry syntax; its methodtypeofgives its type. The keywordexprtypestates the type of the description; the other keywords are its anchors. SeeDescription.
- curry.eval(*args, **kwds)[source]
Evaluate a Curry goal.
- Parameters:
*args – Positional arguments that specify the goal. These are passed to
Interpreter.expr. One function symbol whose scheme has class constraints and no value parameter, a goal without a signature such asmain = Just 5, is applied to its dictionaries first: the constraints are defaulted with the table of the PAKCS REPL (seecurry.typecheck.defaulting), so the goal evaluates to a value and not to a partial application. An expression ofcurry.compile(mode='expr')whose text declaredwhere x freevariables absent from its result type yields its values with the bindings of those variables (curry.typecheck.goals.Bindings).converter – Keyword-only argument specifying the converter to use when returning results. The default is ‘default’, the flag
defaultconverter.'topython'appliescurry.topython(),Noneand any other name leave the Curry value, and a callablef(interp, value)converts as it pleases. See :func:curry.interpreter.conversions.getconverter.exprtype – Keyword-only argument: the type of the goal in Curry syntax, passed to
Interpreter.expr.**kwds – Any other keyword names an anchor, as in
Interpreter.expr.
- Raises:
EvaluationError – A Curry error occurred during evaluation.
CurryTypeError – The table cannot default a class constraint of the goal.
- Returns:
A generator producing the values of the specified Curry program.
- curry.expr(*args, **kwds)[source]
Builds a Curry expression.
The expression is typed before it is built (see
curry.typecheck.builder): the type schemes of the symbols are read from the FlatCurry interfaces of their modules, the arguments are unified with the parameter types, the class constraints are defaulted with the table of the PAKCS REPL, and the class dictionaries are supplied. Soexpr(curry.symbol('Prelude.+'), 1, 2)builds the call of the method atInt, andexpr(P.show, [P.Just, 1])finds theShowinstance ofMaybe Int. A typing failure raisesCurryTypeErrorat construction; nothing is evaluated. The flagtyped_exprturns the typing off.The arguments specify the expression to build. Each positional argument must be directly convertible to Curry or describe a node. A Python value converts by the type its position expects:
bool: Converted toPrelude.Bool.intPrelude.Int;Prelude.FloatunderFloat; thefromIntconversion under anotherNuminstance.floatConverted toPrelude.Float.strUnder[Char]one string of any length. Elsewhere a string of length one is aPrelude.Char, and another string is[Char].listConverted to a Curry list, in a loop. Every element takes the element type, so[1, 2.5]is[Float].tupleConverted to a Curry tuple.iteratorLazily converted to a Curry list. The element type is fixed when the expression is built; an item that does not convert ends the evaluation with anEvaluationError.NoneAn error that names the expected type.a Curry node Typed by a walk of its content, up to 100000 nodes;
curry.typed(node, 'T')states the type instead. A node alone passes through untouched.
Any (possibly nested) sequence whose first element is an instance of
NodeInfospecifies a node. The remaining arguments are recursively converted to Curry expressions to form the successors list. Thus, given suitable definitions, it is possible to build the Curry list[0,1,2]with the following code:expr([Cons, 0, [Cons, 1, [Cons, 2, Nil]]])
Fewer arguments than the symbol takes give a partial application; more arguments go through
Prelude.applywhen the result is a function. A symbol without a type scheme (a module without a FlatCurry interface, or a built-in of Sprite’s own Prelude) is built untyped when it stands alone, as the goal of a saved module does, and is an error when it is applied to arguments;typeof()refuses it either way.Several special symbols are provided. See
anchor,choice,cons,fail,free,nil,ref,typed, andunboxed. Afreemarker becomes a call ofPrelude.unknown, one node per marker, and achoicemarker a call ofPrelude.?, so the runtime assigns the ids.raw_exprbuilds the rawFreeandChoicenodes instead. Anunboxedmarker stands only as the payload of a primitive,[Prelude.Int, curry.unboxed(3)]; anywhere else it is aCurryTypeError.- Parameters:
interp – An interpreter object.
*args – Positional arguments used to construct expressions.
**kwds – Keyword arguments specifying subexpressions that may be referenced via
ref. Each keyword specifies the name of an anchor. See the examples below.exprtype – Keyword-only argument. The type of the expression in Curry syntax, for example
'Maybe Float'. Its type variables are rigid.target – Reserved keyword-only argument. If a target is supplied, then it will be rewritten with the specified expression. Otherwise a new node is created.
- Returns:
A Curry expression. Its type is recorded, so
typeof()answers for it, andevalconverts its values by it.
- curry.fail
Places a failure into a Curry expression.
- curry.flags
The
flagsattribute of the global interpreter. Change its entries in place to reconfigure the interpreter,curry.flags['defaultconverter'] = 'topython'. An assignment tocurry.flagsrebinds the name in the package and changes nothing in the interpreter.
- class curry.free(vid=0, exprtype=None)[source]
Bases:
objectUsed with
expr()to place a free variable into a Curry expression.Through
expr, one marker is one variable. The builder makes one node for the marker, a call ofPrelude.unknownapplied to theDatadictionary of its type, and reuses it for every occurrence of the marker, in that expression and in later ones. The first rewrite step on the node creates the variable with a fresh id and forwards the node to it. The node belongs to one interpreter state:curry.resetinstalls a new state, and the marker becomes a new variable there.exprtypefixes the type of the variable, in Curry syntax; without it the type comes from the context, and a variable whose type stays polymorphic gets the dictionary ofBool, whichunknownnever reads. Throughraw_expr, every occurrence is a separateFreenode with the idvid, 0 by default; that form serves the tests of the runtime.
- curry.import_(currypath=None, is_sourcefile=False)[source]
Import one or more Curry modules.
- Parameters:
arg – A module descriptor indicating what to import. A module descriptor is a module name (string),
curry.icurry.IModuleobject, or a sequence of module descriptors.currypath – The search path for Curry files. By default,
self.pathis used.is_sourcefile – Indicates whether to interpret
argas a source file name rather than a module name.
- Returns:
A
CurryModuleor sequence thereof.
- curry.load(filename, **kwds)[source]
Loads a Curry module saved with
save().Aside from how the file is located, this follows the import protocol, so the module is added to the interpreter’s
modulesdict.- Parameters:
filename – The path to a file to load. The file type and suffix must match the interpreter.
from_plan – True when the import plan loads the current object of a module it imports, False for a file the user named (the C++ backend decides some refusals by it; see its loader).
- Returns:
A
CurryModule.
- curry.module(name)
Look up a module by name.
- curry.modules
The
modulesattribute of the global interpreter. This is adictthat contains the imported Curry modules.
- curry.nil
Places a list terminator into a Curry expression.
- curry.path
The
pathattribute of the global interpreter. Initialized from environment variable CURRYPATH. Change it in place to adjust the Curry search path,curry.path.insert(0, '.'). An assignment tocurry.pathrebinds the name in the package and changes nothing in the interpreter.
- curry.raw_expr(*args, **kwds)[source]
The untyped builder. Equivalent to
expr()without the types: every Python value converts by its Python type, only the arity of a symbol is checked, no dictionary is supplied, afreemarker becomes a rawFreenode with the id of the marker, a new node per occurrence, and achoicemarker a rawChoicenode with the id of the marker. Fewer arguments than the arity of a symbol give a partial application; a function applied to more goes throughPrelude.apply, one node per surplus argument, as a point-free definition needs; a constructor applied to more is an error. An expression that is not well typed evaluates with undefined behaviour.
- class curry.ref(name=None)[source]
Bases:
objectUsed with
expr()to create a reference to a named subexpression. This can be used to construct nonlinear expressions.The argument is optional when the expression contains exactly one anchor at the point where the reference appears.
- curry.reload(flags={})[source]
Hard-resets the interpreter. Any flags supplied will be forwarded to the constructor, overriding flags supplied via the environment variable SPRITE_INTERPRETER_FLAGS.
- curry.reset()
Soft-resets the interpreter.
Clears the loaded modules, except the Prelude and the packages. Restores I/O streams to their defaults, resets the Curry path from the environment, releases the expression modules, and clears the signature table. The names of anonymous modules are not reused; see compile.py. This is much faster than building a new interpreter, which loads the Prelude.
- curry.save(filename=None, goal=None, **kwds)[source]
Saves a Curry module.
- Parameters:
cymodule – The argument to dump. Must be a valid argument to inspect.geticurry.
filename – A file name, stream, or None. If None, a string is returned. Otherwise, the file is created, if specified, and the output is written to the file or stream.
goal – The goal the saved program evaluates when it runs, unless
-gon its command line names another. A program needs one: withoutgoalthe call raisesValueError(issue #35). To save a module without a main program, forload(), passmodule_main=False. A goal with class constraints and no signature is defaulted with the table of the PAKCS REPL at run time; the file records its type, so it runs from any directory. A goal the table cannot default raises here, at save time. On the C++ backend the saved file is C++ source, and its record names the source of the module relative to the directory of the object (the product directory beside the source,.curry/<subdir>/). Compile the file in that directory, assprite-make --sodoes; an object compiled elsewhere loads, but its module has no source file (backends.cxx.loader.source_file).kwds – Additional keyword arguments passed to
IBackend.write_module. Possibly specific to the backend.
- Returns:
If
filenameis None, the module contents are returned as a string. Otherwise, None.
- curry.show_value(value)[source]
Converts a Python Curry value to a string in Curry format. This does a few things, such as lowering one-tuples; adjusting containers, such as tuples and lists, to print elements as with
strrather thanrepr; and converting free variable to friendly names _a, _b, etc. The output should match other Curry systems.
- curry.stats()[source]
Reports the statistics of the run.
- Returns:
wallSeconds since this process started (on Linux; elsewhere, since the Curry system was imported). The start time of a process has a resolution of one clock tick, 10 ms on most systems.
cpuUser plus system CPU seconds of this process. Child processes, such as the Curry front end and the C++ compiler, are not included.
stepsThe rewrite steps taken by the evaluations of this interpreter, a running evaluation included. A soft reset keeps the count.
forksThe number of times a configuration forked at a choice in those evaluations.
collectionsThe collections run in this process by the node collector of the C++ backend. The Python backend reports zero.
peak_rssThe peak resident set size of this process, in bytes.
compileSeconds this process spent in the steps of the toolchain: the Curry front end, the ICurry-JSON conversion, the code generator, and the C++ compiler. Zero when every file was current.
gc_secondsSeconds the node collector of the C++ backend spent in its collections. The Python backend reports zero.
swappedThe functions that tiered execution of the C++ backend swapped from the interpreter to compiled code in this process (the interpreter flag
interpretset to ‘tiered’). The Python backend reports zero.failed_compilesThe background compiles of tiered execution that failed in this process; the modules stay interpreted. The Python backend reports zero.
gc_roots_seconds,gc_trace_seconds,gc_sweep_seconds,gc_registries_secondsSeconds the collections of the node collector spent in each phase: the roots (the configurations of the queues and the nodes Python holds), the trace from the roots, the block sweep, and the registries (the free-variable tables, the generator nodes, the queues and the sets). The verifier of the stress mode is in none of them. The Python backend reports zero.
gc_marked,gc_marked_old,gc_marked_youngThe nodes the collections marked: all, those marked in the collection before as well (old), and those allocated since (young).
gc_configurations_pushedThe configurations whose roots the collections pushed.
gc_queues_destroyed,gc_configurations_destroyedThe queues of set functions no root reached, destroyed by the collections, and the configurations destroyed with them.
gc_old_redexes,gc_old_slot_writes,gc_old_nodes_written,gc_old_blocksThe writes into old nodes between the collections: the writes of a step into an old redex, the other pointer writes into an old node, the distinct old nodes written, and the blocks with such a write, summed over the intervals. Only a runtime built with the write counters (make GC_WRITE_COUNTERS=1) counts them; the default build reports zero.
A C++ runtime built with the scheduler counters (make COUNTERS=1) adds the keys of
SCHEDULER_KEYS; seescheduler_fields().- Return type:
A
Statsobject, a dict with these keys, in this order
- curry.symbol(modulename=None)
Look up a symbol by its fully-qualified name,
'Prelude.+'. The name splits at its first dot into a module and a name in it, so'Data.List.nub'needs the packageDataloaded, as an import ofData.Listleaves it. The second parameter has no effect.
- curry.topython(convert_strings=True, exprtype=None)[source]
Converts a Curry value to Python by substituting built-in types.
This functions converts (recursively) the types
int,float,str,bool,list, andtuple. Other types are passed through untouched.- Parameters:
value – The Curry value to convert.
convert_strings – If True, then lists of characters are converted to Python strings.
exprtype – The static type of the value, in Curry syntax or as a FlatCurry type, or None. The type is threaded through the lists and the tuples: an empty list under
[Char]converts to'', while a list under a type variable or without a type converts to a string when it holds characters.curry.evalpasses the type of the goal it built.
- Raises:
NotConstructorError – Non-ground data was encountered along a list spine.
- Returns:
The value converted to Python.
- curry.type(name)
Returns the constructor info tables for the named type.
- class curry.typed(value, exprtype)[source]
Bases:
objectUsed with
expr()to annotate a part of an expression with its type:curry.typed(value, 'T')convertsvalueat the typeT, in Curry syntax, and unifiesTwith the type the context expects. Socurry.typed('a', 'String')is the string"a", andcurry.typed(node, '[Int]')states the type of a large value instead of a walk of its content.raw_exprbuilds the value and ignores the annotation.
- curry.typeof(defaulted=False)[source]
The type of an expression in Curry syntax. Without
defaultedthe undefaulted scheme, what:typeprints:typeof(expr(plus, 1, 2))isNum a => a. Withdefaultedthe type after the table of the PAKCS REPL:Int.eis a nodeexpr()returned, any other Curry node (typed by its content), a symbol, a description ofdescribe(), or any argumentexpr()accepts.
- class curry.unboxed(value)[source]
Bases:
objectUsed with
expr()to place the unboxed payload of a primitive into a Curry expression:[Prelude.Int, curry.unboxed(3)]is the node<Int 3>, andPrelude.CharandPrelude.Floattake the marker the same way. A plain Python value builds the same node, so the marker is seldom needed. The payload must fit the primitive: a PythonintunderInt, astrof length one underChar, afloatunderFloat; another value is aCurryTypeErrorfrom both builders (unboxed_payload()). Anywhere else the marker is aCurryTypeErrorat construction, from both builders: alone, in a list or a tuple, or as the argument of another symbol, a node is expected, and an unboxed value in its place is an ill-formed node, which ended the process on the C++ backend (issue #107). An item of an iterator is converted when the list is demanded, so the marker there is anEvaluationErrorat that time.
Subpackages
- curry.backends package
IBackendIBackend.after_evaluation()IBackend.backend_nameIBackend.before_evaluation()IBackend.compileIBackend.compile_pending()IBackend.create_evaluation_rtsIBackend.extend_plan_skeletonIBackend.find_or_create_internal_module()IBackend.fundamental_symbolsIBackend.gc_counters()IBackend.gc_seconds()IBackend.get_interpreter_state()IBackend.getimpl()IBackend.init_interpreter_state()IBackend.load_moduleIBackend.lookup_builtin_module()IBackend.make_nodeIBackend.materializeIBackend.module_loaded()IBackend.module_unlinked()IBackend.num_collections()IBackend.object_file_extensionIBackend.scheduler_counters_enabled()IBackend.tiered_counts()IBackend.write_module
Node- Subpackages
- curry.icurry package
- Subpackages
- curry.icurry.analysis package
CaseBodyExpressionBodyInlineralias_target()alias_target_of_body()body_shape()find_static_strings()inline_body_text()inline_shape()is_apply()is_recursive()lookup_constructor()lookup_function()lookup_module()lookup_symbol()node_count()nullary_body()partial_head()recordable()recorded_functions()recursive_functions()resolve_alias()saturate()set_monadic_metadata()unfolding()unfolding_text()varinfo()- Submodules
- curry.icurry.types package
- curry.icurry.analysis package
- Submodules
- Subpackages
- curry.interpreter package
InterpreterInterpreter.backendInterpreter.compile()Interpreter.currytype()Interpreter.describe()Interpreter.eval()Interpreter.expr()Interpreter.flagsInterpreter.import_()Interpreter.load()Interpreter.module()Interpreter.modulesInterpreter.optimize()Interpreter.pathInterpreter.preludeInterpreter.raw_expr()Interpreter.reset()Interpreter.save()Interpreter.setfunctionsInterpreter.sigtableInterpreter.stats()Interpreter.symbol()Interpreter.topython()Interpreter.type()Interpreter.typeof()Interpreter.unbox()
- Subpackages
- Submodules
- curry.lib package
- curry.objects package
- curry.toolchain package
compile_seconds()currentfile()curry2icurry()curryfilename()icurry2json()icurryfilename()jsonfilenames()loadcurry()loadjson()makecurry()mergebuiltins()mergemodule()- Subpackages
- curry.toolchain.flat2icurry package
Flat2ICurryErrorInterfaceFinderload_flatcurry()load_interface()module_root()optimize_bindings()optimize_file()optimize_set0()product_path()read_flatcurry()rewrite_file()rewrite_prog()show_flatcurry()showhaskell()showterm()translate()translate_file()write_flatcurry()write_icurry()- Submodules
- curry.toolchain.flat2icurry package
- Submodules
- curry.tools package
- curry.typecheck package
InstanceInterfaceInterfaceErrorPredicateSchemeSignatureTablefind_interface()interface_candidates()show_predicate()show_scheme()show_type()- Submodules
- curry.typecheck.builder module
- curry.typecheck.defaulting module
- curry.typecheck.engine module
- curry.typecheck.errors module
- curry.typecheck.exprtype module
- curry.typecheck.goals module
- curry.typecheck.instances module
- curry.typecheck.serialize module
- curry.typecheck.sigtable module
- curry.typecheck.terms module
- curry.typecheck.unify module
- curry.utility package
formatDocstring()maxrecursion()translateKwds()unique()- Subpackages
- Submodules
- curry.utility.binding module
- curry.utility.breakpoint module
- curry.utility.curryname module
- curry.utility.encoding module
- curry.utility.filesys module
- curry.utility.fmap module
- curry.utility.formatting module
- curry.utility.proptree module
- curry.utility.shared module
- curry.utility.showflags module
- curry.utility.strings module
- curry.utility.textcolor module
- curry.utility.timer module
- curry.utility.trampoline module
- curry.utility.unionfind module
- curry.utility.visitation module
Submodules
- curry.cache module
- curry.common module
- curry.config module
curry2icurry_tool()curry_frontend()currypath()cxx_compiler()cxx_flavor()cxx_gc()cxx_gc_write_counters()cxx_pch_cache_dir()cxx_pch_root()cxx_tool()cyrt_lib()debugging()expression_modname()force_recompile_cxx()icurry_tool()in_conda_prefix()installation_key()installed_path()interactive_modname()is_anonymous_modname()is_expression_modname()log_file_name()log_level()log_level_map()log_level_names()logging_enabled_for()prefix()product_cache_dir()python_exe()sprite_exec()supported_syslibs()syslibs()syslibversion()system_curry_path()unsupported_syslibs()user_cache_dir()verify_syslibs()
- curry.exceptions module
- curry.expressions module
- curry.inspect module
cons_head()cons_tail()fwd_chain_target()fwd_target()get_choice_alternatives()get_choice_id()get_freevar_id()get_left_alternative()get_right_alternative()get_set_id()get_setguard_value()geticurry()geticurryfile()getimpl()getjsonfile()getsymbol()gettype()info_of()is_boxed()is_data()isa()isa_bool()isa_boxed_char()isa_boxed_float()isa_boxed_int()isa_boxed_primitive()isa_char()isa_choice()isa_cons()isa_constraint()isa_ctor()isa_curry_expr()isa_curry_expr_or_none()isa_failure()isa_false()isa_float()isa_freevar()isa_func()isa_fwd()isa_int()isa_io()isa_list()isa_nil()isa_operator_name()isa_primitive()isa_setguard()isa_true()isa_tuple()isa_tuple_name()isa_unboxed_char()isa_unboxed_float()isa_unboxed_int()isa_unboxed_primitive()symbols()tag_of()types()unboxed_value()
- curry.show module