[HN Gopher] Adding C-style for loops to Python for fun
___________________________________________________________________
Adding C-style for loops to Python for fun
Author : RojerGS
Score : 96 points
Date : 2023-02-03 16:54 UTC (6 hours ago)
(HTM) web link (sadh.life)
(TXT) w3m dump (sadh.life)
| traverseda wrote:
| Anyone looking to do this kind of thing, the macropy library
| makes it a fair bit easier:
| https://macropy3.readthedocs.io/en/latest/
|
| You really do need to be modifying the AST and not just applying
| a regex to the source code text. This can be a challenge if you
| want to modify python syntax as you first need to get an AST you
| can modify, personally I recommend starting with the LARK library
| and modifying the python syntax grammer it includes.
|
| https://lark-parser.readthedocs.io/en/latest/examples/advanc...
|
| I use similar techniques to transpile openscad code into a python
| AST in my "pySdfScad" project, while still theoretically getting
| the benefits of fancy tracebacks and debugging and the like.
| Probably should have gone with a simple parser instead, but what
| can you do.
|
| I think they should have stopped at the "cursed way" and not the
| "truly cursed way", if they really wanted the syntax changes than
| having your own python parser like the LARK implementation I
| mention above is a must.
| epr wrote:
| Some people have a lot of time on their hands.
| (defmacro cfor [initialize condition advance #* body] `(do
| ~initialize (while ~condition (do ~@body ~advance))))
| (cfor (setv i 0) (< i 10) (+= i 1) (print i))
|
| This runs on the python vm with hy right now. Took about 2 mins
| to have it up and running after noticing this post on hn.
| Couldn't pass it up.
| [deleted]
| ihatepython wrote:
| I don't understand, this gives C style for loops with C syntax?
| __jem wrote:
| looks like it to me cfor(setv(i, 0), i < 10,
| i += 1) { print(i) }
| ihatepython wrote:
| Do the brackets actually work or do you still have to get
| the indentation right?
| __jem wrote:
| no, just saying you can trivially convert any lisp code
| to c style syntax by moving the function call parenthesis
| to the right and converting wrapping parens into curly
| braces.
| epr wrote:
| This adds c style for loops to hy, which runs on the normal
| cpython vm, and therefore can make use of the thousands of
| open source python libraries available.
|
| My reply to the post was tongue in cheek. The point is that
| you can add on arbitrary language features to python using hy
| (any lisp, really). The syntax in question is normally
| referred to as an s-expression.
| hot_gril wrote:
| "It is recognized that you have a funny sense of fun."
| akkartik wrote:
| Just from the description I think this doesn't handle _continue_.
| mixmastamyk wrote:
| The range builtin already gives 98% of the functionality, just
| need to put "i in range" before it.
| chriskw wrote:
| I did something similar to option 3 to make the builtin numeric
| types "callable", since the dunder __call__ methods can't be
| overwritten for builtins. For example, in regular arithmetic
| notation, something like 6(7+8) could be read as 6*(7+8), but
| trying to do this in Python gives you `SyntaxWarning: 'int'
| object is not callable;`, since you're essentially trying to do a
| function call on the literal 6. The workaround was to use a
| custom codec to wrap all integer literals to give them the
| expected call behavior.
|
| Repo if anyone is interested: https://github.com/ckw017/blursed
|
| This was inspired by a way less silly usecase, future f-strings,
| which added f-string support to older versions of Python in a
| similar way using codecs: https://github.com/asottile-
| archive/future-fstrings
| atorodius wrote:
| Thanks for this wild ride, it went way further than I anticipated
| ..
| winterqt wrote:
| (2022)
| ur-whale wrote:
| Didn't know about codecs ...
|
| The idea of using (abusing in fact) codecs to pre-process python
| code before it gets to the actual python interpreter is just
| fantastic!
|
| I'm starting to think of all the terrible things I'm going to be
| able to do with this to work around things that have annoyed me
| for years in python.
|
| [EDIT]: I'm thinking one can probably plug the C preprocessor in
| python now ... oh the sheer joy :D
| com2kid wrote:
| > The idea of using (abusing in fact) codecs to pre-process
| python code before it gets to the actual python interpreter is
| just fantastic!
|
| Coming from Javascript which has Babel, this is kind of an
| everyday occurance. Through the magic of source code transforms
| You can easily add whatever experimental new JS features you
| want to your project!
| ___kaukas___ wrote:
| A long time ago I stumbled upon (and contributed to)
| https://github.com/delfick/nose-of-yeti. The most delightful bit
| of cursed Python I've seen!
| masklinn wrote:
| > Or alternatively: How I made the most cursed Python package of
| all time.
|
| Beg your pardon, http://entrian.com/goto/ exists.
| [deleted]
| albertzeyer wrote:
| I don't understand the reasoning why the transformation directly
| on the source code is better than on the AST level?
|
| Because you can use coding and then it's somewhat automatic?
|
| But you can do sth similar on AST level, namely installing a meta
| path finder, i.e. an import module hook which does the AST
| transformation automatically
| (https://docs.python.org/3/library/sys.html#sys.meta_path).
|
| Then, there is also the new frame evaluation API
| (https://peps.python.org/pep-0523/), which allows you to
| dynamically rewrite bytecode. This has been used by PyTorch 2.0
| for torch.compile.
| adrianmonk wrote:
| In part 1, they say, "I wanted it to look like a regular for-
| loop from C as much as possible."
|
| The AST method seems to require you to write "with _for"
| instead of "for".
|
| The method in part 3 allows you to write "for", which is
| closer.
|
| So presumably it's better because it gets closer to the
| objective, although at quite a cost of course.
| traverseda wrote:
| That only work in an import statement, not when you run the
| code directly.
| [deleted]
| benrutter wrote:
| There really is nothing greater than an completely idiotic idea
| implemented with pure genius - this was immense reading and I
| learnt a lot!
| nothrowaways wrote:
| it is like a sitcom.
| mjburgess wrote:
| So it seems you can register a source transformer with python
| which will trigger when a `# coding: ...` header is used (to
| signal character encoding).
|
| This seems like an interesting avenue for static analysis tools,
| code generators, (etc.) to explore. Is it a viable approach?
|
| I'd be interested in some analysis on this as a mechanism:
| performance, maintability, etc. wise.
|
| The "dont do this" argument writes itself; nevertheless, its
| worth exploring.
| ktpsns wrote:
| Funnily this reminds me of how racket defines a language
| (https://beautifulracket.com/explainer/lang-line.html). Or how
| basically a shebang line does the same for any kind of script
| (https://en.wikipedia.org/wiki/Shebang_(Unix)).
| leethargo wrote:
| True, but I think that source transformation on import are
| already supported in Python ("officially") based on importlib
| [0-1].
|
| Here's an example use cases where the author is trying to
| create a Python enum from Thrift specs: [2]. The issue here is
| that the spec code is not necessarily valid Python, but can be
| fixed easily with some search & replace operations.
|
| [0] https://docs.python.org/3/reference/import.html [1]
| https://docs.python.org/3/library/modules.html [2]
| http://wakandan.github.io/2018/06/07/python3-import-hook.htm...
| leethargo wrote:
| One of the benefits of implementing your own module finder
| and loader is that you could use a separate file extension to
| avoid confusion with actual Python code.
___________________________________________________________________
(page generated 2023-02-03 23:00 UTC)