Hyding Hy to win the Py #2662
-
Hello ! TL;DRWhy does hy2py print code for the macros and not just the result of their execution ? Once upon a time...I recently discovered Hy and am having a lot of fun. I was brought here thus:
And thus is my question: has it already been done, in the spirit of Rescript and JS, or of jujutsu and git, to silently write Hy while the rest of your team uses python, without them noticing "too much" ? The very, very short POC I tried to write led me to believe that was not the case, because hy2py copies over macros in the generated python code... If it were possible to write a bunch of macros / eval-when-compile functions, call the macros, run hy2py and then just hand over the generated python, it would be a massive time and effort save, all the while being more fun. What I'm aiming forclass Context(RootModel[Annotated[str, StringConstraints(strict=True, pattern="^[a-z_]+$")],],
frozen=True,
):
"""Some docstring thingy""" What I wrote(defmacro annot-str-model [name pattern docstr]
(setv typ (fn [pat]
`(get RootModel
(get Annotated
#(str (StringConstraints :strict True :pattern ~pat))))))
`(defclass ~name [~(typ pattern)]
~docstr
))
(annot-str-model ContextName "^[a-z-]+$" "docstr") What I get with hy2pyimport hy
def _hy_anon_var_1(name, pattern, docstr):
typ = lambda pat: hy.models.Expression([hy.models.Symbol('get', from_parser=True), hy.models.Symbol('RootModel', from_parser=True), hy.models.Expression([hy.models.Symbol('get', from_parser=True), hy.models.Symbol('Annotated', from_parser=True), hy.models.Tuple([hy.models.Symbol('str', from_parser=True), hy.models.Expression([hy.models.Symbol('StringConstraints', from_parser=True), hy.models.Keyword('strict', from_parser=True), hy.models.Symbol('True', from_parser=True), hy.models.Keyword('pattern', from_parser=True), pat])])])])
return hy.models.Expression([hy.models.Symbol('defclass', from_parser=True), name, hy.models.List([typ(pattern)]), docstr])
hy.macros.macro('annot-str-model')(_hy_anon_var_1)
class ContextName(RootModel[Annotated[str, StringConstraints(strict=True, pattern='^[a-z-]+$')]]):
"""docstr""" If macros are compiled and ran at compile time, why does the "compiled" result contain both the result of the execution of the macro (the class declaration, my goal) and a definition for the macro ? Said definition should never be run at run-time, no ? So there's no point in having its code in the final program ? What am I missing ? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
Hi @jedesroches ! I don't have an answer to your actual question about the macros, just the intuition that the Python code produced by I have been lightly using Hy more or less on and off for about a year now, and the impression that I get is that what is coming out of |
Beta Was this translation helpful? Give feedback.
-
I am still curious as to why the macros end up in the final source code though. Conceptually, my understanding of metaprogramming in a general sense is that things happen like this: parsing => AST with macros => macro compilation => macro execution on AST => final AST without macros => compilation => bytecode Locally in Hy, From what I can understand by reading the Is that understanding correct, and if yes, are there examples of how this is useful ? |
Beta Was this translation helpful? Give feedback.
-
In case you want to use macros at runtime, or in another module that Removing macro definitions is the kind of post- |
Beta Was this translation helpful? Give feedback.
In case you want to use macros at runtime, or in another module that
require
s this one. Consider a program like(defmacro m [] 1) (print (hy.eval '(m)))
. This can only work in Python ifhy2py
keeps macro definitions.Removing macro definitions is the kind of post-
hy2py
surgery you can do if you want cleaner Python and you know that you don't need the definitions.