-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
make macros generic functions #14563
Conversation
Seems like a first-class kind of solution 😎 |
Love it. Since all the tests pass, should we merge this? |
make macros generic functions
Nice! |
If it fixes that many issues, could use a few more test cases couldn't it? |
Probably could use a NEWS entry, too. This is very nifty: julia> macro foo(x::Int)
:($x + 1)
end
@foo (macro with 1 method)
julia> macro foo(x::Symbol)
@show x
end
@foo (macro with 2 methods)
julia> @foo 1
2
julia> @foo show
x = :show
show (generic function with 122 methods)
julia> @foo 1+2
ERROR: MethodError: `@foo` has no method matching @foo(::Expr)
in eval at ./boot.jl:265 |
Pretty awe-inspiring that this comes with a net reduction of 13 lines of code, and a churn < 100 lines. |
Merging this appears to have introduced a failure on 32 bit appveyor: https://ci.appveyor.com/project/StefanKarpinski/julia/build/1.0.12336/job/smqeb0ravuyaroa3 |
Hmm, I've seen this failure appears on #14541 lin32 for some time and haven't been able to figure out why. I suspect it's related to the IOContext/ImmutableDict and very likely also related to the UndefRefError in dict test and a similar one I've just reproduced repeatedly on ARM. |
I understand that this would replace generated functions, am I right? On generated functions:
Edit: changed generic fucntions to generated functions, sorry ...muscle memory. |
No, after this macros are basically the same as they always were. But the implementation is changed so that a bit more flexibility exists, e.g. having separate definitions for cases with different numbers of arguments. |
@JeffBezanson but @mbauman's example would suggest that they are not the same as they always were? In that you can now have different implementations for different input types. |
Yes, but for the types of the expression objects, not the types of run time values. So the types are almost always just |
Ah, understood. Thanks. |
Oh! that makes a lot of sense now, thank you very much! |
Super cool! Unless I've missed something we can't extend a macro without first explicitly importing it, ie. module A
macro m(x::Int)
"an integer"
end
end
# I'd expect this to work as it does for methods
macro A.m(x::Expr)
"an expression"
end
# but it throws a
#
# ERROR: syntax: invalid macro definition
# in eval at ./boot.jl:265
# this does work as expected though
import .A: @m
macro m(x::Expr)
"an expression"
end
Would it be too greedy to ask for |
Since JuliaLang#14563 made macros into generic functions we should naturally handle them in the same way as functions in the docsystem. Since the expression `@time` is no different to `@time()` this is slightly problematic for querying the docsystem for the docs associated with the `Function` rather than any one particular `Method` of the macro. Hence I've added the syntax `help?> :@time` to get docs for the whole macro while `help?> @time`, `help?> @time(x)`, etc. will get docs for a particular signature. The quote (`:`) syntax mirrors that of "..." :@time syntax which is already available for use to document `@time` so using it for retrieving as well as setting docs doesn't seem too much of a stretch.
Here's another tidbit from jb/functions that's easy to apply to master.
fixes #9627, #8846, and #8701, and might help #3377