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

WIP: fix invoke for overloaded call #8862

Closed
wants to merge 1 commit into from

Conversation

stevengj
Copy link
Member

This is for issue #8861. However, something is not quite working ... the following error seems rather mysterious to me: (Update: this test now passes.)

julia> type A; end

julia> invoke(A, ())
ERROR: `call` has no method matching call(::Type{A})

julia> methods(A)
2-element Array{Any,1}:
 call(::Type{A})                         
 call{T}(::Type{T},args...) at base.jl:34

I'm guessing that there is a simple tweak to my patch that will fix this, but I don't understand where the problem lies.

cc: @simonster, @JeffBezanson, @vtjnash

@stevengj stevengj force-pushed the invoke_overload branch 2 times, most recently from d82f1c9 to 733c774 Compare October 31, 2014 03:44
@JeffBezanson
Copy link
Sponsor Member

If the first argument is a type it needs to be wrapped with jl_wrap_Type instead of using jl_typeof.

Using jl_current_module is not correct here; that does not tell you the module of the calling code. I almost wonder if it would be better for invoke, applicable and method_exists to operate only on generic functions directly instead of callable objects.

@stevengj
Copy link
Member Author

Okay, I added the wrap_Type and the test passes for me now. Getting the correct module seems more of a pickle.

Certainly, in all the applications that I can think of where you use invoke etcetera, you know precisely what function you have and so you could invoke on call if it is a callable object. The arguments for making them work on arbitrary callable objects would be:

  • Convenience.
  • The fact that constructors look like generic functions when they are declared, so there is some argument for preserving the illusion.
  • Easier backwards compatibility with 0.3 in cases where you need invoke on a constructor.
  • Writing generic code that needs to call invoke etc. on a function supplied by the user...but I can't think of any such situation right now, and it seems a bit dubious since invoke still doesn't work on anonymous functions.

I was hoping that this would be a trivial patch, but if it starts getting hairy and brittle (because of the difficulty of determining the correct module), then it's probably not worth it.

@simonster
Copy link
Member

My reason for reporting this was that there's code in DataFrames that calls invoke on the DataFrame constructor, which breaks since #8712. I can obviously use different code for 0.4 if we decide that invoke works only on generic functions.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Nov 5, 2014

Using jl_current_module is not correct here; that does not tell you the module of the calling code. I almost wonder if it would be better for invoke, applicable and method_exists to operate only on generic functions directly instead of callable objects.

Isn't this really just the same problem that eval has, and why julia has to stick that awkward little eval() definition stub code into each new module (that isn't a baremodule)?

@JeffBezanson
Copy link
Sponsor Member

Yes, very similar.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Nov 5, 2014

Could we play some trickery for a small set of these Core builtin functions and pass the function lambda's definition module as a "magic" parameter? I guess I don't really know how that would work with generic jl_apply, however.

@JeffBezanson
Copy link
Sponsor Member

The only efficient way I can see to do that is what I did for apply and kwcall, where the front end passes call explicitly as an argument.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Nov 5, 2014

That's perhaps not too terrible, although not particularly general. The alternative would seem to be to parse them differently, like ccall

@jakebolewski
Copy link
Member

The alternative would seem to be to parse them differently, like ccall

Isn't that worse?

@tkelman
Copy link
Contributor

tkelman commented Jul 6, 2015

Is this still relevant or should it be closed?

cc @yuyichao since some of your open PR's are in a similar area

@yuyichao
Copy link
Contributor

yuyichao commented Jul 6, 2015

Actually I didn't know about this one...

I think this is still relavant since this is a slightly different approach.

@quinnj
Copy link
Member

quinnj commented Apr 28, 2016

This is probably no longer relevant since jb/functions?

@yuyichao
Copy link
Contributor

yuyichao commented Apr 28, 2016

edit: pressed the wrong key...

Yes, I think this is fixed by jb/functions

julia> type A
       end

julia> (::A)(::Int) = 1

julia> (::A)(::Integer) = 2

julia> A()(1)
1

julia> invoke(A(), Tuple{Integer}, 1)
2

@yuyichao yuyichao closed this Apr 28, 2016
@tkelman
Copy link
Contributor

tkelman commented Apr 29, 2016

Should the test be committed first?

@stevengj
Copy link
Member Author

Yeah, might be good to commit the test.

stevengj added a commit to stevengj/julia that referenced this pull request Apr 29, 2016
@stevengj stevengj deleted the invoke_overload branch April 29, 2016 02:29
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.

None yet

8 participants