# Why can't it find that method?

**URL:** https://discourse.julialang.org/t/why-cant-it-find-that-method/110860
**Category:** General Usage
**Created:** [February 27, 2024, 7:33pm UTC](https://discourse.julialang.org/t/why-cant-it-find-that-method/110860 "2024-02-27T19:33:16Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Mark\_Nahabedian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mark_nahabedian/32/16562_2.png) [@Mark\_Nahabedian](https://discourse.julialang.org/u/Mark_Nahabedian)
#### Post date: [February 27, 2024, 7:33pm UTC](https://discourse.julialang.org/t/why-cant-it-find-that-method/110860/1 "2024-02-27T19:33:16Z")

</div>

I normally post to Slack, but seems too long winded for that venue.

I’m having some trouble that might be related to a macro I’ve defined, but as near as I can tell the macro expands as I expect.

I’m hoping you can help me figure out what’s going wrong.

Here’s the relevant output snippet from my unit tests (it explicitly lists the mehods for debugging):

```julia
# 3 methods for generic function "install" from Rete:
 [1] install(root::BasicReteNode, ::JoinSequentialLetterDigram2)
     @ Main C:\Users\Mark Nahabedian\.julia\dev\Rete\src\rules.jl:56
 [2] install(root::BasicReteNode, ::JoinSequentialLetterTrigram2)
     @ Main C:\Users\Mark Nahabedian\.julia\dev\Rete\src\rules.jl:56
 [3] install(root::BasicReteNode, rule_group)
     @ C:\Users\Mark Nahabedian\.julia\dev\Rete\src\basic_node.jl:32
rule example 2: Error During Test at C:\Users\Mark Nahabedian\.julia\dev\Rete\test\rule_example_2.jl:14
  Got exception outside of a @test
  MethodError: no method matching install(::BasicReteNode, ::JoinSequentialLetterDigram2)
  Stacktrace:
    [1] macro expansion
      @ C:\Users\Mark Nahabedian\.julia\dev\Rete\test\rule_example_2.jl:17 [inlined]

```

As near as I can tell, the method it claims is missing is the first on the list. It results from (line numbers elided for readability):

```julia
@macroexpand @rule JoinSequentialLetterDigram2(a::Char, b::Char) begin
    if codepoint(a) + 1 == codepoint(b)
        emit((a, b))
    end
end
quote
    struct JoinSequentialLetterDigram2 <: Rule
    end
    function Rete.install(root::BasicReteNode, ::JoinSequentialLetterDigram2)
        join = JoinNode("JoinSequentialLetterDigram2", JoinSequentialLetterDigram2())
        connect_a(ensure_IsaMemoryNode(root, Char), join)
        connect_b(ensure_IsaMemoryNode(root, Char), join)
        connect(join, root)
    end
    function (::JoinSequentialLetterDigram2)(node::JoinNode, a::Char, b::Char)
        begin
            if codepoint(a) + 1 == codepoint(b)
                emit(node, (a, b))
            end
        end
    end
end

```

Here’s the macro. Most of it is parameter decoding. I use `esc` because I don’t think I’m using any identifiers that require alphatization and, in my observations, `esc` does something completely random. Maybe Dave Moon’s fixes will be incorporated in my lifetime, but I’m not holding my breath.

```julia
macro rule(call, body)
    if !isexpr(call, :call)
        error("The first expression of rule should look like a call")
    end
    supertype = Rule
    rule_name = call.args[1]
    if isexpr(rule_name, :(.))
        supertype = rule_name.args[1]
        rule_name = rule_name.args[2].value # Unwrap QuoteNode
    end
    rule_name_str = string(rule_name)
    @assert isexpr(call.args[2], :(::))
    @assert isexpr(call.args[3], :(::))
    a_var = call.args[2].args[1]
    a_type = call.args[2].args[2]
    b_var = call.args[3].args[1]
    b_type = call.args[3].args[2]
    # Add the node argument to all calls to emit:
    body = postwalk(body) do e
        if isexpr(e, :call) && e.args[1] == :emit
            Expr(:call, :emit, :node, e.args[2])
        else
            e
        end
    end
    
    esc(quote
        struct $rule_name <: $supertype end

        function Rete.install(root::BasicReteNode, ::$rule_name)
            join = JoinNode($rule_name_str, $rule_name())
            connect_a(ensure_IsaMemoryNode(root, $a_type), join)
            connect_b(ensure_IsaMemoryNode(root, $b_type), join)
            connect(join, root)
        end

        function(::$rule_name)(node::JoinNode,
                               $a_var::$a_type,
                               $b_var::$b_type)
            $body
        end
    end)
end

```

Thanks.

---

<div class="post-metadata">

### Author: ![Mark\_Nahabedian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mark_nahabedian/32/16562_2.png) [@Mark\_Nahabedian](https://discourse.julialang.org/u/Mark_Nahabedian)
#### Post date: [February 28, 2024, 1:41am UTC](https://discourse.julialang.org/t/why-cant-it-find-that-method/110860/2 "2024-02-28T01:41:39Z")

</div>

I tink I found the problem, but I don’t understand why.

`install == Rete.install` is false.

`Rete` exports `install`. The tunit test environment imports Rete. What’s going wrong?

---

<div class="post-metadata">

### Author: ![Mark\_Nahabedian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mark_nahabedian/32/16562_2.png) [@Mark\_Nahabedian](https://discourse.julialang.org/u/Mark_Nahabedian)
#### Post date: [February 28, 2024, 2:47am UTC](https://discourse.julialang.org/t/why-cant-it-find-that-method/110860/3 "2024-02-28T02:47:08Z")

</div>

And the answer is …

Another test was defining `install` methods without prefixing them. That’s how there got to be two versions of `install.
