m28

command module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2025 License: MIT Imports: 13 Imported by: 0

README

M28 - A Lispy-Pythonic Programming Language

Version License Go Version

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.

Quick Start

# 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]

Installation

# 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.m28

Language Features

S-Expression Syntax

Everything is an expression in prefix notation:

(+ 1 2 3)           # 6
(print "Hello")     # Hello
(= x 5)
(if (> x 0) "positive" "non-positive")  # "positive"
Python Semantics
  • # for comments (Python-style)
  • def only 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.
Modern Data Structures
# Lists
(= fruits ["apple", "banana", "orange"])

# Dictionaries  
(= person {"name": "Alice", "age": 30})

# Sets
(= unique {1, 2, 3})

# Tuples
(= point (tuple [10, 20]))
Object-Oriented Programming
(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
Functional Programming
# 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)])
Exception Handling
(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")))
Module System
(import math)
(import pandas as pd)
(from datetime import date)

(= root (math.sqrt 16))
(= df (pd.DataFrame data))

Documentation

Examples

Hello World
(print "Hello, World!")
Factorial
(def factorial (n)
  (if (<= n 1)
      1
      (* n (factorial (- n 1)))))

(print (factorial 5))  # 120
File I/O
(with (open "data.txt" "r") as f
  (for line in f
    (print (strip line))))
Quick Sort
(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]

New in v0.2.0: Protocol System

M28 now supports Python-style protocols for creating extensible custom types:

Iterator Protocol
(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
Container Protocols
(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"
Other Protocols
  • 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

Why M28?

  1. S-expressions - Code is data, enabling powerful metaprogramming
  2. Python semantics - Familiar and pragmatic design choices
  3. Prefix notation - Consistent, unambiguous syntax
  4. Functional programming - First-class functions, map/filter/reduce
  5. Modern features - List comprehensions, context managers, generators
  6. Simple implementation - Easy to understand and extend

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

License

M28 is licensed under the MIT License. See LICENSE for details.

Acknowledgments

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

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package builtin provides built-in functions for the M28 language.
Package builtin provides built-in functions for the M28 language.
operators
Package operators provides arithmetic and comparison operators for M28
Package operators provides arithmetic and comparison operators for M28
common
builders
Package builders provides function builders that eliminate boilerplate in builtin function implementations.
Package builders provides function builders that eliminate boilerplate in builtin function implementations.
errors
Package errors provides standardized error types for the M28 language.
Package errors provides standardized error types for the M28 language.
types
Package types provides utilities for type checking and conversion in M28
Package types provides utilities for type checking and conversion in M28
validation
Package validation provides utilities for validating function arguments in M28.
Package validation provides utilities for validating function arguments in M28.
Package core provides the fundamental types and interfaces for the M28 language.
Package core provides the fundamental types and interfaces for the M28 language.
ast
Package ast provides the abstract syntax tree types for M28.
Package ast provides the abstract syntax tree types for M28.
protocols
Package protocols defines standard interfaces for M28 types to implement common operations like arithmetic, indexing, and iteration.
Package protocols defines standard interfaces for M28 types to implement common operations like arithmetic, indexing, and iteration.
m28shell command
Package eval provides the evaluation system for M28 expressions.
Package eval provides the evaluation system for M28 expressions.
examples
Package modules provides the io module for M28
Package modules provides the io module for M28
Package parser provides a parser for the M28 programming language.
Package parser provides a parser for the M28 programming language.
Package repl provides the read-eval-print loop for interactive M28 sessions.
Package repl provides the read-eval-print loop for interactive M28 sessions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL