Simple example package to imitate


#1

Although I’ve found coming to Julia from Python to be straightforward and even delightful sometimes. However, as I’m scaling up my program (a Julia implementation of the UCR Dynamic Time Warping Suite of Optimisations), I’m hitting a few problems.

Are there any relatively small packages I could imitate the structure of?


Julia vs Python project/package structure
#2

GeoIP.jl is pretty simple though I don’t know whether it’s what you’re looking for.


#3

The problem in the stackoverflow question is that you have managed to create two Query types. One inside of Structs (which would be Structs.Query) and one inside of Utils (which would be Utils.Structs.Query).
Remember that include is pretty much copy and pasting the code in place so if you include a file twice, it will get executed twice.

We can look at what type dist is defined on:

julia> methods(dist)
# 1 method for generic function "dist":
[1] dist(x::Main.Utils.Structs.Query, y::Main.Utils.Structs.Query) in Main.Utils at utils.jl:9

There is no way for Julia to know that Utils.Struct.Query is the same as Query. Rewriting your file to use the same Query struct:

include("utils.jl")
using .Utils: dist

a = Utils.Query("a", 1)
b = Utils.Query("b", -1)

println(dist(a, b))

and it works.


#4

You are absolutely correct. However, this solution seems a bit (subjectively) ugly. It seems to tell a potential reader of the code to look for the definition of Query inside of Utils, when it is actually defined in Structs. Is this a symptom of my project structure or something else?


#5

This is a very good example of a small, but understandable package. Thank you for sharing it with me!


#6

Use using ..Structs: Query inside Utils.jl instead of reincluding the file. The .. goes up one module higher and uses the existing Structs module defined there.

In general, you not have to include a file twice.


#7

Do you mean switch to using ..Structs: Query inside import_test.jl. Either way, I still get Structs not defined error.

Also, you are free to stop debugging with me anytime you like.


#8

I meant to change utils.jl to look like:

module Utils

using ..Structs: Query

export dist

function dist(x::Query, y::Query)
    return (x.data - y.data) ^ 2
end

end

#9

This is the same what I have written on SO (I have read the question there first).

However, you could define Query module inside a local Query package and then after adding this package you can do using Query inside Utils module and also do using Query in the outer scope and Julia will know that this is the same Query - right?


#10

What do you mean by a “local Query package”?


#11

local Query package

I mean that this package does not have to be globally registered.

  1. You can generate a package with Query as described in https://docs.julialang.org/en/latest/stdlib/Pkg/#Creating-your-own-packages-1.
  2. Then create a project for the main of your code as described in https://docs.julialang.org/en/latest/stdlib/Pkg/#Creating-your-own-projects-1.
  3. Then you activate this project and add the Query package form a local path as described in https://docs.julialang.org/en/latest/stdlib/Pkg/#Adding-a-local-package-1.

EDIT
Then in your project, when it is activated you can load Query using using Query without having to write a dot or two dots in front of it.