# Is it possible to "precompile" a method with a set of argument types?

**URL:** https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730
**Category:** General Usage
**Created:** [February 16, 2020, 6:28pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730 "2020-02-16T18:28:15Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)
#### Post date: [February 16, 2020, 6:28pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/1 "2020-02-16T18:28:15Z")

</div>

I swear i saw a macro at some point that allowed you to precompile methods. However I haven’t been able to google for it. I do find lots on compileing my whole application or compiling to an executable.

I’m trying to figure out a compilation error, but it’s inside a channel inside a callback from a 3rd party module. And to make it even better, it’s function pointer. I’ve been staring at the code and cannot figure out what the issue is and I’m hoping that compiling it outside of all the other stuff will make the error clearer.

For more details, the error is:

```julia
┌ Error: error handling request
│ exception =
│ MethodError: Cannot `convert` an object of type Array{UInt8,1} to an object of type Bool
│ Closest candidates are:
│ convert(::Type{T}, ::T) where T<:Number at number.jl:6
│ convert(::Type{T}, ::Number) where T<:Number at number.jl:7
│ convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
│ ...
│ Stacktrace:
│ [1] take_unbuffered(::Channel{Union{Array{UInt8,1}, Array{String,1}}}) at ./channels.jl:418
│ [2] take! at ./channels.jl:394 [inlined]
│ [3] iterate(::Channel{Union{Array{UInt8,1}, Array{String,1}}}, ::Nothing) at ./channels.jl:460
│ [4] test(::Main.ms.var"#22#25"{Main.ms.NS,Main.ms.var"#inc_a#23",Main.ms.var"#inc_b#24"}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /home/pixel27/julia/ms/src/test.jl:86

```

Line 4 is where we finally end up in my code. An example of what I’m trying to do, which **works** where as the real code **does not** is:

```julia

function queue()
    Channel{Union{Vector{String}, Vector{UInt8}}}() do ch
        put!(ch, ["a"])
        put!(ch, Vector{UInt8}([1, 2]))
        put!(ch, Vector{UInt8}([3, 4]))
        put!(ch, ["b", "c"])
        put!(ch, Vector{UInt8}([100, 200]))
        put!(ch, Vector{UInt8}([101, 201]))
    end
end

function execute(f)
    local c = nothing

    for val in queue()
        if typeof(val) == Vector{String}
            c = f(val)
        else
            if c(val) == false
                println("error")
            end
        end
    end
end

function test()
    local a = 0
    local b = 0

    function inc_a(arr::Vector{UInt8})::Bool
        for i in arr
            a += i
        end
        return a < 1000
    end

    function inc_b(arr::Vector{UInt8})::Bool
        for i in arr
            b += i
        end
        return b < 1000
    end

    execute() do names
        if names[1] == "a"
            return inc_a
        elseif names[1] == "b"
            return inc_b
        else
            return nothing
        end
    end

    println("a = $a")
    println("b = $b")
end

```

Translating the error to the simplified code, the error would be at line 21 which is `println("error")`. So my best bet is the error is the function pointer assigned to “c”. However since it appears to fail at compilation it makes it hard to figure out what “c” was pointing to and why it would be trying to convert an array to a boolean…

In my real code inc\_a and inc\_b are both defined to take a Vector{Uint8} and return a Bool.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [February 16, 2020, 6:36pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/2 "2020-02-16T18:36:51Z")

</div>

> [@pixel27](#):
>
> I’m trying to figure out a compilation error

It’s not. It’s a runtime error.

---

<div class="post-metadata">

### Author: ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)
#### Post date: [February 16, 2020, 8:39pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/3 "2020-02-16T20:39:43Z")

</div>

> [@yuyichao](#):
>
> It’s not. It’s a runtime error.

But if I put a print message before that function call, it never prints.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [February 16, 2020, 8:47pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/4 "2020-02-16T20:47:24Z")

</div>

Well, then either that function call is not where it happens (in fact, from the backtrace it is clear that it isn’t) or the output is somehow redirected (or otherwise) and you didn’t see it.

> [@pixel27](#):
>
> However since it appears to fail at compilation it makes it hard to figure out what “c” was pointing to and why it would be trying to convert an array to a boolean…

Put it another way, if this was a compilation error, which doesn’t really exist in julia, then what you are trying to figure out here, which is strictly runtime information, won’t matter at all.

---

<div class="post-metadata">

### Author: ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)
#### Post date: [February 16, 2020, 8:51pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/5 "2020-02-16T20:51:01Z")

</div>

Okay, then the line number reported by the stack trace is a red herring…I’m assuming the convert is happening somewhere along the stack to where it’s called. I will widen my search.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [February 16, 2020, 8:56pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/6 "2020-02-16T20:56:06Z")

</div>

> [@pixel27](#):
>
> I’m assuming the convert is happening somewhere along the stack to where it’s called.

No. The error happens before the first call in the backtrace, i.e. in `take_unbuffered`. That’s the definition of the stack trace.

> [@pixel27](#):
>
> I will widen my search.

And no. The entry point from your `test` to the error is shown to you in the backtrace. It’s

> [@pixel27](#):
>
> │ [3] iterate(::Channel{Union{Array{UInt8,1}, Array{String,1}}}, ::Nothing) at ./channels.jl:460

or the iteration (loop) on the channel.

Now how other part of the code not directly in the backtrace interacts with the channel is something you need to figure out. (i.e. the producer could be what’s generating the error)

---

<div class="post-metadata">

### Author: ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)
#### Post date: [February 16, 2020, 9:59pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/7 "2020-02-16T21:59:05Z")

</div>

Well I “found” it…but not really. My main loop had a error check at the beginning. Basically if an error was tripped it would just empty the channel and no do anything. However the check was incorrect and always returned true. So the body of the loop would always be skipped.

Basically:

```julia
    local e = false

    for val in queue()

        if e == false
            continue
        end

        if typeof(val) == Vector{String}
            c = f(val)
        else
            if c(val) == false
                println("error")
            end
        end
    end

```

I found that if I commented out the body of the loop I would get the same basic stack trace. Unfortunately I haven’t been able to reproduce the stacktrace with a short example 😕.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [February 16, 2020, 10:06pm UTC](https://discourse.julialang.org/t/is-it-possible-to-precompile-a-method-with-a-set-of-argument-types/34730/8 "2020-02-16T22:06:44Z")

</div>

As I said, the error happens on the iteration, it did not happen on the loop body. (Also see updated comment) you mostly need to figure out what’s going on in `queue()`.
