Making a Python interpreter in 1024 bytes (austinhenley.com)
239 points by azhenley 12 hours ago
jrdres 10 hours ago
The code makes me smile, because it's nasty. This isn't like C4, a tiny but complete C compiler which does error checking on its subset. Instead, this is worse than Sector C, which takes every shortcut and just plain assumes everything in the source is right.
This "Python" just plain assumes for keywords: Any "f" is a "for [x] in range[y]" (exactly that, no other for's). Any "w" is a "while". Any "i" is an "if". Any "d" is a "def". Any "p" is a "print("
Nasty, nasty.
(Also nasty is that the code snippets in the article has more comments than the github copy of the "readable" version. You need the article to understand what's going on.)
This is a just a bit too simple for a "Tiny Python". If somebody is willing to allow a few more K's of bytes, I'd love to see at least lists & dicts here--Lisp can do them!
tveita 5 hours ago
As they say in TDD, write a test, then write the simplest code that will make it pass.
Clearly supporting multiple functions starting with 'p' would be overengineering.
bloppe 2 hours ago
By that standard, this is totally over-engineered. Just hardcode it.
eru 9 hours ago
If you are willing to sacrifice performance, you can implement dicts via linear lookup in much less code than a proper hash table.
Someone 3 hours ago
Because Python dicts guarantee iteration order is the same as insertion order (https://docs.python.org/3.7/library/stdtypes.html#typesmappi...) Python dicts aren’t just proper hash tables.
Because of that it wouldn’t surprise me much if that sped up some standard benchmarks, for example ones parsing lots of small json objects into dictionaries.
FridgeSeal 8 hours ago
It’s Python, you’ve already sacrificed performance, what a little bit more?
eru 7 hours ago
adamddev1 2 hours ago
Reminds me of the good 'ol Apple II BASIC. You can name your variables whatever you want, but only the first two letters matter.
userbinator 2 hours ago
Two letters is luxury, when most BASIC interpreters in those days only recognised 1-letter variables.
kristianp 5 hours ago
> Any "w" is a "while"
Meaning that something as simple as "w = 4" would fail? A little too nasty for my liking. Not a choice I would have made, but admire the amount of work done here and the readability of the article. And it's more human-written code than I've done in a number of months!
stevefan1999 an hour ago
But to be honest, I wonder what is the smallest interpretable and practical Turing Complete VM? I would argue that implementing a brainfuck that we lower Python interpreter to, or even say like an interpreter untyped lambda calculus or SKI combinator would be very useful, especially for the hardware bootstrapping.
I'm talking about things like SectorLisp https://justine.lol/sectorlisp/
teddyh 11 hours ago
For those who actually need something like this in production, there is Snek: <https://sneklang.org/> “Snek is a tiny embeddable language targeting processors with only a few kB of flash and ram.”
jrdres 10 hours ago
Yes, but compiling or modifying Snek from source is very challenging. I wish it was one single C file for an example base like Posix, instead of many files for many platforms plus a custom parser in Python (Lola).
eru 9 hours ago
Or Forth.
marcelo-earth 9 hours ago
Reading the article, I can't believe I just found out Code Golf is a thing. I've been a programmer for more than a decade.
But yes, amazing project! I like that it's human-made :)
kylecazar 9 hours ago
The quintessential example is donut.c. I was amazed when I first came across it.
eclipticplane 8 hours ago
> This was my first attempt at obfuscated C and I feel it's pretty amateurish
I love feelings of inadequacy at 11:07pm on a Sunday.
Here's the judges' remarks and author commentary on the second edition of this from the 2006 results: https://www.ioccc.org/2006/sloane/index.html
HappMacDonald 4 hours ago
This one is my favorite:
https://github.com/ioccc-src/winner/blob/master/2025/ncw1/pr...
agumonkey 5 hours ago
Always fun to see this pop up years later. (Damn, 20 years now)
bolangi 8 hours ago
Thanks, this makes me happy.
Forgeties79 7 hours ago
Absolute legend
> it’s worked on every system I’ve tried so far though
Still my favorite part of the whole thing. Classic moment of “who among us hasn’t doesn’t this?” lol
Lerc 7 hours ago
Get thee to
Also https://github.com/nanochess
And then if you really want to go large
https://phoboslab.org/log/2021/09/q1k3-making-of
I still have a soft spot for https://www.pouet.net/prod.php?which=1221
rottc0dd 4 hours ago
This is my favorite : https://www.cise.ufl.edu/~manuel/obfuscate/pi.c
NooneAtAll3 3 hours ago
userbinator 8 hours ago
To be precise this is 1024 bytes of C, which compiles to a binary many times larger, and implements a very tiny subset of Python.
loops work by jumping backwards and reparsing the source each iteration
This is how the DOS .bat processing works; not sure if Unix-style shells are the same, as I've never had the need to exploit that "feature".
Another comment here has mentioned C4, but another extremely dense (and slightly larger, since it wasn't actually deliberately(!) "code-golfed") interpreter you may want to look at is the J Incunabulum:
https://www.jsoftware.com/ioj/iojATW.htm
More generally, the array programming culture seems to consider this level of density the norm:
shakna 5 hours ago
Bash lines are buffered, so modifying behind the program position doesn't really work, but you can self-append to the file to keep a script going infinitely.
anitil 10 hours ago
This is really cool! It's so fun to see what you can achieve and what's optional. I have seen the 'single character variable' limitation in some other minilangs before, but using the source itself as the target of function calls and loops is new to me. It does make a lot of sense but I wouldn't have thought of that.
userbinator 8 hours ago
but using the source itself as the target of function calls and loops is new to me
This was standard practice on interpreters for 8-bit microcomputers; with only a 64K total address space, creating an AST first seems immensely wasteful, so you interpret from the source directly.
I believe shells still do this when you run shell scripts; I know the DOS COMMAND.COM definitely does.
andai 7 hours ago
Scubabear68 11 hours ago
I was very disappointed that this is “interpreting” some tiny made up language.
This is not Python, or even within three orders of magnitude of Python.
stingraycharles 9 hours ago
Yeah the amount of Python code that would work here is probably not a lot more than this specific FizzBuzz example. Lots of shortcuts taken, which I guess is understandable.
SPBS 11 hours ago
It’s true, the title should have said “Python-like”
happycube 10 hours ago
TBF the fizzbuzz code works just fine in CPython.
benatkin 9 hours ago
benatkin 9 hours ago
I like python subset. However, many don't see it that way.
hmry 9 hours ago
tyilo 3 hours ago
tempodox 11 hours ago
This seems to be in the same spirit as Justine Tunney's SectorLISP. Very cool.
forgotpwd16 4 hours ago
SectorLISP makes an important question in its implementation: how much can strip down Lisp before stops being Lisp. Same is not done for submitted interpreter. So, although SectorLISP goal is to be a Lisp-reduced-to-its-essentials implementation, the Python-1024 goal seems to be imitating Python in most minimal code possible.
gabrielsroka 10 hours ago
hankbond 11 hours ago
Good use of free will and well-written. Very nice walkthrough austin!
peter_d_sherman 7 hours ago
The condensed version is impressive to be sure, but I'm an even bigger fan of the readable version:
https://github.com/AZHenley/python1024/blob/main/python1024_...
Well done!
krttherealest an hour ago
well written, looks cool ngl
galkk 4 hours ago
I hate when they measure the size of source code instead of the size of a binary.
I appreciate .kkrieger much more than this monstrosity
TZubiri 11 hours ago
A lot of criticism of python often mentions the whitespace as lexical scope tokens, and that criticism is usually posited by users of the language.
As implementer of an interpreter, did you feel that whitespace for lexical scoping made the job of writing the lexer significantly more complex?
nomel 11 hours ago
And, there are multiple white space symbols!
<space><space><tab><space>
is different than
<space><tab><space><space>
So you also have to track the actual sequence of counts of white space used for each level, rather than just a simple count.
rmunn 11 hours ago
Or you just forbid mixing spaces and tabs in the same indentation sequence, the way most whitespace-sensitive languages seem to end up doing. Or you make a slightly more reasonable rule: spaces may follow tabs, but no tabs may follow a space. That's at least unambiguous.
hmry 9 hours ago
fc417fc802 11 hours ago
jubilanti 11 hours ago
> <space><space><tab><space> is different than <space><tab><space><space>
in my view, both are the same, both `is` (or ===) an IndentationError raise
fc417fc802 11 hours ago
It's just a stack containing strings at the end of the day. Really not a big deal.
TZubiri 10 hours ago
TZubiri 10 hours ago
For a 1024 byte implementation (and even way more complex impl.) You would just force one whitespace char, and definitely no mixing.
pansa2 9 hours ago
> did you feel that whitespace for lexical scoping made the job of writing the lexer significantly more complex?
Significant indentation requires a more complex lexer because it means the lexical grammar is no longer regular. The lexer can't just be a finite state machine, instead it has to maintain a stack of previous indentation levels.
But I don't think many modern languages have a regular lexical grammar anyway. Without significant indentation, some other features still require the lexer to maintain a stack - e.g. string interpolation (Python's f-strings).
zephen 10 hours ago
> that criticism is usually posited by users of the language.
Uhhh, no. Sure, it's posited by people who feel they are are forced to use it, but it's basically unlearning other syntax.
Here's a study about people with no experience. They do better with python:
https://www.researchgate.net/publication/262256894_An_Empiri...
When the scala language made whitespace optional, it was very divisive, but now it's extremely well accepted.
mbirth 10 hours ago
At a former workplace where most stuff was done in PHP, some colleagues used whitespace very liberally. Like, indentation was just a random amount of whitespace, every line slightly different. Sometimes 2 or more spaces between keywords, etc.
After that experience Python code is like eye-bleach to me.
TZubiri 10 hours ago
I meant users of languages ( application programmers) as opposed to compiler programmers, not python programmers specifically, so I'm including devs that use other languages and see in python a tool that they would consume.
ni5arga 11 hours ago
the blog post is pretty well-written! loved how he wrote about the the code-golfing part.
einpoklum 3 hours ago
tl;dr:
1. Choose a small fragment of the language
2. Adapt an existing interpreter
3. Use a tool to shorten the code, 'minify'
ssfdg 8 hours ago
I don't understand the point of this. If they wanted to make a Python interpreter, why didn't they just ask an AI to do it?
Donald 8 hours ago
> To feel human, I write code by hand on the weekends.
"Things won are done; joy’s soul lies in the doing." - Troilus and Cressida
bblb 6 hours ago
Why do anything. Why even do the AI version of this.
Probably curiosity.
If there's an AI version of code golfing, I'd be curious to see it. Maybe they golf worse or much better than us meat bags.
userbinator 2 hours ago
Just ask your preferred AI tool if it can shrink the OP's code while keeping the same functionality; I suspect it could. At this point, LLMs are probably no worse than an average human at sizecoding or targeting resource-constrained platforms in general; https://news.ycombinator.com/item?id=49226923 is a recent example of how powerful they've become.