The following S-Expression forms would improve code readability, AST semantics, and help avoid syntax workarounds (like raw string insertion or helper function fallbacks).
Currently, writing (raise (ValueError "msg")) compiles to raise(ValueError("msg")), which wraps the raise statement in function-call parentheses.
;; Lisp Input
(raise (ValueError (string "invalid value")))# Emitted Python
raise(ValueError("invalid value"))Introduce a dedicated statement form that prints raise followed by the exception expression without surrounding the raise keyword in parentheses.
;; Proposed Lisp Input
(raise_ (ValueError (string "invalid value")))# Expected Python Output
raise ValueError("invalid value")Currently, decorators are written as sibling expressions in a do0 block, which is a structural hack.
;; Lisp Input
(do0
(@rt.route (string "/"))
(def index ()
(return (string "Hello"))))# Emitted Python
@rt.route("/")
def index():
return "Hello"Introduce a semantic structure linking decorators explicitly to the functions or classes they decorate.
;; Proposed Lisp Input
(decorator (@rt.route (string "/"))
(def index ()
(return (string "Hello"))))# Expected Python Output
@rt.route("/")
def index():
return "Hello"Currently, comprehensions reuse for-generator wrapped in list / curly, and repurpose slice to represent : inside dictionaries.
;; Lisp Input
(curly (for-generator ((ntuple i s) (enumerate chars)) (slice s (+ i 1))))# Emitted Python
{s: i + 1 for i, s in enumerate(chars)}Provide explicit, semantic comprehension forms.
;; Proposed Lisp Input (Dict Comprehension)
(dict-comp ((ntuple i s) (enumerate chars))
s
(+ i 1))
;; Proposed Lisp Input (List Comprehension)
(list-comp (x (range 5))
(* x 2))# Expected Python Output
{s: i + 1 for i, s in enumerate(chars)}
[x * 2 for x in range(5)]The assert keyword is commented out in py.lisp because it conflicts with the Common Lisp assert macro if used without qualification.
;; Lisp Input (Function call fallback)
(assert (== x y))# Emitted Python
assert(x == y)Provide a shadow-safe dedicated assertion form that formats as a statement.
;; Proposed Lisp Input
(assert_ (== x y) (string "x and y must be equal"))# Expected Python Output
assert x == y, "x and y must be equal"Currently, global statements are written using raw string injection:
;; Lisp Input
"global f_num"# Emitted Python
global f_numProvide a dedicated statement form that prints global followed by space-separated variable names.
;; Proposed Lisp Input
(global_ f_num)# Expected Python Output
global f_numCurrently, nonlocal statements are written using raw string injection:
;; Lisp Input
"nonlocal x"# Emitted Python
nonlocal xProvide a dedicated statement form that prints nonlocal followed by space-separated variable names.
;; Proposed Lisp Input
(nonlocal_ x)# Expected Python Output
nonlocal xAsynchronous functions and awaits currently rely on joining async and await with spaces as a prefix:
;; Lisp Input
(space async (def post (comment)
(return (space await (self.cli.request ...)))))# Emitted Python
async def post(comment):
return await self.cli.request(...)Introduce semantic forms for asynchronous functions and await expressions.
;; Proposed Lisp Input
(async-def post (comment)
(return (await_ (self.cli.request ...))))# Expected Python Output
async def post(comment):
return await self.cli.request(...)Writing (del x) falls back to function-call syntax del(x).
;; Lisp Input
(del (aref _job_store uid))# Emitted Python
del(_job_store[uid])Provide a dedicated statement form that prints del followed by space-separated expressions.
;; Proposed Lisp Input
(del_ (aref _job_store uid))# Expected Python Output
del _job_store[uid]Class variable type annotations (often required by @dataclass or schema definitions) are currently written as raw string literals.
;; Lisp Input
(class GenerationConfig ()
"prompt_text:str"
(setf "model:str" (string "gemini-flash-latest")))# Emitted Python
class GenerationConfig:
prompt_text: str
model: str = "gemini-flash-latest"Allow declaring typed attributes in classes natively.
;; Proposed Lisp Input
(class GenerationConfig ()
(typed-var prompt_text str)
(setf (typed-var model str) (string "gemini-flash-latest")))# Expected Python Output
class GenerationConfig:
prompt_text: str
model: str = "gemini-flash-latest"Writing (yield x) falls back to function-call syntax yield(x).
;; Lisp Input
(yield (dictionary :type (string "thought") :text part.text))# Emitted Python
yield({"type": "thought", "text": part.text})Support yield as a keyword/expression statement without parenthesizing its argument.
;; Proposed Lisp Input
(yield_ (dictionary :type (string "thought") :text part.text))
(yield-from iterable)# Expected Python Output
yield {"type": "thought", "text": part.text}
yield from iterable