Files
orchid/notes/papers/demo/notes.md

2.4 KiB

Orhid is a lazy, pure functional langauge with an execution model inspired by Haskell. It has a simple, principled syntax resembling mathematical notation commonly used to describe the lambda calculus. State is held in closures and multi-parameter functions are represented using currying.

This minimalism is in an effort to make parsing and code generation easier, as complex structures are defined using syntax-level macros. The macro system is insipred by generalized kerning which is a well-known Turing-complete system.

Macros consist of substitution rules applied to the tokenized, namespaced source. These rules can make use of placeholders to transform the expression tree. Placeholders can match exactly one, at least one, or any number of tokens. Macros are used to define infix operators, name bindings, friendly loop syntax over the Y-combinator and more.

Because substitution rules are applied to the namespaced tokens, macro programs can interact with each other; parts of the pattern that triggers a macro can be generated by other macros while other parts may be provided by the user. In this way, libraries can define extension interfaces where other libraries can integrate with their constructs, and an individual token can take on many meanings depending on context.


Orchid is designed to be embedded in a Rust application. The entire program lifecycle consists of three stages which can be individually configured:

  1. The parser pipeline is responsible for converting text - usually files - into a module tree. It allows the embedder to define the environment the code will see in terms of a series of file trees that are parsed in the context of preceding layers.

  2. The macro executor operates entirely on the output of the pipeline. Macro programs don't necessarily halt, so the executor provides an API to find and resolve one match at a time.

  3. The interpreter is a single function operating on an expression with a symbol table for resolving named constants. It also allows setting a limit to the number of normalization steps - this is commonly known as gas.

Interfacing between eager procedural and lazy functional code can be challenging, especially with the vastly different suites of optimizations. To make this a little easier, we provide an array of Rust macros that streamline the process of exposing Rust functions to Orchid code. The usage of these is demonstrated in the standard library.