Search code examples
juliatypedefequivalent

Is there a concept in Julia like C++'s typedef


I'm trying to learn julia and started by rewriting one of my C++ programs.

I'm having problems in finding a good way of representing the following concept in Julia.

I have a few structs all of which are some sort of collection. Let's say I have an AddressBook and a PhotoAlbum. Each collection has very different elements. Now, in C++ it's quite easy to create a variable of type Photo if I know that a PhotoAlbum was passed into a function.

I can't quite think of a equivalent way in julia. Ideally, the compiler should know exactly which type the collection consists of so it can optimise as much as possible.

This is how I would do it in C++

class AddressBook
{
  public:
    typedef PersonalDetail Element;
}


class PhotoAlbum
{
  public:
    typedef Photo Element;
}


template<typename Collection>
void printFirstElement<Collection>(const Collection& c)
{
  const typename Collection::Element firstElement = //c.first();...
  // do something with firstElement
}

Solution

  • If I understand your problem correctly I would say that you do not have to think about it, because the compiler will know the required types. For example in your code above when you would call first(c) (this would be an equivalent of c.first()) the type of this variable will be known at compile time (you can confirm this by running @code_warntype on your function).

    If you would provide a complete small working example I could give you a working code for this.

    A more advanced topic is attaching some metadata to your types. There are several ways you could do it. Let me show you one of them - via a parametric abstract type.

    abstract type AbstractCollection{T} end
    struct PersonalDetail end
    struct AddressBook <: AbstractCollection{PersonalDetail} end
    struct Photo end
    struct PhotoAlbum <: AbstractCollection{Photo} end
    getcollectiontype(::AbstractCollection{T}) where T = T
    

    and now you can write something like this to extract the metadata

    julia> ab = AddressBook()
    AddressBook()
    
    julia> pa = PhotoAlbum()
    PhotoAlbum()
    
    julia> getcollectiontype(ab)
    PersonalDetail
    
    julia> getcollectiontype(pa)
    Photo
    

    Of course it is a MWE, and I am not sure if you need it in your code (if you show a small full working code we can discuss the best implementation strategy).

    Also something like this might be not needed at all. For example you have a standard function eltype that is expected to return a type of element in a collection. For this function you could add methods for your specific types to get the information about element type they hold. Then you can simply run eltype(collection) in your code and again - at compile time - you will have the information about element type of the collection.

    Also note that types in Julia as also values so for example the following code just works and compiler knows all types as need (the function f tries to convert its second argument y to the type of its first argument x using the type constructor):

    julia> f(x,y) = typeof(x)(y)
    f (generic function with 1 method)
    
    julia> f(10, 2.0)
    2
    
    julia> f(10.0, 2)
    2.0
    
    julia> @code_warntype f(10.0, 2)
    Body::Float64
    1 ─ %1 = (Base.sitofp)(Float64, y)::Float64
    └──      return %1
    

    The definition above is equivalent to the following one f(x::T,y) = T(y).