aboutsummaryrefslogtreecommitdiff

About chains

Chains is a Lisp inspired programming language designed to serve as a preprocessor replacement. Just as Lisp stands for List Processing, Chains is in a sense Tree Processing. It was originaly designed with the generation of HTML in mind, but it does not restrict itself to this task.

The result of evaluating a program is a tree, which may then be used to generate other markup languages. However, chains is not a macro language like the C preprocessor or m4.

One of the issues of generating markup text from within a conventional programming language is how cumbersome this is. Due to the syntax rules of the language, the markup must be in a way escaped e.g. by writing a string between quotes. Meanwhile unquoted items are syntactic elements of the language. This way writing code is "easy" while writing markup is "cumbersome".

In Chains, text is a first class citizen and all other syntactic elements have to be escaped. Because of this, you probably won't want to write Chains code directly but instead define it inside of the interpreter. On the other hand, writing markup is as easy as writing markdown or TeX.

The language also has a built-in notion of paragraph

At the moment, chains is more a proof of concept rather than a complete language. Many features are still undecided.

Syntax

Character Description
%
\
{ }
[ ]
# Raw function. All special characters in the arguments are taken literal
@
$

Primitives

Chains is built on 3 type of objects: text, chains and atoms.

Evaluation rules

Unless a chain is escaped, the following rules apply. The chain to be evaluated may only have a single object inside the first link. The function is value of evaluating this first element.

Text evaluates to itself.

Atoms consists of symbols or numbers. Symbols evaluate to the bound value in the environment. Numbers evaluate to themselves.

Defining a function with a group predicate causes the chain to consume all its siblings up to the first primitive for which the predicate is true. When evaluating the body of such a chain, an additional variable @siblings is defined in the scope and expands to the content of all consumed siblings.

How to contribute

If you would like to contibute to the development of chains please send a mail with your patch to the following address: thomas at thomaslabs dot org

Misc

;; next-token : cache raw block for further reads. avoid creating list (1 pass) ;; build link directly instead of returning block start tokens

;; read link ;; {} link := list of objects ;; { }{ }{ } chain := list of links ;;

;; special form : does not get its arguments pre-evaluated

;; after eval, unevaluated links are spliced into tree ;; {@if}{{@=}{2}{2}}{1}{2} -> {1} ;; needs to return link, in case text is also inside ;; @if{@={@2}{@2}}{1}{2} ;; alias syntax

;; use chains as library for static website generator, define-syntax and define ;; to define "callbacks" from library and read/eval file

;; tree from file may be discarded ;; writing libraries

;; a chain is evaluated by first evaluating the first link and applying the ;; other links as arguments for the function

;; a link with one element is evaluated to that element

;; inside the evaluation of a lambda, the argument is spliced into the link of ;; the body

;; {{@lambda}{@x @y}{@x}}{Hello}{World} -> {{Hello}} -> {Hello} -> Hello

;; Metaprogramming is hard :(

;; make closure return links instead of plain lists? dont use flatten?

;; type 1 - {{@lambda}{{@x}{@y}}{@x}}{Hello}{World} ;; type 2 - {{@lambda}{@x @y}{@x}}{Hello}{World}

;; semantically. What exactly is a chain? ;; is syntax just like define-syntax in scheme?