March 24 meeting notes

Waldemar Horwat waldemar at
Thu Mar 24 16:54:59 PDT 2011

Here are my notes from today's meeting.



DaveH's presentation on using generators to write asynchronous code.

How do you compose generators?  yield*

Waldemar: Given yield*, writing base-case trivial generators that
don't yield becomes useful but its syntax is a problem.  Generators
should not be distinguished from functions by the presence of a yield
Cormack: Why can't yield* work on both generators and functions, doing
a type test?
Dave, Waldemar: Flattening using type testing like this leads to
trouble. What if the return type of the generator/function is a
Deferred issue about Next API throwing vs. multiple methods.

Moved generators to harmony

Proxy handler parameter:
Why not use "this"?  Crossing levels; interferes with inheritance of
handler object.

Brendan: delete doesn't need a receiver parameter because it only
works on own properties.  It will still get a proxy parameter.
Bug on Tom's slide: set needs a receiver parameter.  get and set need
a proxy parameter.

Completion values source statements are currently statically uncomputable:
eval("1; if (...) 2;") can produce a completion value of either 1 or 2
eval("1; while (...) 2;") ditto
Dave: Propose making the above examples return either 2 or undefined.
That fixes behavior for #-functions:
#(...) {1; if (...) 2;}
#(...) {1; while (...) 2;}

eval("3;;;") would still produce a completion value of 3, not undefined.

Refutable matching and switch extensions:
Multiple objections to syntax chosen for pattern-matching switch:
colon vs. no colon after default clause, need for blocks, etc.
Refutable matching doesn't retrofit into imperative switch syntax
Waldemar: Refutable matching is half-baked at this point, with too
many syntactic and semantic problems.  Not clear it's worth its added

The refutable matching wiki has the following consequences on
irrefutable matching:
Pattern [x,y]:
Matched to [3,4], produces x=3, y=4.
Matched to [3,4,5], produces x=3, y=4.
Matched to [3], produces x=undefined, y=undefined.  (wiki spec bug.)
Pattern [..., x, y]:
Matched to [3,4], produces x=3, y=4.
Matched to [3], looks up negative array indices.  (wiki spec bug.)

Pattern [x,y] behaves like [x,y,...] for refutable matching.  (wiki spec bug.)
Can't match on zero-length arrays. (wiki spec bug?)

Lucas: Feature value should overcome complexity costs.
Waldemar: if guards introduce unknown syntactic and semantic complexity
Waldemar: where can you use refutable matching outside of switch/match
statements and perhaps catch guards?  switch/match statements are too
heavyweight and differ too much from irrefutable matching assignment;
catching doesn't really need destructuring but benefits from
conditions.  The typical usage (as in Perl) is to use them in if
statements:  if (pattern =~ expr) {we have matched!}

catch({z,w} if z < w):  OK, but then you can't get to the entire
exception object from the catch clause.
catch(z if z instanceof T):  Useful

Waldemar: Refutable matching should integrate trademarking to be compelling.
Concern about backing ourselves into a corner by implementing
irrefutable pattern matching in catch guards that will later preclude
refutable matching.  Brendan's example:  catch({x, y}) would succeed
on {x:3} now but fail later if we change to refutable pattern

Alex, Erik: No longer support #-functions with a different semantics
from functions.
Brendan's proposal:
#(a,b) {a + b}  // Inherits "this" only lexically
#(this | a,b) {...}  // behaves like regular functions with respect to "this"
Alex: Make function objects soft-bind "this"
Dave, Waldemar, Brendan: Object to soft-binding "this".
Allen: We should respect the intent for "this" binding, as expressed
by whoever is defining the function (as opposed to whoever is calling
Alex: Debating soft-bind use case of users wanting to override "this"
in a function bound with Function.bind.
Waldemar: We're discussing raw closures here, not functions produced
by Function.bind.
Lively debate.

Discussion on what #(x | ...) would mean.  Brendan: it would bind "x"
instead of "this" with the caller-supplied this-value.  "this" would
then be unconditionally inherited from the enclosing scope.
#(self = this | a, b):  Default value for "self" is "this".
Waldemar:  Don't like defaulting here.  How would you call such a
function indirectly via Function.apply without supplying a value for
Cormack: Use | syntax for regular functions?
Luke: User confusion with two slightly different ways of doing the
same thing (function vs. #).  Users will then want to use #-functions
for constructors, etc.
Alex: How do you express functions in terms of #-functions?
If we do #-functions, does that eliminate the "const foo(x,y) {...}"
shorthand for const function definition syntax?  Brendan: Yes.
Alex: Willing to consider #-functions with a different semantics from functions.
Waldemar: Don't want implicit "return" of completion value in
#-functions due to leakage and inversion of behavior vs. functions.

To sort field names or not to sort:
Brendan, DaveH: Nor sorting may be cheaper
Waldemar: Don't like hidden state.  A canonical order such as sorting
(as currently on wiki) is much simpler conceptually. When specifying
behavior of various methods that create records, no need to be careful
about property order.
Philosophical discussion:  Can one make a language simpler by adding
features?  Yes, over the long term, if new simple features obviate old
complex features and people forget the old way of doing things.
DaveH:  Fear of Structured Clone between web-workers.
How does toString work on records?
Duplicate property names in #{p: v, p: v}? Error.
Duplicate property names between explicitly specified properties and
properties introduced by ... in #{p:v, ... rest}? ... wins?
=== is elementwise.

Brendan: Does anyone here really hate records and tuples?
Lucas: Likes dicts (mutable, but otherwise identical to records) in
preference to records.
Allen: Not much benefit to dicts over some way to provide null for the
Waldemar: No, a null prototype is not sufficient.  Even if you don't
have a prototype, in lots of contexts the language will still look for
a toString property in your object and call it if it finds it.  Thus
you're not safe using a null-prototype object to store arbitrarily
named properties.  Dicts or tuples avoid that problem because they're
a distinct primitive type.
Debate about weak vs. strong keys.
Dave: If you have a size-querying method, you can't have weak keys
without becoming nondeterministic.

More information about the es-discuss mailing list