Re: Bytecode

2014-05-15 Thread K. Gadd
It's my understanding that the vast majority of the CLR's dynamic
language support is at the runtime level, not the bytecode level. The
bytecode is strongly typed (with lots of instructions/mechanisms for
boxing, unboxing and type casts), and dynamic support is done through
something called the 'DLR' that sits on top of the CLR. The DLR
provides machinery for things like late binding and inline caches.

For this C# snippet:
```
using System;

public static class Program {
public static void Main (string[] args) {
dynamic one = (Funcint)(
() = 1
);
dynamic doubleInt = (Funcint, int)(
(int x) = x * 2
);

Console.WriteLine({0} {1}, one(), doubleInt(1));
}
}
```

The desugared (well, decompiled from IL - the arg_XXX_X variables are
from the decompiler, not actually in the IL) C# looks like this:

```
public static void Main(string[] args)
{
object one = () = 1;
object doubleInt = (int x) = x * 2;
if (Program.Maino__SiteContainer0.p__Site1 == null)
{
Program.Maino__SiteContainer0.p__Site1 =
CallSiteActionCallSite, Type, string, object,
object.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded,
WriteLine, null, typeof(Program), new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType
| CSharpArgumentInfoFlags.IsStaticType, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType
| CSharpArgumentInfoFlags.Constant, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}));
}
ActionCallSite, Type, string, object, object arg_15C_0 =
Program.Maino__SiteContainer0.p__Site1.Target;
CallSite arg_15C_1 = Program.Maino__SiteContainer0.p__Site1;
Type arg_15C_2 = typeof(Console);
string arg_15C_3 = {0} {1};
if (Program.Maino__SiteContainer0.p__Site2 == null)
{
Program.Maino__SiteContainer0.p__Site2 =
CallSiteFuncCallSite, object,
object.Create(Binder.Invoke(CSharpBinderFlags.None, typeof(Program),
new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}));
}
object arg_15C_4 =
Program.Maino__SiteContainer0.p__Site2.Target(Program.Maino__SiteContainer0.p__Site2,
one);
if (Program.Maino__SiteContainer0.p__Site3 == null)
{
Program.Maino__SiteContainer0.p__Site3 =
CallSiteFuncCallSite, object, int,
object.Create(Binder.Invoke(CSharpBinderFlags.None, typeof(Program),
new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType
| CSharpArgumentInfoFlags.Constant, null)
}));
}
arg_15C_0(arg_15C_1, arg_15C_2, arg_15C_3, arg_15C_4,
Program.Maino__SiteContainer0.p__Site3.Target(Program.Maino__SiteContainer0.p__Site3,
doubleInt, 1));
}
```

So you can see all the inline cache and binding machinery at work
there. As far as I know there were 0 bytecode changes to introduce
this feature; I certainly didn't have to implement any special
bytecodes to support 'dynamic' in JSIL.

There are certainly some aspects of the CLR bytecode that make dynamic
languages easier/harder to build on top of it, though. I just don't
know what they are. I know a lot of the pain was reduced with the
addition of 'lightweight code generation' or LCG, which allows jitting
a single method on the fly and attaching it to a given context (like a
method) so that it can access private members. This is used heavily in
dynamic languages on the CLR now.

On Wed, May 14, 2014 at 10:54 PM, C. Scott Ananian
ecmascr...@cscott.net wrote:
 On Wed, May 14, 2014 at 9:12 PM, Axel Rauschmayer a...@rauschma.de wrote:

 It'd be great if there was material on the limits of the JVM and the CLR.
 AFAICT these are the only virtual machines that are trying to be universal
 (run both static and dynamic languages well).


 Well, from experience, the JVM is/was handicapped by some incidental
 decisions in its original standard library[*] that have a large adverse
 impact on startup time.  This has restricted the 'usefulness' of the JVM
 from its inception.  There are projects to re-engineer the standard library
 around this, but they have been slow (and are not yet complete)[**].
 Similarly, the support for dynamic languages is fairly recent (JDK 7,
 JavaScript implementation using these features in JDK 8), so it's a bit
 early to know how that will play out in terms of adoption and practical use.

 So I'm not sure how much you're going to learn from the JVM, other than no
 matter how good/bad your bytecode is, other factors may dominate.  That is:
 I would doubt most conclusions about bytecodes drawn from the example of the
 JVM, since I don't believe the bytecode design was a first order effect on
 its trajectory to date.

 

Re: Iterators, generators, finally, and scarce resources (Was: April 10 2014 Meeting Notes)

2014-04-29 Thread K. Gadd
Minor correction to Domenic's comments in this (interesting)
discussion; IEnumerable and IDisposable are separate concepts in C#.
Neither IEnumerable or IEnumerator are disposable objects in C#;
*however*, if you use 'for each' on an object that yields an
enumerator that is *also* disposable, the compiler-generated sugar for
the enumeration will dispose it.

This is an important distinction: As described in the discussion
thread here, not all enumerables and/or enumerators are disposable.
Many of them are not, and have zero cleanup logic, so there's no need
to include or call a Dispose method. That sugar support is explicitly
there for enumerators that, if disposed explicitly, can release
important resources earlier than the garbage collector would (file
handles, sockets, etc.)

On the other side (enumerator/enumerable authoring), C# solves this
rather lazily: You can use try/finally (but not try/catch) around a
'yield' in an enumerator function, allowing you to do basic cleanup -
the cleanup logic is moved into the compiler-generated object's
Dispose method. This means that if you want cleanup, you opt into it
explicitly, and use the same mechanism you use in normal
non-enumerator functions. There's one caveat that this causes
unexpected disposal behavior in some corner cases (due to how C#
initializes generators), but that's more of an issue with their
generator implementation than anything else.

On Tue, Apr 29, 2014 at 12:17 PM, Domenic Denicola
dome...@domenicdenicola.com wrote:
 Dave and Andy's responses have me pinging back and forth as to which side 
 I'm on. Both seem convincing. Dave's response especially brought the issue 
 into focus for me in a way that I think is clear, so let me explain what I 
 learned from it:

 What we are essentially talking about here are two types of things:

 - Disposable resources
 - Iterable resources

 We are talking about both the sync case, and the async case. Andy's 
 contention is that most sync iterable resources are not disposable, whereas 
 Dave's is that most async resources are disposable. Both of these positions 
 seem plausible to me.

 The question then comes, should for-of handle iterable resources only (as it 
 does today), or should it take care of disposable resources as well (as it 
 does in e.g. C#)?

 Andy's code example, viz.

 ```js
 var file = openFile(foo.txt);
 try {
   for (var line of lines(file)) {
 if (line == '-- mark --') {
   break;
 }
   }
 } finally {
   file.close();
 }
 ```

 advocates for this separation, putting the burden on the user to handle the 
 disposable part, letting for-of focus on the iterable aspect. Dave advocates 
 that this code become

 ```js
 for (var line of lines(openFile(foo.txt))) {
   if (line == '-- mark --') {
 break;
   }
 }
 ```

 and the disposableness be handled automatically, which is certainly more 
 convenient for the user.

 This second code example, however, hides two kinds of magic: iterability, and 
 disposability, in the same syntax.

 An alternative would be to introduce a construct specifically to handle 
 disposability, like C#'s `using`. You could use it generically such that 
 `using(x) { ... }` becomes `try { ... } finally { x.dispose(); }`. In 
 particular the example would become

 ```js
 using (var file = openFile(foo.txt)) {
   for (var line of lines(file)) {
 if (line == '-- mark --') {
   break;
 }
   }
 }
 ```

 This still isn't all that convenient, of course. And going along with Dave's 
 argument, it will become especially inconvenient when async iterables, most 
 of which will be disposable, start appearing. Perhaps this is why C# decided 
 to include both iterable and disposable functionality in their `foreach`.

 But inconvenience is easily solved via MOAR SUGAR:

 ```js
 for (var line using files) {
   if (line == '-- mark --') {
 break;
   }
 }
 ```

 I like this approach for a few reasons:

 - It decouples iterability and disposability, giving each distinct syntax 
 constructs
 - Via sugar, it composes them into something just as convenient as if we had 
 baked both of them into `for`-`of`, while giving you an explicit signal of 
 what's going on and what the different semantics are.
 - It of course avoids any optimization hazards, being opt-in.
 - Most importantly, it pushes off this question into ES7, when we can 
 properly design a counterpart `using` block to build on top of.

 The drawback of this approach is that it doesn't bake in a disposability 
 protocol into the language. By saying that `for`-`of` will invoke `return()`, 
 we are essentially saying if you want a disposable object, use the method 
 named `return()` to dispose of it. This kind of ecosystem standardization is 
 a good thing. But on the other hand, if in ES6 this disposability protocol is 
 only useful for synchronous iterators---which, as Dave admits, are less 
 likely to represent disposable resources than async ones---then it's unclear 
 that much is gained. I'd 

Re: setPrototypeOf vs obj.__proto__ assignment

2014-04-07 Thread K. Gadd
Is my understanding correct that __proto__/setPrototypeOf are still
required if you want to do things like that with instances of
Function? Or did Function's constructor finally get patched to let you
set a prototype?

On Mon, Apr 7, 2014 at 2:26 AM, David Bruant bruan...@gmail.com wrote:
 Le 07/04/2014 11:05, Andreas Rossberg a écrit :

 On 4 April 2014 19:49, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 __proto__ is there for legacy compatibility.
 setPrototypeOf should be preferred for new code

 For new code, neither should be used.

 yup.

 For new code, in most practical cases, people can use classextend including
 to subclass Array and Date where __proto__ used to be the only way.

 David

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Value Types as map keys in ES7

2014-04-06 Thread K. Gadd
I guess the analog for this in traditional JS 'Object' instances is
that when you use the [] operator, i.e. obj[valueObject], it actually
does obj[valueObject.toString()], so you can control the 'hashing
function' in a sense by overriding toString. It seems natural to want
something equivalent here, preferably not based on strings... (though
I don't know how people feel about exposing hash internals and saying
'your hash key needs to be an integer')

Map would certainly be far more useful if it had support for
customizable hashing, otherwise it's just a slightly faster
replacement for Objects with cleaner semantics. Maybe making it
possible to get the same value back using two different keys that
don't compare the same with === is against the purposes here, though.

On Sat, Apr 5, 2014 at 10:21 PM, Benjamin (Inglor) Gruenbaum
ing...@gmail.com wrote:
 I'd like to raise an issue with ES7 value objects with maps raised here:

 http://esdiscuss.org/topic/maps-with-object-keys

 To save you all time, let me sum things up:

 ES6 maps don't solve a particular (but common) issue for me - using compound
 objects as keys. I do a lot of statistical analysis and I need keys to be
 compound tuples or other values. This is currently not possible with ES6
 since map key equality is checked with `===` so it is always reference
 equality

 ES7 introduces value objects - which are really cool anyway. This allows for
 compound keys.which partially solves my issue because value keys are
 compared structurally with `===`.

 However, it does not let me index on partial information (described in my
 last commend on that issues). Since it is impossible to override `===` in
 value objects from what I understand - It would be impossible for me to use
 partial objects as keys.

 To illustrate, if for example I have a lot of 10 dim vectors, and I want to
 index them as keys based on their first two dimensions - it is impossible at
 the moment and I have to project them into their 2d counterparts which have
 no further use for me.

 Is this somehow addressed? I'm unsure where to look for answers. It seems
 natural to me to allow specifying a hashing function in the `Map`
 constructor (rather than on every type) to solve this particular (but again,
 rather common in code that does crunching) problem.

 Thanks,
 Benjamin

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Source maps (was: Multiline Strings)

2014-03-16 Thread K. Gadd
The accuracy of this aside, history shows that most of my users are
not satisfied by 'just debug the JS, it's fairly readable'. Maybe
emscripten, gwt, etc. users are more fluent in JS and don't mind
debugging it, but based on what I've seen, maybe not...

I do think it's important that source maps don't obscure what's
happening at the JS level, though - presumably all the modern
debuggers let you toggle them back off once they're loaded, so that's
satisfied?

-kg

On Sun, Mar 16, 2014 at 11:03 AM, Bill Frantz fra...@pwpconsult.com wrote:
 On 3/14/14 at 3:02 PM, fitz...@gmail.com (Nick Fitzgerald) wrote:

 I feel very strongly that users debugging their sources that were
 compiled to js should be able to set watch expressions and conditional
 breakpoints in their source language.


 My experience with debuggers says the while the vast majority of the time
 you want to be able to debug it in the language you wrote, sometimes you
 want to debug it in the language it broke in. Being able to look at the
 lower level language can clear up misconceptions about what a higher level
 construct means. It can also reveal compiler bugs.

 It should also be recognized that all compiled programs break in machine
 language. :-)

 Cheers - Bill

 ---
 Bill Frantz| Concurrency is hard. 12 out  | Periwinkle
 (408)356-8506  | 10 programmers get it wrong. | 16345 Englewood Ave
 www.pwpconsult.com |- Jeff Frantz | Los Gatos, CA 95032


 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Source maps (was: Multiline Strings)

2014-03-12 Thread K. Gadd
I agree that the current source maps format does a poor job of
handling many translation/transpiling/js-as-compilation-target
scenarios. I do think it is worthwhile to try and build on the
existing format instead of reinvent it or significantly overhaul it,
though. The things it does, it does a pretty decent job of [1], and it
seems to be composable, so you can update your source map at each
stage in your JS build pipeline. It just needs to do a good job of
mapping other things like scopes, stack frames, etc.

I'll also point out that the current proposal (rev 3, as linked) is
very opaque, and despite multiple readings I failed to understand core
features until someone explained them to me. Even now, I can't really
tell how variable name mapping is accomplished with the current
proposal, and VLQ is barely understandable. A clearer description of
the spec would probably make it much easier for people to generate
usable source maps or write software that uses them.

My particular projects would definitely benefit greatly from a usable
version of the source maps spec, so I would love to help contribute to
the process of improving them. I have not seen any obvious way to
contribute in the past as the format seems to have been the result of
private development at Google and/or Mozilla. I do applaud the
original developers' attempts to keep the spec narrowly focused in
terms of what problems it solves and how it solves them.

-kg

[1] One exception to this: Dear god, why are the mappings a giant
string full of oddly-encoded variable-length data represented as
base64? I cannot imagine a worse format. This fails on multiple
counts:

a) I can't see any way to efficiently stream in this data; you have to
parse it all at once (especially since it's JSON)
b) You have to perform multiple passes on this data to make sense of
it, unless you create a customized parser: First you have to parse the
JSON, then you have to parse the mapping string to find the split
points (the semicolons), and then once you've done that you have to
undo the weird base64+VLQ encoding to get actual integers that you can
use as an internal representation. The third step can be deferred, at
least.
c) The fact that the data is all in one big chunk (even if it is
condensed) means that you have to generate it all at once and load it
all at once. That seems intrinsically awful for large source files and
it increases memory demands on each stage of your compilation pipeline
(this may be a big issue given that compilation can already be really
demanding on memory.)

The alternate 'sections' format seems to address some of this, but it
is not clear if it addresses all of it. It is unclear to me why
mappings is a single string instead of an array of smaller strings. In
all honesty, I think this entire format could be replaced with a
considerably simpler protobuf-based format, and all the
parsing/generation code could be automatically generated by the tools
that handle protobuf formats. It would be a win for everyone (but then
we'd have to figure out a way to roll the new format out; yck.)
JSON + base64 is simply not appropriate for a file format that will
largely be handled by JS *runtimes* and debuggers with significant
performance and memory concerns.

On Wed, Mar 12, 2014 at 2:00 PM, Nick Fitzgerald fitz...@gmail.com wrote:
 4) Browsers are still all over the place in how they report Error stack 
 trace information.

 We (Firefox Developer Tools) purposefully don't expose source mapped
 stacks to the web because it would require adding some kind of API to
 know when source maps are done being fetched or blocking(!) on
 Error.prototype.stack until the source map is fetched. We also avoid
 fetching source maps unless the debugger is open, so this would expose
 to the web if the debugger is open. Furthermore, we wouldn't want to
 only have the source mapped stack, you would also want the plain JS
 stack if you think that the source map could be bogus or if you are
 debugging the source maps you are generating as a tool author. This
 would further complicate the stack string.

 1) There is not yet a standard for sourcemaps. But see 
 https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k,
 https://developers.google.com/chrome-developer-tools/docs/javascript-debugging#source-maps,
 and https://github.com/mozilla/source-map/. Would someone care to champion 
 this for inclusion
 in ES7?

 If a debug format for targeting JavaScript were to be standardized, it
 should do more than simply file/line/column translation. My thoughts
 on this subject outgrew an email reply, so I have collected them here:
  http://fitzgeraldnick.com/weblog/55/

 _Nick_
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org

Re: Typed Objects / Binary Data Polyfills

2013-11-18 Thread K. Gadd
(Re: minor off-list clarification on non-transparent objects)

I see, it looks like this is the relevant bit of the strawman:

There are three built-in types that are considered *opaque*: Object, string,
and Any. For security, they are not allowed to expose their internal
storage since they may contain pointers (see below). A struct or array type
is opaque if it contains opaque fields or elements, respectively.

A type that is not opaque is *transparent*.
Overlooked it on my first read-through since it isn't directly referenced
elsewhere. That seems like it addresses the problem.


Looking at the strawman and the polyfill and the spidermonkey
implementation, each one seems to have a different API for arrays. Is this
something that will get standardized later? I've seen get, getItem and []
as 3 different ways to read values out of a typed object array; [] seems
like an obvious poor choice in terms of being able to polyfill, but I can
see how end users would also want typed object arrays to act like actual
arrays.

The spidermonkey implementation seems to expose 'fieldNames' in addition to
fieldOffsets/fieldTypes for reflection, which seems like a good idea.


If DataView were to also get optimized in SpiderMonkey, that would release
a lot of the pressure (use-case wise) for Typed Objects to expose
fine-grained control over alignment/padding and it would make it less
immediately necessary for them to exist. That's probably a good thing.


What is the intended use scenario when trying to pass a typed object array
to WebGL? Pass the array's .buffer where a typed array would normally be
passed? Or is it basically required that WebGL be updated to accept typed
object arrays? It's not totally clear to me whether this will work or if
it's already been figured out.


The elementType property on typed object arrays is a great addition; I'd
suggest that normal typed arrays also be updated to expose an elementType.
i.e. (new Uint8Array()).elementType === TypedObject.uint8



On Mon, Nov 18, 2013 at 2:35 AM, Dmitry Lomov dslo...@chromium.org wrote:

 We definitely are looking for feedback on the proposal! Please keep it
 coming.
 Here are some answers reflecting our current thinking.


 On Sun, Nov 17, 2013 at 4:07 PM, K. Gadd k...@luminance.org wrote:

 Since the strawman is close to the final spec, questions/nitpicks:

 I noticed the current spec explicitly provides no control over element
 alignment/padding. Are there specific reasons behind that? It dramatically
 reduces the value of typed objects for doing file I/O (aside from the
 endianness problem, which actually doesn't matter in many of those cases),
 and it means they can't be used to provide direct compatibility with C
 struct layouts in specific cases - for example, filling vertex buffers. I
 understand that there is no desire to provide the *full* feature set
 available in C (fixed-size arrays, variable-size structs, etc.) but
 alignment/padding control is used quite a bit.

 DataView has significant performance issues (some due to immature
 v8/spidermonkey implementations, some due to the design) that make it
 unsuitable for most of these use cases, even if it's the 'right' way to
 handle endianness (disputable).

 The handwaving that WebGL implementations can 'just introspect' in these
 cases seems shortsighted considering the reality of WebGL: hundreds of
 shipped libraries and apps using current WebGL cannot be guaranteed to keep
 doing the right thing when interacting with typed arrays. If a typed array
 full of Typed Objects can still be treated like an array full of bytes or
 float32s, that allows existing WebGL code to keep working, as long as you
 ensure the layout of the objects is correct. That means people can start
 incrementally adding uses of Typed Objects to their code right away - and
 it means they can introduce them based on a polyfill of Typed Objects
 instead of waiting for the browser to implement *both* Typed Objects and
 new WebGL support for Typed Objects.


 The idea for alignment/padding is to _specify_ it for typed objects. There
 is a rule that tell the user how the typed object will be aligned and that
 rule is set in stone. If the programmer declares a typed object, she/he
 knows what the memory layout is. However, we do not (at least in the first
 version) provide any explicit API for changing the alignment.

 The rule is Each field is padded to reside at a byte offset that is a
 multiple of the field type’s byte alignment (specified below via the
 [[ByteAlignment]] internal property). The struct type’s byte length is
 padded to be a multiple of the largest byte alignment of any of its
 fields.  So every field is at its natural boundary, and the natural
 boundary of the struct is the largest of the natural boundaries of its
 field types. This rule is pretty much what C compilers do anyway.

 This appears to us a good compromise between API and implementation
 complexity and expressiveness.

 BTW, DataView are indeed

Typed Objects / Binary Data Polyfills

2013-11-17 Thread K. Gadd
Are there any known-good polyfills for the current draft Typed Objects /
Binary Data spec?

Presently, JSIL has a set of primitives that roughly correspond with a big
chunk of the draft specification. I'm interested in seeing whether they can
work atop ES6 typed objects, which means either adapting it to sit on top
of an existing polyfill, or turning my primitives into a polyfill for the
draft spec. If it's useful I might be able to find time for the latter -
would having a polyfill like that be useful (assuming a good one doesn't
already exist)?

Having an efficient equivalent to the spec in JS VMs is pretty important
for JSIL to ever be able to deliver emscripten-level performance (a single
emscripten-style fake heap is not an option because .NET relies on garbage
collection). If a polyfill (even a partial one) could help move the process
along for the spec, that'd be great. If what the process actually needs is
some sort of feedback, maybe I could offer that instead. The status of the
spec is unclear to me :)

-kg
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Typed Objects / Binary Data Polyfills

2013-11-17 Thread K. Gadd
Since the strawman is close to the final spec, questions/nitpicks:

I noticed the current spec explicitly provides no control over element
alignment/padding. Are there specific reasons behind that? It dramatically
reduces the value of typed objects for doing file I/O (aside from the
endianness problem, which actually doesn't matter in many of those cases),
and it means they can't be used to provide direct compatibility with C
struct layouts in specific cases - for example, filling vertex buffers. I
understand that there is no desire to provide the *full* feature set
available in C (fixed-size arrays, variable-size structs, etc.) but
alignment/padding control is used quite a bit.

DataView has significant performance issues (some due to immature
v8/spidermonkey implementations, some due to the design) that make it
unsuitable for most of these use cases, even if it's the 'right' way to
handle endianness (disputable).

The handwaving that WebGL implementations can 'just introspect' in these
cases seems shortsighted considering the reality of WebGL: hundreds of
shipped libraries and apps using current WebGL cannot be guaranteed to keep
doing the right thing when interacting with typed arrays. If a typed array
full of Typed Objects can still be treated like an array full of bytes or
float32s, that allows existing WebGL code to keep working, as long as you
ensure the layout of the objects is correct. That means people can start
incrementally adding uses of Typed Objects to their code right away - and
it means they can introduce them based on a polyfill of Typed Objects
instead of waiting for the browser to implement *both* Typed Objects and
new WebGL support for Typed Objects.

My primitives have control over alignment/padding and it doesn't seem to be
that hard to implement (in JS, that is) - are there things that make this
hard to provide from inside a VM? Being able to add extra padding, at
least, would be pretty useful even if alignment has to remain locked to
whatever the requirements are.

I see reference types are exposed (string, object, any) - the way this
actually works needs to be clearly stated. Is it storing a GC pointer into
the buffer? Are there safety concerns if it's overwritten, or loaded from a
json blob or something else like that? How big are string/object/any in the
internal representation? Does their size depend on whether the running
browser is 32-bit or 64-bit?

I'd be open to collaborating on a polyfill of Typed Objects once it's clear
how they actually work. We can repurpose JSIL's existing implementation and
modify it to get the semantics in the spec.


On Sun, Nov 17, 2013 at 5:04 AM, Till Schneidereit 
t...@tillschneidereit.net wrote:

 On Sun, Nov 17, 2013 at 10:23 AM, K. Gadd k...@luminance.org wrote:

 Are there any known-good polyfills for the current draft Typed Objects /
 Binary Data spec?


 I want this, too, and will start working on it soon-ish if nobody else
 does or already did.


 Presently, JSIL has a set of primitives that roughly correspond with a
 big chunk of the draft specification. I'm interested in seeing whether they
 can work atop ES6 typed objects, which means either adapting it to sit on
 top of an existing polyfill, or turning my primitives into a polyfill for
 the draft spec. If it's useful I might be able to find time for the latter
 - would having a polyfill like that be useful (assuming a good one doesn't
 already exist)?

 Having an efficient equivalent to the spec in JS VMs is pretty important
 for JSIL to ever be able to deliver emscripten-level performance (a single
 emscripten-style fake heap is not an option because .NET relies on garbage
 collection). If a polyfill (even a partial one) could help move the process
 along for the spec, that'd be great. If what the process actually needs is
 some sort of feedback, maybe I could offer that instead. The status of the
 spec is unclear to me :)


 The strawman at [1] is fairly close to what's going to end up in the spec,
 content-wise. Additionally, the implementation in SpiderMonkey is pretty
 complete by now, and there are lots of tests[2]. I don't know what the
 timing for integrating Typed Objects into the spec proper is, cc'ing Niko
 for that.


 cheers,
 till


 [1]: http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects
 [2]:
 http://mxr.mozilla.org/mozilla-central/source/js/src/tests/ecma_6/TypedObject/

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Weak callbacks?

2013-11-12 Thread K. Gadd
Finding out at runtime (by doing a sanity check in the finalizer) is a way
to catch bugs in the application that were not caught at
compile/development time, so you can log/report them and go back and fix
them. This is an incredibly useful facility since (generally speaking)
promise libraries have lots of opportunities for human mistakes to hide
failures at runtime. When you have error handlers written properly for
something like 95% of your promises, catching the other 5% when they rarely
fail gets pretty complicated. Consider how a developer testing out some
network code might only ever run the application in the office, so they'll
never see the kind of exceptions you get when running an application over a
modem. Getting useful diagnostic information when one of those rare
exceptions isn't handled correctly lets you fix those problems without
being able to necessarily reproduce them on demand.

On Tue, Nov 12, 2013 at 8:07 PM, David Bruant bruan...@gmail.com wrote:

 Le 12/11/2013 13:42, Kris Kowal a écrit :

  One of the concerns with promises is that they consume exceptions that
 may or may not be handled. I have been looking forward for WeakRef as one
 of the avenues available to mitigate this problem. A post-mortem finalizer
 would be able to surface an error that was trapped by a promise or promises
 that were eventually garbage collected, and therefore provably
 never-to-be-handled.

 It is true that this problem can be decisively mitigated in other ways,
 like requiring a promise to forward to a terminal done() in the same turn
 of the event loop, but I find this particular solution unpalatable. I do
 find a promise inspector compelling, one that will show an error until it
 is handled, but even in this case, I think it is compelling to visually
 elevate an unhandled error to a provably never-to-be-handled error, and
 this is not possible, at least outside chrome-space, without WeakRef.

 I understand the need to know when a promise has an unhandled error at
 development time, I'm less clear on why you need to know it at runtime. Why
 would you do with this information? handle the error?
 If you think of wrapping promises in weakrefs, why not just add error
 handling?
 To me, it looks like the same amount of effort.

 David

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: an idea for replacing arguments.length

2013-11-10 Thread K. Gadd
Dispatching entirely off argument types and not anything else (like count)
is an interesting idea. I'm not sure it's on topic for this discussion
though. Is there a way to actually do type dispatch in ES at present, let
alone efficiently?

Based on my understanding of current VMs, you'd have to do a song and dance
(per argument) like this:
Is it undefined? Terminate argument scanning.
Check typeof to see if it is a special type; dispatch based on that if so.
If it's not a special type, check to see if it's null. If so, dispatch
based on 'object' since you can't know more about the type than that and
have to guess.
If it's not null, call Object.getPrototypeOf and then somehow look up that
prototype against the type information you're doing overload dispatch
against.

It's not clear to me how this would interact with newish features like
proxies, either, but I suppose it would at least work. At present doing
fast dispatch based on argument count and THEN only doing per-argument type
checks if necessary is a huge performance boost because VMs can actually
generate relatively fast native code for an arguments.length check. Typeof
checks and getPrototypeOf do not generally produce fast code in my
experience so it would be problematic to do them for every overloaded call
site instead of just call sites that actually care about the types of
particular arguments. Doing this type of dispatch is comparatively simple
in .NET since for any non-null value you can request a Type object for it
(via GetType) and then use that as a key into a lookup table/dictionary -
so the operation becomes 'if (x == null) typeId = 0 else typeId =
typeTable[x.getType()]' or something along those lines, which you can
optimize down to a set of conditionals when the number of types you care
about is small. The fact that ES does not allow setting properties on all
values means it's impossible to hang type information off values like that.

To put it another way, if I have an overloaded functions with two
signatures - like say writeline(s) and writeline(f, s) - then in practice I
just dispatch off the argument count. Because there are not multiple
signatures with the same count, there's no way the user could have intended
to call something else. In use cases where correctness is more important,
you'd probably want to rigorously check every argument and dispatch off
that.

From a performance perspective I also find the idea of having to 'scan' the
arguments list sequentially looking for an undefined sentinel to be pretty
gross. Do we really need to introduce the awful null terminated string
pattern, along with all its problems, in more places?

On Sun, Nov 10, 2013 at 1:49 PM, Mark S. Miller erig...@google.com wrote:

 On Sun, Nov 10, 2013 at 1:30 PM, K. Gadd k...@luminance.org wrote:

 JSIL and embind both need arguments.length for efficient method call
 dispatch when dealing with overloaded functions. Is it your intent that all
 such scenarios must now pay the cost of creating an array (to hold the rest
 arguments) and then destructuring it, for every call? At present it's
 possible to avoid this overhead in V8 and SpiderMonkey by using
 arguments.length + arguments[n] or by using arguments.length + patterned
 argument names.


 Hi Katelyn,

 No one is taking arguments away. Perhaps we would if we could but we
 can't. So as I said just now to Allen, if you really need to do this, go
 ahead and use arguments.length.

 But do you really need to do this? Assuming for a moment that we were all
 agreed that the best practice is to treat absence the same as undefined,
 why not go with the best practice and be done?





 On Sun, Nov 10, 2013 at 1:24 PM, David Bruant bruan...@gmail.com wrote:

 Le 10/11/2013 22:19, Brendan Eich a écrit :

  On Nov 10, 2013, at 9:12 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 Not sure why this is so needed though.

 Allen's posts make the case: webidl and varargs-style functions. Not
 all legacy.

 WebIDL creates spec, not code. The language syntax doesn't need to
 evolve for that. Allen showed that rest params+destructuring allows
 self-hosting without |arguments|
 Varargs functions have rest parameters.

 David

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss



 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




 --
 Cheers,
 --MarkM

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Weak callbacks?

2013-11-08 Thread K. Gadd
More tooling is great for developing new software in ES, but it does
nothing to address use cases where existing software and algorithms can't
be ported without Weak References. Perhaps enough research will allow us to
arrive at some sort of general 'best practice' for replacing the use of
weak references with something else; sounds like something some people with
PhDs could write a paper on :)


On Fri, Nov 8, 2013 at 8:57 AM, David Bruant bruan...@gmail.com wrote:

 Le 08/11/2013 17:09, Jason Orendorff a écrit :

  (As a bonus, the weirdness will happen in one implementation and not
 another, and you and your users will blame the implementation. So
 there will be pressure on implementers to reduce the nondeterminism by
 doing GC more frequently—which trades off against other performance
 measures.)

 Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging)
 https://en.wikipedia.org/wiki/Heisenbug


  And in this case, it all seems unnecessary. There is apparently
 already explicit code for both removing B and C, and later coping with
 their disappearance (since the weak reference may go null). That code
 could just as easily set a bit on B and C marking them as removed, and
 then test that in the chasing code.

 Agreed. In a way, Kevin conceded it when he wrote in an earlier message:

  I had to manually remove the event listeners at an appropriate time (and
 finding an appropriate time can be difficult!)

 And this looks very much like a software engineering issue, not a language
 issue. Maybe we (JavaScript developers!) should invest in better memory
 tooling see how far it gets us. We have fantastic tooling for studying time
 perf (Chrome has 2 types of profilers and the timeline view to help with
 the 60fps, Firefox and IE11 getting there too), how come we're still doing
 low-level heap snapshots for memory perf? Is space fundamentally that much
 harder to study than time?

 Taking the tooling road first, worst case, we throw the tooling away...
 not an option when a feature is in the wild.

 Let's try at least?

 David

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Weak callbacks?

2013-11-08 Thread K. Gadd
The difference is that if the large cycle is only uncollected because the
weak references haven't been zapped, in a low memory/out of memory
situation, the runtime's collector can go through and zap all weak
references. If I write an ES application and do my own cycle
collection/weak reference zapping, I have no way to respond to that low/out
of memory situation by doing a collection on demand, so instead my
application will run out of memory at arbitrary points in time.

The latency is not actually a major concern here, and I wouldn't argue that
weak references improve on latency. Weak references make it *possible* for
the language's collector to collect those cycles *at all*. Without them,
the only way they can be collected is if the *application* collects them,
and it has no trivial way to do so at the correct time.

I can't comment on how weak references would work in an ES collector
either, but I can imagine weak reference implementations that would not
prevent collection in the first place, so zapping would not be necessary in
order for those cycles to be collected. IIRC, some weak reference
implementations work by having the strong object maintain a list of the
weak references that point to it, and the weak references do not actually
keep the strong object alive. In such a scenario, you would not need to zap
references for the object to be collected; rather, collecting the object
would replace all the weak references with null, thus ensuring that the
dead object stays unreachable.

On Fri, Nov 8, 2013 at 2:42 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Nov 7, 2013, at 3:16 PM, Mark Miller wrote:

 I agree. This is a good use for weakrefs without the need for
 finalization. Thanks!


 On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.org wrote:

 The problem is that the cycles remain uncollectable for a very long
 period of time, even though functionally the references don't need to be
 strong.


 Ah, these are all basically the same problem and you will likely see the
 same latency effects for all of them.  Any GC design where you may have
 serious latency for collection cyclic structures (for example, a
 generational heap where the circular structure crosses generations) is very
 likely to also have similar latency for zapping weak references that are
 used in the similarly shaped data structures.

 Allen

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Weak callbacks?

2013-11-07 Thread K. Gadd
When I talk about the importance of weak references I am *not* talking
about the importance of finalization for managing native/remote resources;
that's an important consideration but it's a separate one. When I talk
about why weak references are important, I mean for the purposes of
building large applications without creating uncollectable cycles in object
graphs. Doing this without weak references is *very* difficult in some
scenarios, and in other scenarios requires manual management of all object
lifetimes (addref/release style, or having a single lifetime owner that
'deletes' an object on demand).

That's the sort of obstacle that factors into a developer's choice of
language and toolset. I've seen this particular concern with ES crop up in
the past on real projects, and I've seen firsthand how difficult it is to
avoid uncollectable cycles in a language environment without any sort of
weak reference mechanism. Leaking large uncollectable cycles can have
catastrophic consequences in multimedia applications and games, where those
cycles might be retaining images or sounds or other huge game assets.

On Thu, Nov 7, 2013 at 9:19 AM, Terrence Cole tc...@mozilla.com wrote:

 On 11/06/2013 07:37 PM, K. Gadd wrote:
  Generally speaking, all the discussions on this list about WRs so far
 have
  not suggested that there is any way to introduce WeakRefs without making
 GC
  behavior observable in some fashion. WeakRefs functionally make GC
  observable because when you try to get at the target of the weakref, you
  either get it or you don't. Once you introduce the ability to get back
  'null' when asking for the target of a WR (or any similar failure case),
  you can use that to determine things about GC behavior.
 
  If you somehow eliminate this weakness, WRs no longer solve the problems
  they are intended to solve. Or at the least, they solve only a small
  reduced subset of the problems solved in real software via the use of
 weak
  references. Being able to access the target of the WR (and have this
  operation fail) is core to their value (even if finalization
 notifications
  are also used quite often).
 
  I've already argued in the past about why weak references are important,
  and why not having solutions for those problems will kneecap the
  development of web applications by either preventing certain types of
  software from running in the browser, or forcing implementers to write
  their own GCs (or entire runtime environments) inside the browser, as is
  done with environments like emscripten and native client. Once that
 becomes
  the solution, the ES spec is irrelevant for those applications because
 they
  have had to abandon the language. While the risk of something like this
  happening is still relatively low, the risk increases over time as more
  people begin seriously considering solutions like emscripten and nacl -
  we're starting to see companies ship real products using them already. If
  this spreads to popular reusable libraries (physics libraries, rendering
  libraries, etc), there's a risk that those libraries will pull new
  applications out of the ES realm because it's not possible to use those
  libraries without abandoning ES in favor of a custom GC/runtime
 environment.
 
  Based on the conversations thus far, a choice just has to be made between
  the two downsides: exposing some amount of GC internals, or making it
  impossible to write some subset of applications in ES. It's possible that
  exposing GC semantics has such catastrophic security consequences that
  ruling those applications out is merited. It's also possible that
  workarounds can be applied to reduce the harm of GC visibility (I think
 in
  the past someone - maybe Mark? - suggested that disabling cross-realm WRs
  would mitigate the damage considerably?)

 This is a false dichotomy. At the extreme, we could simply ship a new
 builtin resource manager which has it's own GC behaviour that we can
 expose at will. Given that the sorts of resources that people want to
 use the memory GC to manage generally have very different cost and
 volume tradeoffs than memory [1], this is actually much more reasonable
 than it sounds.

 The real problem with weak things is that they do have a performance
 impact on the GC, even when not used. Missing weak-maps can at least be
 worked around; a slow environment cannot.

 -Terrence

 1 -

 http://www.mail-archive.com/dev-tech-js-engine-internals@lists.mozilla.org/msg00572.html

  On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote:
 
  On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com
 wrote:
 
 
 
 
  On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola 
  dome...@domenicdenicola.com wrote:
 
  Thanks Mark for the education, especially on the pre- vs. post-morterm
  finalization distinction. I don't think I was specifically advocating
 for
  pre-mortem in my OP, since I didn't really understand the difference
 :P.
  Post-mortem finalization

Re: Weak callbacks?

2013-11-07 Thread K. Gadd
I'll try and restate an example I used before.

Let's say you're building a somewhat simple tab-based application, where
each tab represents a different 'mode'. In this case, you need a higher
level coordinating object that manages the tab bar, and it needs to own
references to all of the active modes in order to manage the tabs.
Similarly, each mode may need to have a reference to the coordinator in
order to interact with it - like by setting the title of the tab, or
opening a new tab containing another mode - and it may need to have
references to other modes in order to communicate (like if one tab opens a
tab containing related information).

In a model like that, you can trivially end up with object cycles. All the
references (going in every direction) are strong, so to successfully
collect a mode you need to ensure that every reference to it from live
objects is released. This is problematic because it means that, for example:

If Mode A opens a new tab containing Mode B, and Mode A wants to respond to
things happening in Mode B, Mode A now has to register some sort of event
listener on Mode B. This means that Mode A and Mode B have now formed a
strong cycle: Mode B's event listener list contains a strong reference to
Mode A (to fire the event notification), and Mode A has a strong reference
to Mode B in order to be able to respond to those events.

Now, if you close Mode B, the coordinator gets rid of the tab and drops its
strong references to Mode B - the tab is 'gone' - but there's no trivial
way to ensure that everyone else holding a reference to it is dead. If
multiple tabs interact in this way it's possible for a huge graph of
objects to be hanging off one live tab. Eventually, if you close enough
tabs you might 'free' the graph, but if you aren't careful the coordinator
itself can end up keeping dead tabs alive, with things like event listener
lists.

In the real apps I've worked on like this, the solution was some form of
weak references - making event listeners own weak self-references instead
of strong self-references, so that in normal circumstances event
subscriptions expire along with the subscriber, along with using weak
references directly in cases like 'tab a spawns tab b' in order to ensure
that you aren't keeping an object alive just to monitor it.

IIRC, cycles like this are already common in some DOM scenarios, where
event subscription and such result in big graphs of objects hanging off a
single live object? I've certainly run into it in a few cases, where an
event listener hanging off an audio element caused a huge graph of
objects to leak, and I had to manually remove the event listeners at an
appropriate time (and finding an appropriate time can be difficult!)


On Thu, Nov 7, 2013 at 2:33 PM, Mark S. Miller erig...@google.com wrote:

 Could you give an example, hopefully simple, of such a problem you can
 solve better with GC + weakmaps + weakrefs but without finalization, vs
 just GC + weakmaps ? Thanks.


 On Thu, Nov 7, 2013 at 1:46 PM, K. Gadd k...@luminance.org wrote:

 When I talk about the importance of weak references I am *not* talking
 about the importance of finalization for managing native/remote resources;
 that's an important consideration but it's a separate one. When I talk
 about why weak references are important, I mean for the purposes of
 building large applications without creating uncollectable cycles in object
 graphs. Doing this without weak references is *very* difficult in some
 scenarios, and in other scenarios requires manual management of all object
 lifetimes (addref/release style, or having a single lifetime owner that
 'deletes' an object on demand).

 That's the sort of obstacle that factors into a developer's choice of
 language and toolset. I've seen this particular concern with ES crop up in
 the past on real projects, and I've seen firsthand how difficult it is to
 avoid uncollectable cycles in a language environment without any sort of
 weak reference mechanism. Leaking large uncollectable cycles can have
 catastrophic consequences in multimedia applications and games, where those
 cycles might be retaining images or sounds or other huge game assets.


 On Thu, Nov 7, 2013 at 9:19 AM, Terrence Cole tc...@mozilla.com wrote:

 On 11/06/2013 07:37 PM, K. Gadd wrote:
  Generally speaking, all the discussions on this list about WRs so far
 have
  not suggested that there is any way to introduce WeakRefs without
 making GC
  behavior observable in some fashion. WeakRefs functionally make GC
  observable because when you try to get at the target of the weakref,
 you
  either get it or you don't. Once you introduce the ability to get back
  'null' when asking for the target of a WR (or any similar failure
 case),
  you can use that to determine things about GC behavior.
 
  If you somehow eliminate this weakness, WRs no longer solve the
 problems
  they are intended to solve. Or at the least, they solve only a small
  reduced subset

Re: Weak callbacks?

2013-11-07 Thread K. Gadd
I am not aware of any way to implement my described scenario using WeakMaps
without having the same cycle collection issues. I haven't seen any
examples of WeakMap used for this in the wild either.

On Thu, Nov 7, 2013 at 2:48 PM, felix lee feli...@gmail.com wrote:

 That example looks to me like it could be implemented with WeakMap instead
 of WeakRef. Am I missing something?


 On Thu Nov 07 2013 at 2:43:45 PM, K. Gadd k...@luminance.org wrote:

 I'll try and restate an example I used before.

 Let's say you're building a somewhat simple tab-based application, where
 each tab represents a different 'mode'. In this case, you need a higher
 level coordinating object that manages the tab bar, and it needs to own
 references to all of the active modes in order to manage the tabs.
 Similarly, each mode may need to have a reference to the coordinator in
 order to interact with it - like by setting the title of the tab, or
 opening a new tab containing another mode - and it may need to have
 references to other modes in order to communicate (like if one tab opens a
 tab containing related information).

 In a model like that, you can trivially end up with object cycles. All
 the references (going in every direction) are strong, so to successfully
 collect a mode you need to ensure that every reference to it from live
 objects is released. This is problematic because it means that, for example:

 If Mode A opens a new tab containing Mode B, and Mode A wants to respond
 to things happening in Mode B, Mode A now has to register some sort of
 event listener on Mode B. This means that Mode A and Mode B have now formed
 a strong cycle: Mode B's event listener list contains a strong reference to
 Mode A (to fire the event notification), and Mode A has a strong reference
 to Mode B in order to be able to respond to those events.

 Now, if you close Mode B, the coordinator gets rid of the tab and drops
 its strong references to Mode B - the tab is 'gone' - but there's no
 trivial way to ensure that everyone else holding a reference to it is dead.
 If multiple tabs interact in this way it's possible for a huge graph of
 objects to be hanging off one live tab. Eventually, if you close enough
 tabs you might 'free' the graph, but if you aren't careful the coordinator
 itself can end up keeping dead tabs alive, with things like event listener
 lists.

 In the real apps I've worked on like this, the solution was some form of
 weak references - making event listeners own weak self-references instead
 of strong self-references, so that in normal circumstances event
 subscriptions expire along with the subscriber, along with using weak
 references directly in cases like 'tab a spawns tab b' in order to ensure
 that you aren't keeping an object alive just to monitor it.

 IIRC, cycles like this are already common in some DOM scenarios, where
 event subscription and such result in big graphs of objects hanging off a
 single live object? I've certainly run into it in a few cases, where an
 event listener hanging off an audio element caused a huge graph of
 objects to leak, and I had to manually remove the event listeners at an
 appropriate time (and finding an appropriate time can be difficult!)


 On Thu, Nov 7, 2013 at 2:33 PM, Mark S. Miller erig...@google.comwrote:

 Could you give an example, hopefully simple, of such a problem you can
 solve better with GC + weakmaps + weakrefs but without finalization, vs
 just GC + weakmaps ? Thanks.


 On Thu, Nov 7, 2013 at 1:46 PM, K. Gadd k...@luminance.org wrote:

 When I talk about the importance of weak references I am *not* talking
 about the importance of finalization for managing native/remote resources;
 that's an important consideration but it's a separate one. When I talk
 about why weak references are important, I mean for the purposes of
 building large applications without creating uncollectable cycles in object
 graphs. Doing this without weak references is *very* difficult in some
 scenarios, and in other scenarios requires manual management of all object
 lifetimes (addref/release style, or having a single lifetime owner that
 'deletes' an object on demand).

 That's the sort of obstacle that factors into a developer's choice of
 language and toolset. I've seen this particular concern with ES crop up in
 the past on real projects, and I've seen firsthand how difficult it is to
 avoid uncollectable cycles in a language environment without any sort of
 weak reference mechanism. Leaking large uncollectable cycles can have
 catastrophic consequences in multimedia applications and games, where those
 cycles might be retaining images or sounds or other huge game assets.


 On Thu, Nov 7, 2013 at 9:19 AM, Terrence Cole tc...@mozilla.com wrote:

 On 11/06/2013 07:37 PM, K. Gadd wrote:
  Generally speaking, all the discussions on this list about WRs so far
 have
  not suggested that there is any way to introduce WeakRefs without
 making GC
  behavior observable in some fashion

Re: Weak callbacks?

2013-11-07 Thread K. Gadd
The problem is that the cycles remain uncollectable for a very long period
of time, even though functionally the references don't need to be strong.


On Thu, Nov 7, 2013 at 3:10 PM, David Bruant bruan...@gmail.com wrote:

 Le 07/11/2013 22:46, K. Gadd a écrit :

  That's the sort of obstacle that factors into a developer's choice of
 language and toolset. I've seen this particular concern with ES crop up in
 the past on real projects, and I've seen firsthand how difficult it is to
 avoid uncollectable cycles in a language environment without any sort of
 weak reference mechanism. Leaking large uncollectable cycles can have
 catastrophic consequences in multimedia applications and games, where those
 cycles might be retaining images or sounds or other huge game assets.

 The repeated use of the word cycle worries me. Cycles aren't a problem
 by themselves with mark and sweep, do we agree?

 David

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Weak callbacks?

2013-11-07 Thread K. Gadd
Please reread my example, events are a part of it but it is not exclusively
about events. My example explicitly demonstrates the modes holding
references in *both* directions, and only one of them is an event listener.

You're correct that weak event listeners solve some of the problems that
are usually used to justify weakrefs, but they're not the only problems.
Sometimes objects really do need to interact bidirectionally without
keeping each other alive :)

To restate things, part of the problem here is that objects need to
interact, so they need to either have references to each other or have a
third party act as an intermediary. You can remove references entirely with
some sort of message bus or other intermediary (interacting through opaque
handles?) but at that point you've just moved all the lifetime management
concerns around, and now you're manually calling addref/decref or doing
things like that. Alternately, you can keep the strong references and
carefully plumb 'release' code through every object that holds references,
so that for example when a tab dies, it tells literally every object in the
application to let go of any references to the tab. I hope the complexity
inherent to *that* method is evident.

Apologies if my contrived example is not clear enough for these purposes;
the applications I write on a day-to-day basis do not use WRs much. I'm
speaking from past experience and the things I hear from users of my
compiler, and my past experience was on closed-source projects I can't
easily reproduce here verbatim.

To contrive a scenario that might illustrate where event listeners aren't
necessarily enough: Let's say I have an entity system for a game that is
modelling thousands of independent entities that interact. In this system,
entity A might decide to chase after entity B, so it grabs a reference to
entity B in order to chase after it. Meanwhile, entity B might be chasing
after entity C, so it has a reference to entity C. Now, let's say entity C
and entity B both are removed from the simulation. At this point, as long
as entity A is alive, so are B and C (in GC terms) even though the latter
two are not participating in the simulation. Now every place where an
entity can refer to another entity has to be manually audited to ensure
that 'dead' references are actually nulled out, which means you're
basically doing your own GC sweeps over your heap using your own lifetime
rules.

On Thu, Nov 7, 2013 at 4:27 PM, Marius Gundersen gunder...@gmail.comwrote:



 On Thu, Nov 7, 2013 at 11:42 PM, K. Gadd k...@luminance.org wrote:

 I'll try and restate an example I used before.

 Let's say you're building a somewhat simple tab-based application, where
 each tab represents a different 'mode'. In this case, you need a higher
 level coordinating object that manages the tab bar, and it needs to own
 references to all of the active modes in order to manage the tabs.
 Similarly, each mode may need to have a reference to the coordinator in
 order to interact with it - like by setting the title of the tab, or
 opening a new tab containing another mode - and it may need to have
 references to other modes in order to communicate (like if one tab opens a
 tab containing related information).

 In a model like that, you can trivially end up with object cycles. All
 the references (going in every direction) are strong, so to successfully
 collect a mode you need to ensure that every reference to it from live
 objects is released. This is problematic because it means that, for example:

 If Mode A opens a new tab containing Mode B, and Mode A wants to respond
 to things happening in Mode B, Mode A now has to register some sort of
 event listener on Mode B. This means that Mode A and Mode B have now formed
 a strong cycle: Mode B's event listener list contains a strong reference to
 Mode A (to fire the event notification), and Mode A has a strong reference
 to Mode B in order to be able to respond to those events.

 Now, if you close Mode B, the coordinator gets rid of the tab and drops
 its strong references to Mode B - the tab is 'gone' - but there's no
 trivial way to ensure that everyone else holding a reference to it is dead.
 If multiple tabs interact in this way it's possible for a huge graph of
 objects to be hanging off one live tab. Eventually, if you close enough
 tabs you might 'free' the graph, but if you aren't careful the coordinator
 itself can end up keeping dead tabs alive, with things like event listener
 lists.

 In the real apps I've worked on like this, the solution was some form of
 weak references - making event listeners own weak self-references instead
 of strong self-references, so that in normal circumstances event
 subscriptions expire along with the subscriber, along with using weak
 references directly in cases like 'tab a spawns tab b' in order to ensure
 that you aren't keeping an object alive just to monitor it.

 IIRC, cycles like this are already common in some DOM scenarios

Re: Weak callbacks?

2013-11-06 Thread K. Gadd
Generally speaking, all the discussions on this list about WRs so far have
not suggested that there is any way to introduce WeakRefs without making GC
behavior observable in some fashion. WeakRefs functionally make GC
observable because when you try to get at the target of the weakref, you
either get it or you don't. Once you introduce the ability to get back
'null' when asking for the target of a WR (or any similar failure case),
you can use that to determine things about GC behavior.

If you somehow eliminate this weakness, WRs no longer solve the problems
they are intended to solve. Or at the least, they solve only a small
reduced subset of the problems solved in real software via the use of weak
references. Being able to access the target of the WR (and have this
operation fail) is core to their value (even if finalization notifications
are also used quite often).

I've already argued in the past about why weak references are important,
and why not having solutions for those problems will kneecap the
development of web applications by either preventing certain types of
software from running in the browser, or forcing implementers to write
their own GCs (or entire runtime environments) inside the browser, as is
done with environments like emscripten and native client. Once that becomes
the solution, the ES spec is irrelevant for those applications because they
have had to abandon the language. While the risk of something like this
happening is still relatively low, the risk increases over time as more
people begin seriously considering solutions like emscripten and nacl -
we're starting to see companies ship real products using them already. If
this spreads to popular reusable libraries (physics libraries, rendering
libraries, etc), there's a risk that those libraries will pull new
applications out of the ES realm because it's not possible to use those
libraries without abandoning ES in favor of a custom GC/runtime environment.

Based on the conversations thus far, a choice just has to be made between
the two downsides: exposing some amount of GC internals, or making it
impossible to write some subset of applications in ES. It's possible that
exposing GC semantics has such catastrophic security consequences that
ruling those applications out is merited. It's also possible that
workarounds can be applied to reduce the harm of GC visibility (I think in
the past someone - maybe Mark? - suggested that disabling cross-realm WRs
would mitigate the damage considerably?)

On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote:

 On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote:




 On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola 
 dome...@domenicdenicola.com wrote:

 Thanks Mark for the education, especially on the pre- vs. post-morterm
 finalization distinction. I don't think I was specifically advocating for
 pre-mortem in my OP, since I didn't really understand the difference :P.
 Post-mortem finalization sounds quite reasonable. What do people think of
 introducing it into ECMAScript?


 This may be a naïve question, but how would the handler know which
 object/weakref had been gc'ed?

 You wouldn’t :)

 I’m kind of anti-finalisers in JS for all of the reasons people have
 raised - they are extremely hazardous, expose non-deterministic behaviour,
 etc

 Given our general desire to avoid exposing internal GC semantics, and the
 difficulty in defining observable GC behaviour (I suspect this would be a
 non-starter in any case), I can’t see any specification that would allow
 useful finalisers or WeakRefs.

 If MarkM has an idea for WeakRefs that don’t leak observable GC behaviour
 i’d love to hear, but in general i’m opposed to both them and finalisers :-/

 —Oliver

 Rick

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss



 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promises and Decidability in Asynchronous Error Handling

2013-10-21 Thread K. Gadd
Requiring early registration prevents the use of futures as value
containers; i.e. kicking off an operation and storing the Future somewhere
so anyone can use it at a later date.

I agree that an improved error handling policy would be very, very good to
have, though.


On Mon, Oct 21, 2013 at 9:40 AM, Kevin Smith zenpars...@gmail.com wrote:

 A well-known problem with Promises, as implemented in various Javascript
 libraries, is that program errors are silenced by default.  Consider the
 following program, which simply makes an HTTP request and then prints out
 the HTTP response headers:

 fetchUri(http://someauthority.com/;).then(response = {
 for (let header of repsonse.heders) // Note the misspelling!
 console.log(header.key, header.value);
 });

 On line 2, the property headers is misspelled, which should cause the
 program to report an unhandled error.  Under the current Promises
 specification, however, the error will be silenced and the program will end
 happily with success.

 Various solutions have been proposed for dealing with this problem, such
 as:

 - Extending debugging tools so that unhandled rejections are visible
 through a specialized tab or view.

 - Using the garbage collector to determine when rejections can no longer
 be handled, and therefore constitute a program error.

 - Adding a `done` method to the promise type which propagates rejections
 as program errors.

 While each of these approaches provides a partial solution to the problem,
 they are ultimately inadequate because they do not address the underlying
 cause.

 The root cause of this issue is that, as currently specified, **the
 problem of determining whether a particular runtime error has an associated
 handler is Turing undecidable**.

 This is *not* a desirable property for an error handling mechanism to
 have, and it is not a design choice that can be reversed at a later date.

 In order to make error handling decidable, it is sufficient to require
 that an error handler must be attached to the promise *within a
 well-defined window*.  One such window would be the lifetime of the
 currently executing user call stack.

 The designers of Dart have made a similar decision with their Future API.
  In the following document, users are instructed to register error handlers
 early:


 https://www.dartlang.org/articles/futures-and-error-handling/#potential-problem-failing-to-register-error-handlers-early

 A quick search on StackOverflow relating to Futures and early error
 handling in Dart yielded no results.  This cursory evidence suggests that
 requiring early registration of error handlers is not a significant problem
 for Dart users.

 In my view, it would be a mistake to standardize the undecidable error
 handling model of current Promises design.

 Thanks,

 { Kevin }

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Non-extensibility of Typed Arrays

2013-09-04 Thread K. Gadd
Did anyone address what should be done in the use case where it's necessary
for information to 'tag along' with an array or typed array, for interop
purposes? The existence of interior binary data objects seems to complicate
this further; for example I had said that it seems like WeakMap allows
attaching information to a typed array in that case even if it isn't
extensible. If interior objects lose identity, though, it now becomes
*literally impossible* for data to follow an instance of Uint32array (or
whatever) around the runtime, which is kind of troubling. Obviously I
understand *why* this is the case for interior objects.

Is the meaning of an assignment to an interior object well specified? The
data is copied from the source typed array into the interior object, I
assume.

I'm going to describe how I understand things and from that how it seems
like they could work:
At present when you construct a typed array it is a view over a particular
buffer. You can construct an array with a size `new Uint32Array(32)` in
which case a buffer is allocated for you behind the scenes; you can
construct an array from a buffer + offset/size pair in order to create a
view over a subregion of the buffer. In both cases, the 'array' does not
actually represent or contain the data, it is merely a proxy of sorts
through which you can access elements of a particular type.
It is my understanding that this is the same for binary data types: you can
construct a heap instance of one, in which case it has an invisible backing
buffer, or you can 'construct' one from an existing buffer+offset, in which
case it is more like a proxy that represents the given data type at that
given offset in the buffer, and when you manipulate the proxy you are
manipulating the content of the buffer.

In both cases, I believe it is consistent that these objects are all
'views' or 'proxies', not actual data. The fact that you can create an
instance directly creates the *illusion* of them being actual data but in
every case it is possible for multiple instances to share the same backing
store without sharing referential identity (via ===).

In both cases, I don't believe a user should expect that attaching an
expando to one object instance should modify the expandos on another object
instance. Given this, it seems perfectly reasonable to be able to attach
expandos to a typed array, and I've previously described why this use case
is relevant (interop between compilers targeting JS, and native
hand-written JS, for one).

In the same sense, if typed arrays must be constructed to act as proxies
for the 'interior' arrays in a binary data type, being able to attach
expandos to them does not cause much harm, other than the fact that the
lifetime of the expando does not match the lifetime of the underlying
binary data. But this is already true for typed arrays, in a sense.

I think the best way to address the confusion of expandos on interior
arrays is simply non-extensibility, as has been discussed. I don't see why
non-extensibility for interior arrays requires crippling the functionality
of typed arrays in general, since JS already seems to have 2-3 exposed
concepts in this field (seal, freeze, preventExtensions) along with query
methods to find out if those concepts apply to a given object (isSealed,
isFrozen, isExtensible)

If interior arrays are not extensible, I should hope that
Object.isExtensible for them returns false. If it were to return true when
they have no expando support that would be incredibly confusing.

Anyway, given all this I would propose that the optimal solution (in terms
of usability, at least - can't speak for the performance consequences) is
for typed arrays to be extensible by default, as they are Objects that
point to underlying sequences of elements, just like Array. This gives good
symmetry and lets you cleanly substitute a typed array for an Array in more
cases (resizability and mixed types being the big remaining differences).
In cases where extensibility is a trap for the unwary or actively
undesirable, like interior objects, the instance should be made
non-extensible. This allows all end user code to handle cases where it is
passed an interior array or object without reducing the usefulness of typed
arrays.

FWIW I would also argue that a free-standing instance of any Binary Data
type (that you construct with new, not using an existing buffer) should
maybe be extensible by default as well, even if 'interior' instances are
not. However, making binary data types always non-extensible wouldn't
exactly break any compatibility or use cases, since they're a new feature -
but it does mean now we have to add checks for extensibility/typeof in more
cases, which is awful...

(A related area where this is a big problem for me and authors of similar
packages is emulating the java/C# 'getHashCode' pattern, where objects all
have an associated static hash code. Implementing this often requires
attaching the computed hash to the object as 

Re: Non-extensibility of Typed Arrays

2013-08-27 Thread K. Gadd
To me the compelling argument against using encapsulation instead of
extensibility is that it breaks compatibility with existing JS code. Once
you encapsulate an array, the encapsulated object no longer acts like an
array and you can't use it in contexts where a normal array is expected.
The ability to do python style 'quacks like an array' duck typing simply
doesn't exist for arrays in JS.

This is a huge problem for JSIL interop - I can't preserve type information
for arrays, or expose other array features, without either breaking interop
with pure JS or otherwise eating some enormous perf hit (proxies,
spidermonkey's deopt from named slots on arrays, etc). Baking this
limitation into the spec for typed arrays is kind of awful, but I can
understand if it's absolutely necessary...

Maybe WeakMap is the right solution for this? I can't remember what the
performance consequences are for that use case. (Can you use an Array as a
weakmap key? I forget, since it's an object-like type but it has special
properties...)

Note that I'm not arguing for array subclassing here, just the ability to
'bless' an array instance with extra information. Such use cases are no
doubt fairly rare, even if it's possible to come up with a handful of them.

I assume StructType and ArrayType will address a lot of this, but I'm not
sure how I feel about having to wait for those features when (were typed
arrays specced to allow named expandos) you could do this stuff in a mostly
cross-browser way and ship it right now. (WeakMap fails this test since
IIRC it's still only available in Firefox. :/ I love it and wish I could
use it in the wild!)


On Tue, Aug 27, 2013 at 3:49 PM, David Herman dher...@mozilla.com wrote:

 On Aug 27, 2013, at 9:47 AM, Filip Pizlo fpi...@apple.com wrote:

  I do. Placing named properties on arrays makes sense. Consider a matrix
 implemented as a Float32Array, with named properties telling you the
 numRows and numCols. Just one example.

 There are of course other ways to achieve this that don't involve patching
 the array object, such as building a data abstraction for matrices that
 has-a Float32Array, or creating a new array type with additional methods:

 var Matrix = new ArrayType(float32);
 Matrix.prototype.numRows = function() { ... }
 // or
 Object.defineProperty(Matrix.prototype, { get: function() { ... }, ...
 });

  TA instances having no indexed expandos but allowing named ones is
 weird. Better to be consistent to users
 
  Consistency would imply doing what other indexed types do.

 Consistency arguments won't get you very far. The indexed properties of
 typed arrays by design act very differently from other indexed types.
 That's their whole reason for existence.

 And the other consistency dimension is between array types and struct
 types. Is anyone arguing that structs should also have expandos?

 Dave

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Binary Data types in window context (was Some Typed Objects Confusion)

2013-08-21 Thread K. Gadd
moving back onto list

It might be worth doing. On the one hand, I don't really feel like these
names *should* collide with anything, but it seems like the risk is kinda
high... and it's a little weird seeing them in global scope and having to
figure out that they're actually types for binary data and not, for
example, the constructor for boolean or some sort of value type ctor.

Once 64-bit signed/unsigned ints are in will there be two names for those
as well? I.e. Uint64(...) produces one of the new 64-bit unsigned ints,
while uint64 is the name you use when creating a StructType to specify the
type of a field?

If the type names used by binary data actually work as constructors to get
an instance of that type, that might make it more justified for the names
to be in global scope, but that seems like probably unmerited scope creep.

Having the types be in a single 'BinaryTypes' namespace or something at
window-level seems like it would be pretty reasonable; if you're going to
be referring to types a lot you can pull them into locals, or use 'with' in
a gross non-strict function (yuck yuck yuck)

I assume specifying type names as strings, i.e. { field: uint32 } was
considered and ruled out (it would definitely be strange to mix that with
passing in actual StructType instances).

-kg

On Wed, Aug 21, 2013 at 10:36 AM, Dmitry Lomov dslo...@chromium.org wrote:

 On Wed, Aug 21, 2013 at 6:50 PM, K. Gadd k...@luminance.org wrote:

 Does this mean the addition of binary data to a browser defines dozens of
 new names in 'window' scope, like 'string' and 'boolean' and 'uint32'
 alongside existing names? That's kind of surprising to me (though I can
 understand why it might be necessary)


 Yes, this is where we are at now.
 Maybe we should pack the whole thing into a module.

 Dmitry




 On Wed, Aug 21, 2013 at 4:21 AM, Dmitry Lomov dslo...@chromium.orgwrote:

 string, boolean, object and any are all lowercase (we should fix the
 wiki)

 FWIW, I am already working on a new version of polyfill. It is fully ES5.
 Here is a pull request: https://github.com/dherman/structs.js/pull/12 -
 I'll merge it soon, and work more to cover everything in the proposal.

 Thanks,
 Dmitry



 On Wed, Aug 21, 2013 at 3:21 AM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 sorry, point 3 was actually the question about point 2


 On Tue, Aug 20, 2013 at 6:20 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 Uhm, just a couple of extra question about that page if/when you have
 time:

1. string and boolean are mentioned, but nowhere in your
`struct.js` prolyfill code. Will string and boolean be accepted?
2. `Object` and `Any` are mentioned, but exported as object and
any in your `struct.js` prolyfill example. W
3. Which is the right way?

 The reason I am asking is to be able to create code that does
 absolutely nothing (for performance reason) but will look like the real
 thing so I can start experimenting with static structures and possibly a
 develop VS production version of an ES3 to ES5 compatible polyfill since I
 believe your code won't run anywhere except in SpiderMonkey (which is OK
 but it's not suitable for a lightweight migration to structure like 
 logic)

 Thanks.


 On Tue, Aug 20, 2013 at 4:55 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 Awesome, thanks!


 On Tue, Aug 20, 2013 at 4:12 PM, David Herman dher...@mozilla.comwrote:

 On Aug 20, 2013, at 1:31 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

  [In this page](
 http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects), and
 in the latest meeting note too, I can read both uint8 and Uint8, as 
 example.

 Bug. Fixed, thanks.

  **The Question**
  How is `new StructType({x:Uint32, y:Uint32})` supposes to
 understand the type? `instanceof Uint32` or `typeof v === uint32` or 
 ...
 both in case of `boolean` and `string` ?

 Neither. It tells you that the x and y fields have typeof 'number'
 and that their values are constrained to be integers in the range [0, 
 2^32).

  A bonus question would be: does anybody know when this stuff is
 planned to go out? Not a single beta/alpha channel is exposing anything 
 at
 all so far.

 Nikhil Marathe and Niko Matsakis are actively working on the
 implementation for SpiderMonkey:

 https://bugzilla.mozilla.org/show_bug.cgi?id=578700

 Dmitriy Lomov is actively working on updating the prollyfill to
 match the current API:

 https://github.com/dherman/structs.js
 https://github.com/dherman/structs.js/pull/12

 Not sure if anyone on the V8 team (which includes Dmitriy) has
 started implementation but I believe they're interested. Right now 
 Dmitriy
 is focused on the prollyfill and spec.

 Dave





 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss



 ___
 es-discuss mailing list
 es-discuss@mozilla.org

Re: setImmediate

2013-08-08 Thread K. Gadd
Why is the slow script dialog box even relevant for setImmediate? As I
understand it, setImmediate is equivalent to DoEvents in Visual
Basic/Windows Forms and pumping the message loop in a normal C application.
That is, you can use setImmediate to make your application run as fast as
possible while still allowing the browser to pump messages, which ensures
keyboard/mouse inputs are processed and the window does not get flagged as
unresponsive.

This is *ideal* (especially compared to setTimeout 0, which introduces the
use of timers and slows everything down in this use case, and compared to
requestAnimationFrame which needlessly would slave computation to vsync).
People who are writing long computation loops right now that hang the
browser main thread for multiple seconds can split them up with
setImmediate without causing any major performance regressions.

Whether or not setImmediate would increase battery usage is something you'd
have to test; this isn't a case where timers would be waking the CPU up and
keeping it awake, though; this is a case where *computation* would be
keeping the CPU awake, and ultimately computation has to finish sooner or
later. You're not going to save power just by making computation take
longer unless you can ensure the CPU and other components remain in a
low-power state during the computation.


On Thu, Aug 8, 2013 at 1:26 PM, David Bruant bruan...@gmail.com wrote:

 Le 08/08/2013 22:04, Jason Orendorff a écrit :

  On Thu, Aug 8, 2013 at 9:40 AM, David Bruant bruan...@gmail.com wrote:

 Small delays between (micro)task sounds like a local maximum it's hard to
 get away from unfortunately :-(

 I think I was wrong here when it comes to microtasks.
 Microtasks bypass the event queue, so delaying them delays all the other
 messages in the queue by definition. Forcing a delay on microtasks means an
 irresponsive UI.


  What if, instead of a slow script dialog, browsers responded to
 microtask/setTimeout(0) abuse with gradual throttling? Well-behaved
 applications would get immediate setTimeout(0) callbacks. Badly
 behaved applications would run slowly.

 That's already the case with setTimeout in a way. Try:

   setTimeout(function f(){
   setTimeout(f, 0);
   }, 0)
 You never get the slow script dialog. The 4ms clamping is here to make
 that code this code runs yet does not burn the CPU.

 Other than that, the browser with the shortest delay wins the battle, I
 believe. my application runs faster in X than in Y forcing Y to reduce
 the delay and align with X.

 Now that I think about it, maybe the proposal I made for microtasks [1]
 could work for setImmediate. setImmediate would be guaranteed to run asap
 (in a different task, not microtask) without clamping.
 The mitigation for browsers is possible via kill too-deeply-nested
 setImmediates (preferably before running one and not in the middle of one
 :-p) and telling the script if it asked to be notified.
 That's a version of setImmediate I would agree with as it would be a
 significant improvement over what we have today.

 David

 [1] https://mail.mozilla.org/**pipermail/es-discuss/2013-**
 August/032630.htmlhttps://mail.mozilla.org/pipermail/es-discuss/2013-August/032630.html

 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: WeakRefs leading to spec-imposed memory leaks?

2013-07-27 Thread K. Gadd
If memory serves,
http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.htmlwas
also complaining about a similar closure/scope leak in v8 where locals
that you wouldn't expect to be retained are retained by closures in some
cases.

Arguably those cases just need to be fixed. Locals that aren't ever
reachable from a closure being retained by the closure is definitely
non-obvious and it's difficult to even identify or debug these cases with
current debugging tools. JSIL has had huge memory leak issues caused by
this in a few cases. Of course, I don't know how difficult it actually is
to fix this.

I agree that WeakRefs going in with these sorts of leaks remaining would be
a big problem, but it would be worse for developers if these leaks just
stuck around and kept WRs from ever getting into the language. Better to
put them in and have them serve as a strong motivator for fixing those
leaks for good, IMO.


On Sat, Jul 27, 2013 at 8:52 AM, David Bruant bruan...@gmail.com wrote:

 Hi,

 There seems to be a consensus on bringing in WeakRefs in the language. I
 came around to the idea myself as some use cases seem to require it (as in:
 some use cases can't be achieved even with a .dispose convention like
 distributed acyclic garbage collection). However, I worry.

 Recently, some memory leaks where found in Gaia (FirefoxOS front-end). The
 investigation led to a subtle nested function scopes condition under which
 the reference to some variables are kept alive unnecessarily [1].

 One of these days the SpiderMonkey folks will certainly fix this bug and
 will that creates 2 worlds. A before world where some objects *never*
 gets collected because of the bug and an after world where some of the
 same objects get collected.
 If all current major JS engines have common limitations ([1] or any
 other), I worry that code using WeakRefs could implicitly (and mistakenly!)
 rely on these common limitations and break if one of these limitation is
 fixed. We know the rest of the story; it involves browser competition,
 don't break the web and this time would put in spec to require some
 missed opportunities for optimization. Phrased differently, we could end up
 with memory leaks imposed by the spec...

 I understand the necessity of WeakRefs for some use cases, but I worry.

 David

 [1] 
 https://bugzilla.mozilla.org/**show_bug.cgi?id=894971#c0https://bugzilla.mozilla.org/show_bug.cgi?id=894971#c0
 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: new Symbol(obj)

2013-07-15 Thread K. Gadd
The builtin could have weak values (i.e. Symbol instances expire when no
longer referenced by JS) instead of weak keys, which is not something we
can currently express in JS. This would also make it possible to use
strings/integers/floats as Symbol keys without leaking those Symbol
instances forever. This is not something we can express in JS either.

Both of these behaviors would not, as I understand it, be directly
observable since keeping an old Symbol instance around (to compare with)
would prevent the cached one from being collected. On the other hand, I
think if you were to resynthesize the number/string used as a symbol key
and make a new symbol, that might allow you to observe whether the symbol
had been collected. This doesn't seem like a huge problem to me but I
forget the exact reasoning why weak references were unacceptable in the
past; maybe it still applies to this.


On Mon, Jul 15, 2013 at 9:08 AM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Jul 15, 2013, at 6:49 AM, Jeremy Martin wrote:


 In some (most?) cases, but not all.  There's already a consensus that the
 garbage collection semantics of WeakMaps aren't always appropriate [2].  By
 parameterizing the Symbol constructor, developers can create custom map/set
 types without the overhead of a Symbol Factory (as previously suggested
 by Allen).  I believe this would be a useful building block for interesting
 and innovative custom types.

 [1]: https://en.wikipedia.org/wiki/Injective_function#Definition
 [2]: http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets


 An implementation of your proposal is going to have to have to internally
 use  some wort of weak-keyed table, in practice an implementation would
 probably use the same GC mechanisms that are there to support WeakMap.  So,
 I doubt there would be much performance difference between a built-in and a
 roll-your-own implementation.

 Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread K. Gadd
Sorry Jeff, but this is actually not the case. The performance consequences
from using .bind() can be quite severe because it pollutes type information
and disables fast paths. Not 'your entire application runs in the
interpreter' slow, but surprisingly slow. It can even slow down code paths
where .bind()/bound functions are not being used because of how inline
caches and such tend to work in modern engines.

The problem here isn't that 'calling a bound function is slow'; it's a more
general problem that the introduction of bound functions into an existing
application can make the application get slower in places where the bound
functions aren't being used.

I do agree with the general principle that it is not likely to be the
biggest performance problem, but it's surprisingly harmful. On a related
note, it would certainly be unwelcome if arrow functions had the same
downsides.

-kg

On Sat, Jul 13, 2013 at 12:15 PM, Jeff Walden jwalden...@mit.edu wrote:

 On 07/12/2013 02:54 PM, Allen Wirfs-Brock wrote:
  Looking at it another way, if implementation haven't found it
 straightforward to optimize ES5 bound functions why would you expect that
 would have an easier time with Proxys?

 I'm pretty sure no implementation has seriously tried to optimize bound
 functions, and that that's the major reason for any slowness.  I don't
 think there's anything fundamentally difficult about optimizing bound
 functions.  It's just never been a priority for engines, because it doesn't
 show up in benchmarks and because the perf bugs for it are less pressing
 than other perf work is, as bound functions remain underused on the web.
  Chicken and egg?  Sure.

 In the meantime, while I wouldn't currently question (as a purely
 pragmatic choice) avoiding bind in highly intensive code where every bit of
 perf matters, I do think bound functions are fast enough for the vast
 majority of cases.  The overhead of calling a bound function will rarely be
 the difference between adequate and inadequate performance.

 Jeff

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread K. Gadd
I've had some back and forth with v8 devs about this since it affects my
compiler. I believe they already have open issues about it but I don't know
the bug #s.

In general, the problem seems to be that Function.bind creates functions
that have different type information from normal functions you wrote in
pure JS; they're 'special' native functions in the same fashion as say, a
DOM API:

document.createElement
function createElement() { [native code] }
 function f () {}
f
function f() {}
 f.bind(null)
function () { [native code] }

This is important because v8 tries to gather information about callees at
various call sites. Having a mix of these special and non-special functions
means that the JIT is not able to make safe optimizations based on all the
callers being the same type.

IIRC there are also some other problems specific to v8, like it only being
able to optimize Function.apply and Function.call if the .apply/.call
methods are the implementations used for pure-JS functions (so bind breaks
those too).

I can't comment on why it's slow in SpiderMonkey (I've never asked... I
should file a bug) but it is indeed the case that f.bind(null) produces a
'native code' function in SpiderMonkey, so I expect some of the same
optimization consequences apply.

I also expect that it is much harder for v8 and spidermonkey to inline a
function that contains native code, if not entirely impossible.

All of these problems, as I understand them, are completely fixable. It
might be as simple as making bind return a pure-JS function instead of a
native function. This is supported by the fact that a pure-JS polyfill for
.bind is usually faster in my tests. In general VM authors are much more
helpful when shown real world applications affected by these issues, based
on my experience. They tend to ignore jsperf microbenchmarks, etc.

I don't know that this could be addressed at all from a specification
perspective. The only thing I can think of would be specifying that the
result of Function.bind should somehow be indistinguishable from a
hand-written JS function (no 'native code' in tostring, etc) but I don't
think that sort of spec requirement would actually prevent any of these
performance traps.

Hope this helps,
-kg

On Fri, Jul 12, 2013 at 10:59 AM, Brendan Eich bren...@mozilla.com wrote:

 Allen Wirfs-Brock wrote:

 you might consider ticketing performance bugs against the various
 implementations.


 Right, and at most summarize with links to those issues for es-discuss.
 This is not a language issue, rather a quality of implementation one.

 /be


 Allen


 On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:

  The TypeScript project tries to emulate arrow functions through the
 _this = this pattern and keeps running into corner cases where a
 semi-naïve renaming is not sufficient.

 I have been trying to suggest using .bind to emulate arrow functions
 instead, but the counter-arguments are (a) .bind might not be available
 (supporting pre-ES5 targets) and (b) .bind is slow.

 The polyfill isn't the problem, but I'm a bit shocked every time
 someone reminds me of the performance hit for using .bind. Given
 that a bound function has strictly more info than an unbound one,
 I wouldn't expect that (I expected a bound function to be roughly
 the same as an unbound function that does not use this). Unless
 there is no special casing for the just-add-this case, and .bind is
 always treated as a non-standard (meta-level) call.

 While playing with test-code, I also found that v8 does a lot better
 than other engines when using an .apply-based .bind emulation.

 Can anyone explain what is going on with .bind, .apply and the
 performance hits?

 The TypeScript issue is 
 https://typescript.codeplex.**com/workitem/1322https://typescript.codeplex.com/workitem/1322.
 My test code (*) is attached there as bind-for-arrows.html.

 Claus
 http://clausreinke.github.com/

 (*) I also tried to make a jsperf test case, but the way jsperf
runs the loop seems to prevent the optimization that makes
v8 look good for the .apply-based bind.

 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss


 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

  __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: new Symbol(obj)

2013-07-12 Thread K. Gadd
I would welcome (with fanfare and parades) a new Symbol(obj) that worked
for strings and integers. Such is not possible using the WeakMap shim
(you'd have to detect the type of the value and have multiple dictionaries,
or something, and you'd leak the symbols forever...)

Of course, what that means is I'm asking for weakly cached symbols with
referential identity, which means it would allow detecting garbage
collections, so this is probably around the point where people chime in and
say it's not possible. Oh well. :(

On Fri, Jul 12, 2013 at 12:42 PM, Jeremy Martin jmar...@gmail.com wrote:

 Good point, that's definitely a usable solution (also a better
 representation of what I was attempting to describe).

 I'd still be interested in a less-verbose/more-efficient approach using
 the Symbol constructor, but it may not be a common enough scenario to
 justify it when a workaround does exist.


 On Fri, Jul 12, 2013 at 3:32 PM, Allen Wirfs-Brock 
 al...@wirfs-brock.comwrote:


 On Jul 12, 2013, at 12:14 PM, Jeremy Martin wrote:

 In brief: allow Symbol's to be constructed with a single parameter, with
 the following behavior:

  var obj = {};
 undefined
  new Symbol({}) === new Symbol({})
 false
  new Symbol(obj) === new Symbol(obj)
 true


 You can use a WeakMap to build your own object-selected Symbol factory:

 let known = new WeakMap;

 function ObjSymFactory(obj) {
//handle obj === undefined however you want
let sym = known.get(obj);
If (!sym) {
   sym = new Symbol;
   known.set(obj,sym);
}
return sym;
 }

 Allen





 --
 Jeremy Martin
 661.312.3853
 http://devsmash.com
 @jmar777

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: thisArg in Array#find and Array#findIndex

2013-07-10 Thread K. Gadd
In addition to the perf savings from not having to allocate (to call bind)
not needing to use bind() for cases like .find() can have beneficial
effects for JITs as well. It's my understanding that at a recent point in
time (maybe even still today?) functions created by bind() had the ability
to deoptimize call sites in V8 and Spidermonkey in certain scenarios. If
the existing design lets developers use free functions without having to
use bind(), that makes it easier for them to end up in the performance
sweet spot we know about when it comes to crunching data. The longer they
can stay in that sweet spot and still use built-ins like find/findIndex,
the better.


On Wed, Jul 10, 2013 at 10:28 AM, Brendan Eich bren...@mozilla.com wrote:

 David Bruant wrote:

 I can't find it anymore, but I read a message from Mike Shaver (I think
 it was him) saying that these methods have been standardized after
 SpiderMonkey implementation without other form of rationale.
 Who needs this particular consistency anyway?


 Users generally benefit from this kind of consistency; we hear complaints
 about reduce/reduceRight.

 The perf savings is an allocation, but the cognitive load win seems more
 important. Telling people to use .bind (polyfilled) involves more typing
 and thinking.

 /be

 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Object#extra hazard

2013-07-10 Thread K. Gadd
I think at this point we have a long history of language designs where
random stuff has been tacked onto the core base class (i.e. Object) that
really shouldn't have gone there - hashCode/toString in Java/C#, etc - such
that any proposal to put something on Object instances deserves extreme
skepticism. Static methods on Object aren't nearly so bad.

In this case, the problem being solved can almost certainly be solved
through composition or some other design mechanism. Bolting it onto every
instance of Object, even if the only universally paid cost is a reserved
name on the prototype, is simply not the right solution unless the
downsides of other approaches are intolerable. Which they aren't.

In practice a lot of these use cases call for event subscription and
broadcasting to occur through a separate coordinator ('event bus') object
and not through the object in question, anyway. This addresses a bunch of
reference cycle problems that are caused when you subscribe directly to an
object. You don't need to look much further than the DOM for examples...


On Wed, Jul 10, 2013 at 3:57 PM, Rick Waldron waldron.r...@gmail.comwrote:

 I don't want any of this on my Object objects. Not all objects represent
 something that can or should emit/publish/trigger/broadcast.

 For example...

 class Light {
   constructor() {
 // initialize Light control instance
   }
   on() {
 // send bits to turn Light on
}
   off() {
 // send bits to turn Light off
   }
 }


 So what happens now? All of my Led instances have emit, trigger, once and
 boundTo methods that are actually useless now. No thanks. I also don't want
 Object.prototype.* and Object.* to suffer the same way that the [[Global]]
 (window) object in browsers has suffered. Give a hoot, don't pollute.

 Post ES6 world makes creating emitter objects trivial—so why not a blessed
 standard lib module that can be imported and used to extend a class
 declaration?


 import { Emitter } from @event;

 class Foo extends Emitter {}

 Easy.

 More inline...



 On Wed, Jul 10, 2013 at 3:58 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 I know but people use prefixes and unique ids for events too and I am not
 sure if that would work so well.

 Also, this is not backward compatible, or better, this is impossible to
 polyfill so it won't bring benefits to the current scenario.

 If only I could already `Object.mixin(Object.mixin({}, EventEmitter),
 EventTarget)` and alias those prolix names as `on()` and `off()` it would
 be already great but this is too much in between the DOM, behind WebIDL,
 and ECMAScript ... something I know already historically incompatible,
 that's why I've proposed new names hopefully one day (and hopefully soon)
 in core, something that will be inherited in current implementation in any
 case, as it was in my case simply polluting the `Object.prototype` with
 those non enumerable properties luckily inherited in hosted DOM objects too.

 best regards


 On Wed, Jul 10, 2013 at 12:46 PM, Matthew Robb matthewwr...@gmail.comwrote:

 You can do chainability at object define time with the sugar form:

 var obj = {
 on type1(){},
 on type2(){},
 on type3(){}
 }


 This is the dark days of DOM element properties as event handlers:

   elem.onclick...

 Assigning to this paves over the previous assignment, leaving no way to
 have multiple handlers registered for the same event type.





 OR add to it using one of the following options:

 Object.mixin(obj, {
 on type1(){},
 on type2(){},
 on type3(){}
 })

 obj.{
 on type1(){},
 on type2(){},
 on type3(){}
 }

 obj := {
 on type1(){},
 on type2(){},
 on type3(){}
 }


 On Wed, Jul 10, 2013 at 12:41 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 my implementation works already with `DOM` nodes and browser
 environment, including `window`.

 I've also already written an `EventTarget` mixin object but in my case
 I'd use that via `Object.mixin(Object.prototype, EventTarget);` 'cause
 almost every object I use in my logic should be observed or should emit
 something to some other object.


 Standard lib approach (a la node) works today and tomorrow.



 Of course Dictionaries are out of the game but that's OK, as long as
 it's possible to promote them later on via `Object.setPrototypeOf(dict,
 Object.proottype)`

 I find the `Object.addEventListener(obj, type, handler)` approach
 very boring for the simple reason that it does not make sense to use
 chainability there, another de-facto thing when it comes to events.


 It's also (subjectively) hideous.




 ```javascript
 // current eddy.js status
 var obj = {}
   .on(type1, handler1)
   .on(type2, handler2)
   .on(type3, handler3)
 ;
 ```


 That's great for your use case, but I would never want this by default.


 Rick

 (snip)

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___