Using struct defined in a different module results in an error

Hi!

I am new to julia, so I wanted to try out some code. Everything was nice and clear until I started using multiple scripts. I simplified them to necessary minimum to reproduce error that is bugging me.

“trees.jl”

module Trees

export Tree

mutable struct Tree
    connective::Char
    left::Tree
    right::Tree

    # Root constructor
    Tree(symbol) = new(symbol)
end

end #module

“parser.jl”

module Parser

export parseFormula

include("trees.jl")

using .Trees

function parseFormula(a::Char)
    return Tree(a)
end

end #module

“interface.jl”

module Interface

export foo

include("parser.jl")
include("trees.jl")
#include("solver.jl")
using .Parser
using .Trees

function foo(a::Char = 'a')
    initlist = Tree[]
    push!(initlist, parseFormula(a))
end

end #module

Given these 3 files, you can run using .Interface and foo(), which will produce the following error:

ERROR: MethodError: Cannot `convert` an object of type Main.Interface.Parser.Trees.Tree to an object of type Main.Interface.Trees.Tree

To me this is a weird behaviour, because these two classes are exactly the same since they are defined in “trees.jl”. However, julia for some reason treats the Tree defined in “parser.jl” as Main.Parser.Trees.Tree, and Tree defined in “interface.jl” as Main.Interface.Trees.Tree. If that wasn’t enough when I call parseFormula from within “interface.jl” the Tree becomes Main.Interface.Parser.Trees.Tree.

I figured out that I can get rid of the error by changing initlist = Tree[] to initlist = Parser.Tree[], but to me this seems like a bad practice. So I would like to know:

  1. Why is Julia doing this?

  2. How can I make julia treat every Trees.Tree as equivalent?

Any general tips on using modules will also be appreciated!

Thanks in advance!

Hi!
From what I can tell, the source of your problems is that you include trees.jl twice: once within Interface and once within Interface.Parsers. Remove either of those two and you should end up with only one definition.
As a side note, many Julia packages (including fairly large ones) actually don’t use submodules at all, and put all of their include statements in the root source file. I’m guessing that would make your life even easier

5 Likes

Welcome to our community! :confetti_ball:

I recommend you reading this previous but recent thread.

2 Likes

It works now! Thank you both for your help!

1 Like