M28 is a modern programming language that blends the elegant s-expression syntax of Lisp with the pragmatic design and extensive ecosystem of Python. It offers the best of both worlds: the power of homoiconic code and macros with Python's clean semantics and familiar keywords.
# Variables use = (never def)
(= message "Hello, M28!")
(print message)
# Functions use def
(def greet (name)
(print "Hello," name))
(greet "World")
# Python-style data structures with Lisp syntax
(= numbers [1, 2, 3, 4, 5])
(= doubled (map (lambda (x) (* x 2)) numbers))
(print doubled) # [2, 4, 6, 8, 10]# Clone the repository
git clone https://github.com/mmichie/m28.git
cd m28
# Build the interpreter
make build
# Run the REPL
./bin/m28
# Run a script
./bin/m28 script.m28Everything is an expression in prefix notation:
(+ 1 2 3) # 6
(print "Hello") # Hello
(= x 5)
(if (> x 0) "positive" "non-positive") # "positive"#for comments (Python-style)defonly for functions=only for variables- Python keywords:
if,elif,else,for,in,while,try,except,class,import, etc. - Python built-ins:
len,range,sum,map,filter,print, etc.
# Lists
(= fruits ["apple", "banana", "orange"])
# Dictionaries
(= person {"name": "Alice", "age": 30})
# Sets
(= unique {1, 2, 3})
# Tuples
(= point (tuple [10, 20]))(class Person
(def __init__ (self name)
(= self.name name))
(def greet (self)
(print f"Hi, I'm {self.name}")))
(= alice (Person "Alice"))
(alice.greet) # Hi, I'm Alice# First-class functions
(= numbers [1, 2, 3, 4, 5])
(= evens (filter (lambda (x) (== (% x 2) 0)) numbers))
(= squared (map (lambda (x) (* x x)) evens))
# List comprehensions
(= squares [(** x 2) for x in (range 10) if (== (% x 2) 0)])(try
(/ 1 0) # This will raise an error
(except
(print "Caught an error!")))
# With finally block
(try
(print "Attempting operation...")
(/ 10 2)
(except
(print "Error occurred"))
(finally
(print "Cleanup complete")))(import math)
(import pandas as pd)
(from datetime import date)
(= root (math.sqrt 16))
(= df (pd.DataFrame data))- Language Guide - Comprehensive language reference
- Tutorial - Step-by-step introduction
- Standard Library - Built-in functions and modules
- Debugging Guide - Debug flags, logging system, and troubleshooting
- Examples - Code examples and patterns
(print "Hello, World!")(def factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
(print (factorial 5)) # 120(with (open "data.txt" "r") as f
(for line in f
(print (strip line))))(def quicksort (lst)
(if (<= (len lst) 1)
lst
(let pivot (first lst)
rest (rest lst)
less (filter (lambda (x) (< x pivot)) rest)
greater (filter (lambda (x) (>= x pivot)) rest)
(+ (quicksort less) [pivot] (quicksort greater)))))
(print (quicksort [3, 1, 4, 1, 5, 9, 2, 6])) # [1, 1, 2, 3, 4, 5, 6, 9]M28 now supports Python-style protocols for creating extensible custom types:
(class Counter
(def __init__ (self max)
(= self.max max)
(= self.current 0))
(def __iter__ (self)
self) # Return self as iterator
(def __next__ (self)
(if (< self.current self.max)
(let ((val self.current))
(= self.current (+ self.current 1))
val)
(raise StopIteration))))
# Use in for loop
(for i in (Counter 5)
(print i)) # Prints 0, 1, 2, 3, 4(class MyList
(def __init__ (self)
(= self.data {}))
(def __getitem__ (self index)
(get-item self.data (str index)))
(def __setitem__ (self index value)
(set-item self.data (str index) value))
(def __delitem__ (self index)
(del-item self.data (str index))))
(= ml (MyList))
(set-item ml 0 "hello")
(print (get-item ml 0)) # "hello"- Arithmetic:
__add__,__sub__,__mul__,__div__for operator overloading - Comparison:
__eq__,__lt__,__le__for custom comparisons - String:
__repr__,__str__for string representations - Boolean:
__bool__for truthiness - Length:
__len__for container size - Contains:
__contains__for membership testing
- S-expressions - Code is data, enabling powerful metaprogramming
- Python semantics - Familiar and pragmatic design choices
- Prefix notation - Consistent, unambiguous syntax
- Functional programming - First-class functions, map/filter/reduce
- Modern features - List comprehensions, context managers, generators
- Simple implementation - Easy to understand and extend
Contributions are welcome! Please read our Contributing Guide for details.
M28 is licensed under the MIT License. See LICENSE for details.
M28 stands on the shoulders of giants:
- Lisp for s-expressions and homoiconicity
- Python for pragmatic design and clear semantics
- Scheme for minimalism and elegance
- Clojure for modern Lisp innovations