-
-
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
Expand @static
docstring
#54206
Expand @static
docstring
#54206
Conversation
Thank you for catching starting a fix for this! The docstring, as it was originally written, is not correct. The Julia execution order is
The What it actually does is evaluate the conditional (recursively macro expand, lower, and execute) and then, depending on the resulting value, returns only one (or zero) branch of the sub expression, deleting the rest of the branches before they are macro-expanded, lowered, or executed. The key difference between that and normal conditionals is in the macro expansion and lowering phases. Another quirk you should know about is that julia> ccall
ERROR: UndefVarError: `ccall` not defined in `Main`
Suggestion: check for spelling errors or missing imports.
julia> ccall(:jl_get_current_task, Ref{Task}, ()) # ccall is not defined, so this shouldn't work, right.....????
Task (runnable, started) @0x0000ffff19b20200 # Ha! ccall is special and confusing. You can also see that it lowers differently than real functions julia> Meta.lower(Main, :(foo(blah, blah, blah)))
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope`
1 ─ %1 = foo
│ %2 = blah
│ %3 = blah
│ %4 = blah
│ %5 = (%1)(%2, %3, %4)
└── return %5
))))
julia> Meta.lower(Main, :(ccall(blah, blah, blah)))
:($(Expr(:error, "ccall argument types must be a tuple; try \"(T,)\"")))
So, ccall magic happens, at least in part, during lowering which means it can be skipped by Aside, not relevant to this PR: Hopefully someday we can fix this quirk. In the meantime, a PR documenting the strange behavior of ccall would also be welcome, though ideally phrased in such a way as to allow ccall to become more like an ordinary function in the future Does that help clarify what this macro does? |
Thank you very much for providing this comprehensive explanation! It definetely helps :) I updated the docstring adding more information from @LilithHafner's message. |
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.
Thanks! This is a significant improvement over the existing docstring.
such as a `ccall` to a non-existent function. | ||
`@static if Sys.isapple() foo end` and `@static foo <&&,||> bar` are also valid syntax. | ||
This is useful in cases where a construct would be invalid in some cases, such as a `ccall` | ||
to a os-dependent function, or macros defined in packages that are not imported. |
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.
to a os-dependent function, or macros defined in packages that are not imported. | |
to an OS-dependent function, or macros defined in packages that are not imported. |
|
||
# Example | ||
|
||
Suppose we want to parse an expression `expr` that is valid only on MacOS. We could solve |
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.
Suppose we want to parse an expression `expr` that is valid only on MacOS. We could solve | |
Suppose we want to parse an expression `expr` that is valid only on macOS. We could solve |
|
||
Suppose we want to parse an expression `expr` that is valid only on MacOS. We could solve | ||
this problem using `@static` with `@static if Sys.isapple() expr end`. In case we had | ||
`expr_apple` for MacOS and `expr_others` for the other operating systems, the solution with |
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.
`expr_apple` for MacOS and `expr_others` for the other operating systems, the solution with | |
`expr_apple` for macOS and `expr_others` for the other operating systems, the solution with |
Oops! I only saw your comments when the page refreshed after I clicked merge. Sorry! |
When I first learned about
@static
, I found its docstring not very clear or helpful. For example, I didn't understand that I had to use a conditional (yes, once you understand what@static
does, it is obvious, but the reason I was reading the docstring is precisely because I didn't know how to use it). I also found the meaning of@static foo <&&,||> bar
rather unclear.I rephrased the docstring to something that I think is clearer and more helpful.