Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: Self-referential and recursive types

What I am trying to do is not very straight forward, maybe it is easier if I start with the result and then explain how I am trying to get there.

I have a struct with two fields:

struct data{T}
    point::T
    mat::Array
end

What I would like to do is nest this and make the field mat self-referential to get something like this:

data{data{Int64}}(data{Int64}(1, [1]), [1])

The 'outer' type should not store [1] but reference to the innermost mat. I am not sure if this makes sense or is even possible. The field mat should store the same large array repeatedly.

I have tried something like this (n is the number of nested types.

struct data{T}
    point::T
    g::Array
    function D(f, g, n)
        for i = 1:n
            (x = new{T}(f, g); x.f = x)
        end
    end
end 

Again I am not sure if I understand self-referential constructors enough, or if this is possible. Any help/clarification would be appreciated, thanks!

like image 836
secretsanta Avatar asked Apr 24 '26 08:04

secretsanta


1 Answers

The exact pattern will depend on what you want to achieve but here is one example:

struct Data{V, A <: AbstractArray{V}, T} 
    mat::A
    point::T

    Data(mat::A, point::T = nothing) where {V, A <: AbstractArray{V}, T} =
        new{V,A,T}(mat,point)
end

Usage

julia> d0 = Data([1,2,3])
Data{Int64,Array{Int64,1},Nothing}([1, 2, 3], nothing)

julia> d1 = Data([1.0,2.0],d0)
Data{Float64,Array{Float64,1},Data{Int64,Array{Int64,1},Nothing}}([1.0, 2.0], Data{Int64,Array{Int64,1},Nothing}([1, 2, 3], nothing))

Tips:

  1. Never use untyped containers. Hence, when you want to store an Array you need to have its type in your struct defintion.

  2. Use names starting with a capital letter for structs

  3. Provide constructors to have your API readable

Last but not least. If you want to have several nesting levels for such structure the compiling times will hugely increase. In that case it would be usually better to use homogenous types. In such scenarios you could use perhaps type Unions instead (unions of small number of types are fast in Julia).

like image 95
Przemyslaw Szufel Avatar answered Apr 26 '26 12:04

Przemyslaw Szufel