Could anyone provide a formal definition of these concepts please?
- value type
- reference type
- value semantics
- reference semantics
Could anyone provide a formal definition of these concepts please?
- value type
- reference type
- value semantics
- reference semantics
I'd also add another dimension:
Typically those would be a subset of value types that do not allocate memory or take locks e.g. a struct or a tuple of ints
is realtime safe, while a struct or a tuple of strings - is not.
It's tempting to say that identity
and ===
operation strongly hint reference types, but OTOH we can imagine:
struct Value: Identifiable {
private (set) var value: Int
var id: ObjectIdentifier { ... }
static func === (lhs: Self, rhs: Self) -> Bool {
lhs.value == rhs.value
}
func foo() {
// ....
}
}
and a modification to ObjectIdentifier.init(...)
to accept this value type, then the line is further blurred.
Note, that this is still a value type:
struct S {
private (set) var ref = NSObject()
func foo() {
...
}
}
As a very very very rough approximation - instances (themselves) of a reference type would be allocated with malloc. Their fields may in turn be either value or reference types on their own.
This post outlines the fundamentals, and section 2 of this paper defines Mutable Value Semantics (a slightly more precise term) and contrasts it with reference semantics. I believe that paper is the current state of the art in understanding these concepts.
A contrived counter example:
struct JustAnInt {
var value: Int
}
extension JustAnInt: RawRepresentable {
private static var positions: [(Float, Float)] = []
public var rawValue: (Float, Float) {
get { Self.positions[value] }
nonmutating set { Self.positions[value] = newValue }
}
public init(rawValue: (Float, Float) = (0, 0)) {
value = Self.positions.count
Self.positions.append(rawValue)
}
}
let ref = JustAnInt()
print("\(ref): \(ref.rawValue)")
let ref2 = ref
ref2.rawValue = (69.0, 105.0)
print("\(ref): \(ref.rawValue)")
Why so elaborate
extension Int {
func foo() { malloc(1) }
}
42.foo() // "wow, Int is not realtime safe!"
There are an infinite number of dimensions of safety that could be used to classify types. Safety for use in realtime systems is certainly an interesting one, but I don't think it's any more related to the value-vs-reference distinction than any other safety property… is it?
If extending a type to have some method or computed property with reference semantics makes the type have reference semantics, every type can have reference semantics.
var x = 5
extension Equatable {
var x: Int { get { x } set { x = newValue } }
}
If extending a type to have some method or computed property with reference semantics makes the type have reference semantics…
It doesn't. Every type with value semantics has a notional value, defined by its author. This x property is not part of the notional value of any type.