Description
Long conversation with Jeff. Part of the discussion was around structs. We concluded that the main goal here is maximum compatibility with C. A struct
is similar to a composite type (which we discussed renaming to class
instead of type
) except that it has immediate value semantics:
struct Foo
bar::Int32
baz::Int32
end
julia> foo = Foo(1,2)
Foo(1,2)
julia> foo2 = foo
Foo(1,2)
julia> foo2.bar = 3
3
julia> foo2
Foo(3,2)
julia> foo
Foo(1,2)
This is kind of like immutability but without not allowing anything. Types like Rational
and Complex
would be structs rather than classes. However, we don't go as far as preventing reaching in and changing a field value. If you want to do that, you can, but don't. It's rude. So we have immutability by convention.
A couple more things about structs:
- struct fields must be typed
- struct fields can only be bits types, other struct types, or refs
- a ref is a pointer to the data part of a bits types or a struct type
Think of Ref
like a C pointer in a struct — and it can be passed to C as-is since it points to the actual data part. However, if you look at the word before what the pointer points to, it is a valid Julia object too, so you can program with it in Julia and then just pass it to C without having to change anything. This provides maximum compatibility with C code. You could even write a linked list struct type in Julia and then just pass it to C code and have the C code traverse the linked list without any problems. Having C code pass structures back to Julia is more of a problem, however. Maybe it's a one-way street.
Structs are laid out exactly the way C lays them out; they can also be stored in concrete arrays without any tags, giving C compactness and efficiency. If you do Array(Foo,n)
then it is initially just filled with junk like Array(Int32,n)
would be. Structs are just plain old data. They can, however, have constructors.
Some issues we haven't fully thought through are fixed-size array fields and struct unions. But we can worry about those later.