Crate teko [] [src]

The Teko Programming Language implemented in Rust.

About

This implementation provides parsing and evaluation utilities of the Teko programming language. Teko belongs to the family of Lisp-1 languages and features dynamic scoping, first-class macros, and tail call optimization.

Teko is made to be used as an everyday scripting language. The language was designed to be easy to implement yet useful. Comparing Teko to other Lisps reveals the core motivation: to implement a super-minimal Lisp capable of being a fully fledged programming language.

Teko is has the property that it's strictly evaluated yet lacks interior mutability. This allows the implementation to opt for reference counted garbage collection - because cycles can't be created - which is desirable in real-time applications as it doesn't cause unforeseen pauses in execution.

Why Lisp?

Here's my favorite excerpt that words it perfectly, from Let Over Lambda, ch. 1:

Macros are the single greatest advantage that lisp has as a programming language and the single
greatest advantage of any programming language. With them you can do things that you simply
cannot do in other languages. Because macros can be used to transform lisp into other
programming languages and back, programmers who gain experience with them discover that all
other languages are just skins on top of lisp. This is the big deal. Lisp is special because
programming with it is actually programing at a higher level. Where most languages invent and
enforce syntactic and semantic rules, lisp is general and malleable.
With lisp, you make the rules.

Examples Code

Here is the iconic hello world in Teko:

(" Hello world!)

No functional-like language is complete without the definition of the tail-recursive factorial function.

(def factorial (fn (n accum)
                   (if (= n 1)
                       accum
                       (factorial (- n 1) (* n accum)))))
(factorial 5 1)

Usage

Example: using this library to interpret Teko:

extern crate teko;
extern crate num_traits;
use num_traits::cast::ToPrimitive;
fn main() {
    let program = teko::parse::parse_string("
    (def factorial (fn (n accum)
                       (if (= n 1)
                           accum
                           (factorial (- n 1) (* n accum)))))
    (write (factorial 5 1))").ok().unwrap();
    let env = teko::interpret::interpret(program);

    match env.result.1 {
        teko::data_structures::Coredata::Integer(ref value) => {
            assert_eq![value.to_i32().unwrap(), 120];
        }
        _ => {
            panic!["Expected Integer but got a different data type"];
        }
    }
}

Note that write doesn't yield a result in the example above so the previous result from factorial is left inside the environment instead.

Modules

builtins

Builtins for extending Teko

data_structures

Data structures used by the Teko library

interpret

Evaluation and library functions.

parse

Parsing interface for Teko.

utilities

Utilities used by the implementation.