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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lythp-0.0.1.tar.gz.
File metadata
- Download URL: lythp-0.0.1.tar.gz
- Upload date:
- Size: 8.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
316c519504f301546beb23e604bb41031385ad93b01203bf75939fd4cd807e47
|
|
| MD5 |
bfa7deae000eff10461ae5028fecbd72
|
|
| BLAKE2b-256 |
17f7dfc649eb6867b127c6cd370f76c6cada0c05fea0e59947db9ef2e456ccf7
|
File details
Details for the file lythp-0.0.1-py3-none-any.whl.
File metadata
- Download URL: lythp-0.0.1-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
643ebc233a2dc6360b6199d30264e195eeab89e8b825ac01d46a366ea5ad2d55
|
|
| MD5 |
5936bac4e146128fec297431e607c839
|
|
| BLAKE2b-256 |
bdd187a90cf658e4c1bfaff3bef1cc10d35c201a11c3f4cb8e71e6014ec8785b
|