Why Julia's Ecosystem Stands Out with Consistency
Written on
Introduction
The ecosystem of a programming language plays a crucial role in its popularity. Programmers often prefer languages that come equipped with the necessary tools. While Julia is relatively new and has a smaller ecosystem compared to many other languages, it has significantly expanded in recent years alongside its growth.
A frequently overlooked aspect of these ecosystems is consistency. This includes uniformity in syntax, documentation, and formatting. In Julia, method calls and constructors are structured in a consistent manner, which extends across various packages. In this discussion, I'll highlight this facet of Julia, delve into its underlying principles, and illustrate how to create a package that aligns with the ecosystem’s consistency.
For those interested in exploring the code referenced in this article, you can find it in this GitHub notebook:
Emmetts-DS-NoteBooks/julias consistent ecosystem via method extension.ipynb at master ·… Random notebooks for various projects. Contribute to emmettgb/Emmetts-DS-NoteBooks development by creating an account… github.com
Julia's Ecosystem's Consistency
When compared to various programming languages, Julia's packages exhibit a remarkable level of consistency. Seasoned Julia developers can often predict the method calls they need, regardless of the specific types they are working with. This consistency stems from Julia's core principle of multiple dispatch.
It’s difficult to discuss Julia without addressing multiple dispatch. I’ve written extensively on this subject, and if you’re interested in understanding how Julia has perfected this concept, you can read my article here:
How Julia Perfected Multiple Dispatch - A look at the awesome ways that the Julia language made multiple dispatch perfect towardsdatascience.com
For instance, when utilizing the DataFrames.jl package, you’ll notice that the same base functions found in Julia's core data structures are prevalent throughout the ecosystem. This means that if you want to filter values in an array or a DataFrame, you can simply use the filter!() method in both cases. Such design consistency makes programming with Julia feel more fluid compared to other languages, reducing the need to learn an extensive API.
How is This Achieved?
Now that we’ve established the consistency of Julia's ecosystem, it’s essential to understand the reasons behind it. This consistency is largely due to Julia's extendable nature. In Julia, all method definitions can be extended, as they are semantically distinct from function definitions. For example, while a function is merely a defined name, a method is defined in relation to specific types.
To illustrate, let's extend the filter!() function. First, we import the function:
import Base: filter!
Next, we will create a simple type that contains two arrays:
mutable struct TwoArrays
first::AbstractArray
second::AbstractArray
end
Currently, if we attempt to call filter!() on this type, it will result in a method error. However, we can accomplish our goal in a single line of code:
filter!(f::Function, ta::TwoArrays) = begin filter!(f, ta.first); filter!(f, ta.second) end
This function will efficiently filter both arrays within the struct. To demonstrate, let’s test our function:
tas = TwoArrays([5, 6, 7, 8], [5, 6, 7, 8])
filter!(x -> x > 6, tas)
For readers unsure about using anonymous functions, I’ve covered that topic in detail in another article:
What On Earth Is An Anonymous Function? Uncovering the ins and outs of anonymous functions and types in Julia towardsdatascience.com
When we run the code, we see the filtered output:
println(tas.first)
println(tas.second)
Output:
[7, 8]
[7, 8]
Conclusion
Julia is an impressive language, and its capabilities are further enhanced by the innovative applications of multiple dispatch. Features like constructors and method extension are unmatched in other programming languages. Julia’s approach to maintaining consistent base methods throughout its ecosystem greatly simplifies the use of various packages. This consistency allows users to make educated guesses about functionality, often with successful outcomes. Thank you for engaging with this article; I hope it has provided both inspiration and insight into extending Julia!
Chapter 1: GPU Programming in Julia
Explore the fundamentals of GPU programming using Julia, its benefits, and practical applications.
Chapter 2: Full Stack Development with Julia
Discover how to leverage Julia for full stack development in modern applications.