On Oct 1, 2010, at 4:38 PM, Waldemar Horwat wrote:
> Here are my raw notes from our second day.
Thanks again for taking these. Best tc39 note taker. ever. still.
> Unique names
> Question: In what ways does this differ from weak tables?
> - A client can look up a property p using a[p] without knowing whether
> p is a traditional string or a unique name.
>
> Debate about private names leaking via proxies. It's trivial to get
> at private names by passing a proxy to code that accesses them.
>
> It's not clear what private names are trying to do well. If they want
> to provide privacy, they can't be visible to proxies. If they want to
> provide extension without collision (i.e. namespacing), they should be
> visible to Object.keys, enumeration, etc.
>
> Allen: private syntax is the primary usage of this proposal. Debate
> over whether there should be two independent concepts of scope or one
> with a flag.
I think Allen's position is more on the "unique name" rather than truly
"private name" side of the trade-off. FWIW.
> Brendan: list of questions:
> 1. Private for sure?
> No: unique name weak encapsulation
> Yes: Private name strong encapsulation
Perhaps we want both "unique n;" and "private n;".
> 2. Visible via for-in?
> Object.defineProperty
> Assignment via private
This bit included "either/or/both" with a dashed line, unlike the solid line
between the "No: ..." and "Yes: ..." alternatives to 1, above.
> 3. Visible via Object.keys/getOwnPropertyNames?
The answer here depends not on 2 but on 1: if private names are truly private,
then they don't leak via Object.keys/getOwnPropertyNames; else they do, and no
worries ("weak encapsulation", par for the JS course).
> MarkM: Desugar
> private n;
> x.n = ...
> x.n()
> into:
> const n = SoftField();
> n.set(x, ...);
> n.get(x).call(x);
>
> Analogously, desugar
> unique n;
> x.n = ... // Maybe make it nonenumerable by default?
> x.n()
> into:
> const n = Name();
> x[n] = ...
> x[n]()
>
> It's useful to view soft-fields as a kind of property names, but then
> have to address what happens on preventExtensions, freeze, etc. If
> you think of these private fields as properties then they should be
> subject to freezing and such.
If you don't think of these soft fields as private fields *on the object* (so
subject to preventExtensions etc.), then only inherited soft fields (not
private name objects) can handle this novel use-case.
> A proxy having the right to get at an object's private field names is
> equivalent to a proxy having the right to obtain all weak maps for
> which the object is the key. The security implications are the same.
> If a proxy can do a faithful membrane without one of these rights, it
> can do a faithful membrane without the other of these rights. If a
> proxy has no rights to get at an object's private field names, the
> membrane will still work as follows:
>
> proxy[name] does not trap
> object[proxy] calls a trap on the proxy
Good point -- need a new trap here? Or is this get with an object-type property
name?
be
> When a name object itself (not merely an object merely containing
> privately named fields) is passed through a membrane, the membrane
> wraps the name in a proxy p and then uses object[p] traps to maintain
> the membrane. Private names would be used completely on either the
> wet or dry side of the membrane, so they'd stay private. Public names
> that cross the membrane get proxied by the membrane.
>
>
> Binary data
>
> Given
> const Point2D = new StructType({ x: uint32, y: uint32 });
> const Color = new StructType({ r: uint8, g: uint8, b: uint8 });
> const Pixel = new StructType({ point: Point2D, color: Color });
> p = new Pixel({point: {x: 3, y:8}, color:{r: 100, g: 50, b: 0}});
>
> p.point.y returns the primitive integer 8
> p.point returns an alias (lvalue) to the Point2D substructure (block)
> of p. Modifying data visible via such aliasing is visible to all
> aliases.
>
> Debate over whether values such as 3.8 or -1 should be assignable to a
> uint32 field. Current proposal says no and provices a uint32(x)
> coercer method: uint32(-1) = 0xFFFFFFFF.
>
> Does calling p.point twice return block references that are === to
> each other? Dave says he's agnostic. Produced a bit of debate.
>
> Special updateRef feature to avoid creating lots of block wrapper
> objects (the blocks themselves are aliased so are less of an issue):
>
> var T = new StructType(...);
> var A = new ArrayType(T, 1000000);
> t = T.ref(); // allocate a homeless struct object
> for (i = 0; i < 1000000; i++) {
> t.updateRef(a, i); // no allocation of struct wrapper
> }
>
> Given this feature, it's no longer possible to be agnostic on ===.
> One can't make block references a === b if and only if a and b are
> aliases of the same block.
>
> One way out would be to have T.ref() return a separate updatable block
> type, while p.point or a[3] would produce nonupdatable block type
> objects. Nonupdatable block type objects would have the above natural
> definition of === and not support updateRef.
>
> The counterpoint to the above is the creation of two kinds of block
> types, similar to each other.
>
> Debated desire for having blocks inherit from Array.prototype.
> Debated desire for having some Array generic methods on blocks.
>
> Endianness is invisible to users except when using blocks for file
> i/o, in which case the routines doing the i/o will take a parameter
> specifying the endianness of the file and convert as needed.
>
> How does one represent variable-length strings?
>
> Why no character types for fixed-size arrays? Punted from proposal
> for time reasons for now, but are desirable.
>
> When using this for file i/o, handling of variable-length strings will
> become important. How to do this? No specific design, but some ideas
> are:
>
> Given struct {x: uint32, y: uint32, z: uint32, name: String}, an idea would
> be:
> string = new Layout({
> length: uint16,
> contents: function(me) {return new ArrayType(uint8, me.length)}
> });
> color = new Layout({
> x: uint32,
> y: uint32,
> z: uint32,
> name: string
> })
>
> How to store these in memory? One can't have a pointer to a string
> inside a block.
>
> int64's: Open issue. Reference semantics are annoying, but what's a
> realistic alternative?
> int128's? Those come up increasingly often in SSE programming.
>
> Waldemar: Reify uint64's as 4-char big endian strings and uint128's
> as 8-char big endian strings. A significant advantage is that these
> would have value semantics, and ==, ===, <, <=, etc. would all work
> correctly. Would need to call methods to do arithmetic or signed
> inequality comparisons on them.
>
> More debate about block ===. Reached consensus that two
> (nonupdatable) block references a and b should be === if and only if
> they are the same type and alias to the same data. Updatable block
> references will have separate rules.
>
>
> Discussion on the use of put vs. defineOwnProperty in the ES5 spec as
> they relate to proxies and library classes. Efficiency concerns with
> creating descriptors for defineOwnProperty. Most array classes turn
> out to use put for objects which can be proxied; the places where they
> use defineOwnProperties tend not to be proxyable because they're done
> on locally created Array objects.
>
> Can a proxied [[construct]] return a primitive? Yes.
>
>
> Brendan: How do we do feature detection and top-level patching in ES-harmony?
> if (!window.fooQuery)
> var fooQuery = ....
>
>
> let clarifications:
> let x and var x at same scope: error
> let x at top scope of a function or catch block with parameter x: error
> let x at script top leve: ok
> module M {
> export let x;
> }
> var binding that would hoist across a let binding: error
>
> let has a read barrier before the let statement gets executed:
> {
> let x = 1;
> if (x) {
> alert(x); // Read barrier error here because inner x hasn't been
> initialized yet
> let x = 2;
> }
> }
>
> {
> x = 42; // Write barrier error because x hasn't been initialized yet
> print(x);
> let x = 99;
> }
> Questions about whether
> let x;
> should be treated as:
> let x = undefined;
> so it has a barrier too. Could take either position on this one.
>
> Brendan: What if let and const don't hoist at all (as in C++ scoping)?
> This was Waldemar's position before the grand ES4 scoping compromise
> a few years ago.
>
> Mutually recursive example (wouldn't work with const without some extension):
> let f, g;
> f = function() {... g ...};
> g = function() {... f ...};
>
> Another alternative for mutual recursion:
> let [f, g] = [function() {... g ...}, function() {... f ...}];
>
> This assumes that f and g are visible in the initializer, which would
> bring the barrier issues back. Read barrier would be needed. Debate
> about whether write barrier would be needed, even if we have
> expressions for typed/guarded let.
>
>
> Discussion of pragma syntax:
> use bignums;
> use harmony;
> use modules {A, B, C};
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss