Help with where 0.6 syntax

question

#1

My Julia 0.5 code looks like this. What is the 0.6 syntax?

using StaticArrays
immutable Point3 <: FieldVector{Float64}
    x::Float64
    y::Float64
    z::Float64
end

Thank you very much for any hint.
Petr

edit:
the problem was the missing dimension. The implicit constructor still works


#2

The code you wrote would be the same. The difference comes in the constructors. Even then you only need to use it for parametric types (should Point3 be Point3{T}?).

You would use where in the following example

(fixed as per @tamasgal’s suggestion below so as not to cause confusion)

immutable Point3{T} <: FieldVector{3, T<:AbstractFloat}
    x::T 
    y::T
    z::T 
    Point3{T}() where T = Point3{T}(rand(T), rand(T), rand(T))
end

In this example you don’t need where T<:AbstractFloat because this constraint already appears in the type definition. You are free to declare these types of constructors both inside and outside of immutable. You can also create Point3(...) constructors that don’t take type parameters (the parameter will be determined by the function’s return type).


#3

And btw. you should define the dimension like FieldVector{3, T<:AbstractFloat}, otherwise it’s an invalid subtype.

Just a slightly modified answer from ExpandingMan:

struct Point3{T} <: FieldVector{3, T<:AbstractFloat}
    x::T 
    y::T
    z::T 
    Point3{T}() where T = Point3{T}(rand(), rand(), rand())
end

#4

Thank you a lot for the answers.
Actually, as @tamasgal pointed out, the problem was with the specification of the dimension.
So, the code

using StaticArrays
immutable Point3 <: FieldVector{3,Float64}
    x::Float64
    y::Float64
    z::Float64
end
a = Point3(1, 1,1)
3-element Point3:
 1.0
 1.0
 1.0

works without definition of the constructor - there is still the implicit constructor available. So, actually, the problem was not related to the 0.6 syntax but to the interface change in the StaticArrays.
Thank you both for the hints.


#5

Another similar story. Is it possible to create an abstract type of following properties?
Again, old 0.5 era code

using StaticArrays

abstract FEM_Struct <: FieldVector{UInt32}

immutable Edge <: FEM_Struct
    v1::UInt32
    v2::UInt32
end

immutable Triangle <: FEM_Struct
    v1::UInt32
    v2::UInt32
    v3::UInt32
end

immutable Quadrilateral <: FEM_Struct
    v1::UInt32
    v2::UInt32
    v3::UInt32
    v4::UInt32
end
etc... up to hexahedron

Again, the same problem with the interface StaticArray dimension.

julia> abstract CST_Struct <: FieldVector{UInt32}

WARNING: deprecated syntax "abstract CST_Struct<:FieldVector{UInt32}" at REPL[21]:1.
Use "abstract type CST_Struct<:FieldVector{UInt32} end" instead.
ERROR: invalid subtyping in definition of CST_Struct

How can I propagate the dimension N into the abstract and concrete type information?


#6

So, after some permutation of keywords, the simple solution is:

julia> abstract type FEM_Struct{N} <: FieldVector{N,UInt32} end
julia> immutable Edge <: FEM_Struct{2}
           v1::UInt32
           v2::UInt32
       end

julia> a = Edge(1,1)
2-element Edge:
 0x00000001
 0x00000001

Still, the type system with abstract hierarchy seems little bit magical to me, and even more magical with the 0.6 syntax.
Is there a blog post that would explain this for “spaghetti coders” like myself?


#7

Have you read the relevant parts of the manual? I found them pretty clear, they are full of examples.


#8

I’ve just read that section of the manual, and finally found the small missing piece of information well hidden for quick reading (for me unfortunately up till now)

If I understand it right, there are actually 2 completely different uses of types mixed together in the manual chapter.

  1. A type representing some data. Can be concrete or parametric, this doesn’t matter. I use it as a template to store my data somewhere in the memory.
  2. A type definition used only for dispatch (flow of types). Never carrying data, just representing a pattern which some real object may or may not match. And this is the only case in which the where clause is used to restrict/specify the set of different kinds of objects.

Is my view correct, or am I missing something more fundamental.


#9

I think you missed quite a bit.

  1. concrete and parametric are orthogonal concepts. A type can be abstract/concrete, with or without parameters, all four combinations are valid.

  2. types and their parameters can be used for dispatch. Values cannot (unless you convert them to types, see Val). Whether the type has fields is not relevant for dispatch per se in this sense.

I reread the manual from time to time. It changes quite a bit (kind people invest a lot of time in improving it, actually), and even parts that don’t change much reveal multiple layers. Not unlike a good piece of literature.

Also, it pays not to be very teleological. Instead assigning each concept a single purpose, think of the language as a big box of building blocks, which you can use to create programs. Accidental features and applications emerge all the time, some end up in the manual, some get better compiler support, etc.


#10

I see. This needs some digestion and I copy your view on not diving into theology. Even with my limited knowledge of the type system I’m very happy with how Julia language and the ecosystem serves me to be productive. The same with C++ where I use only the parts I’m familiar with and that’s OK.

Regarding the manual - I thing the manual is very well written. What I’m missing is a jupyter notebook with more hard-core examples on the given topics. Definitely, at least the UnionAll concept may deserves such approach.

I’d like to thank you all for your time and thank for the help - with the hints I’ve now managed to migrate my code to 0.6 syntax.

Petr


#11

Then check out


It is treasure chest of real eye-openers. Many gave me food for thought for days.

BTW, I wrote teleology, ie the looking at the language constructs from the perspective of a construed purpose.