# How do I reference a custom call operator?

**URL:** <https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400>\
**Category:** General Usage\
**Created:** [April 22, 2019, 11:48am UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400 "2019-04-22T11:48:38Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dzhang314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dzhang314/32/8098_2.png) [@dzhang314](https://discourse.julialang.org/u/dzhang314)\
**Post date:** [April 22, 2019, 11:48am UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/1 "2019-04-22T11:48:38Z")

</div>

Suppose I’ve defined a data type in Julia with its own call operator.

```julia
struct Adder
    x::Int
end

@noinline function (a::Adder)(y::Int)
    a.x + y
end

```

How do I refer to the call operator I’ve just defined as a function? For example, I might want to check what sort of native code it compiles down to. However, `code_native(Adder, (Int,))` gives me the code for the `Adder` constructor, while `code_native(Adder, (Adder, Int))` tells me there’s “no unique matching method found for the specified argument types.” What I really want to say is `code_native((a, x) -> a(x), (Adder, Int))`, but this adds an additional level of indirection:

```julia
julia> code_native((a, x) -> a(x), (Adder, Int), syntax=:intel)

	.text
; ┌ @ In[23]:1 within `#15'
	push	rbp
	mov	rbp, rsp
	sub	rsp, 32
	movabs	rax, offset Adder
	call	rax
	add	rsp, 32
	pop	rbp
	ret
	nop	word ptr [rax + rax]
; └

```

Of course, this could be fixed by marking `@inline function (a::Adder)(y::Int)`, but sometimes I define very long call operators for which this is wasteful.

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [April 22, 2019, 12:10pm UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/2 "2019-04-22T12:10:41Z")

</div>

You can use an instance of the type:

```julia
julia> code_native(Adder(1), (Int,))
        .text
; ┌ @ REPL[2]:2 within `Adder'
; │┌ @ REPL[2]:2 within `+'
        addq (%rdi), %rsi
; │└
        movq %rsi, %rax
        retq
        nopw (%rax,%rax)
;

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [April 22, 2019, 11:41pm UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/3 "2019-04-22T23:41:56Z")

</div>

Can’t you just use the macros like `@code_native`?

---

<div class="post-metadata">

**Author:** ![dzhang314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dzhang314/32/8098_2.png) [@dzhang314](https://discourse.julialang.org/u/dzhang314)\
**Post date:** [April 22, 2019, 11:42pm UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/4 "2019-04-22T23:42:15Z")

</div>

@maleadt Thanks, I didn’t think of that! Is there a way to do this without constructing an instance? Say, for example, `Adder` has a really expensive inner constructor.

---

<div class="post-metadata">

**Author:** ![dzhang314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dzhang314/32/8098_2.png) [@dzhang314](https://discourse.julialang.org/u/dzhang314)\
**Post date:** [April 23, 2019, 5:11am UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/5 "2019-04-23T05:11:56Z")

</div>

@dpsanders I can use a macro for `code_native` in this situation, but one could imagine a scenario where the function `(a::Adder, x::Int) -> a(x)` itself would be passed as a callback to another function. Does Julia not provide a mechanism for referring to `function (a::Adder)(x::Int)` directly?

I seem to remember that in very old versions of Julia (around v0.4?) an invocation of `Adder(1)(x)` would get translated into `Base.call(Adder(1), x)`, and so my `function (a::Adder)(x::Int)` would instead have been defined as a new method of `Base.call`. I guess what I’m asking for is a mechanism in v1.1 to directly name what `Base.call` used to refer to in v0.4 – i.e., what Python calls `obj. __call__ `, and what C++ calls `MyClass::operator()`.

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [April 23, 2019, 7:10am UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/7 "2019-04-23T07:10:44Z")

</div>

The `signature_type` that gets constructed by `_dump_function` does deal with the type of `Adder`, and not the instance:

```julia
julia> f = Adder(1);

julia> t = (Int,);

julia> t = Base.to_tuple_type(t)
Tuple{Int64}

julia> Base.signature_type(f, t)
Tuple{Adder,Int64}

```

(vs. `Tuple{Type{Adder},Int64}` for the constructor method)

But you can’t pass that into any of the public reflection functions. You can do it manually though:

```julia
julia> world = typemax(UInt)
0xffffffffffffffff

julia> meth = which(f, t)
(a::Adder)(y::Int64) in Main at REPL[2]:2

julia> (ti, env) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), tt, meth.sig)::Core.SimpleVector
svec(Tuple{Adder,Int64}, svec())

julia> meth = Base.func_for_method_checked(meth, ti)
(a::Adder)(y::Int64) in Main at REPL[2]:2

julia> linfo = ccall(:jl_specializations_get_linfo, Ref{Core.MethodInstance}, (Any, Any, Any, UInt), meth, ti, env, world)
MethodInstance for (::Adder)(::Int64)

julia> InteractiveUtils._dump_function_linfo(linfo, world, #=native=# true, #=wrapper=# false, #=strip_ir_metadata=# false, #=dump_module=# false, #=syntax=# :att, #=optimize=# true, #=debuginfo=# :default);

julia> println(ans)
        .text
; ┌ @ REPL[2]:2 within `Adder'
; │┌ @ REPL[2]:2 within `+'
        addq (%rdi), %rsi
; │└
        movq %rsi, %rax
        retq
        nopw (%rax,%rax)
; └

```

---

<div class="post-metadata">

**Author:** ![dzhang314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dzhang314/32/8098_2.png) [@dzhang314](https://discourse.julialang.org/u/dzhang314)\
**Post date:** [April 23, 2019, 7:40am UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/8 "2019-04-23T07:40:42Z")

</div>

@maleadt Thanks pointing me to these reflection functions! I should have known to take a look at the source of `InteractiveUtils` to see what was really going on. It’s interesting to see that Julia itself displays the `MethodInstance` for `function (a::Adder)(y::Int)` as `(::Adder)(::Int64)`.

Do you think it would be reasonable to propose new language syntax to reflect this internal representation? I don’t think `(::Adder)` conflicts with anything right now, so this hypothetical language extension would let you write `code_native((::Adder), (Int,))` to achieve the same result.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 23, 2019, 1:35pm UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/9 "2019-04-23T13:35:45Z")

</div>

> [@dzhang314](#):
>
> How do I refer to the call operator I’ve just defined as a function?

`(a,y) -> a(y)`

---

<div class="post-metadata">

**Author:** ![dzhang314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dzhang314/32/8098_2.png) [@dzhang314](https://discourse.julialang.org/u/dzhang314)\
**Post date:** [April 24, 2019, 9:00pm UTC](https://discourse.julialang.org/t/how-do-i-reference-a-custom-call-operator/23400/10 "2019-04-24T21:00:50Z")

</div>

@stevengj I clearly explained in the original post that I considered that solution and why it isn’t satisfactory.
