MVPy: Minimum Viable Python

Over 29 posts spanning 2 years, this is the final post in my blog series on Python's syntactic sugar. I had set out to find all of the Python 3.8 syntax that could be rewritten if you were to run a tool over a single Python source file in isolation and still end up with reasonably similar semantics (i.e. no whole-program analysis, globals() having different keys was okay). Surprisingly, it turns out to be easier to list what syntax you can't rewrite than re-iterate all the syntax that you can rewrite!

  1. Integers (as the base for other literals like bytes)
  2. Floats (because I didn't want to mess with getting the accuracy wrong)
  3. Function calls
  4. =
  5. :=
  6. Function definitions
  7. global
  8. nonlocal
  9. return
  10. yield
  11. lambda
  12. del
  13. try/except
  14. if
  15. while

All other syntax can devolve to this core set of syntax. I call this subset of syntax the Minimum Viable Python (MVPy) you need to make Python function as a whole. If you can implement this subset of the language, then you can do a syntactic translation to support the rest of Python's syntax (although admittedly it might be a bit faster if you directly implemented all the syntax 😉).

If you look at what synatx is left, it pretty much aligns to what is required to implement a Turing machine:

  1. Read/write data (=,  :=, integers and floats)
  2. Make decisions about data (if,  while, and try)
  3. Do things to that data (everything involving defining and using functions)

You might not be as productive in this subset of the language as you would be with all the syntax available in Python 3.8 (and later), but you should still be able to accomplish the same things given enough time and patience.