Value type and reference type

[1][2] Even among languages that have this distinction, the exact properties of value and reference types vary from language to language, but typical properties include: Even when function arguments are passed using "call by value" semantics (which is always the case in Java, and is the case by default in C#), a value of a reference type is intrinsically a reference; so if a parameter belongs to a reference type, the resulting behavior bears some resemblance to "call by reference" semantics.

Call by sharing resembles call by reference in the case where a function mutates an object that it received as an argument: when that happens, the mutation will be visible to the caller as well, because the caller and the function have references to the same object.

While C++'s approach is more flexible, use of non-references can lead to problems such as object slicing, at least when inheritance is used; in languages where objects belong to reference types, these problems are automatically avoided, at the cost of removing some options from the programmer.

At the end, a refers to the second object with its prop field having the value 1, while b refers to the first object with its prop field having the value 3.

In a functional programming language where nothing is mutable (such as Haskell), such distinction does not exist at all and becomes an implementation detail.