I want to write modules inside of a module. Is there a way to avoid repeating the same using line of code?
module Module0
using Pkg1, Pkg2, Pkg3
module Module01
using Pkg1, Pkg2, Pkg3
some_code_1
end
module Module02
using Pkg1, Pkg2, Pkg3
some_code_2
end
end
Function names should be short and simple, and should use dispatch in order to distinguish between methods. So they should all be named the same, but dispatch will take care of any possible issues.
Types should have unique names. Otherwise it would be confusing, right?
Most of Julia is encoded in functions and types.
This is the same reason why import * from ... is not good in Python, but exporting stuff from Julia modules is okay. “Clashing” isn’t really a problem if you are doing dispatch on unique (and aptly named) types. This gives a lot less of an incentive to submodulize compared to other languages.
But if you do need to, then yes, the @def macro will do compile time copy/pasting for you.
I love submodules. My packages typically use them generously. But if all the submodules are using the same dependencies, that is a strong indicator that perhaps they are more coupled than is typical, and might be better off in the same module.
I’m having a discussion with our software lead about how we implement an API in Julia, where users call a function analyze. She wants different analyze functions that perform different types of analyses, and to avoid namespace issues, she wants me to use modules, i.e. using different module names for different types of analyses, but every such module will have one function called analyze. Among the types of analyses we already set up, many of them will have essentially the same dependencies (using the same set of packages), meaning they are too coupled to be in separate modules? The issue of using multiple dispatch is that she wants exactly the same function signature for each analyze function. So I’m not sure how to propose better alternatives.
One alternative to submodules in your case would be to use an additional argument to distinguish the type of analysis to do. For example:
abstract AnalysisType
immutable Linear <: AnalysisType
end
immutable Quadratic <: AnalysisType
end
analyze(::Type{Linear}, x) = println("Linear analysis of $x")
analyze(::Type{Quadratic}, x) = println("Quadratic analysis of $x")
which you could run like this:
analyze(Linear, [1,2,3])
With a design like this, users can implement their own compatible analysis types by creating a new AnalysisType and a new method for the same analyze() function.
Or, if you don’t like using types as values, a slightly different signature for analyze would be:
analyze(::Linear, x) = println("Linear analysis of $x")
analyze(::Quadratic, x) = println("Quadratic analysis of $x")