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

invoke does not accept keyword arguments #7045

Closed
simonbyrne opened this issue May 30, 2014 · 13 comments · Fixed by #20345
Closed

invoke does not accept keyword arguments #7045

simonbyrne opened this issue May 30, 2014 · 13 comments · Fixed by #20345
Assignees
Labels
domain:types and dispatch Types, subtyping and method dispatch status:help wanted Indicates that a maintainer wants help on an issue or pull request
Milestone

Comments

@simonbyrne
Copy link
Contributor

This makes it impossible to pass keyword arguments to other calls:

foo(x::Float64; y=true) = y ? 1 : invoke(foo,(Real,),x,y=y)
foo(x::Real; y=true) = y ? 2 : 3

gives

julia> foo(1)
2

julia> foo(1.0)
1

julia> foo(1;y=false)
3

julia> foo(1.0;y=false)
ERROR: function does not accept keyword arguments
 in foo at none:1
@quinnj
Copy link
Member

quinnj commented May 30, 2014

Possibly related: #2758, #5230

@jakebolewski
Copy link
Member

Closing as a dup of #2758.

@JeffBezanson
Copy link
Sponsor Member

I don't see how this is a dup; this issue is specifically about invoke.

@JeffBezanson JeffBezanson reopened this Oct 28, 2014
@yuyichao
Copy link
Contributor

yuyichao commented Jan 1, 2015

Having invoke accepting keyword arguments would be nice although AFAIK it's not possible to call a builtin with keyword arguments yet. Before that happens, I think anyone that wants to do this can use this modified version.

# Pack keyword arguments, logic copied from jl_g_kwcall
function pack_kwargs(;kws...)
    kwlen = length(kws)
    ary = Array(Any, 2 * kwlen)

    for i in 1:kwlen
        ary[2 * i - 1] = kws[i][1]
        ary[2 * i] = kws[i][2]
    end
    return ary
end

function get_kwsorter(f::Function)
    if !isdefined(f.env, :kwsorter)
        error("function $(f.env.name) does not accept keyword arguments")
    end
    return f.env.kwsorter
end

## Custom implementation of `invoke`
# Supports keyword arguments
function my_invoke(f::Function, types::Tuple, args...; kws...)
    # FIXME, replace with the builtin invoke after it supports keyword arguments
    if isempty(kws)
        return invoke(f, types, args...)
    else
        return invoke(get_kwsorter(f), tuple(Array, types...),
                      pack_kwargs(;kws...), args...)
    end
end

I'm not sure if this is the fastest way to do it or if it is compiler friendly though....................

@StefanKarpinski
Copy link
Sponsor Member

Could potentially be backported to 0.5 even.

@tkelman
Copy link
Contributor

tkelman commented Aug 19, 2016

backporting features is iffy

@StefanKarpinski
Copy link
Sponsor Member

Sure, but there's no way this feature can break anyone's code.

@tkelman
Copy link
Contributor

tkelman commented Aug 19, 2016

Actually it could, but in an indirect way. If say it were backported into 0.5.3 or similar, then code written in 0.5.3 or later that started making use of it wouldn't work for anyone who's happily using 0.5.1 and doesn't upgrade. It's fine if people test against a range of point releases and are careful about their minimum Julia version requirements, but not many people are.

@StefanKarpinski
Copy link
Sponsor Member

That's a fair point.

@yuyichao
Copy link
Contributor

FWIW, if we add kw support using @invoke, both (the @invoke macro and the kw support) can be backported using Compat.

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented Nov 10, 2016

The end goal here seems to be adding keyword support directly to invoke and then adding something like my proposed @callsuper macro which passes keyword arguments through.

@StefanKarpinski StefanKarpinski added the status:help wanted Indicates that a maintainer wants help on an issue or pull request label Nov 10, 2016
@JeffBezanson
Copy link
Sponsor Member

The way functions work now it's possible to add a keyword sorter method to invoke that forwards the keyword arguments. However the easiest way to do this is to put @yuyichao 's implementation in #7045 (comment) in Base, and rename the current invoke to Core._invoke.

@StefanKarpinski
Copy link
Sponsor Member

Should we just have it be Core.invoke and replace Base.invoke with @callsuper?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:types and dispatch Types, subtyping and method dispatch status:help wanted Indicates that a maintainer wants help on an issue or pull request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants