-
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
Macros do not like unpack-mapping #1730
Comments
How would you expect this to work, if it did work? Imagine a less trivial case, like |
|
I expected this because AFAICT |
That's even weirder than I expected, but to be clear, I was using a lowercase letter L there. (Consider switching monospace fonts.) In other words, what would |
|
I presume you meant that |
Excuse me if this is dumb, but isn't it not at top-level because it's nested in the |
Hmm, that's a good point. By contrast, |
Either that, or some kind of multi-pass compilation. |
Would it not be possible to have arguments be compiled not in sequential order but macro-first? |
You mean, to have the compiler expand all macros before compiling special forms? Perhaps, although you'd need to make an exception for special forms that are needed to collect macros. |
I think I meant something that doesn't make sense. After squinting at the code for a bit, it seems that it would be sufficient to expand only one level extra--just arguments to functions, if those arguments are macro calls--rather than all the way. Related, am I correct in saying that Hy does "no" evaluation? Hy expressions are compiled to the Python AST which is then evaluated? So it wouldn't make sense to have the checks for |
Mostly, yeah, but |
Maybe changing this is as simple as making sure the loop in |
It's still not totally clear to me that this is a bug. |
can macros even use keywords to begin with? You can define a macro with keyword args in the lambda list, but as far as i can see there's no way to actually take advantage of that because the keywords are taken literally as positional arguments => (defmacro something [[x 1]] x)
=> (something :x 2)
hy.errors.HyMacroExpansionError:
File "<string>", line 1
(something :x 2)
^--------------^
expanding macro something
TypeError: something() takes from 1 to 2 positional arguments but 3 were given |
Arguments in macros have names, like any function arguments, but you can't use |
So it sounds like we need to fix the lambda list parser for macros to make this explicit. In which case this wouldn't be a bug like you said, more a failure by us to telegraph that macros can't use keyword args and by extension |
I think the only fix needed is to forbid additional arguments after |
the fact that macros can define default arguments, but there's no way to call them in any way other than positionally definitely seems like a doc me issue. So in terms of action items it's:
=> (defmacro something [[a 1] [b 2] #* body]
... `[~a ~b ~body])
=> (something 2 3 :hello)
[2 3 #(:hello)]
;; trying to use keyword arguments to pass arguments out of order leads
;; to unexpected results
=> (something :b 1 :a 2 :world)
[:b 1 #(:a 2 :world)]
;; or trying to skip a default argument does not do what you might expect
=> (something :b 1 :world)
[:b 1 #(:world)] |
actually, given that default argument behavior in macros are so different than regular functions and prone to unexpected behavior, does it make sense that macros can define default args in the lambda list at all? It seems like if you want to have default args in a macro you should handle that manually in the body |
I don't really agree, in the sense that default arguments in macros work just like default arguments in ordinary functions; what's different is how keywords are handled. (In the old days, before autopromotion, you had to say e.g. |
it should be documented then that all arguments in macros are position only then. adding defaults to positional arguments acts like an using an implicit |
Agreed. |
I tried to test this on devel, but devel wouldn't compile 😐. Perhaps I'm doing something wrong; not sure.
The text was updated successfully, but these errors were encountered: