Reference Semantics and Value Semantics

The concept of an object, record, structure, or product type occurs inalmost every programming language. Being able to declare a type ofvalue that groups a number of other values together is a fundamentallyuseful thing.

As similar as the various record-ish constructs are in their basicfunctionality, the way such values are actually looked at and handledcan be rather sharply divided in two different styles. Someprogramming languages or systems strictly prescribe one or the other,but in many cases you can use both.

Reference Semantics

Records are implemented as a piece of memory where their content islaid out at adjacent memory positions. The way to identify such arecord value is by its memory address.

Memory can be changed, so records can be changed. You can write newvalues into their fields, and thus the content of a record changesover its lifetime.

But it's still the same record, even though some of its fields mayhave changed value. So the way to compare two records is by address.You're interested in the identity of a record, not so much itscurrent content. When implementing a hash table that uses records askeys, you hash the memory addresses.

Value Semantics

Mathematical product types allow us to treat a group of values as asingle value. A two-dimensional coordinate is a pair of numbers.

In implementing computer programs that manipulate such types, we mayor may not put these numbers in memory somewhere. But that is notterribly relevant to our programming model.

Changing the x position of an existing coordinate pair is not a thing.You can create a new record if you need a new pair of coordinates. Itis possible to define algebraic rules on records, definingequivalences that hold when you perform certain operations on them.

Comparing two records is done by comparing their contents. Whetherthey happen to occupy the same memory is immaterial. A hash table withrecords as keys obviously hashes their contents.

With value semantics, a record is just the sum (product?) of itscontents, and nothing beyond that. It doesn't have its own identity.

Know Your Semantics

Both of these approaches provide a coherent way of dealing with recordvalues, and kind of force you to use the whole package���if you're goingto mutate your record, you probably also need to compare them byidentity. If you're going to make them immutable, you must implementupdates by creating new values, and will generally want to compare byvalue, because object identity has little meaning then.

In Haskell, you're going to be using value semantics whether you likeit or not (you probably do like it, or you wouldn't be using Haskell).

In most imperative programming languages there are situations thatcall for reference semantics and situations that call for valuesemantics. A mutable container or a stateful subsystem is bestimplemented with a reference-semantics type. A small composite valueor a data structure where referential transparency is valuable is muchbetter treated a value.

Some languages provide different constructs for these two types ofrecords, making it clear what you are dealing with in any givensituation. But many, such as JavaScript, don't. They may not evenprovide reasonable mechanisms for indicating what can be mutated andwhat is immutable. When working with such a crude language it isimportant to be aware of the way a given type is intended to be used.

All this is to say, when a JavaScript type provides no operations thatchange its content, when the TypeScript types list its fields asreadonly, and the author goes on about it being an immutable type inthe documentation, please stop mutating its properties and wonderingwhy things break.

 •  0 comments  •  flag
Share on Twitter
Published on October 24, 2024 16:00
No comments have been added yet.


Marijn Haverbeke's Blog

Marijn Haverbeke
Marijn Haverbeke isn't a Goodreads Author (yet), but they do have a blog, so here are some recent posts imported from their feed.
Follow Marijn Haverbeke's blog with rss.