Decoy
It's a simple functional language with a syntax markedly inspired by Scheme and semantics markedly inspired by Scheme.
But it's not Scheme. Thus the name.
It is also very much a work in progress.
How is this not Scheme
Lots of things are missing:
- Cons cells aren't mutable
- There's no tail recursion
- There's no vectors
- There's no numeric tower
- There's no quote or quasiquote notation
- There's no character or boolean constants
define
can only be used at top-level- There's no
call-with-current-continuation
ordynamic-wind
- There's no ports
- There's no support for SRFIs
All the same, the set of programs that are both R5RS Scheme programs and Decoy programs ought to be fairly large.
Some things are added:
- A module system of sorts
- Some libraries, supplied as modules in this system
Again, these would not be too difficult to suppoort in Scheme by means of some support functions and/or macros.
Why?
Having pure functions that transform an system state (plus possibly some input parameters) into a "next system state" (plus possibly some output events) is a really spiffy way to define and implement things like programming languages and user interfaces.
In programming languages they call this small-step operational semantics. In JavaScript web development they call these functions reducers. There are a number of other variations on this theme out there.
I wanted a language for writing these state-transformation functions in.
Since the functions themselves are pure (have no side effects), the language
should support (or even better, enforce) that. (Thus, no set!
.)
It should also be simple to implement, and straightforward to compile to (or otherwise interoperate with) other more conventional languages such as JavaScript. (Thus the simplified type system, and lack of tail recursion.)
Finally, it shouldn't innovate too much in the areas of syntax or semantics, to improve learnability and transferrability, if not strict compatibility. (Thus the significant Scheme borrowings, without actually being Scheme.)
Grammar
This is how the parser understands the program text:
Expr ::= "(" {Expr} ")"
| Symbol
| StrLit
| NumLit
.
On another level, we don't actually parse these (as of this writing), but we do interpret them as "special forms" while evaluating expressions:
(let* ((name expr) ...) expr)
(define name expr)
(lambda (name ...) expr)
(cond (expr expr) ... (else expr))
(if expr expr expr)
There is also a standard environment containing symbols which are mainly bound to functions. This is a work in progress, but includes
(list ...)
(list? expr)
(equal? expr)
Related works
Pixley is a much earlier project by the same author to define a minimal subset of Scheme in which a self-interpreter could be written. While Decoy has some similarities to Pixley, here is how Decoy is not Pixley:
- There are numbers
- There are many more built-ins (
list
, etc)
Notes
In the Decoy evaluator written in Lua, the following mapping is used for the types:
lambda function function
empty list Nil (singleton table)
cons cell Cons (table)
string String (table)
symbol Symbol (table)
boolean Boolean (table)
number Number (table)
The first one is not a table like the latter ones so you cannot access
.class
on it. When splitting into cases, test for it first.
TODO
- Support floating-point numbers.
- Arithmetic operations.
- Comparison operators.
and
,or
,not
- Refine the "module system".
import-from
- Start on the compiler framework.
if
- Evaluation of forms given on command line.
Commit History
@54df9aa9dbb1662a39a05998280c52706be7affb
git clone https://git.catseye.tc/Decoy/
- Basic support for strings and numbers. Chris Pressey 1 year, 7 months ago
- Move two builtins to standard environment. Depict booleans. Chris Pressey 1 year, 7 months ago
- Update some things in the README. Chris Pressey 1 year, 7 months ago
- Refactor with an eye towards better defining what a module is. Chris Pressey 1 year, 7 months ago
- Implement `list` builtin and refactor internally to support it. Chris Pressey 1 year, 7 months ago
- Place under a BSD 3-clause license. Chris Pressey 1 year, 7 months ago
- Replace `nil` usage with singleton Nil table. All tests pass! Chris Pressey 1 year, 7 months ago
- Pass one more test, but note why the parser breaks on another. Chris Pressey 1 year, 7 months ago
- Pass more tests. Only three failures now! Chris Pressey 1 year, 7 months ago
- Pass more tests. Chris Pressey 1 year, 7 months ago