Are objects values?
Yes, objects/functions are values, but they are not primitive values.
The current draft uses the phrasing "object value" several times.
Section 4.3.3 explains that objects are "members of type Object", and a type is, by definition, a set of values. Therefore, objects must be values.
But references are also values. It's not a mutually exclusive thing
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20170819/64c65d47/attachment
I never claimed it was. I'm sure the notion of "value" that ECMAScript wants to convey is supposed to be something along the lines of "can be bound to an identifier".
The semantics that are then defined over primitive/non-primitive values are a completely different matter.
While it does appear the that ECMAScript spec calls objects values, that seems pretty unintuitive to me. My intuition is that values are immutable (functions can and frequently do have properties added to them). The typical distinction seems to me between values and variables. If you set a variable to an object value how is it that the variable value changes when you change another variable? If, on the other hand, you view object values as references to object then changing one variable's value will never change another's which seems a nicer view of the world. But that was T.J.'s point, I think.
Note that strings are also generally indistinguishable from immutable objects and are generally passed by reference under the covers but, because they're immutable, one can safely think of the value being the actual string rather than the reference. Numbers can be and sometimes are implemented as immutable objects too. Like V8 implements 32-bit signed integers as pure values and larger numbers are boxed (into hidden objects) double values.
Objects contain references to their fields, but they are always passed by value. This is probably the distinction you're looking for.
note 1) 'pointer' and 'reference' are not synonymous. Although they should be, c++ and languages evolved from it have changed the definition such that they are not.
Unfortunately; 'reference' when used by C++ people means a pointer to the value being passed; but hides the details that it is a pointer by making '.' operator behave like '->'. transparently, and just setting 'a = new
thing()' actually be '(*a) = new thing()', again, transparently.
( I really wanted to use 'reference' in the place of 'pointer' at several places in this; and have instead used 'pointer to a value' when I want to say 'a reference of a value' which, since C++ does not mean the same thing at all really)
there's a few good, diferent explanations of the terms but I'll add my own. stackoverflow.com/questions/373419/whats-the- difference-between-passing-by-reference-vs-passing-by-value
by there are really 3 options, pass by value, pass by reference, pass by pointer; and in this case the world should not be so black and white.
any primitive value passes by value. 1, 2,3; "apple", "banana" null, etc. a copy of the value is passed to the called function. Changing values does not change the original value... if you add to a string the caller does not get its string updated.
pass by pointer, a pointer to the value is passed. Changing the pointer in the callee does not change the caller's pointer. changing the content of what the pointer is pointing does change the content in the caller's pointer.
pass by reference, setting a reference to a new value updates the (pointer) in the caller. In javascript there is no good way to pass by reference. So given the choice of 'pass by value' or 'pass by reference' the only choice is that javascript is always 'pass by value' because changing the values that are passed do not change the caller's original variables.
Wish I had more knowledge of what sort of language background you have.
in C...
pass by value ( A pretty obvious thing)
void f( int a ) {
a = 3; // this does not change the caller's variable.
}
f( 86 );
pass by pointer
void f( int *a ) {
(*a) = 5; // de'referenc'ing the pointer, allows changing the value in
the caller
a = (some other pointer to int); // this would not change the caller's
value.
}
int value = 3;
f( &value );
pass by reference (and this, being a double pointer might be tough to wrap your head around)
void f( int **a ) {
(*a[0] ) = 5; // change the value in a
( *a ) = New( int ); // New being a macro that allocates a new int,
updates the 'reference' in caller.
a = (some other change); // this is never reflected back to the caller.
}
int a = 5;
int *b = &a;
f( &b ); // gives the function the ability to change the pointer that is b,
or the value a
In the third case the double-pointer is hidden in C++ so you never have the choice to try and affect the local copy of the variable, and all changes update the variables that the caller has passed.
in C# there is a parameter attribute 'ref' that you can pass pointers values. Structures are simple values like numbers, so if they are passed to a function, they are copied so the callee's changes to the content of the structures does not update in the caller.
(and this is not something javascript has, nor should have)
struct Point { int x, int y };
Point p;
void byValue( p ) {
p = new Point( 1,2 ); // updates to 'p' do not update the caller
p.x = 44; // updates to values in structures do not update to the
caller
}
Point a = { 1, 3 };
byValue( a );
so in the previous case, since no changes to the arguments are given to the caller, this is 'pass by value'
struct Point { int x, int y };
Point p;
void byValue( Point ref p ) {
p = new Point( 1,2 ); // updates to 'p' DO update the caller's variable
p.x = 44; // updates to values in structures DO update the caller's
values
}
Point a = { 1, 3 };
byValue( ref a );
in this case, a doesn't need to be allocated by the caller, and instead the called function can create a new point, or update values in the referred to pointer. This is much more like C++ 'reference' in which there is no way to make a change in the called function the does not update to the caller.
a class type in C# is passed by pointer (a copy of the pointer is passed) but the contents of a class can update. Although you can also use the 'ref' parameter argument to pass the pointer to the caller's class (hmm pointer-value), so the callee can update the caller's class pointer. (there are no pointers in c# and a C# purist will flame me for saying so, but I'm trying really hard to not use 'reference to a value; see note 1')
Java behaves a lot like C#; but doesn't have structure type to cloud the issue. Passing by reference allows the callee to update the caller's value that references a class instance. by normal calls in that regard are pass by value, so changes to the argument value itself does not update the caller; although of course if there are values contained within the argument passed (a pointer to a class) changes to contents do propagate.... I don't know; I shouldn't talk about java.
So at this point, I'm going to change my rules and allow myself to say 'reference' because there are no pointers in javascript; and there are no c++-esque references.
So in javascript, a function itself is a value, it is passed by reference, updating the argument of a function never modifies the caller's values. Updating what a parameter references does change the values in the caller's values.
var thing = { a : 5 };
function f( arg ) {
arg.a = 6; // will update the caller
arg = { a : 9 }; // does not update the caller
}
f( thing );
now I have diverged a lot from the original question....(going back to read what it was)
I recently had an exchange which started out with my "correcting" someone who said "Functions are values" by saying "Function *references* are values. Functions are objects." He/she replied that objects are also values, and after much back and forth, cited [this part of the JavaScript spec][1]:
................. after considering my reply and the question there's actually no equate..................
var f = function() {
}
f.x = 3;
function references are values, not sure you can really have any context that you're not dealing with a reference to a function.
functions can have properties too; so they are objects... but that's not really whether they are values or references. basically every variable in javascript is a pointer though; not a reference or a value.
FWIW I wrote a dissertation on this very topic a few years ago: bjouhier.wordpress.com/2010/05/15/objects-values
tldr;
- Expressions have a sense and a denotation.
- The sense of an expression accounts for its “cognitive significance”
- The denotation of an expression is the thing that the expression denotes.
- Two expressions may have different senses but the same denotation.
- A variable expression is an expression that takes different denotations over time.
- A constant expression is an expression that always has the same denotation.
- An object is a mutable denotation.
- A value is an immutable denotation.
- Objects have an identity which is immutable.
- Objects have a mutable state.
- Numbers and physical quantities are values.
- Dates and timestamps are values.
- Booleans are values.
- Characters and strings are values.
- Sets are values.
- A representation is an object that represents an object or a value.
- An expression is a value that denotes an object or a value.
- The value of an object is its identity.
- Values are symbolic and don’t exist in the real world.
- Objects are usually real, but not always.
This was not written in the context of a specific programming language, like JavaScript. So there is are mismatches: dates (and usually sets too) are objects in JS.
@T.J. Going back to your original post:
According to the definitions that I gave, objects are not values (they are mutable) but they have a value. Their value is their identity which is a memory handle (a reference) in JavaScript. Objects are more than their value; they are identity + state. When you pass or assign an object, you pass/assign the identity. The state is not copied.
The ES spec that you quote does not bluntly say that "objects are values"; it says that objects are manipulated as values. I think that you can take the viewpoint that objects are not values, but that they are manipulated through their identity, which is a value.
I did not discuss functions in my write-up (was saving this for a later
post that I never wrote)
but I would classify functions as values, conceptually.
This is an area where my model disagrees with JavaScript because functions
are mutable in JS: (_ => {}).foo = 1;
.
But this is not the only disagreement: dates are values in my model and objects in JS.
Bruno
On 17-08-19 01:34 PM, T.J. Crowder wrote:
An ECMAScript language type corresponds to values that are directly manipulated by an ECMAScript programmer using the ECMAScript language. The ECMAScript language types are Undefined, Null, Boolean, String, Symbol, Number, and Object. An ECMAScript language value is a value that is characterized by an ECMAScript language type.
...and said "So objects are values."
Is he/she right?
Within the context of the ECMAScript spec, yes.
I've used the term "value" in explanations of variables, properties, and function arguments and in particular when explaining why
b = a
copies an object reference, not an object, froma
tob
. (Saying the object reference is the value.) It's been an invaluable aid to helping people "get" object references.
(Note that the spec has a Reference type, but Reference values are not used in this way.)
I'd be very sorry to hear that I was misusing a term of art. But I'd rather know. :-)
I wouldn't say you're misusing a term of art, you're just using different terminology from the spec.
If I'm misusing "value," what should I use instead for that thing that actually gets stored in memory? How to explain the
b = a
thing with object references to beginners?
You should just keep using whatever works. If necessary, you can say that the terminology you're using doesn't quite match the spec's terminology, but that's unlikely to be a problem.
Still, it's an interesting question of how to explain "the b = a
thing" in
spec terms. It depends on the context, but typically the interesting part
will boil down to an invocation of SetMutableBinding, and then bottom out
with an action like:
Set the bound value for 'b' (in some environment record)
to the value that is currently bound to 'a'.
or
Set the [[Value]] attribute of the property named 'b' (of some object)
to the value that is currently bound to 'a'.
(I think I got that right.)
The point is that, if a
is currently bound to an object, then the value
being bound to 'b' is (in spec terms) that object, not a reference to it or
a pointer to it or the address of it -- those terms don't exist in the spec.
To understand the spec's model (or make sense of its wording), it may help to imagine all the various values just floating around in value space. When an environment record binds 'b' to a value X (object or number or string, whatever), it doesn't stuff that value into a box somewhere, it merely creates an association between 'b' and X. (You could say that assignment always shares values, never copies values. But it's only with objects that the distinction is observable.)
I recently had an exchange which started out with my "correcting" someone who said "Functions are values" by saying "Function references are values. Functions are objects." He/she replied that objects are also values, and after much back and forth, cited this part of the JavaScript spec:
...and said "So objects are values."
Is he/she right? Wikpedia isn't much help, at least not to me. I asked a friend who, unlike me, did get comp sci theory at Uni, and he said "...you're not wrong, but it's very Humpty Dumpty: When I use a word, it means just what I choose it to mean -- neither more nor less."
I've used the term "value" in explanations of variables, properties, and function arguments and in particular when explaining why
b = a
copies an object reference, not an object, froma
tob
. (Saying the object reference is the value.) It's been an invaluable aid to helping people "get" object references.I'd be very sorry to hear that I was misusing a term of art. But I'd rather know. :-)
If I'm misusing "value," what should I use instead for that thing that actually gets stored in memory? How to explain the
b = a
thing with object references to beginners?This is slightly off-topic for the list, but also not, as I spend a lot of time explaining things to JavaScript beginners, and the authors of the text being used to tell me I'm wrong are on this list. :-)
Thanks,
-- T.J. Crowder