Pointers
Please no, mutable objects are bad enough imho.
And even if we could get pointers into JS, I'd strongly not want it to be like what's proposed here. Instead, I'd prefer an object encapsulating a reference to a variable, something like this (although engines could avoid the ceremony of closures here):
let foo = 1;
func(ref foo, bar)
// Equivalent to:
func({deref: () => foo, set: v => foo = v}, bar)
function func(ref foo, bar) {
foo += 2
}
// Equivalent to:
function func(foo) {
foo.set(foo.deref() + 2)
}
I've found myself more than once wanting a way to manipulate a variable by reference, in a way that's a bit more ergonomic than just creating a single-property object. It doesn't need to be much, but it doesn't need to be much. As a concrete example, recursive string joining could just pass a shared reference instead of an object with a single property:
function recursiveJoinLoop(ref str, array, sep) {
if (Array.isArray(array)) {
for (const item of array) recursiveJoinLoop(ref str, item, sep)
} else {
if (str == null) str = ""
str += String(array)
}
}
function recursiveJoin(array, sep) {
let str
for (const item of array) recursiveJoinLoop(ref str, array, sep)
return str
}
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
Pointers are also useful for microoptimization of stepping through arrays... but it wouldn't help JS without a lot of work in the engines...
for( var x = 0; x < width*height; x++ ) { arr[x] = 3; }
var ptr = arr; for( var x = 0; x < width*height; x++ ) { ptr[0] = 3; ptr++; }
since a pointer plus a constant is always more efficient than a pointer plus a variable amount that usually also has to be multiplied.
The second also serializes into SSE instructions when optimized so it can do multiple loop steps at a time.
-----Original Message----- From: es-discuss <es-discuss-bounces at mozilla.org> On Behalf Of Isiah Meadows Sent: Monday, March 19, 2018 3:21 PM To: Michael J. Ryan <tracker1 at gmail.com> Cc: es-discuss <es-discuss at mozilla.org> Subject: Re: Pointers
And even if we could get pointers into JS, I'd strongly not want it to be like what's proposed here. Instead, I'd prefer an object encapsulating a reference to a variable, something like this (although engines could avoid the ceremony of closures here):
let foo = 1; func(ref foo, bar) // Equivalent to: func({deref: () => foo, set: v => foo = v}, bar) function func(ref foo, bar) { foo += 2 } // Equivalent to: function func(foo) { foo.set(foo.deref() + 2) }
I put together a strawman for this last year at rbuckton/proposal-refs, but I haven't had much time to work on it.
Ron
Yeah, I meant "references", not "pointers"... My bad.
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
So the proposal is basically having references to primitives like strings, bools, etc?
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20180319/16f26d2e/attachment-0001
-----Original Message----- From: Pier Bover <pierbover11 at gmail.com> Sent: Monday, March 19, 2018 5:06 PM To: Isiah Meadows <isiahmeadows at gmail.com> Cc: Ron Buckton <Ron.Buckton at microsoft.com>; es-discuss <es- discuss at mozilla.org> Subject: Re: Pointers
So the proposal is basically having references to primitives like strings, bools, etc?
If you are talking about my proposal, then no. References wouldn't be limited to primitives, for example:
function tryGet(map, key, ref value) {
if (map.has(key)) {
value = map.get(key);
return true;
}
value = undefined;
return false;
}
const map = new Map();
map.set("a", { x: 1 });
let value;
console.log(tryGet(map, "a", ref value), value); // true { x: 1 }
console.log(tryGet(map, "b", ref value), value); // false undefined
Ron
Ron: Very interesting, in particular, the function arguments by reference aspect. Thanks.
Claude
This is basically what I was proposing, ironically enough. There's a
few small differences, but the only one that substantially varied from
mine I filed an issue in your repo against. (I almost went for
value
.)
BTW, yours looks a lot like OCaml's ref 'a
type, which is just
sugar for {mutable contents : 'a}
. The only difference is that OCaml
doesn't allow you to take a reference to a mutable property, while
yours does.
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
Ahh parameters by reference yes have wished for that...
ref is C#-ism to me... which also maybe 'out' which really isn't different in JS.... in C# it enforces that the value is set in the function receiving an out 'must give value to parameter'.
C# isn't the only OO language to have references. PHP has them too, although the awkwardness isn't the references themselves as much as how the language integrates with them. OCaml also has reified references as separate from their mutable record properties.
Note that C#'s "out" parameters aren't the same as what's being
proposed here. Ron's proposal shares more in common with Rust's foo: &mut Foo
parameters and C/C++'s &foo
(address-of) operator than
C#'s out
parameters, since the proposal doesn't restrict their use
to just parameters, and it doesn't just treat them as alternate return
targets. C# has those just for C interop and little else, while Rust
and OCaml have them for general use. If we're going to have
general-use references, let's not mimic C#'s very awkward mess when we
do it.
(JS is a much lower level language than it looks. It abstracts less than most other common dynamic languages.)
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
On Mon, Mar 19, 2018 at 6:01 PM, Isiah Meadows <isiahmeadows at gmail.com>
wrote:
C# isn't the only OO language to have references. PHP has them too, although the awkwardness isn't the references themselves as much as how the language integrates with them. OCaml also has reified references as separate from their mutable record properties.
Note that C#'s "out" parameters aren't the same as what's being proposed here. Ron's proposal shares more in common with Rust's
foo: &mut Foo
parameters and C/C++'s&foo
(address-of) operator than C#'sout
parameters, since the proposal doesn't restrict their use to just parameters, and it doesn't just treat them as alternate return targets. C# has those just for C interop and little else, while Rust and OCaml have them for general use. If we're going to have general-use references, let's not mimic C#'s very awkward mess when we do it.(JS is a much lower level language than it looks. It abstracts less than most other common dynamic languages.)
I didn't mean to stress 'out'. 'ref' was really the only thing I meant for a take-away.
other than in parameters, I don't see a use... I went back to the top and re-read with these new colored glasses...
var:prt is terrible; that would be a printer...or maybe part :) var:ptr; and since it's not a pointer, maybe ref instead?
what if the property is a setter/getter reference when getting a set/get property.
var x = { name : 'foo', get Name() { return name } set Name() { this.name = name }; }
var:ref getterRef = x.Name // retain both set and get?
var:ref xName = x.name;
(then changing either xName or x.name (or x.Name) to a new value
On Mon, Mar 19, 2018 at 6:17 PM, J Decker <d3ck0r at gmail.com> wrote:
On Mon, Mar 19, 2018 at 6:01 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
C# isn't the only OO language to have references. PHP has them too, although the awkwardness isn't the references themselves as much as how the language integrates with them. OCaml also has reified references as separate from their mutable record properties.
Note that C#'s "out" parameters aren't the same as what's being proposed here. Ron's proposal shares more in common with Rust's
foo: &mut Foo
parameters and C/C++'s&foo
(address-of) operator than C#'sout
parameters, since the proposal doesn't restrict their use to just parameters, and it doesn't just treat them as alternate return targets. C# has those just for C interop and little else, while Rust and OCaml have them for general use. If we're going to have general-use references, let's not mimic C#'s very awkward mess when we do it.(JS is a much lower level language than it looks. It abstracts less than most other common dynamic languages.)
I didn't mean to stress 'out'. 'ref' was really the only thing I meant for a take-away.
other than in parameters, I don't see a use... I went back to the top and re-read with these new colored glasses...
var:prt is terrible; that would be a printer...or maybe part :) var:ptr; and since it's not a pointer, maybe ref instead?
what if the property is a setter/getter reference when getting a set/get property.
var x = { name : 'foo', get Name() { return name } set Name() { this.name = name }; }
var:ref getterRef = x.Name // retain both set and get?
var:ref xName = x.name;
(then changing either xName or x.name (or x.Name) to a new value
and I meant to say you could keep references
var xNameRef = { obj : x, field : 'name' }
xNameRef.obj[xNameRef.field]
as a generic way of referencing anything. ...
There is a spec reference type. It was initially there for host objects, and IIRC, most were happy to see it go.
www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262, 3rd edition, December 1999.pdf
8.7 The Reference Type The internal Reference type is not a language data type.
It is defined by this specification purely for expository purposes. An implementation of ECMAScript must behave as if it produced and operated upon references in the manner described here. However, a value of type Reference is used only as an intermediate result of expression evaluation and cannot be stored as the value of a variable or property.
The Reference type is used to explain the behaviour of such operators as delete, typeof, and the assignment operators. For example, the left-hand operand of an assignment is expected to produce a reference. The behaviour of assignment could, instead, be explained entirely in terms of a case analysis on the syntactic form of the left-hand operand of an assignment operator, but for one difficulty: function calls are permitted to return references. This possibility is admitted purely for the sake of host objects. No builtin ECMAScript function defined by this specification returns a reference and there is no provision for a user-defined function to return a reference. (Another reason not to use a syntactic case analysis is that it would be lengthy and awkward, affecting many parts of the specification.)
Another use of the Reference type is to explain the determination of the this value for a function call. A Reference is a reference to a property of an object.
A Reference consists of two components, the base object and the property name.
The following abstract operations are used in this specification to access the components of references: • GetBase(V). Returns the base object component of the reference V. • GetPropertyName(V). Returns the property name component of the reference V.
The following abstract operations are used in this specification to operate on references:
www.ecma-international.org/ecma-262/#sec-reference-specification-type is the much reduced equivalent in the current draft. 6.2.4The Reference Specification Type
Trying to expose the reference specification type as an actual user manipulable type would have a lot of consequences, and would not actually address the local variable use case.
If your use case can be satisfied by objects like some syntactic sugar like { get content() { return x }, set content(v) { return x = v } } then you might find it easier asking for that instead of a new type.
It sounds like you'd like to have the with
statement back.
On Mon, Mar 19, 2018 at 8:47 PM, Sebastian Malton <sebastian at malton.name>
wrote:
a reference to the data which it has been assigned to but modifies also the original reference when modified.
const obj = {field: {name: {fullname: 'before'}}};
with (obj.field.name) {
console.log(fullname);
fullname = 'after';
}
console.log(obj.field.name.fullname);
Combined with(aProxy)
that pattern was able to do so much magic !!! ...
although I'm not sure it's a good idea to re-introduce it through
self-contained references.
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20180319/a8b53c91/attachment