Why do I get an error if I define the correct type for a function argument?

I managed to some code to work but there is something that puzzles me: if I declare the type of a function argument the code does not run and I get an error message.

The example below involves three different files (I could not do it with less than three files). The files are Test1.jl, Test2.jl, and SomeModule.jl. Test1.jl does not contain a module, only code. The other two files contain modules with the same names (without the “.jl”, of course).

In SomeModule.jl I define a struct:

module SomeModule

struct MyStruct
    A::Bool
end

end

Test2.jl defines a function. In this version no type is defined for the function argument.

cd("C:/Dropbox/Code/Julia/bootstrapwalkforward/BW/src")

module Test2

include("./SomeModule.jl");

import .SomeModule

function bar(a)
    if a.A
        println("AAAAA")
    end
end

end

Finally, Test1.jl calls the function:

cd("C:/Dropbox/Code/Julia/bootstrapwalkforward/BW/src")

include("./SomeModule.jl");
include("./Test2.jl");

import .SomeModule;
import .Test2

a = SomeModule.MyStruct(true)

Test2.bar(a)

The code above runs with no problems.

However, if the function definition’s first line is replaced witn

function bar(a::SomeModule.MyStruct)

then the code does not run, with this message:

julia> Test2.bar(a)
ERROR: MethodError: no method matching bar(::Main.SomeModule.MyStruct)
Closest candidates are:
  bar(::Main.Test2.SomeModule.MyStruct) at C:\Dropbox\Code\Julia\bootstrapwalkforward\BW\src\Test2.jl:9
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

I tried a variety of other alternatives for the first line of the function definition and none of them worked. Only having no type definition worked.

Any ideas on why is this happening?

This is a common question for users new to Julia. The reason is, when you try to replace the the definition of bar in Test2.jl with

function bar(a::SomeModule.MyStruct)

The SomeModule.MyStruct here is referencing the module SomeModule you included in module Test2. Not the one you included in Test1.jl, althought they share the same name.

You could try a = Test2.SomeModule.MyStruct and call Test2.bar(a) instead here.

Usually, it’s not a good practice to include a file twice. I’d rather remove the include("./SomeModule.jl") in Test1.jl and run import .Test2.SomeModule instead.

2 Likes

include is equivalent to copy and paste the content of the included file in the same place. When you included the SomeModule.jl in the Test2 module, you created a Test2.SomeModule.MyStruct, and then you included the file in Test1.jl, you made a Main.SomeModule.MyStruct

1 Like

Your suggestion worked. I understand there is no need to include a file twice. Thanks for your help.

Thanks. I got it.