-
-
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
Add edit, less and code_* macros, mirroring which #5832
Conversation
Also, this needs to be mentioned in |
Oh, cool, yes, I think it should work with all the Question: In the |
|
Ah, sure. The abstract But is that enough? What is |
I just haven't had time to really work on #5779, so this is great! |
these are things related to defining functions, that disappear when running the code. ANY is equivalent to Any, but it prevents code specialization on that argument TypeVar is the Julia type of the T in |
Thanks for the explanation, @vtjnash. So that's not a concern. But there's still a corner case here: tuples. |
Unfortunately I don't think its going to be possible to define one function that does both: for instance The easiest way around this would be to define different functions: one for arguments and one for types, unfortunately this would mean breaking the existing behaviour of either |
Well, this is stretching my macro tinkering abilities to the limit, but I think I've managed to get the type conversion to occur within the macro. Of course, as Simon mentions, that now makes this simple macro tinkering a breaking change. This ended up being more than I intended to bite off. But hopefully it's helpful, if only for the idea of sharing the code from this macro. |
Bump! |
I think I'm good now. I rebased and added one minor extra commit to deprecate the All works well in my tests. It just needs a review. |
What keeps these nice macros from being merged? They are just convenience for the REPL, and will probably never break code if we find a reason to remove them at a later stage. |
Well, there was a big tree conflict with dd60925, but I've pseudo-rebased/squashed. So it's good to go again. |
+1. LGTM, but I'll let @JeffBezanson have a look and do the merge. |
I guess it just gives me pause to export so many new names. It's @JeffBezanson's call. |
typesof(args...) = map(typeof,args) | ||
|
||
for fname in [:which,:less,:edit,:code_typed,:code_lowered,:code_llvm,:code_native] | ||
@eval begin |
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.
This @eval
loop should be removed. There is no reason to copy this entire function body when it is basically identical for each case. Instead, there should be a single code-generating function that takes fname
as an argument, and each macro can be a trivial wrapper around 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.
Ah yes. Something about having a macro-generating macro struck me as not right, but a better way didn't occur to me off the top of my head. That's much simpler.
The macros are programmatically generated, based on the previous macro for which. The arguments are evaluated and their types are determined so the corresponding function may be called. Adds news and documentation.
Thanks for the comments! I think I've addressed them in the updated patch. @JeffBezanson - I'm not entirely sure I understood your comment. I've broken the code generation out into a separate function, but I don't understand how I'd remove the |
@@ -450,3 +450,5 @@ end | |||
export nnz | |||
|
|||
scale!{T<:Base.LinAlg.BlasReal}(X::Array{T}, s::Complex) = error("scale!: Cannot scale a real array by a complex value in-place. Use scale(X::Array{Real}, s::Complex) instead.") | |||
|
|||
@deprecate which(f::Callable, args...) @which f(args...) |
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 don't think this should be deprecated. I'd still want to use the function form in various cases. And doesn't the macro generate calls to it?
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.
No, the macro generates calls to which(f,t::(Type…))
. What I'm deprecating here is the previous definition of which
, which determines the types of its arguments itself.
Both could stay in base, but if the user called a function which(f,(Int,))
there's an ambiguity between whether the user was looking for the method that would be called with f((Int,))
or f(1)
. It's a really slight corner-case, though, and it fails gracefully to the more common case.
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.
Basically, in the current definitions for all the methods (which, edit, less, code_...), which
is the odd man out. All the others get the arguments as tuple of types. So for this macro to generically call all of them I needed to change which
's signature.
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, you are right.
@StefanKarpinski these names are not really new. It's just macro versions of functions that have a clumsy interface, that makes them hard to use for quick debugging. Edit: It will increase |
Yeah, true enough. We should do it. |
Well, I can fix the error messages simply enough, but this is now blocked by #6426. |
Unblocked! |
Add edit, less and code_* macros, mirroring which
Woohoo! Thanks guys! |
Thanks for being patient while that simmered. |
And for doing the work in the first place, of course. |
Awesome. Looking forward to this. |
Also add methods for edit and less that take::Any
vararg (again, mirroring which), and specify that the previous definitions take a tuple of::(DataTypes...)
.This was remarkably easy with the recent refactoring of
which
. The number of changed lines is deceiving due to the indentation of a for loop (over:which,:edit,:less
, and now additionally:code_typed,:code_lowered,:code_llvm,:code_native
) and an@eval
block around the existing@which
definition.The only real changes required were to change:which
to$fname
and adding the equivalent method signatures. Pretty cool that it just works.I've since modified to macro to determine the types of the arguments itself. This prevents a potential ambiguity between an argument that happens to be a tuple of types and specifying the types of the arguments. But to make this work for all of the above functions,
which(f,args…)
needs to be deprecated in favor ofwhich(f,types::(Type…))
(or the macro itself). Both can co-exist, but there's that very small corner case of the ambiguity in discerning whichwhich
the user is asking for.