How To Configure Julia Packages. An in-depth look at configuring and... | by Emmett Boudreau | Towards Data Science

Video for this article:
Repository for our project:
github.com
In the previous addition of “ The Comprehensive Julia Tutorial,” we went over the basics of working with Project.toml files and virtual environments in the Julia programming language. If you haven’t read or watched that iteration of this tutorial series, you can feel free to check it out here if you are interested:
towardsdatascience.com
A Project.toml file is a valuable asset that describes essentially any Julia project. Not only does this file include all of the dependencies that are going to be required by the project, but it also includes the compatible versions of those packages, as well as meta-information about the package. While most of the Project.toml can be mechanically generated by creating a new virtual environment, there are some portions of the configuration that must be done manually.
The first step in the completion of the setup of this project is going to be finishing the configuration of our Project.toml file. Firstly, we should take a look at some of the configuration options that we have in our arsenal, such as “ name,” “ version,” and “ UUID.” Here is our completed Project.toml file, which will make it a lot easier to explain what each of the assets in it do for Julia’s package manager.
authors = ["emmett emmett@emmettboudreau.com"]name = "SuperFrames"uuid = "19a2823e-5050-11eb-208c-916d674a0ad5"[deps]DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"[compat]julia = "1.5"DataFrames = "0.22.1"
“ Authors” is a pretty self-explanatory field; these are the people who collaborated on the project. Of course, inside of here we see me along with my e-mail in a string that is written in a Lisp-style list. That being said, additional entries should be provided in a Julia-style array containing strings of Lisp-style lists.
The name is one of the most important attributes of our package. This is going to be how end-users call and work with the package, so of course it is incredibly important. While “ using” calls might use module names, it might be wise for your module name to use the same name as your Pkg name, because otherwise people will have a hard time even figuring out how to import your package! That being said, the name described in this file is going to be used essentially exclusively for the Julia registry to recognize what your package is called.
A UUID (Universal Unique Identifier,) is a combination of letters and numbers that are used to represent anything abstractly, but have a clear use when it comes to packages. UUIDs allow the package manager, Pkg, to keep track of several packages, potentially with the same name and sometimes from entirely different registries and allow them to work together.
The type of UUID we need for a Julian package can be obtained using the UUIDs.jl package. We can import the module with
using UUIDs
Now that the module is imported, there is now an exported method called
uuid1()
Which will take one positional argument; a random number generator. As usual with these circumstances, the random number generator is a type that will take a seed and return random numbers based on that seed. As a default, this argument takes your global random number generator, which will use a seed that is provided by the compiler at compilation.
With that in mind, we really don’t need a seed, so I just passed the method like so:
uuid = uuid1()
And then logged that resulting UUID into our Project.toml file.
DataFrames is our only dependency in the [deps] section. The corresponding value to this key is the UUID for the DataFrames.jl package. This is of course automatically added to our Project.toml file for us whenever we created our virtual environment.
The compat section is used to tell Julia’s package manager what versions of the dependencies this project was made to work with. For Julia applications in general, it is probably a good idea to make the Julia compatibility at least 1.0 or above. For today’s package, I am going to be setting the compatibility of Julia to 1.5, given that I am on 1.5.2, and I am going to set the DataFrames compatibility to the latest version of DataFrames:
[compat]julia = "1.5"DataFrames = "0.22.1"
As we discussed when we went over explicit importing, we will need to explicitly import any package that we want to extend methods or types from. While we might not be extending the capabilities of the DataFrame type, we will be able to use methods provided by DataFrames.jl on our DataFrame so long as we utilize the type hierarchy of that package.
A type hierarchy is simply a classification of one type over a series of categories. This comes in handy when certain types can be worked with in certain ways because they have common attributes, but sometimes they don’t. For this example, since most methods in the DataFrames.jl package utilize the type “ AbstractDataFrame,” we are going to directly import it and create a new type that will inherit all of its methods. First and foremost, let’s import both of the types we are going to need to build out our own similar type, AbstractDataFrame and Index.
import DataFrames: AbstractDataFrameimport DataFrames: Index
The last thing we are going to do today is create a new type that is going to inherit all of the properties already given to the abstract type, AbstractDataFrame. We do this using the <: operator, which basically means “ Is a sub-type of.” While this is usually used for conditional arguments, this is certainly not the case whenever creating a struct or other abstract type. If you would like to learn more about abstract types, you can check out this article I wrote on it:
towardsdatascience.com
While Julia’s Pkg package manager might require a bit of work to get up-and-running when developing a package, it certainly becomes worth it once the package is published and the benefits are felt. While there wasn’t a lot of programming in this edition of the Comprehensive Julia Tutorials, there are certainly plans to dive more into algorithms and Julian programming in general in the future. I work forward to showing off more of what the language can do with types and methods! Thank you for reading!