-
Notifications
You must be signed in to change notification settings - Fork 371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace special forms with result macros #2104
Conversation
Yo this is awesome! I really dig the idea of Hy itself being a fairly light reader/compiler, and most of the core functionality being implemented as (reader/result/regular) macros through the same API that any user can tap into. |
sorry long week i'll get those patches in today |
It's okay. I haven't been paying much attention to Hy over the past few days, either.
Isn't that an invalid location? |
yes, but previous behavior wouldn't make that assumption about a special form and just returned the tree untouched since special form compilation was further back in the compilation order. Its okay if that's the new desired behavior, but its a departure that should acknowledge and document since it requires extra checking from downstream code. |
Yeah, it seems reasonable enough to me, since special forms per se no longer exist. |
i think its just as easy at listing under breaking changes that macroexpanding a bare |
these fix the walk, destructure, and reserved tests. there is the question of what to do about bad roots. they were tracked in |
this should be all the fixes @Kodiologist have I missed anything? |
2d8ccd7
to
399469c
Compare
Nope, that covers it, Allie. Thanks a lot. I've rebased to undo my test removals. |
Correction: they're already provided by |
your right that they're provided by |
399469c
to
eadcfed
Compare
I've reorganized the edits, and replaced |
@scauligi All tests passing if you want to check it out now. |
Been a bit busy this week but taking a look now! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pyright tells me hy.compiler._module_file_source
is not being used anywhere, so we can delete that function while we're removing stuff from hy/compiler.py.
Other unused imports we can clean up:
- hy/importer.py:
re
,io
,tempfile
,hy_ast_compile_flags
"Python parse error in '{}': {}".format(root, e)) | ||
|
||
return Result(stmts=o) if exec_mode else o | ||
|
||
@builds_model(Expression) | ||
def compile_expression(self, expr, *, allow_annotation_expression=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
allow_annotation_expression
is vestigial, as well as is_annotate_expression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unremoved. Both appear to currently be necessary for compiling annotation forms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see is_annotate_expression
does appear necessary, but the keyword arg allow_annotation_expression
is not longer needed; you should add a forbid
for annotate
in hy/core/macros.hy to replace what it used to be doing.
expr = hy_compiler.this | ||
root = unmangle(expr[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stuck an assert tuple(expr[1:]) == args
here and it passed a run of pytest
.
Can we change the result macro fn signatures so that we can call it e.g. fn(hy_compiler, name, args, *parse_tree)
instead of needing to pass on expr
? From what I can tell, the only reason we need expr
is for source line position, which we can (and probably should) handle up in hy/compiler.py anyway. Then we wouldn't need to muck around with setting/retrieving compiler.this
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The macros need to set the source-line positions when they're constructing the python AST objects. By the time they've returned an AST object up the call stack, it's too late for subordinate AST objects to have their positions set correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would ast.fix_missing_locations()
solve that problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think so. I would try an ast.fix_missing_locations()
step after each macro-expansion that produces a Result
or AST
, with a temporary outermost AST object that has the location information to be copied.
My one concern is that once you can write ast.X(…)
, with no location information, in place of asty.X(expr, …)
, people working on Hy's core macros will be liable to mistakenly write ast.X(…)
when they meant asty.X(some_model, …)
. There won't be a crash; nobody will notice anything amiss unless they see an error message with a position that's not as far into the parse tree as it should be. Do you think getting rid of the expr
parameter and replacing a lot of asty.X(expr, …)
with ast.X(…)
is worth these potential bugs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the compiler calls sets the position on the result of macroexpand()
from the original expr
, then calls ast.fix_missing_locations()
, then none of the core macros will even need to use asty
at all, unless I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll still need to set locations explicitly in order to point to arguments of the macro, or subcomponents of the arguments, instead of the whole form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, that's a good point.
Hmm, I still would prefer a way of not needing to set extra state in the compiler, but I'll leave that for a later PR.
Lot of (small) comments mainly because it's a big PR, but on the whole this looks dope! I'm excited for this to land 🎉 |
eadcfed
to
fd62e31
Compare
Done.
Removed. |
Ugh, my mistake; I forgot to |
6dd1768
to
63822b2
Compare
0accd7e
to
1e6459e
Compare
@scauligi Okay, how's that? |
I updated the documentation (dumping a section on implementation details which is only going to get further out of date as we get to Hy 1.0), so this is ready to merge if you're okay with it, @scauligi. |
Co-authored-by: Allison Casey <allie.jo.casey@gmail.com>
This commit consists mostly of cutting special-form methods of the compiler and pasting them over as macros. Likewise, a lot of private compiler methods have become helper functions. The following changes are made: - Replace `@special` with `@result_macro` - Replace `self` with `compiler`, and change some method calls to function calls accordingly - Remove some leading underscores in names - Adjust spacing and the order of definitions - Add Outshine headers for Emacs in comments - Add a module docstring
Now that there are no special forms. `names` has also been updated. Co-authored-by: Allison Casey <allie.jo.casey@gmail.com>
Co-authored-by: Allison Casey <allie.jo.casey@gmail.com>
Implementation details that aren't supposed to affect the user shouldn't be documented.
e541115
to
d5c8428
Compare
I'm so hype for this 🎉 |
Oh minor nit if there's still time: looks like |
I'm afraid you're about 1 minute 30 seconds too late. |
Closes #2046.
I've implemented macros that can return
Result
objects or AST, and converted all special operators into such macros. This change has little immediate consequence for most Hy users, but simplifies how Hy works somewhat, and opens the way to users hiding or replacing "special operators" with their own implementations, or writing new result macros.I removed some tests that are currently breaking. I think @allison-casey has fixes for most of these; could you add that in? I'll take a hack again at what's left.
I haven't yet made docs or NEWS changes. Let's make sure we like the code first.
Things we'll want to consider after this is merged: