๐Ÿ 

Zen notation

what JSON is to JavaScript, Zen is to Python.

a quick thought experiment

Think about what JSON is. It's a subset of JavaScript syntax that only knows how to express data. No functions, no classes, no side effects โ€” just literal values.

JSON is "the part of JavaScript that's safe to treat as data."

Python already has a similar subset. It's called Zen (or Zef Entity Notation). The idea is identical โ€” only, for Python.

the whole thing fits on one card

# strings
'a plain string'
"or with double quotes"

# numbers (and it really is "numbers" โ€” int, float, scientific)
1234
-56
3.14
1e10

# booleans + None
True
False
None

# lists
[1, 2, 3, 'four', None, True]

# dicts
{'key1': 'value1', 'key2': 42}

# SETS โ€” unlike JSON!
{1, 'two', 3.0, None}

# tuples
(1, 'two', 3.0)

That's it. Every Zen expression is valid Python, and every Python literal data structure is valid Zen.

JSON vs Zen

JSON ๐Ÿ˜
  • true, false, null
  • no sets
  • no trailing commas
  • double-quotes only
  • no comments
  • no integers vs floats distinction
Zen ๐Ÿ˜Œ
  • True, False, None
  • sets are fine
  • trailing commas welcomed
  • single or double quotes
  • # comments OK
  • int vs float preserved
  • pastes straight into a REPL

what Zen is NOT

It deliberately excludes anything that can execute code:

# โŒ NOT Zen โ€” these have side effects
print("hello")
open("file.txt")
my_list.append(1)

# โŒ NOT Zen โ€” definitions, not data
def f(x): return x
class Foo: pass
x = 42

# โŒ NOT Zen โ€” references runtime state
my_variable
config['key']
mental model โ€” zen = safe data literal

If a piece of text only describes values, it's Zen. If it does anything (assigns, calls, defines), it's not.

Why draw this line? Because you can safely ast.literal_eval any Zen expression. You can store it in a file, send it over a socket, pipe it between processes โ€” and the worst thing it can do is be wrong. It can't execute code.

this shows up EVERYWHERE in zef

Configuration files: Zen. Database entries: Zen. Entity definitions: Zen. Test cases: Zen. Error payloads: Zen. Once you start looking, you see it.

# ~/.config/zef/config.zen.py โ€” a zef config file
ET.ZefConfig(
    zef_source_dir='/home/me/code/zef',
    vault_=['~/zef-vault', '~/shared-vault'],
)

That's a valid Python expression you can from some_file import * from. It's also a data value you can ship around.

Zen with entity types

Zen extends to entity constructors. These are valid Python and valid Zen:

ET.Person(name='Alice', age=30)

ET.Company(
    name='Acme',
    founded=1948,
    employees_=[
        ET.Person(name='Alice', role='CEO'),
        ET.Person(name='Bob',   role='CTO'),
    ],
)

why this is powerful

Your entire data model โ€” the "schema" + the values โ€” can be expressed in Python literal syntax. No YAML, no TOML, no custom DSL. The file with your entities is executable Python that evaluates to data.

Zef leans on this heavily: the file-backed DB stores Zen, the config system uses Zen, tests are Zen, docs embed Zen snippets that the runtime can parse.

round-tripping

Because every Zen expression is Python, and the parser is the Python parser, you can always convert in either direction:

import ast

zen_text = """
{
    'name': 'Alice',
    'tags': ['admin', 'python'],
    'meta': {'active': True, 'visits': 42},
}
"""
data = ast.literal_eval(zen_text)    # safe โ€” no code execution

Write it, edit it, store it, ship it. Safe as plain text.

the five key takeaways

practice

Write a Zen expression for a small company:

answer
{
    'name': 'Green Widgets',
    'tags': {'b-corp', 'founded-2020'},
    'employees': [
        {'name': 'Alice', 'age': 30, 'role': 'admin'},
        {'name': 'Bob',   'age': 25, 'role': 'dev'},
        {'name': 'Carol', 'age': 40, 'role': 'ceo'},
    ],
}

Next up: types are sets โ€” and that single sentence rewrites how you think about typing. โ†’