You can’t define constructors for aliases. This is because aliases aren’t a new type. They’re just a new name. As such, if you want to define this constructor, you would have to define a constructor for 1 dimensional arrays of Stuff. What you probably want is
struct boo
stuff::Array{Stuff}
end
Then you’re actually making a separate thing which can have it’s own methods.
So I just had to add a const to the snippet and it works!
const boo = Array{Stuff,1}
function boo(x,y,z)
someStuff = .....
return someStuff
end
I like Julia! Looks so logical.
But in this case, why does the const make all the difference?
At least a (potentially) “variable” type would make little sense.
First, I like to use alias, just to improve readability.
When specifying type in method signature, having a familiar name is more readable than having thing like
Array{Stuff,1} where stuff can also be “complicated”
Second, the default constructor for an alias can be sufficient, but of course it might happen that I need a more specialize constructor. In my last example, it was simply constructing from a dictionary with some selection.
Before I learned that an alias must be const , I had to use the solution proposed by Oscar_Smith which add a layer.
What is your point of view? Would you suggest to avoid using an alias?
I would not be pretentious to “have a point of view” that deserves really to be taken into consideration because I am still learning. Nevertheless, I would mention these points below.
First, I just realized that there are cases where aliases are created with the purpose you have in mind. For example in StaticArrays, we have const SVector{S, T} = SArray{Tuple{S}, T, 1, S}.
Nevertheless, I was thinking in the following points:
Using the alias will make the code less clear to everyone else and, in the future (when you forget why the alias was defined), to you as well. The standard syntax everyone understands. Unless, of course, if the purpose of the package is to provide the new type, such as in the example above.
You do not really need an alias just for creating a complicated type. Just write a function with the name you want, for instance. In many cases that will be more clear than the alias, probably.
julia> struct A
x
end
julia> function initialize_vector_of_A(n)
return Vector{A}(undef,n)
end
initialize_vector_of_A (generic function with 1 method)
julia> a_vec = initialize_vector_of_A(10)
10-element Array{A,1}:
It is common to use aliases when the types become long, for example with unions const MyTypes = Union{MyTypeA,MyTypeB,MyTypeC}, but that is for simplifying the annotations of function dispatch mosty. For example:
julia> struct A x end
julia> struct B x end
julia> struct C x end
julia> const MyTypes = Union{A,B,C}
Union{A, B, C}
julia> f(a::MyTypes) = a.x
f (generic function with 1 method)
julia> a = A(1);
julia> f(a)
1
julia> f(1)
ERROR: MethodError: no method matching f(::Int64)
Specialized constructors can be defined as you wish, using functions as I mentioned above, or if you have a new type, like Stuff, using new constructors Stuff(...) = or new(..) inside the definition of Stuff.
Just to point that Vector is an alias for Array{T,1}, which simplifies that the notation a little to Vector{Stuff}, and it is important that the meaning of that is very transparent.