git @ Cat's Eye Technologies Argyle / master README.md
master

Tree @master (Download .tar.gz)

README.md @masterview markup · raw · history · blame

Argyle

See also: LariatLanthorn


Argyle is a Lisp-like programming language which is homoiconic at a higher level than Lisp: an Argyle program is represented as an Abstract Binding Tree (ABTs), and ABTs are first-class values. These ABTs are also hygienic in the sense that all defined ABT operations are, quite unlike Lisp's cons-lists, designed to preserve their name-binding structure.

This is an embryonic iteration of the language, aiming only to present a proof-of-concept. The basic ideas are implemented but their exact design and implementation surely can and ideally will be improved upon.

For more details on the language, see "Documentation" below.

Quick Start

Assuming you have a relatively modern version of ghc installed, along with cabal.

cabal update
cabal install --lib HUnit
./build.sh

You can then start the REPL with

./bin/argyle repl

If you wish to run the test suite (recommended), you may run

pip install falderal
./test.sh

Documentation

For the full definition of Argyle, see the Definition of Argyle document, a literal test suite written in Falderal format that aims to serve as the specification for the language.

What follows is a more informal introduction.

Lisp is usualy promoted as being homoiconic, but presentations of its homoiconicity often gloss over the following detail: not every valid S-expression is a valid Lisp program. In essence Lisp has two syntaxes, the "low-level syntax" of S-expressions, and the "high-level syntax" of special forms. The traditional treatment is to completely ignore that fact, and allow expressions such as (quote (let 123)) to be perfectly acceptable quoted form, even though (let 123) is not a valid expression -- and to have the argument to eval is a list, even though a list need not contain a valid expression.

Argyle regards this as a shortcoming, and intends to address it. Although they are written in an S-expression syntax, Argyle programs are not parsed into cons-lists. More precisely, even if the implementation parses them into cons-lists (as the reference implementation does), those cons-lists are not directly exposed to the interpreter. Rather, the cons-lists go through an extra step of being parsed into Abstract Binding Trees (ABTs), and it is those that are exposed to the interpreter.

And it is ABTs that an Argyle program works with; the argument to eval is not a list, it is an ABT, giving a strong guarantee that it represents a valid program and not some cons-list junk like (let 123).

That said, it is possible to represent cons lists with ABT nodes! The example source eg/cons-list.argyle demonstrates how you could define the functions cons, car, and cdr using the facilities that Argyle provides for creating, manipulating, and examining ABT values.

Where is this all headed?

Really, Argyle is only part of a grander vision I have; but it is a reasonably well-delimited and independently-implementable part, so, here it is.

In the grander vision, ABT nodes are defined as an abstract data type (ADT), and a program is able to define new ADTs and use them.

Whether Argyle will be extended to allow that, or whether that will appear in a separate language, the idea to have first-class ABTs is aiming to support two things well:

  • hygienic macros
  • program analysis and program transformation

The currently somewhat crude tools Argyle exposes for working with ABTs will likely need to be improved significantly, to achieve these goals.

But one could expect that, once they are in place, that support would extend to:

  • defining constructs such as letrec, if, cond, etc. as macros
  • writing static analyzers, such as for flow-typing and binding-time
  • writing optimizers, such as constant subexpression eliminators
  • installing any of the above as a pre-evaluation step

TODO

  • actually use locally nameless style (bound vars in own namespace)