for line in open("python_yacc.py"):
if line =~ m/def (\w+)/:
print repr($1)
See http://www.dalkescientific.com/writings/diary/archive/2008/0...I started by writing a Python grammar definition based on PLY (see http://www.dabeaz.com/ply/) , then tweaked it to handle the new feature and emit the right AST. It's when I discovered the following was valid Python:
>>> a=b=c=d=e=1
>>> del a, (b, (c, (((((d,e)))))))
I don't think PLY can handle the newest Python grammar, but I haven't looked into it.For what it's worth, my Python grammar was based on an older project I did called GardenSnake, which still available as a PLY example, at https://github.com/dabeaz/ply/tree/master/example/GardenSnak... .
I've been told it's was one of the few examples of how to handle an indentation-based grammar using a yacc-esque parser generator.
Anyway, if you found this interesting, you might enjoy Eli Bendersky's blog post from nearly 15 years ago where he adds an "until ... do" statement to Python.
https://eli.thegreenplace.net/2010/06/30/python-internals-ad...
I suspect that’s mostly because the `until` statement is more complex - but another factor seems to be Python’s change in parsing technology from LL(1) to PEG.
(defmacro do* [body expr cond]
`(~expr ~cond
~body))
(do* (println "hello") if true)
(do* (println "hello") when-not (> 1 2)) Above all the wonders of Lisp's pantheon stand its metalinguistic tools; by their grace have
Lisp's acolytes been liberated from the rigid asceticism of lesser faiths. Thanks to Macro and
kin, the jolly, complacent Lisp hacker can gaze through a fragrant cloud of setfs and defstructs
at the emaciated unfortunates below, scraping out their meager code in inflexible notation, and
sneer superciliously. It's a good feeling.
-- iterate manual, A.1 Introduction
do..while is also the example used here https://www.tcl-lang.org/man/tcl9.0/TclCmd/uplevel.htmlI have worked on a similar series of CPython customization articles that you might find interesting:
spam = eggs if bar
# vs
spam = eggs if bar else None x = func1() if something else func2()
In this example, only func1() or func2() is being called, but not both.Related to your comment, though: Python has had this syntax for a VERY long time.
pyhton-dev is a corporate shark tank where only personalities and employer matter (good code or ideas are optional).
The effort is very much appreciated.
1 if True else 2I would say it's a good thing, I don't want to see a hundred of half baked, badly tested and vaguely document DSL with no decent tooling support.
When this comes up I usually link to the work of Alan Kay and others (the very mystical sounding STEPS project at VPRI)
""" The big breakthrough is making it easy to create new DSLs for any situation. Every area of the OS has its own language (and you can just add more if you feel the need) so that the whole OS including networking and GUI is very compact, understandable, and hackable. This particular project focused on compactness, just to prove that it is quantitatively more expressive. """
comment by sp332 https://news.ycombinator.com/item?id=11687952
final report from 2016 https://news.ycombinator.com/item?id=11686325
The reason we don't have such metaprogramming available everywhere is mostly because you have to subscribe to a particular ideology to allow it. If you think programmers are generally intelligent and responsible, you put macros and metaclasses in your language. If, on the other hand, you think most programmers are dumb code monkeys (with a few exceptions, maybe) your language becomes like early Java or early Go.
Since you mention it, Python does have a fairly elaborate metaclass system, but it seems like it's only really used for implementing the language and rarely if ever wielded by "users". I guess that's a reflection of the language ideology you're talking about.
Also for what it's worth, I know myself to be a dumb code monkey, but being in the CRUD gutter doesn't preclude me from looking at the metasyntactic stars.
Rust for example has a solution for this in std, there's a `bool::and_some` method (and `bool::then` that takes a closure to avoid eagerly evaluating the value), but `if { ... }` isn't an expression like `if { ... } else { ... }` is, probably to avoid coupling the language to `Option`.