-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Define @__FUNCTION__
as an alias to var"#self#"
#58909
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
base: master
Are you sure you want to change the base?
Conversation
Referencing the discussion about implementations of this in #6733. |
This should also be added to the docs. I'm surprised this isn't caught by CI. |
Thanks; done |
tagging triage to talk about an expansion of the public API |
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.
SGTM
Could you add some tests for kwarg handling too, since those functions are tricky (even if you have to make them test_broken for now)
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
Thanks; added |
x-ref #58940 which defines |
The doc string has an unfortunate number of caveats. The keyword handling being broken, ok, we could fix. The comprehension example seems rather unfortunate though and seems to me to very much leak an implementation detail of the language. There's no explicit function in the comprehension, that's just how it happens to be implemented. If we're going to have this it should return the innermost syntactic function. |
Quick note; callable struct compatibility is added by #58940. For other cases I prefer these as a developer so I can capture the real innermost enclosing function objects in code analysis. In other words, I see these potential caveats as correct, desirable behavior, rather than things to conceal from the user. From a practical point of view, when writing macros, I can already grab the innermost syntactic functions by parsing the expression. It is instances where I do not have access to this, like closures, On comprehensions: if the implicit closure function might be removed internally in the future, perhaps one idea is to throw an error specifically when |
rather than
I understand there are type stability problems and that might be a hard (impossible?) problem for the compiler, but maybe something like
would be nicer? |
This PR isn't to solve that particular issue, although concrete (or anonymous) self-references is indeed a benefit. I view this PR as moreso adding a public API for a internal that seems to be broadly useful. Some others have used it despite its internal status (GH search) as well as myself in DispatchDoctor.jl (this line). In my library, my macro will self-reference a function inside its own body to look up whether there are any overloads to ignore it from type instability checking - this self-reference itself was causing type instabilities if that function happened to be a closure (due to boxing). Using But in general I also find the Even if the boxing issue is somehow fixable, I think it will be broadly useful to have an API for function self-references, just as there have been many for |
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.
Hi @StefanKarpinski,
Addressing your feedback, #58940 now rejects Expr(:thisfunction)
when used in a list comprehension or generator. It copies the same logic used for preventing return
from being used in these contexts:
julia> f() = [return x for x in 1:5]
ERROR: syntax: "return" not allowed inside comprehension or generator around REPL[4]:1
Stacktrace:
[1] top-level scope
@ REPL[4]:1
julia> macro __FUNCTION__(); esc(Expr(:thisfunction)); end;
julia> g() = [(@__FUNCTION__) for x in 1:5]
ERROR: syntax: "thisfunction" not allowed inside comprehension or generator around REPL[6]:1
Stacktrace:
[1] top-level scope
@ REPL[6]:1
julia> f2() = [() -> return x for x in 1:5]
f2 (generic function with 1 method)
julia> g2() = [() -> (@__FUNCTION__) for x in 1:5]
g2 (generic function with 1 method)
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 docstring has been updated assuming the fixes of #58940. These PRs are still technically independent and address different parts of the codebase, but let me know if you'd prefer them evaluated together.
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've also moved the docstring example about type stability in recursive closures to the performance tips page. It seems more suitable there
Just as
@__MODULE__
refers to the enclosing module object, the internal variablevar"#self#"
can be used to refer to the enclosing function object.This PR creates an alias
@__FUNCTION__
for this variable to match the naming conventions of existing reflection macros (@__MODULE__
,@__FILE__
, etc.).Fixes #58908 Fixes #6733