Skip to main content

Python as a LISP

Project description

Lythp

It's Python turned into a LISP!

(def greet (name)
    """A function which greets someone.

        >>> (greet "Jim")
        Hello Jim!

    """
    (print (+ "Hello " name "!"))
)

The goal is not to preserve LISP traditions, keywords, and features; rather, the goal is to have fun fitting Python into a LISP syntax in the most natural way I can find, using Python's built-in tokenizer.

Here is a slightly more interesting example:

# A global dict for caching function values:
(= _fib_cache (dict))


(def fib (n)
    """Returns the nth Fibonacci number.
    Maintains a global cache of values, to avoid needless recalculation."""
    (if
        ((< n 0) (raise (ValueError "Less than 0")))
        ((< n 2) n) # Base cases: 0, 1
        ((in _fib_cache n) ([n] _fib_cache))
        (else
            (= value (+ (fib (- n 1)) (fib (- n 2)) ))
            (= [n] _fib_cache value)
            value
        )
    )
)


# Print out the first 10 Fibonacci numbers:
(for x (range 10) (print (fib x)))

For more examples, see: examples

The interpreter

Currently, Lythp has its own runtime, instead of transpiling to Python. For instance, variables are stored in a stack of contexts, i.e. a list of dicts. It would be nice to transpile to Python instead, either by using exec or by generating bytecode directly.

In any case, make sure you're in a python3 virtual environment:

python3 -m venv venv
. venv/bin/activate

Then run files like so:

./lythp.py examples/fac.lsp

You can also run the interpreter in REPL mode like so:

./lythp.py

It may be helpful to install rlwrap to improve the REPL experience:

rlwrap ./lythp.py

You can run the unit tests like so:

pip install pytest pytest-cov
pytest

And run all example programs like so:

./run.sh

Syntax

The basic syntax is quite simple: the source code is chopped into tokens using Python's built-in tokenize module, and a tree structure representing the program is then built, with the following types of node:

  • Names: x, None, True, ,, *, ==
  • Literals: 100, "Hello!", """Docstrings too!"""
  • Parentheses: (...)
  • Brackets: [...]
  • Braces: {...}

NOTE: f-strings (e.g. f"Hello, {name}!") are not currently supported.

As usual in a LISP, parentheses represent statements and function calls. Here is the syntax of specific statements:

Built-ins and literals

The following values have the same syntax as in Python:

None
True
False
123
"hello"
r"(\n+)"
b"beep boop"
...  # the "ellipsis" object

TODO: describe lists, dicts, sets, etc

Attribute and item lookup: ., [...]

Basic usage:

# Python
obj.x
arr[i]
obj.x.y.z[n + 1]

# Lythp
(.x obj)
([i] arr)
(.x.y.z[+ n 1] obj)

Assignment: =

Basic usage:

# Python
x = 1
x += 1

# Lythp
(= x 1)
(+= x 1)

Assigning with setattr/setitem:

# Python
obj.x.y.z[n + 1] = value

# Lythp
(= .x.y.z[+ n 1] obj value)

NOTE: there is no equivalent of Python's destructuring (e.g. x, y = a, b).

Function calls

Basic usage:

# Python
x + y
f(x, y, z=3)
obj.method(x)

# Lythp
(+ x y)
(f x y [z 3])
((.method obj) x)

Args and kwargs:

# Python
f(x, y, *args, z=3, **kwargs)

# Lythp
(f x y [*args] [z 3] [**kwargs])

Lambdas and function definitions: lambda, def

Basic usage:

# Python
def f(x, y, z=3): ...etc...
f = lambda x: x + 1

# Lythp
(def f (x y [z 3]) ...etc...)
(= f (lambda (x) (+ x 1)))

NOTE: while Python only allows a single expression per lambda, Lythp allows statements, like a regular function definition.

Args and kwargs:

# Python
def f(x, /. y, *args, z=3, **kwargs): ...etc...

# Lythp
(def f (x [/] y [*args] [z 3] [**kwargs]) ...etc...)

Classes

# Python
class A(B, C):
    x = 3
    def __init__(self, value):
        ...etc...

a = A(value)

# Lythp
(class A (B C)
    (= x 3)
    (def __init__ (self value)
        ...etc...
    )
)

(= a (A value))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lythp-0.0.1.tar.gz (8.7 kB view hashes)

Uploaded Source

Built Distribution

lythp-0.0.1-py3-none-any.whl (9.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page