Value semantics

All primitive and composite SPL types have value semantics, not reference semantics.

SPL treats streaming data as pure copies rather than having an identity in an address space because that is most efficient and natural. Disallowing references also prevents null pointer errors, simplifies memory management, and prevents unintended side effects of mutating a value that is stored in a collection or used as a map key.

Value semantics means that:

  • An assignment (=) copies the contents, instead of aliasing the location.
  • An equality comparison (==) compares the contents, instead of comparing the locations.

One consequence of value semantics is that modifying the original after an assignment does not change any copies. Consider this example:

 void test() {
   mutable map<rstring, tuple<int32 x, int32 y>> places = { };
   mutable tuple<int32 x, int32 y> here = { x=1, y=2 };
   places["Hawthorne"] = here;
   here.y = 3;
 }

Line 3 initializes variable here with the value {x=1,y=2}. Line 4 assigns a copy of that value into the map at key "Hawthorne". Line 5 modifies the version of the value in variable here, so variable here now contains {x=1,y=3}. However, this code does not affect the copy at places["Hawthorne"], which is still {x=1,y=2}. Another consequence of the value semantics is that since there is no notion of a reference, there is no notion of a null pointer, nor can there be any cyclic data structures in SPL.

Tip: If you need a more powerful type system than that provided by SPL, use SPL's extension mechanisms and implement your code in a low-level language such as C++ or Java.