Guidelines for creating a package

Hi all,

I would like to hear the recommendations for creating a new package “properly”. From my questions, you will see that I don’t fully understand what a package is, especially compared to a (collection of) module(s).

For example, should a package always have a “main” module, or could it have several modules on equal footing? In fact, must there be a module bearing the same name as the package?

I heard that it’s bad form to have submodules within a module, is it equally bad to have several modules in a package? (surely not…?) Are the different modules always meant to include one another automatically, or is this sometimes left to the user of the package?

Generally speaking, I feel that should simply know more about packages and what they are – a little beyond “a package is like a module which you can download with the package manager” :slight_smile:

Say I start working on my own package, and for the moment there is really just one module, and having the thing on Github is only in the far, far future. Should I really prepare a package already, or just work on a module for the moment?

The example uses of the Revise package seem to assume that people create a new package as a matter of routine, even just to try out a couple of ideas… this is puzzling to me.

I have not found much in the documentation about packages, but perhaps I’m not looking at the right place.

any help appreciated!

thanks,
Pierre

2 Likes

@PetrKryslUCSD’s package is a good example to look at for using multiple modules in a package. The top-level file to start with is src/FinEtools.jl.

1 Like

Many questions … here are a few answers.

Creating packages: I just taught something like this (very condensed ; to econ phd students). So I have notes:

https://lhendricks.org/julia_notes/packages.html

https://lhendricks.org/econ890/julia/outline.html

Modules: A package MyPkg must define the module MyPkg in src/MyPkg.jl. There can be other modules, which would usually be sub-modules of MyPkg. Multiple modules on equal footing would defeat the purpose of the package (avoid includet statements and their associated problems).

Submodules are not bad. This is, in my view, a matter of taste. I have found that they often create more problems than they are worth (lots of exports and usings). I tend to create packages when I think a separate module would be worth it.

Many people work with modules that are just environments, not packages. I have had issues with includet (from Revise.jl) tracking nested files. I don’t know if that’s still an issue these days. But since making a package is extremely easy, I usually work with packages right from the start.

5 Likes

Yes, there should be a module matching the name of the package. It’s possible to have multiple independent modules (or even independent packages) in a single repository of code, but I don’t think there’s any way to have independent top-level modules sharing the same package.

In other words, when you pkg> add Foo you should now have access to exactly the Foo module. This is very different from, for example, Python, where you might pip install Pillow to get a module named PIL (which I’ve always found pretty annoying).

This is a matter of opinion, and not an opinion that I share. Feel free to use submodules if you find it helpful to organize your work.

Making a package just means having a src folder and a Project.toml, so it’s not a particularly high bar to cross. Once you’ve done that, it suddenly becomes easy to pkg> activate that package’s environment, which in turn makes it very easy to ensure that your project always has exactly the correct set of dependencies available, no matter what you do elsewhere on your computer. That alone is worth the price of admission for me. (feel free to ask more questions about package environments and dependencies if you have follow-ups).

You don’t have to–you can also just create a Foo.jl file with module Foo in it, and then put that on your LOAD_PATH (e.g. push!(LOAD_PATH, "/path/to/your/code")). But making a package with a Project.toml is pretty easy, and has some nice benefits, so I’d certainly recommend learning that workflow.

4 Likes

Not to mention that using PkgTemplates.jl makes it incredibly simple to also set up testing, docs, and other goodies with barely less effort. I have a template in my startup.jl so it’s basically 2 commands to generate a complete package skeleton - I often do this even for scratch code since it’s so dead simple.

2 Likes

Thank you all for your answers! it gives me much food for thought.

Sorry for not acknowledging your help earlier, i’ve been very busy.

Pierre

2 Likes