Skip to content
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

Enable @edit @time 1+1, fix #3377 #15282

Closed
wants to merge 1 commit into from
Closed

Conversation

dhoegh
Copy link
Contributor

@dhoegh dhoegh commented Feb 28, 2016

This allows for writing methods(:@time), edit(:@time) and @edit @time 1+1 plus the equivalent for which and less. methods can also check for macro methods as methods(:@time, Tuple{Any}). The @edit, @less and @which do also check for method specialization of the macro.

@StefanKarpinski
Copy link
Member

💯

if !isa(ex, Expr)
if fcn in [:which, :less, :edit] && ex0.head == :macrocall
# special case @edit @time 1+2 to edit the macro
is_macro = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the special case needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The special case is needed because when the expand function called above expands the macro/insert its code into the expression, and hence the edit call will call edit on the expanded code. The special casing makes which, less and edit macro call the macrocall instead of the code the macro expands to. This enables the user to write: @edit @time 1+1, this will go to the @time macro's definition.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a case you don't want to use operate on the macro?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main concern is that this doesn't seem to be the way this should work. If it is somehow really necessary to have different behavior for different macros that use this function, it should be controlled explicitly with a optional/keyword argument to this function instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your concern, but from my point of view it do not make sense to ask for @edit @random_macro max(1,1) and not point to the macro. As a macro can generate arbitrary code for you, and hence you do not know what you call @edit on.

@dhoegh
Copy link
Contributor Author

dhoegh commented Feb 29, 2016

I have pushed a new commit which adresses the comments. I did also find a bug, caused by wrong esc. I have addressed it and changed the tests to test it. Ping me when it is ready for a merge, then i will squas the commits.

@dhoegh
Copy link
Contributor Author

dhoegh commented Feb 29, 2016

I have squashed the commits.

@@ -179,6 +194,10 @@ function methods(f::ANY,t::ANY)
Any[m[3] for m in _methods(f,t,-1)]
end
function _methods(f::ANY,t::ANY,lim)
#special case Expr to allow methods(@time,Tuple{Any})
if _is_empty_macrocall(f)
f = _get_macro(current_module(),f.args[1])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is incorrect --- it makes it impossible for the system to query the methods of an Expr object. Exprs don't have any methods of course, but that just means this function must return an empty array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not quite follow you. The meaning of the function is to get function object of the macro from the getfield expression. Do you have an alternative way of obtaining the result?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't do this in _methods. _methods(f, ...) must return the list of methods you could call by doing f(...) with the specific object f. The following (current) behavior is correct:

julia> e = Expr(:macrocall, symbol("@time"))
:(@time)

julia> e()
ERROR: MethodError: objects of type Expr are not callable
 in eval(::Module, ::Any) at ./boot.jl:275

julia> methods(e)
# 0 methods for generic function "(::Expr)":

@JeffBezanson
Copy link
Member

This functionality is great, but we need to figure out a different way to provide it. This implementation works via a pun, where methods "lies" about what the answer is for certain Exprs.

@dhoegh
Copy link
Contributor Author

dhoegh commented Feb 29, 2016

If there was a way to obtain the function object of the macro, then it would be easier, to solve correctly. Because Base.(Symbol("@time")) feels awkward.

@JeffBezanson
Copy link
Member

I think the best approach for now is to limit this to user-interface-level features like @edit and @which. We could even add @methods.

@dhoegh dhoegh force-pushed the edit_macro branch 2 times, most recently from ca9241e to 8ecd97f Compare March 1, 2016 19:10
@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 1, 2016

@JeffBezanson I have changed the PR to suite your comments. I have added @methods and @functionloc macro. The only hatch by adding @methods @boundscheck do not return all methods for @boundscheck but return empty as it check for a zero argument method of @boundscheck. Hence @methods and @which is strictly speaking returning the same thing. The only difference is the @methods return a Array{Any,1} with one element. An alternativ approach would be to make @methods return all methods and if an argument is given throw an error and pointing to @which.

m = getfield(current_module(), Symbol("@boundscheck"))
methods(m) == @methods @boundscheck
@methods @boundscheck 1 # throw an error.

@dhoegh dhoegh changed the title Enable methods(:@time), fix #3377 Enable @edit @time 1+1, fix #3377 Mar 1, 2016
@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 2, 2016

I have added docs to @functionloc and edited docs for @edit, @less and @which. I have moved the docs inline. The commit do also removed the @methods macro as it provided almost the same as @which.

ex = expand(ex0)
if !isa(ex, Expr)
if fcn in [:which, :less, :edit, :functionloc] && ex0.head == :macrocall
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should check isa(ex0, Expr) here.

Also, I still don't understand why are the special cases necessary here. Why do you want @code_lowered @time 1 + 2 to error instead of showing the ast?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see where you are going now:). I have removed the special casing of @edit etc. The Ast displayed by @code_warntype is pretty ugly, but it displays.

julia> @code_warntype @time 1+1
Variables:
  #self#::Base.#@time
  ex::Expr
  ####args#787#8911::TUPLE

Body:
  begin  # util.jl, line 152:
      return (top(_expr))(:block,$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 153:)))))),$(Expr(:copyast, :($(QuoteNode(:(local stats = gc_num())))))),$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 154:)))))),$(Expr(:copyast, :($(QuoteNode(:(local elapsedtime = time_ns())))))),$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 155:)))))),(top(_expr))(:local,(top(_expr))(:(=),:val,(Core._expr)(:escape,ex::Expr)::ANY)::Expr)::Expr,$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 156:)))))),$(Expr(:copyast, :($(QuoteNode(:(elapsedtime = time_ns() - elapsedtime)))))),$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 157:)))))),$(Expr(:copyast, :($(QuoteNode(:(local diff = GC_Diff(gc_num(),stats))))))),$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 158:)))))),$(Expr(:copyast, :($(QuoteNode(:(time_print(elapsedtime,diff.allocd,diff.total_time,gc_alloc_count(diff)))))))),$(Expr(:copyast, :($(QuoteNode(:( # util.jl, line 160:)))))),:val)::Expr
  end::Expr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trust me, it's not going to be "uglier" than the AST of this function (gen_call_with_extracted_types) itself.

@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 2, 2016

I will do. I will squash the commit away, when I have updated genstdlib.jl

@dhoegh dhoegh force-pushed the edit_macro branch 2 times, most recently from 9be0c68 to 6c4e05c Compare March 6, 2016 14:37
@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 6, 2016

I have executed genstdlib.jl and squased the commits. This should be ready to merge if no further comment are made.

@functionloc

Applied to a function or macro call, it evaluates the arguments to the specified call, and
return a tuple `(filename,line)` giving the location for the method that would be called for those arguments.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returns

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I have fixed it and updated the PR.

@dhoegh dhoegh force-pushed the edit_macro branch 2 times, most recently from bb1e957 to 09507d7 Compare March 13, 2016 12:32
@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 13, 2016

Bump, I have rebased the PR to resolve merge conflicts.

@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 23, 2016

Bump/any further comment's?

@StefanKarpinski
Copy link
Member

@JeffBezanson, you're the one who had objections before, so please take a look and merge if it's ok.

@dhoegh
Copy link
Contributor Author

dhoegh commented Mar 31, 2016

Bump.

@yuyichao
Copy link
Contributor

LGTM. @JeffBezanson ?

@yuyichao
Copy link
Contributor

yuyichao commented Apr 5, 2016

@dhoegh I think I'll merge this if you can rebase again and no one have further comment.

…ctionloc @time

1+1` plus the equivalent for `@which`, `@edit` and `@less`. The macros check for method specialization of the macro and return the dispatched macro. The `@functionloc` macro is exported and the documentation is updated.
@dhoegh
Copy link
Contributor Author

dhoegh commented Apr 5, 2016

@yuyichao thank you. I have rebased the PR and it should be good to merge when the CI is finished.

@yuyichao
Copy link
Contributor

yuyichao commented Apr 5, 2016

.... Somehow the commit was merged but @github thinks the PR is still open and now with conflicts ..... Manually close since the merge is done....

@yuyichao yuyichao closed this Apr 5, 2016
elsuizo pushed a commit to elsuizo/julia that referenced this pull request Apr 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants