<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey" -->

---
title: Tiny Great Languages: Lisp | daily.dev
description: A hands-on walkthrough of building a minimal Lisp interpreter in Python, covering the history of Lisp (created by John McCarthy in 1958), the shift from...
canonical: https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Tiny Great Languages: Lisp | daily.dev
og:description: A hands-on walkthrough of building a minimal Lisp interpreter in Python, covering the history of Lisp (created by John McCarthy in 1958), the shift from...
og:url: https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey
og:image: https://api.daily.dev/og/posts/lSKtG3WeY.png
og:image:alt: Tiny Great Languages: Lisp
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Tiny Great Languages: Lisp

**[zserge's blog](https://daily.dev/sources/zserge)** · 8 min read · 0 upvotes · 0 comments

## Summary

A hands-on walkthrough of building a minimal Lisp interpreter in Python, covering the history of Lisp (created by John McCarthy in 1958), the shift from M-expressions to S-expressions, and the Lisp 1.5 manual's famous self-hosted eval/apply definition. The piece implements core primitives (atom, car, cdr, cons, eq), lambdas, pairlis for variable binding, and a full eval/apply loop, culminating in a working factorial calculator. Part four of a 'Tiny Great Languages' series that also covers Assembly, BASIC, Forth/MOUSE, APL/K, and PL/0.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://zserge.com/posts/langs-lisp>

## Questions this post answers

### How do you implement a basic Lisp eval/apply interpreter in Python?

A minimal Lisp interpreter can be built using Python lists as the core data structure, with an atom() function distinguishing atoms from lists, and apply()/eval() functions mirroring the classic Lisp 1.5 definitions. Primitives like car, cdr, cons, eq, and arithmetic are handled in apply, while eval handles quote, cond, label, and lambda forms, with pairlis binding parameters to arguments in the environment.

_See the full interpreter walkthrough on daily.dev for anyone building their own Lisp from scratch._

### What was the original syntax of Lisp before S-expressions?

Lisp originally used M-expressions, written in a function-call style like car[cons[A,B]], rather than the parenthesized S-expressions used today. S-expressions were simpler and more uniform, embodying Lisp's 'code is data' philosophy, and quickly replaced M-expressions as the standard syntax, enabling macros to manipulate code as data.

_daily.dev surfaces language history deep dives like this for developers curious about programming language design._

## Similar posts on daily.dev

- [Lisp in 99 Lines of C and How to Write One Yourself](https://daily.dev/posts/lisp-in-99-lines-of-c-and-how-to-write-one-yourself-w2eemvlf7) · Lobsters · 0 upvotes · 0 comments
- [A road to Lisp: Why Lisp](https://daily.dev/posts/a-road-to-lisp-why-lisp-8ozisgpji) · Hacker News · 0 upvotes · 0 comments
- [Ruby And Its Neighbors: Lisp – Noel Rappin Writes Here](https://daily.dev/posts/ruby-and-its-neighbors-lisp-noel-rappin-writes-here-f4hwrudxb) · RUBYLAND · 0 upvotes · 0 comments
- [Exploring Programming Languages](https://daily.dev/posts/exploring-programming-languages-1lqxkzogv) · Beam Bloggers Webring · 64 upvotes · 8 comments

---

Tags: [#python](https://daily.dev/tags/python), [#lisp](https://daily.dev/tags/lisp)

[View this post on daily.dev](https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Tiny Great Languages: Lisp","url":"https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey"},"datePublished":"2026-08-23T10:20:21.700Z","dateModified":"2026-08-23T10:21:40.346Z","description":"A hands-on walkthrough of building a minimal Lisp interpreter in Python, covering the history of Lisp (created by John McCarthy in 1958), the shift from...","image":"https://media.daily.dev/image/upload/s--OHB84bZF--/f_auto/v1722860399/public/Placeholder%2010","thumbnailUrl":"https://media.daily.dev/image/upload/s--OHB84bZF--/f_auto/v1722860399/public/Placeholder%2010","isAccessibleForFree":true,"articleSection":"zserge's blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"zserge's blog","logo":"https://media.daily.dev/image/upload/s--KQnFBOIT--/f_auto,q_auto/v1787480407/logos/zserge","url":"https://daily.dev/sources/zserge"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,lisp","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"zserge's blog","item":"https://daily.dev/sources/zserge"},{"@type":"ListItem","position":3,"name":"Tiny Great Languages: Lisp"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/tiny-great-languages-lisp-lsktg3wey#faq","mainEntity":[{"@type":"Question","name":"How do you implement a basic Lisp eval/apply interpreter in Python?","acceptedAnswer":{"@type":"Answer","text":"A minimal Lisp interpreter can be built using Python lists as the core data structure, with an atom() function distinguishing atoms from lists, and apply()/eval() functions mirroring the classic Lisp 1.5 definitions. Primitives like car, cdr, cons, eq, and arithmetic are handled in apply, while eval handles quote, cond, label, and lambda forms, with pairlis binding parameters to arguments in the environment. See the full interpreter walkthrough on daily.dev for anyone building their own Lisp from scratch."}},{"@type":"Question","name":"What was the original syntax of Lisp before S-expressions?","acceptedAnswer":{"@type":"Answer","text":"Lisp originally used M-expressions, written in a function-call style like car[cons[A,B]], rather than the parenthesized S-expressions used today. S-expressions were simpler and more uniform, embodying Lisp's 'code is data' philosophy, and quickly replaced M-expressions as the standard syntax, enabling macros to manipulate code as data. daily.dev surfaces language history deep dives like this for developers curious about programming language design."}}]}
```

