rbuckton / proposal-refs

Ref declarations and expressions for ECMAScript
BSD 3-Clause "New" or "Revised" License
22 stars 0 forks source link

Refs questions and suggestions #1

Open ghost opened 7 years ago

ghost commented 7 years ago

I'm interseting. If I ref to object or array members, how I can to pass to old functions through spreads?

ref accessor = typecounters[0];
let index = Atomics.add(...accessor, 1); // it means [typecounters, 0]

Also, I suggest change behavior of ref.

  1. ref should refers to left value, not right value.
let objvar = object;
let objref = objvar;
ref leftref = objvar;

objvar = anotherObject;

// objref != objvar // because reference directly with object
// leftref == objvar // because left-value reference
rbuckton commented 6 years ago

Regarding your first example (updated to current syntax):

let ref accessor = typecounters[0];
let index = Atomics.add(...accessor, 1);

This would fail because accessor is a Reference type, and Reference does not have a Symbol.iterator method. A Reference is opaque with respect to its base value, you can't get back typecounters from accessor.

I'm not sure I understand your second point.

hax commented 4 years ago

I think what @ghost want could be something like

let accessor = ref typecounters[0]
let index = Atomics.add(...accessor, 1)

Aka, make ref expression create a Reference object with accessor[0] === typecounters and accessors[1] === '0'.

Theoretically it seems we could directly support using array:

const a = [1]
let ref a0 = [a, 0]

a0 // 1
++a0 // 2
a // [2]
rbuckton commented 4 years ago

I'm concerned that exposing the this binding could possibly leak sensitive internals and could be a security vulnerability when working with untrusted code in a sandbox. I do not believe the suggestion above is a viable option. However, if ref is added to the language, it could be feasible to have a variant of Atomics.add that can accept a ref to a typed array that could have privileged access to the underlying this binding, i.e. Atomics.add(ref typecounters[0], 1).

rbuckton commented 4 years ago

@ghost regarding your second point:

Also, I suggest change behavior of ref.

  1. ref should refers to left value, not right value.
    
    let objvar = object;
    let objref = objvar;
    ref leftref = objvar;

objvar = anotherObject;

// objref != objvar // because reference directly with object // leftref == objvar // because left-value reference

I disagree. There are multiple possible operations we need to be able to perform:

This results in a matrix of operations:

let x = a;         // `x` is a new binding with the value of `a`
let r = ref a;     // `r` is a new binding whose value is a `Reference` object referring to `a`.
let ref z = r;     // `z` is a new binding linked to the underlying binding of `r`.
let ref y = ref a; // `y` is a new binding linked to the same binding as `a`.

// also
ref z = r;         // `z` is linked to the underlying binding of the `Reference` `r`.
ref y = ref a;     // `y` linked to the same binding as `a`.

function f(ref p) {}
f(r); // parameter `p` in `f` is linked to the underlying binding of `r`.
f(ref a); // parameter `p` in `f` is linked to the same binding as `a`.

Therefore:

So your example above, following these rules, would be this:

let objvar = object;
let objref = objvar;
let ref leftref = ref objvar; // take reference to `objvar` and dereference it as `leftref`.

objvar = anotherObject;

// objref != objvar // because reference directly with object
// leftref == objvar // because left-value reference