Tree @master (Download .tar.gz)
Argyle
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)
Commit History
@master
git clone https://git.catseye.tc/Argyle/
- Place under a 2-clause BSD license. Follow REUSE 3.2 convention. Chris Pressey 1 year, 7 months ago
- Implement `cons`, `car`, `cdr` in terms of ABT nodes. Chris Pressey 1 year, 7 months ago
- Add `abt` function, which will (we hope) let us do more with ABTs. Chris Pressey 1 year, 7 months ago
- Improve names. Chris Pressey 1 year, 7 months ago
- Expand the cons list attempt and document why it doesn't work. Chris Pressey 1 year, 7 months ago
- Restore unit tests. Chris Pressey 1 year, 7 months ago
- Fix multiple-values-let-binding still being created by eval quote. Chris Pressey 1 year, 7 months ago
- Informally describe the language in the README. Chris Pressey 1 year, 7 months ago
- Add comments to syntax. Chris Pressey 1 year, 7 months ago
- Replace naive makeArgsTuple with makeNestedApplications. Chris Pressey 1 year, 7 months ago
- Checkpoint banging tests into shape. Chris Pressey 1 year, 7 months ago
- Flesh out README. Chris Pressey 1 year, 7 months ago
- Allow our new builtin to be curried. Chris Pressey 1 year, 7 months ago
- Reorganize more reasonably. Chris Pressey 1 year, 7 months ago
- Add a set of (failing!) tests for the new destructABT builtin. Chris Pressey 1 year, 7 months ago
- Fix the types used in destructABT. Chris Pressey 1 year, 7 months ago
- Clean up a little. Chris Pressey 1 year, 7 months ago
- Checkpoint this. Chris Pressey 1 year, 7 months ago
- Merge branch 'no-let' into lariat-style-destructorizer Chris Pressey 1 year, 7 months ago
- Make the let-form represent only a single binding in AST. Chris Pressey 1 year, 7 months ago
- Lariat-style destructorizer. Chris Pressey 1 year, 7 months ago
- Remove deprecated unit tests. Chris Pressey 1 year, 7 months ago
- Track declared free variables in VABT. Chris Pressey 1 year, 7 months ago
- An attempt at removing "free" operators from ABT. Chris Pressey 1 year, 7 months ago
- Update unit tests. Test performSubstitution, not unused things. Chris Pressey 1 year, 7 months ago
- Completely rewrite S-expression parser. Chris Pressey 1 year, 7 months ago
- Clean up test suite, reframe as specification. Chris Pressey 1 year, 7 months ago
- Update test expectations to match (admittedly brutal) fresh names. Chris Pressey 1 year, 7 months ago
- Fix how generateFreshName is being called. Chris Pressey 1 year, 7 months ago
- Fix collectAllFreeVars. All remaining test failures make sense. Chris Pressey 1 year, 7 months ago