Pointers

# Sebastian Malton (6 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20180319/a8b53c91/attachment

# Michael J. Ryan (6 years ago)

Please no, mutable objects are bad enough imho.

# Isiah Meadows (6 years ago)

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

# J Decker (6 years ago)

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.

# Ron Buckton (6 years ago)

-----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

# Isiah Meadows (6 years ago)

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

# Pier Bover (6 years ago)

So the proposal is basically having references to primitives like strings, bools, etc?

# Sebastian Malton (6 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20180319/16f26d2e/attachment-0001

# Ron Buckton (6 years ago)

-----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

# doodad-js Admin (6 years ago)

Ron: Very interesting, in particular, the function arguments by reference aspect. Thanks.

Claude

# Isiah Meadows (6 years ago)

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

# J Decker (6 years ago)

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'.

# Isiah Meadows (6 years ago)

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

# J Decker (6 years ago)

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#'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.)

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

# J Decker (6 years ago)

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#'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.)

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. ...

# Mike Samuel (6 years ago)

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.

# Andrea Giammarchi (6 years ago)

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.