Re: Resuming execution contexts

2021-03-16 Thread Logan Smyth
> as this code does not seem to take an argument.

The resumption state set by `GeneratorStart` does not take an argument
because there is no way to access the first resumption value in a
generator, though there is the `function.sent` proposal to allow that:
https://github.com/tc39/proposal-function.sent

In the case you're asking about, the `value` applies in the case of
`GeneratorYield` https://tc39.es/ecma262/2021/#sec-generatoryield which
does take a resumption value argument.



On Tue, Mar 16, 2021 at 2:52 AM Alan Schmitt 
wrote:

> Hello,
>
> I am trying to understand how the resuming of execution contexts work.
> For instance, step 9 of
> https://tc39.es/ecma262/2021/#sec-generatorresume says "Resume the
> suspended evaluation of genContext using NormalCompletion(value) as the
> result of the operation that suspended it." I can see that the code to
> run would be the one created by step 4 of
> https://tc39.es/ecma262/2021/#sec-generatorstart, but I do not
> understand what the "using NormalCompletion(value) as the result of the
> operation that suspended it" means, as this code does not seem to take
> an argument.
>
> Please let me know if this is not the right forum to ask such questions.
> And thanks a lot for any help you may provide.
>
> Best,
>
> Alan
> ___
> 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: [Proposal] Allow rest parameter on try... catch

2020-07-15 Thread Logan Smyth
I'm not sure this fits nicely into things. The issue is that `Promise.all`
rejects as soon as it gets _any_ errors, so your `catch` block will run
before there are multiple errors. The syntax used around `Promise.all`
should not influence the behavior of `Promise.all` itself, so the only way
to do what you want would be to manually use `Promise.allSettled` or
something along those lines, and that would already provide the ability to
throw a singular array of errors, which would avoid the need for
`...errors` in the first place.

On Tue, Jul 14, 2020 at 11:29 PM Michaël Rouges 
wrote:

> Hi all,
>
> My proposal's goal is really simple: provide a way to handle any numbers
> of errors, at once, in a synced try... catch.
>
> The problem:
> --
> `
> async function reject (key) {
>   throw new Error(`error with key: ${key}`)
> }
>
> async function test () {
>   try {
> await Promise.all([...new Array(3).keys()].map(reject))
>   } catch (error) {
> console.error(error) // Error: error with key: 0
>   }
> }
>
> test()
> `
>
> Actually, we don't have a simple way to retrieve all errors in the catch
> and it can be difficult to manage when we don't know how many errors we can
> receive.
>
> Then, IMHO, allowing the rest parameter on the `catch (...errors)`
> resolves that problem, without breaking changes.
>
> What do you think about it, please?
>
>
> Cordially,
> Michaël Rouges - https://github.com/Lcfvs - @Lcfvs
> ___
> 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: unhandled rejections and finally()

2020-03-28 Thread Logan Smyth
> Could someone point me to something that would help me to understand the
logic here? It looks like the first finally() is getting a “free pass”
while only the 2nd and subsequent ones trigger their own
unhandled-rejection warnings.

I think the best place to start in understanding this would be to step back
and make sure you understand what it is that triggers these errors. Node
triggers these errors when a promise object has been rejected but has no
handlers to do respond to the rejection. I forget exactly what point Node
checks for handlers these days, if that point is at the end of the job
execution or on GC of promises now or what but that's not important for
this case.

Let's look at your example. I'm also simplifying it to
```
var p = Promise.reject(789);
var one = p.finally(() => {});
var two = p.finally(() => {});
var three = p.finally(() => {});
```

1)
```
var p = Promise.reject(789);
```
There is only one promise here, `p`, and it has no handlers ever attached
to it so there is nothing to handle the rejection error, hence the single
uncaught rejection error.

2)
```
var p = Promise.reject(789);
var one = p.finally(() => {});
```
There are 2 promises here, `p`, which has one handler (the `finally` that
will take the rejection of `p` and in turn reject `one`) and `one`, which
has no handlers attached, so you again get a single uncaught rejection. It
as not that the first "finally" gets a "free pass", it is that rejections
from `p` are no longer uncaught, but you have added a new promise that is
uncaught, so the overall number of uncaught rejections does not change.

3)
```
var p = Promise.reject(789);
var one = p.finally(() => {});
var two = p.finally(() => {});
```
Hopefully you can see where this is going. `p` now has 2 handlers attached
so its rejection isn't uncaught, but now both `one` and `two` have no
handlers, so _both_ will trigger an uncaught rejection error.

4)
```
var p = Promise.reject(789);
var one = p.finally(() => {});
var two = p.finally(() => {});
var three = p.finally(() => {});
```
And finally now we have `one`, `two` and `three` all with no handlers
attached, so you will get three uncaught rejection errors.

Hope that helps!


On Sun, Mar 29, 2020 at 9:03 AM Felipe Gasper 
wrote:

> Hello,
>
> In node 12 as well as the latest Chrome and FF (all on macOS) I see the
> following:
>
> -
> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); n(789);
> ==> produces 1 unhandled-rejection warning
>
> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); p.finally( ()
> => {} ); n(789);
> ==> produces 1 unhandled-rejection warning
>
> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); p.finally( ()
> => {} ); p.finally( () => {} ); n(789);
> ==> produces 2 unhandled-rejection warnings
>
> var y,n; var p = new Promise( (yy,nn) => { y=yy; n=nn } ); p.finally( ()
> => {} ); p.finally( () => {} ); p.finally( () => {} ); n(789);
> ==> produces 3 unhandled-rejection warnings
>
> -
>
> Could someone point me to something that would help me to understand the
> logic here? It looks like the first finally() is getting a “free pass”
> while only the 2nd and subsequent ones trigger their own
> unhandled-rejection warnings.
>
> Thank you!
>
> cheers,
> -Felipe Gasper
> ___
> 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: how many async-modules can js-app practically load?

2019-05-22 Thread Logan Smyth
Can you elaborate on what loading state you need to keep track of? What is
the bottleneck that you run into? Also to be sure, when you say async-load,
do you mean `import()`?

On Wed, May 22, 2019, 20:17 kai zhu  wrote:

> i don't use es-modules.
> but with amd/requirejs, I start having trouble with module-initializations
> in nodejs/browser at ~5 async modules (that may or may not have
> circular-references).  10 would be hard, and 20 would be near inhuman for
> me.
>
> can we say its somewhat impractical for most applications to load more
> than 50 async modules (with some of them having circular-references)?  and
> perhaps better design/spec module-loading mechanisms with this usability
> concern in mind?
>
> p.s. its also impractical for me to async-load 5 or more modules without
> using globalThis to keep track of each module's loading-state.
> ___
> 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: Symbol.inspect

2019-04-04 Thread Logan Smyth
Symbols seems like a good way to do this, but since the ECMA spec doesn't
define anything about IO, I don't think this would be their responsibility.
This seems more like something the console API spec would expose, e.g.
`console.inspect`, where the `Symbol.XX` namespace would be reserved for
ECMAScript-builtin symbols.

On Thu, Apr 4, 2019 at 5:44 PM Sultan  wrote:

> Like Symbol.iterator, a Symbol.inspect symbol for use in implementing
> cross-platform console display introspection.
>
> Currently node has something akin to this with a magic inspect method on
> objects.
>
> This would pave a cow path for how different platforms can afford this
> ability to consumers without each inventing their own heuristic, i.e in the
> browser i might have an exotic object that i want console.error to display
> a toString payload instead of the objects shape.
> ___
> 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: Promise.resolve

2019-02-02 Thread Logan Smyth
`Promise` can be subclassed, so the `this` context for `resolve` affects
what class is instantiated.

On Sat, Feb 2, 2019 at 12:25 PM Sultan  wrote:

> Was there any reason Promise.resolve was not afforded the ability to
> dispatch outside of `this` pointing to the `Promise` constructor?
>
> For example:
>
> const {resolve} = Promise
> resolve(1234)
>
> This currently throws.
> ___
> 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: NumberFormat maxSignificantDigits Limit

2019-01-20 Thread Logan Smyth
It does seem unclear why the limit is 21. Is that maybe the most you need
to uniquely stringify any double value?

> an only encode up to 17 significant decimal digits

That's true for decimal values, but the limit of 21 would also include the
fractional portion of the double value as well, so would need more than 17,
I think?

On Sun, Jan 20, 2019 at 1:18 PM Isiah Meadows 
wrote:

> I feel this is probably best asked at https://github.com/tc39/ecma402,
> since it seems to imply a potential spec bug.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jan 20, 2019 at 2:31 PM Anders Rundgren <
> anders.rundgren@gmail.com> wrote:
>
>> On 2019-01-20 20:18, Ethan Resnick wrote:
>> > Hi,
>> >
>> > Apologies if es-discuss is the wrong venue for this; I've tried first
>> poring through the specs and asking online to no avail.
>> >
>> > My question is: why is the limit for the `maximumSignificantDigits`
>> option in the `NumberFormat` API set at 21? This seems rather arbitrary —
>> and especially odd to me given that, iiuc, all Numbers in JS, as 64 bit
>> floats, can only encode up to 17 significant decimal digits. Is this some
>> sort of weird historical artifact of something? Should the rationale be
>> documented anywhere?
>>
>> I don't know for sure but if you input this in a browser debugger it will
>> indeed respond with the same 21 [sort of] significant digits
>> 0
>>
>> rgds,
>> Anders
>> >
>> > Thanks!
>> >
>> > Ethan
>> >
>> > ___
>> > 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-04 Thread Logan Smyth
The type of the target is what affects typeof, indirectly by setting the
[[Call]] value. If an `apply` or `construct` trap handler is given and the
target isn't a function, they are ignored. See step 7 in
https://www.ecma-international.org/ecma-262/9.0/index.html#sec-proxycreate

On Tue, Dec 4, 2018 at 2:08 PM Isiah Meadows  wrote:

> BTW, `typeof new Proxy({}, {apply() { return 1 }})` returns
> `"object"`, not `"function"`. Not sure this is any different.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> On Tue, Dec 4, 2018 at 2:02 PM Jordan Harband  wrote:
> >
> > What would `typeof` return on a callable object? There's a lot of code
> on the web that uses a typeof of "function" to determine if something is
> safe to call. There's also a lot of code on the web that uses a typeof of
> "function" to do type detection. How would you suggest a callable object
> navigate these potentially conflicting constraints?
> >
> > On Tue, Dec 4, 2018 at 10:07 AM T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
> >>
> >> On Tue, Dec 4, 2018 at 5:02 PM Sultan
> >>  wrote:
> >> >
> >> > Something along the lines of Symbol.iterator protocol for defining
> >> > callback objects i.e: Symbol.callable:
> >>
> >> That's interesting. What's the primary motivation? Binding the data?
> That's easily done with a closure ([fiddle[1]):
> >>
> >> ```js
> >> const obj = (() => {
> >> let value = 'value';
> >> return () => value;
> >> })();
> >>
> >> console.log(obj() === 'value'); // true
> >> ```
> >>
> >> It's a bit more verbose than one would like, but usually that's washed
> out by the implementation (which is really trivial above).
> >>
> >> You can also do it with a Proxy on a function, but it doesn't really
> buy you anything.
> >>
> >> Be interested to know more about why you want non-function callable
> objects.
> >>
> >> -- T.J. Crowder
> >>
> >> [1]: http://jsfiddle.net/8qvpc7Lh/
> >> ___
> >> 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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: New: proposal-class-modifiers

2018-12-02 Thread Logan Smyth
der that when some form of private goes in (assuming it's not
> Symbol.Private) class instances will be quite a bit different than vanilla
> objects.
>
> I get that `final` is something not seen in dynamic languages (outside the
> JVM), but it is a useful tool in giving developers control over how their
> code can be used. Isn't that part of the point of trying to implement
> private data in ES?
>
> On Sun, Dec 2, 2018 at 4:19 PM Isiah Meadows 
> wrote:
>
>> @Logan If this helps explain my stance, I'm skeptical of the use, and
>> it really disrupts the consistency of JS's object model quite a bit.
>> It makes sense to enforce at a static level, but not really at a
>> dynamic runtime level. Also, this is lacking precedent in other
>> dynamic languages with classes: Python, Ruby, Smalltalk, Lua, Io, and
>> pretty much every other dynamic language with class- or
>> prototype-based inheritance (that wasn't made for the JVM) doesn't
>> support final classes. Python (IIRC through a decorator) and Ruby
>> support abstract methods, but not final classes/methods.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Sun, Dec 2, 2018 at 5:10 PM Logan Smyth  wrote:
>> >
>> > Wouldn't it be better `abstract`'s `target.prototype ===
>> newTarget.prototype` check to be `target === newTarget`? It's not really
>> the prototype that is at issue here, it is the class constructor itself. It
>> would not be good if you could sidestep `abstract` by taking the prototype
>> from the class and making a new constructor for it.
>> >
>> > For `final` is it worth throwing an `extends` time vs just throwing
>> when the class is instantiated? It seems like `final` would otherwise
>> require new private state on the constructor itself, where otherwise it
>> would essentially just be the negation of the check `abstract` was doing
>> already.
>> >
>> > Also, if those make sense, what do we gain by having these be keywords
>> instead of decorators?
>> >
>> > On Sun, Dec 2, 2018 at 1:43 PM Isiah Meadows 
>> wrote:
>> >>
>> >> For `abstract`, I could see that being three things:
>> >>
>> >> - Throw a reference error if an abstract method is called with no
>> concrete implementation
>> >> - Throw a type error if the constructor is called without its abstract
>> methods implemented
>> >> - Throw a type error if a subclass fails to implement all remaining
>> abstract methods and is not itself abstract
>> >>
>> >> Each of these could be reasonably tacked on at the end.
>> >>
>> >> For `final`, you'll need to create a way to block all means of
>> `Object.create`, with class constructors being the sole exception. That
>> complicates the mechanism tremendously, since prototype-based inheritance
>> alone can't enforce this unless you make `Object.setPrototypeOf(obj,
>> parent)` no longer directly equivalent to `obj.[[Prototype]] = parent`.
>> >> On Sun, Dec 2, 2018 at 16:28 Ranando King  wrote:
>> >>>
>> >>> Object.create and Object.setPrototypeOf operate on a different level
>> than what I'm targeting. I can conceive of a means to make even these
>> functions respect these tokens. However, if I were going to do that, I'd
>> want these tokens to be applicable to objects and functions directly.
>> Reflect.construct is essentially part of the process for `new` and would be
>> required to respect these tokens. I'm still open on how far the effect of
>> these tokens should extend.
>> >>>
>> >>> On Sun, Dec 2, 2018 at 3:20 PM Isiah Meadows 
>> wrote:
>> >>>>
>> >>>> How would this interop with `Object.create`, `Reflect.construct`,
>> and `Object.setPrototypeOf`?
>> >>>> On Sun, Dec 2, 2018 at 16:16 Ranando King  wrote:
>> >>>>>
>> >>>>> This proposal is intended to add `abstract` and `final` to `class`
>> definitions so as to modify the inheritability of a class.
>> >>>>>
>> >>>>> https://github.com/rdking/proposal-class-modifiers
>> >>>>> ___
>> >>>>> 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: New: proposal-class-modifiers

2018-12-02 Thread Logan Smyth
Wouldn't it be better `abstract`'s `target.prototype ===
newTarget.prototype` check to be `target === newTarget`? It's not really
the prototype that is at issue here, it is the class constructor itself. It
would not be good if you could sidestep `abstract` by taking the prototype
from the class and making a new constructor for it.

For `final` is it worth throwing an `extends` time vs just throwing when
the class is instantiated? It seems like `final` would otherwise require
new private state on the constructor itself, where otherwise it would
essentially just be the negation of the check `abstract` was doing already.

Also, if those make sense, what do we gain by having these be keywords
instead of decorators?

On Sun, Dec 2, 2018 at 1:43 PM Isiah Meadows  wrote:

> For `abstract`, I could see that being three things:
>
> - Throw a reference error if an abstract method is called with no concrete
> implementation
> - Throw a type error if the constructor is called without its abstract
> methods implemented
> - Throw a type error if a subclass fails to implement all remaining
> abstract methods and is not itself abstract
>
> Each of these could be reasonably tacked on at the end.
>
> For `final`, you'll need to create a way to block all means of
> `Object.create`, with class constructors being the sole exception. That
> complicates the mechanism tremendously, since prototype-based inheritance
> alone can't enforce this unless you make `Object.setPrototypeOf(obj,
> parent)` no longer directly equivalent to `obj.[[Prototype]] = parent`.
> On Sun, Dec 2, 2018 at 16:28 Ranando King  wrote:
>
>> Object.create and Object.setPrototypeOf operate on a different level than
>> what I'm targeting. I can conceive of a means to make even these functions
>> respect these tokens. However, if I were going to do that, I'd want these
>> tokens to be applicable to objects and functions directly.
>> Reflect.construct is essentially part of the process for `new` and would be
>> required to respect these tokens. I'm still open on how far the effect of
>> these tokens should extend.
>>
>> On Sun, Dec 2, 2018 at 3:20 PM Isiah Meadows 
>> wrote:
>>
>>> How would this interop with `Object.create`, `Reflect.construct`, and
>>> `Object.setPrototypeOf`?
>>> On Sun, Dec 2, 2018 at 16:16 Ranando King  wrote:
>>>
 This proposal is intended to add `abstract` and `final` to `class`
 definitions so as to modify the inheritability of a class.

 https://github.com/rdking/proposal-class-modifiers
 ___
 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: Expectations around line ending behavior for U+2028 and U+2029

2018-10-29 Thread Logan Smyth
Sounds good. This means that the expectation, from the standpoint of
Unicode spec, is that all existing parsers and tooling for all languages
would also be updated to have line numbering that include U+2028/29, or
else that the line numbers would indefinitely be out of sync with the line
numbers rendered in an editor, when a file contains these characters. I
assume it would be a breaking change for most languages to add U+2028/29 as
line terminators for line comments and potentially string content at a
minimum, meaning that even if the editors render them as line separators,
it would still be a single-line token bridging multiple lines in those
languages.

I understand the desire for all this, but I hope it's understandable why
this situation is a little frustrating. There is no clean way to update any
given tool to treat U+2028/29 as newlines without either special-casing JS
or accepting that the tool's line numbers will not correspond with line
numbers from any tool that does not treat them as newlines, which is
realistically the vast majority of tooling and parsers. It is difficult to
make the argument to migrate any given tool when you're migrating away from
the current defacto behavior, even if you're migrating to the
Unicode-defined behavior, especially when it's not clear that the community
as a whole is even aware that they should be treating these as newlines in
the first place.




On Fri, Oct 26, 2018 at 4:52 PM Isiah Meadows 
wrote:

> So in other words, all these IDEs are broken and in violation of the
> Unicode spec. BTW, VSCode depends on Chrome, so it'll likely have most
> of the same behavior if it doesn't correctly account for them..
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Fri, Oct 26, 2018 at 5:49 PM Logan Smyth  wrote:
> >
> > Great, thank you for that resource Allen, it's helpful to have something
> concrete to consider.
> >
> > What you'd prefer is that that other languages should also be rendered
> with U+2028/29 as creating new lines, even though their specifications do
> not define them as lines? That means that any parser for these languages
> that follows the language spec would them be outputting line numbers that
> would potentially not correspond with the code as rendered inside of the
> developer's editor, if the editor renders U+2028/29 a line separators? That
> would for instance mean that Rust's single-line comments could actually be
> rendered as multiple lines, even though they are a single line according to
> the spec.
> >
> > My frustration here isn't that the characters exist, it's just that
> their behavior in a world of explicitly defined syntactic grammars that
> depend on line numbers for errors and things, they seem poorly-defined,
> even if their behavior in text documents may have more meaning. For
> instance, here is XCode's rendering of 2028/2029
> >
> >
> > 2028 does seem to render as a "line separator" in that visually the code
> is on a new line, but it is rendered within the same line number marker as
> the start of that snippet of text. That seems to satisfy the behavior
> defined by Unicode, but it's not helpful from the standpoint of code
> looking to process sourcecode. Should a parser follow that definition of
> line separator, since 2028 suggests rendering a new line, but since it's
> not a paragraph, it's conceptually part of the same paragraph? What is a
> paragraph in source code? Unicode has no sense of line numbers as far as I
> know, which means it seems up to an individual language to define what line
> number a given token is on.
> >
> >
> > > All of them recognise both characters as newlines (and increment the
> line number for those that display it).
> >
> > Revisiting my tests on my OSX machine, it seems like there is a
> difference in treatment of 2028 and 2029 that threw off at least some of my
> tests.
> > * VSCode: 2028 is a unicode placeholder and 2029 seems to be rendered
> zero-width, no new lines
> > * Sublime 3: 2028/29 rendered zero-width, no new lines
> > * TextEdit: 2028 is a newline, 2029 is zero-width, no new lines
> > * XCode: Per above screenshot, 2028 creates a line but renders within
> the same line number, 2029 creates a new line number
> > * Firefox, Chrome, and Safari, with text in a  or 
> renders them all on one line zero-width, no new lines (though how HTML
> renders may just be a whole separate question)
> >
> >
> > On Fri, Oct 26, 2018 at 7:42 AM Claude Pache 
> wrote:
> >>
> >>
> >>
> >> >
> >> > Would it be worth exploring a definition of U+2028/29 in the spec
> such that they behave as line terminators for ASI, but otherwise do not
> incr

Re: Expectations around line ending behavior for U+2028 and U+2029

2018-10-26 Thread Logan Smyth
Great, thank you for that resource Allen, it's helpful to have something
concrete to consider.

What you'd prefer is that that other languages should also be rendered with
U+2028/29 as creating new lines, even though their specifications do not
define them as lines? That means that any parser for these languages that
follows the language spec would them be outputting line numbers that would
potentially not correspond with the code as rendered inside of the
developer's editor, if the editor renders U+2028/29 a line separators? That
would for instance mean that Rust's single-line comments could actually be
rendered as multiple lines, even though they are a single line according to
the spec.

My frustration here isn't that the characters exist, it's just that their
behavior in a world of explicitly defined syntactic grammars that depend on
line numbers for errors and things, they seem poorly-defined, even if their
behavior in text documents may have more meaning. For instance, here is
XCode's rendering of 2028/2029
[image: Screen Shot 2018-10-26 at 2.33.56 PM.png]

2028 does seem to render as a "line separator" in that visually the code is
on a new line, but it is rendered within the same line number marker as the
start of that snippet of text. That seems to satisfy the behavior defined
by Unicode, but it's not helpful from the standpoint of code looking to
process sourcecode. Should a parser follow that definition of line
separator, since 2028 suggests rendering a new line, but since it's not a
paragraph, it's conceptually part of the same paragraph? What is a
paragraph in source code? Unicode has no sense of line numbers as far as I
know, which means it seems up to an individual language to define what line
number a given token is on.


> All of them recognise both characters as newlines (and increment the line
number for those that display it).

Revisiting my tests on my OSX machine, it seems like there is a difference
in treatment of 2028 and 2029 that threw off at least some of my tests.
* VSCode: 2028 is a unicode placeholder and 2029 seems to be rendered
zero-width, no new lines
* Sublime 3: 2028/29 rendered zero-width, no new lines
* TextEdit: 2028 is a newline, 2029 is zero-width, no new lines
* XCode: Per above screenshot, 2028 creates a line but renders within the
same line number, 2029 creates a new line number
* Firefox, Chrome, and Safari, with text in a  or  renders
them all on one line zero-width, no new lines (though how HTML renders may
just be a whole separate question)


On Fri, Oct 26, 2018 at 7:42 AM Claude Pache  wrote:

>
>
> >
> > Would it be worth exploring a definition of U+2028/29 in the spec such
> that they behave as line terminators for ASI, but otherwise do not
> increment things line number counts and behave as whitespace characters?
>
> Diverging the definition of line terminator for the purpose of line
> counting on one side, and ASI and single-line comment on the other side, is
> adding yet another complication in a matter that is already messy. And I
> suspect that most tools that have issues with the former case, have issues
> as well with the latter case, so that half-fixing is equivalent to not
> fixing.
>
> If we want to ”fix” the definition of line terminator somewhere, we should
> ”fix” it everywhere.
>
> (Note that the recent addition of U+2028 and U+2029 inside string literals
> does not constitutes a modification of the definition of line terminator in
> that context; it is rather allowing string literals to span multiple lines
> in some specific cases.)
>
> —Claude
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Expectations around line ending behavior for U+2028 and U+2029

2018-10-25 Thread Logan Smyth
> Tools that do not consider U+2028/29 to be line breaks are not behaving
as they should according to the latest Unicode standard.

That's part of what I'm attempting to understand. What specifically does
Unicode require for these code points? What are the expectations for
languages that have differing definitions of line separators? The HTML spec
defines newlines in https://html.spec.whatwg.org/#newlines as CR and LF
only. Is that technically in violation of the Unicode spec then? If code
editors were to adopt U+2028 and U+2029 as line separators, is the
expectation that they would apply that to HTML files too, even though that
would put the the editor's concept of a line in conflict with the
language's specification?

It seems unrealistic to expect that all tooling that processes source code
would adopt a new type of line separator. Given that, JS is the outlier.
Similarly, does Unicode make any guarantees about what counts as a line
terminator? If it changes in the future, would JS be forced to add that as
a type of LineTerminator as well? If it did, that could break existing
code, and if it doesn't, then JS would end up right back in the same place
with a concept of line numbers that differs from other tooling. CR and LF
are already the defacto standards, is it really realistic to expect tooling
to _ever_ change? It is much more likely that JS will have simply specified
itself as a special-case forever, which tooling will never handle.

On Thu, Oct 25, 2018 at 3:10 PM Waldemar Horwat  wrote:

> On 10/25/2018 09:24 AM, Logan Smyth wrote:
> > Yeah, /LineTerminatorSequence/ is definitely the canonical definition of
> line numbers in JS at the moment. As we explore
> https://github.com/tc39/proposal-error-stacks, it would be good to
> clearly specify how a line number is computed from the original source. As
> currently specified, a line number in a stack trace takes U+2028/29 into
> account, and thus requires any consumer of this source code and line number
> value needs to have a special case for JS code. It seems unrealistic to
> expect every piece of tooling that works with source code would have a
> special case for JS code to take these 2 characters into account. Given
> that, the choices are
> >
> > 1. Every tool that manipulates source code needs to know what type so it
> can special-case JS it is in order to process line-related information
> > 2. Every tool should consider U+2028/29 newlines, causing line numbers
> to be off in other programming languages
> > 2. Accept that tooling and the spec will never correspond and the use of
> these two characters in source code will continue to cause issues
> > 3. Diverge the definition of current source-code line from the current
> /LineTerminatorSequence/ lexical grammar such that source line number is
> always /\r?\n/, which is what the user is realistically going to see in
> their editor
>
> The Unicode standard is the more relevant one here.  Choice 2 is the
> correct one per the Unicode standard.  Tools that do not consider U+2028/29
> to be line breaks are not behaving as they should according to the latest
> Unicode standard.
>
>  Waldemar
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Expectations around line ending behavior for U+2028 and U+2029

2018-10-25 Thread Logan Smyth
Yeah, *LineTerminatorSequence* is definitely the canonical definition of
line numbers in JS at the moment. As we explore
https://github.com/tc39/proposal-error-stacks, it would be good to clearly
specify how a line number is computed from the original source. As
currently specified, a line number in a stack trace takes U+2028/29 into
account, and thus requires any consumer of this source code and line number
value needs to have a special case for JS code. It seems unrealistic to
expect every piece of tooling that works with source code would have a
special case for JS code to take these 2 characters into account. Given
that, the choices are

1. Every tool that manipulates source code needs to know what type so it
can special-case JS it is in order to process line-related information
2. Every tool should consider U+2028/29 newlines, causing line numbers to
be off in other programming languages
2. Accept that tooling and the spec will never correspond and the use of
these two characters in source code will continue to cause issues
3. Diverge the definition of current source-code line from the current
*LineTerminatorSequence* lexical grammar such that source line number is
always /\r?\n/, which is what the user is realistically going to see in
their editor




On Wed, Oct 24, 2018 at 9:09 PM Richard Gibson 
wrote:

> The only explicit mention of line numbers in the spec is to note that
> "… should be considered a single SourceCharacter for the purpose of
> reporting line numbers", but it's clear from things like ASI and
> termination of single-line comments that every *LineTerminatorSequence* is
> equal in this sense. Editors and HTML are free to do what they want, but in
> my opinion ECMAScript tooling at least should not pretend that these input
> elements don't terminate lines.
>
> On Wed, Oct 24, 2018 at 3:58 PM Logan Smyth  wrote:
>
>> Something I've recently realized just how much U+2028 and U+2029 being
>> newlines introduces a mismatch between different parts of a dev
>> environment, and I'm curious for thoughts.
>>
>> Engines understandable take these two characters into account when
>> defining their line number offsets in stack traces, since they are part of
>> the LineTerminator grammar. Similarly, Babel's parser and I assume others
>> will do the same and take then into account for their line number data. On
>> the other hand, it seems like every editor that I've looked at so far will
>> not render these characters as newlines, which can create confusion for
>> users because error messages will not align with what they see in their
>> editors. This seems like a burden for editors, since they would need to
>> know the type of file in order to know how to render it. There's also a
>> question of mixed content. If I have an HTML file with a 

Expectations around line ending behavior for U+2028 and U+2029

2018-10-24 Thread Logan Smyth
Something I've recently realized just how much U+2028 and U+2029 being
newlines introduces a mismatch between different parts of a dev
environment, and I'm curious for thoughts.

Engines understandable take these two characters into account when defining
their line number offsets in stack traces, since they are part of the
LineTerminator grammar. Similarly, Babel's parser and I assume others will
do the same and take then into account for their line number data. On the
other hand, it seems like every editor that I've looked at so far will not
render these characters as newlines, which can create confusion for users
because error messages will not align with what they see in their editors.
This seems like a burden for editors, since they would need to know the
type of file in order to know how to render it. There's also a question of
mixed content. If I have an HTML file with a 

Re: Module Namespace Objects - "writable"

2018-10-24 Thread Logan Smyth
Here's one other post about this from Allen:
https://github.com/tc39/ecma262/issues/749#issuecomment-265637923

On Wed, Oct 24, 2018 at 10:42 AM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> I'm curious if I've inferred the rationale for something correctly.
>
> The module namespace object properties for exports have `writable: true`
> in their property descriptors, but of course, they aren't writable (the
> module namespace object has its own [[Set]] implementation that returns
> false). I wondered why they weren't `writable: false`, so I went looking.
>
> I found discussion in the March 24 2015 meeting notes about whether to
> even have `getOwnPropertyDescriptor` work. The consensus was yes, it should
> work (mixins!), and that it should report a basic data property that isn't
> configurable -- but is writable. Yahuda Katz points out that:
>
> > it is writable, but it's not writable by you
>
> though that's not always true (it may be declared `const`; that
> information isn't leaked from the module, though).
>
> In the May 25 2017 notes I found a comment from Mark S. Miller in relation
> to `writable: true`:
>
> > Non-writeable provides guarantee. Writable provides no guarantee.
>
> And this exchange between Yahuda Katz, Allen Wirfs-Brock, and Adam Klein:
>
> > YK: There is a a new property that we define as writable that is not
> writable.
> >
> > AWB: Not new.
> >
> > AK: Since... Proxys!
>
> There was some discussion of considering some flag basically saying what
> YK said, e.g., it's writable, but not by you :-) -- but that was more a
> brief digression that didn't go anywhere.
>
> So, then, what I infer is: They're marked writable because:
>
> 1. They may be writable by the exporting module, so code can't assume the
> value won't change; `writable: false` would make that assumption valid
> 2. Whether or not they're writable by the exporting module isn't
> information that should leak out of it
> 3. Non-writable `writable: true` data properties were already a thing
> (Proxies)
>
> So the most sensible thing was `writable: true` rather than `writable:
> false`.
>
> How'd I do? :-)
>
> -- T.J. Crowder
> ___
> 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: await enhancement proposal: Wrap Array return values with Promise.all

2018-09-22 Thread Logan Smyth
Making `await` itself do this would be a breaking change, so that'd be very
unlikely. There was discussion around an `await*` similar to the existing
`yield*` for generators, but I think it was deemed unneeded complexity
since `Promise.all` was already pretty easy to use, especially since it
isn't 100% obvious from the usage of an array what should be done. For
instance `Promise.race` also works on an iterable value. I'm not really
involved with the process, so I can't say more though.

On Sat, Sep 22, 2018 at 12:25 AM Rudi Cilibrasi  wrote:

> Greetings,
>
> I have enjoyed using the `await` keyword tremendously in async code. One
> point I notice in using it is that it is ideal in terms of clarity and
> composability but limited in a sense to sequential composition. That is, I
> cannot easily use `await` (by itself) to do parallel calculations.
>
> A few times, I have myself hit a bug where I return (without thinking) an
> Array of Promise only to find that none will resolve using `await` on the
> Array. I noticed others have similar bugs. [1,2] I frequently wind up
> wrapping them in one of two ways: a) occasionally a for loop that awaits
> each in sequence, but b) more often a `Promise.all`. I think the current
> `await` syntax makes every kind of sequential composition quite simple to
> read, write, and maintain, but the fact that we have to introduce
> `Promise.all` for each case of parallel (overlapping) execution seems to be
> a common cause of bugs and a minor aesthetic issue to me as well as perhaps
> maintenance. It occurs to me that for my cases, and indeed perhaps others,
> a useful rule would be that all `await` on `Array` behave as if the Array
> were wrapped in `Promise.all`.  Then we can have a nice parallel
> composition syntax built into the language with the keyword using Array and
> lists can become idiomatic and concise parallel composition operators. I
> feel like this could improve the readability, power, and real time
> responsiveness of the language without necessarily sacrificing quality nor
> clarity.
>
> await on an Array value v acts as await Promise.all(v)
>
> Weighing against this idea seems to be the usual: operator tricks are
> unsearchable via keywords compared to `Promise.all`. So there is a style
> question however with the latest addition of the great new
> optional-chaining and pipeline ideas I thought it might be a good time to
> give this idea a try.
>
> What does the group think about this await enhancement proposal?
>
> Best regards,
>
> Rudi Cilibrasi
>
> [1]:
> https://stackoverflow.com/questions/38694958/javascript-async-await-for-promises-inside-array-map
> [2]:
> https://stackoverflow.com/questions/37360567/how-do-i-await-a-list-of-promises-in-javascript-typescript
>
> --
> Happy to Code with Integrity : Software Engineering Code of Ethics and
> Professional Practice 
> ___
> 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: constructor, super, and data members issue

2018-08-26 Thread Logan Smyth
Static class fields run their initializers and define the properties at
declaration time, and class constructors have the parent class as the
`[[Prototype]]`, so static field values are inherited. I think this is
adding to confusion though, because while that's absolutely true, that is
not applicable in the same way to non-static class fields, which is what
this original email is focused on. You could indeed also address this with
static properties in a proper ES6 environment as
```
class Base {
  static idAttribute = "id";

  constructor() {
   this.idAttribute = new.target.idAttribute;
  }
}
class Derived extends Base {
  static idAttribute = "_id";

  constructor() {
   super();
  }
}
```

On Sun, Aug 26, 2018 at 10:35 AM Isiah Meadows 
wrote:

> Every object, including functions, have an internal prototype. Functions
> normally have one set to `Function.prototype`, and objects normally inherit
> from `Object.prototype` at least indirectly. But because of how prototypes
> work, the only requirement for something to be used as a prototype is that
> it must be an object. So you can do `Object.create(someFunction)` and
> although you can't call it (it's not a callable object), that object
> inherits all the properties and methods from that function. `class` in
> JavaScript is just sugar over a common pattern (really complex sugar
> requiring `new.target` to emulate, but still sugar), not an entirely new
> concept, and it all builds off of prototypes. Specifically, the instance
> prototype inherits from the parent prototype, and the class constructor
> itself inherits from the parent constructor. That's why if you declare a
> static `call` method on a parent class, you can still access and use it in
> the subclass.
> On Sat, Aug 25, 2018 at 19:58 Ben Wiley  wrote:
>
>> How can they be prototypically inherited if they don't live on the
>> prototype? I feel like I'm missing something.
>>
>> Le sam. 25 août 2018 19 h 53, Isiah Meadows  a
>> écrit :
>>
>>> Class fields are prototypically inherited just like via `Object create`.
>>> This is more useful than you might think, and it's the main reason anyone
>>> actually cares about static fields beyond namespacing.
>>> On Sat, Aug 25, 2018 at 14:36 Ben Wiley 
>>> wrote:
>>>
>>>> All this just reminds me of *my opinion* that class fields is a
>>>> borrowed concept from statically typed languages that is misplaced in a
>>>> dynamically typed languages like JavaScript.
>>>>
>>>> In C++ I use class fields to declare what properties will be allocated
>>>> and instantiated when a new class member is constructed.
>>>>
>>>> In the ES proposal for class fields we mimic this type of behavior by
>>>> instantiating properties on the object when it's constructed, but there's
>>>> no runtime guarantee that this set of properties will remain the same.
>>>>
>>>> There's no reason not to put this in the constructor, and although
>>>> putting class fields on the prototype is debatably not the best idea, it
>>>> would be the only scenario where we get some kind of new helpful behavior
>>>> out of it.
>>>>
>>>> Ben
>>>>
>>>> Le sam. 25 août 2018 14 h 25, Augusto Moura 
>>>> a écrit :
>>>>
>>>>> 24-08-2018 19:29, Aaron Gray :
>>>>>
>>>>> >
>>>>> > Yeah it does look like its badly "broken by design".
>>>>> >
>>>>>
>>>>> Why this behaviour is broken? Every OOP language that I worked with
>>>>> behaves de same way, and there's not many developers complaining about
>>>>> it. If you want to use a property that might be overrided in a
>>>>> subclasss you need to use a method and make the source of the data
>>>>> more versatile (in Java and others similiar languages we have to
>>>>> implement it using getter methods). Luckily Javascript doesn't need
>>>>> getter and setters methods to make a property overridable because of
>>>>> getter and setters descriptors, so we can workaround the first example
>>>>> easily:
>>>>>
>>>>> ``` js
>>>>> class Bar {
>>>>>   bar = 'in bar';
>>>>>
>>>>>   constructor() {
>>>>> console.log(this.bar)
>>>>>   }
>>>>> }
>>>>>
>>>>> class Foo extends Bar {
>>>>>   _initiedSuper = false;
>>>>>   _bar = 'in foo';
>>

Re: constructor, super, and data members issue

2018-08-24 Thread Logan Smyth
Generally if something is required during construction, it would be best to
pass it down as part of the constructor options. For example, you could do
```
class Base {
  constructor({ idAttribute = "id"}) {
this.idAttribute = idAttribute;
  }
}

class Derived extends Base {
  constructor() {
super({
  idAttribute: '_id'
});
  }
}
```

I don't think class fields would be a good way to conceptually do this kind
of thing.


On Fri, Aug 24, 2018 at 2:56 PM, Aaron Gray 
wrote:

> Yeah it does look like its badly "broken by design".
>
> On Fri, 24 Aug 2018 at 22:13, Jordan Harband  wrote:
>
>> I'm afraid that still wouldn't solve the problem; the superclass's code
>> is all 100% completed before the subclass has `this` available.
>>
>> On Fri, Aug 24, 2018 at 1:52 PM, Ranando King  wrote:
>>
>>> Aaron, congratulations! You just tripped over a new reason for me to
>>> revive issue #123. The only way to get that to work is to have the default
>>> values on the prototype. The problem comes because `this` doesn't even have
>>> a value until the last call to `super()` returns. If a `class` doesn't have
>>> a base `class` it essentially has Object as a base `class` and `super` is
>>> implicitly called. So unless the default public field values are on the
>>> prototype, there's literally no way to have them initialized before the
>>> base classes are initialized.
>>>
>>> On Fri, Aug 24, 2018 at 3:15 PM Aaron Gray 
>>> wrote:
>>>
 I am having an issue with order semantics regarding https://github.com/
 tc39/proposal-class-fields with derived classes defining or overriding
 data member values that are used in the base class constructor for
 initialization of properties of the class.

 This means the Super Class / Base Class'es constructor does not yet
 have access to the default field values of the derived class it is
 initiating.

 class Base {
 constructor() {
  
  .. idAttribute ..
  
 }
 idAttribute = 'id';
 }
class Derived extends Base {
 constructor() {
  super();
  
 }
 idAttribute = '_id';
}

 All would mean having a separate initialize() function, but even this
 solution is flawed when there is a third level in the hierarchy. And as
 super() is required it means there seems to be no way round this issue. The
 only way I can see is some form of override keyword ?


 Has anyone got any solutions to this issue or work arounds ?
 --
 Aaron Gray

 Independent Open Source Software Engineer, Computer Language
 Researcher, Information Theorist, and amateur computer scientist.
 ___
 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
>>>
>>>
>>
>
> --
> Aaron Gray
>
> Independent Open Source Software Engineer, Computer Language Researcher,
> Information Theorist, and amateur computer scientist.
>
> ___
> 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: Class data member declarations proposal idea

2018-08-10 Thread Logan Smyth
> That and the syntax.

The syntax snippet you posted is identical to what is already supported by
the class fields proposal alongside Flowtype. You can see this with Babel:
https://babeljs.io/repl/#?babili=false===false=false=true_lz=MYGwhgzhAEAa0FMAeAXBA7AJjAmtA3gFDTTAD26EKATgK7ApnUAUAlAdBLQA4IvsBfYtEwIAZmFogUMALwFhJMAC5oARgA0i6ACNVAJmFCSSaKoCS6NAHM-0eQGZhYALIIUACzKY2HIQKA=false=false=false==false=false=module=true=react%2Cstage-0=false==6.26.0=1.6.2

It would help to clarify what is different about how you envision fields to
behave.

On Fri, Aug 10, 2018 at 2:59 AM, Aaron Gray 
wrote:

> On Fri, 10 Aug 2018 at 00:09, Logan Smyth  wrote:
>
>> It might help if you could clarify how your proposal diverges from the
>> class fields proposal that you linked to. From purely a syntactic view,
>> ignoring the type annotations, I don't see an obvious difference, so it is
>> hard to tell what your expectations are. You state "I have shown the
>> idea of declaring subobject default value declarations.", but I can't
>> actually tell what that means or what you intended to show. Is
>> ```
>> defaults = {
>>   a: 1,
>>   b: 2
>> }
>> ```
>> meant to create a property called `defaults`, or do something else?
>>
>
> That and the syntax.
>
> Aaron
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Class data member declarations proposal idea

2018-08-09 Thread Logan Smyth
It might help if you could clarify how your proposal diverges from the
class fields proposal that you linked to. From purely a syntactic view,
ignoring the type annotations, I don't see an obvious difference, so it is
hard to tell what your expectations are. You state "I have shown the idea
of declaring subobject default value declarations.", but I can't actually
tell what that means or what you intended to show. Is
```
defaults = {
  a: 1,
  b: 2
}
```
meant to create a property called `defaults`, or do something else?


On Thu, Aug 9, 2018 at 3:47 PM, Aaron Gray 
wrote:

> On Wed, 8 Aug 2018 at 14:34, Ranando King  wrote:
>
>> Did you see any similarity with my proposal-object-members
>> ? It doesn't have
>> type annotation either. However, that's probably something best left to a
>> separate proposal since it would affect private and public members alike.
>>
>
> This looks excellent.
>
>
> ___
> 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: Overload str.replace to take a Map?

2018-05-18 Thread Logan Smyth
> It wouldn't necessarily break existing API, since
String.prototype.replace currently accepts only RegExp or strings.

Not quite accurate. It accepts anything with a `Symbol.replace` property,
or a string.

Given that, what you're describing can be implemented as
```
Map.prototype[Symbol.replace] = function(str) {
  for(const [key, value] of this) {
str = str.replace(key, value);
  }
  return str;
};
```

> I don't know if the ECMAScript spec mandates preserving a particular
order to a Map's elements.

It does, so you're good there.

> Detecting collisions between matching regular expressions or strings.

I think this would be my primary concern, but no so much ordering as
expectations. Like if you did
```
"1".replace(new Map([
  ['1', '2'],
  ['2', '3],
]);
```
is the result `2` or `3`? `3` seems surprising to me, at least in the
general sense, because there was no `2` in the original input, but it's
also hard to see how you'd spec the behavior to avoid that if general regex
replacement is supported.

On Fri, May 18, 2018 at 9:47 AM, Alex Vincent  wrote:

> Reading [1] in the digests, I think there might actually be an API
> improvement that is doable.
>
> Suppose the String.prototype.replace API allowed passing in a single
> argument, a Map instance where the keys were strings or regular expressions
> and the values were replacement strings or functions.
>
> Advantages:
> * Shorthand - instead of writing str.replace(a, b).replace(c,
> d).replace(e, f)... you get str.replace(regExpMap)
> * Reusable - the same regular expression/string map could be used for
> several strings (assuming of course the user didn't just abstract the call
> into a separate function)
> * Modifiable on demand - developers could easily add new regular
> expression matches to the map object, or remove them
> * It wouldn't necessarily break existing API, since
> String.prototype.replace currently accepts only RegExp or strings.
>
> Disadvantages / reasons not to do it:
> * Detecting collisions between matching regular expressions or strings.
> If two regular expressions match the same string, or a regular expression
> and a search string match, the expected results may vary because a Map's
> elements might not be consistently ordered.  I don't know if the ECMAScript
> spec mandates preserving a particular order to a Map's elements.
>   - if we preserve the same chaining capability 
> (str.replace(map1).replace(map2)...),
> this might not be a big problem.
>
> The question is, how often do people chain replace calls together?
>
> * It's not particularly hard to chain several replace calls together.
> It's just verbose, which might not be a high enough burden to overcome for
> adding API.
>
> That's my two cents for the day.  Thoughts?
>
> [1] https://esdiscuss.org/topic/adding-map-directly-to-string-prototype
>
> --
> "The first step in confirming there is a bug in someone else's work is
> confirming there are no bugs in your own."
> -- Alexander J. Vincent, June 30, 2001
>
> ___
> 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: Proposal: Add a global Infinitesimal property

2018-05-13 Thread Logan Smyth
Ah I think you're right, I had the value of `MIN_VALUE` wrong, sorry.

On Sun, May 13, 2018 at 6:49 AM, kdex <k...@kdex.de> wrote:

> @Logan:
>
> I think the number you're describing there is exactly `Number.MIN_VALUE`,
> isn't it?
>
> The machine epsilon is the smallest value ε for which 1 + ε > 1.
> If we were to consider the relative-to-zero case, we would instead look
> for an
> ε such that 0 + ε > 0 holds. `Number.MIN_VALUE` has this property, since
>
> ```0 + Number.MIN_VALUE === Number.MIN_VALUE```
>
> and there are no positive values smaller than `Number.MIN_VALUE`.
>
> On Saturday, May 12, 2018 7:01:38 PM CEST Logan Smyth wrote:
> > It doesn't sound like `Number.MIN_VALUE` is what you want, is it? You're
> > asking for something like `Number.EPSILON`, but relative to `0` instead
> of
> > `1`?
> >
> > On Sat, May 12, 2018 at 9:57 AM, kdex <k...@kdex.de> wrote:
> > > Already available, just prepend a minus sign like so:
> > >
> > > ```js
> > > -Number.MIN_VALUE
> > > ```
> > >
> > > Yours would be much longer to type and brings no additional value.
> > >
> > > On Saturday, May 12, 2018 6:54:42 PM CEST Abdul Shabazz wrote:
> > > > Ok. How about Number.NEGATIVE_MIN_VALUE
> > >
> > > ___
> > > 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: Proposal: Add a global Infinitesimal property

2018-05-12 Thread Logan Smyth
It doesn't sound like `Number.MIN_VALUE` is what you want, is it? You're
asking for something like `Number.EPSILON`, but relative to `0` instead of
`1`?

On Sat, May 12, 2018 at 9:57 AM, kdex  wrote:

> Already available, just prepend a minus sign like so:
>
> ```js
> -Number.MIN_VALUE
> ```
>
> Yours would be much longer to type and brings no additional value.
>
> On Saturday, May 12, 2018 6:54:42 PM CEST Abdul Shabazz wrote:
> > Ok. How about Number.NEGATIVE_MIN_VALUE
> ___
> 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: Number.MAX_SAFE_INTEGER incorrect?

2018-05-06 Thread Logan Smyth
To clarify, the "you can still add one to them" is probably the most
important part in that definition, given your question.

> Anyway, this definition departs from similar definitions in other
languages and AFAICT, existing JavaScript implementations have no problems
using 2^53 as an integer.

2^53 can be represented just fine, but `2**53 + 1 === 2**53` is `true`, so
adding one to it does not actually increment the value, meaning it does not
satisfy the definition of `SAFE` in this context.

I think the best source of truth is likely the spec:
https://www.ecma-international.org/ecma-262/8.0/#sec-number.max_safe_integer
which states

> The value of Number.MAX_SAFE_INTEGER is the largest integer n such that n
and n + 1 are both exactly representable as a Number value.


On Sun, May 6, 2018 at 10:47 AM, Anders Rundgren <
anders.rundgren@gmail.com> wrote:

> On 2018-05-06 18:40, Isiah Meadows wrote:
>
>> Technically, "safe" in this context means "can you store this number *and
>> all numbers below it* without loss of precision", and for every single one
>> of these numbers, you can still add one to them. When you get up to 2^53,
>> you can no longer add just 1 - you can only add 2 or more. This is based on
>> the number of significand bits - 2^53 - 1 has all lower 53 bits set and its
>> exponent set to 0 (ignoring bias). You can precisely store up to this
>> number without having to adjust the exponent, no more. This is what is
>> meant by "safe". (The terminology of "exactly representable" is a misnomer
>> - the highest integer you can theoretically represent without loss of
>> precision is `(2^53-1) * (2^971)`.)
>>
>
> Thanx Isiah,
> I (sort of) understand :-)
>
> Anyway, this definition departs from similar definitions in other
> languages and AFAICT, existing JavaScript implementations have no problems
> using 2^53 as an integer.
>
> > var t = 9007199254740992
> < undefined
> > t-1
> < 9007199254740991
> > t
> < 9007199254740992
>
> For JavaScript this may be of limited importance but for (I-)JSON
> canonicalization [1] it is vital that all parties do the same
> interpretation.
> That is, for I-JSON the 2^53-1 limitation is simply put wrong.
>
> Anders
>
> 1] https://github.com/cyberphone/json-canonicalization#json-can
> onicalization
>
>
>
>> This SO answer should help explain the situation better:
>> https://stackoverflow.com/a/1848762
>>
>>
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com 
>> www.isiahmeadows.com 
>>
>> On Sun, May 6, 2018 at 11:58 AM, Anders Rundgren <
>> anders.rundgren@gmail.com >
>> wrote:
>>
>> If you write
>> Number.MAX_SAFE_INTEGER
>> into a browser console it will return
>> 9007199254740991
>>
>> I believe this is wrong, 9007199254740992 the largest correct safe
>> integer using IEEE-754 double precision.
>>
>> Using my own IEEE-754 debugger:
>>
>> Input floating point: 9007199254740991
>> Hex value: 433f
>> Binary value: 0 1110011 11
>> 11
>>
>> Input floating point: 9007199254740992
>> Hex value: 4340
>> Binary value: 0 1110100 00
>> 00
>>
>> Using an external IEEE-754 debugger:
>> http://www.binaryconvert.com/result_double.html?decimal=0570
>> 48048055049057057050053052055052048057057050 <
>> http://www.binaryconvert.com/result_double.html?decimal=057
>> 048048055049057057050053052055052048057057050>
>>
>> Anders
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org 
>> https://mail.mozilla.org/listinfo/es-discuss <
>> 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: About Reference type

2018-02-18 Thread Logan Smyth
> What data is of type Reference in the specification?

If you search for "value of type Reference" in the spec, I think it finds
all of the places where references are created.

References come from references to variable names, or from things like
property accesses like `foo.bar` or `foo['bar']` (also if the key is an
expression that was evaluated). You can see here for instance
https://www.ecma-international.org/ecma-262/8.0/#sec-property-accessors-runtime-semantics-evaluation

> Return a value of type Reference whose base value component is bv, whose
referenced name component is propertyNameString, and whose strict reference
flag is strict.


> The specification says that: "The base value component is either
undefined, an Object, a Boolean, a String, a Symbol, a Number, or an
Environment Record". Almost everything is listed here. What in this case
will not be the Reference type?

That list is the list of types that can be the based, not the list of types
that are references. All of the standard JS types, and environment records
may be the "base" of a reference.

> Yeah, difference in Base value. Can simple string such as "someString" be
Base?

`"someString"` would be the Base value in both of those examples. For
`storage.toString`, the value of `storage` will be evaluated first, so when
the reference is created with the string value as the base. You can see
that in the spec section I linked above

> 1. Let baseReference be the result of evaluating MemberExpression.
> 2. Let baseValue be ? GetValue(baseReference).

So `GetValue(baseReference)` will get the actual value of `storage` and
then it will be used as the base string value.

> With `window.bar` what is base?

`window` would be evaluated to the `Window` object, which would be the Base
value.

> And when `bar`?

This will run
https://www.ecma-international.org/ecma-262/8.0/#sec-getidentifierreference
which will recurse up through the various nested environments until it
either finds one with a `bar` declaration, or finds none. Assuming
`window.bar` exists and you're in the global scope, it would set the global
environment record as the Base for the reference.

> If this is an object environment, then why call through dot will be a
window object, but not an object environment?

I'm not sure I follow here. Where would an object environment come up in
that case?

> If inside of object we work with property object, the property of this
object will have a Declarative Records Environment or Object Records
Environment.

I'm not sure I understand what you're asking here.

On Sat, Feb 17, 2018 at 6:16 PM, Maxim Vaarwel  wrote:

> I want to ask some questions about Reference in ECMAScript.
>
>
>1. What data is of type Reference in the specification?
>2. The specification says that: "The base value component is either
>undefined, an Object, a Boolean, a String, a Symbol, a Number, or an
>Environment Record". Almost everything is listed here. What in this case
>will not be the Reference type? And I would like to see examples of code
>with each base value. For example:
>
> /// Definition variable in javascript code (example of javascript code)
> var a;
> /// Reference structure in engine
> Reference = {
> Base: Environment Record, /// It's one of other cases
> ReferencedName: "a",
> StrictReference: false
> }
>
> /// Is there a difference between the two expressions?
> "someString".toString; /// ƒ toString() { [native code] }
> /// and
> var storage = "otherString";
> storage.toString; /// ƒ toString() { [native code] }
>
> The question is how to calculate these expressions?
> How will the Reference type fields be filled?
>
> What how I think (maybe it's wrong, I don't know)
> /// "someString".toString;Reference = {Base: "someString",
> ReferencedName: "toString", StrictReference: false}
> /// storage.toString;
> Reference = {
> Base: storage,
> ReferencedName: "toString",
> StrictReference: false
> }
> Yeah, difference in Base value. Can simple string such as "someString" be 
> Base?
>
>
>1. In the code, in the global code there is a variable bar (declared,
>bar - example of variable). We can address to it as window.bar orbar ...
>and here the most interesting. With window.bar what is base? And when
>bar? We know that declarations in the global code are the Object
>Records Environment, and if so, base will be appeal to the bar Records
>Environment. But appeal to the window.bar, base will be a window -
>type(Object). And here it is not clear. If this is an object environment,
>then why call through dot will be a window object, but not an object
>environment?
>2. If inside of object we work with property object, the property of
>this object will have a Declarative Records Environment or Object Records
>Environment.
>
> My question is complexity. But type Reference is too hard for
> understanding without additional explanation.
>
> 

Re: Proposal: Alternative public, private, static syntax and questions

2018-01-11 Thread Logan Smyth
The `#foo` shorthand part of the proposal was removed: https://github.com/
tc39/proposal-class-fields/issues/21

On Thu, Jan 11, 2018 at 2:26 PM, Isiah Meadows 
wrote:

> The proposal does a very poor job of explaining this, but `#foo` is a
> shorthand for `this.#foo`, much like `{foo}` is a shorthand for `{foo:
> foo}`. That kind of thing has precedent in other languages:
> CoffeeScript uses `@foo` as a shorthand for `this.foo` (although it's
> not private), and Ruby uses `@foo` as a shorthand for `self.foo`
> (which is private by default). Most traditional strongly typed OO
> languages just let you omit `this` and just reference the property as
> if it were a variable in scope, without the sigil, and Ruby does as
> well for methods.
>
> It saves 5 characters in the most common case, accessing private
> properties of the current instance.
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
>
> Looking for web consulting? Or a new website?
> Send me an email and we can get started.
> www.isiahmeadows.com
>
>
> On Thu, Jan 11, 2018 at 4:26 PM, Naveen Chawla 
> wrote:
> > I hadn't read the proposal properly, but the thrust of my point is the
> same,
> > read remove/add `#` instead of "replace with this"
> >
> >
> > On Fri, 12 Jan 2018, 2:47 am Naveen Chawla, 
> wrote:
> >>
> >> Massive drawback of the # semantic: making a private variable public (a
> >> common transition when the usage of a class evolves) requires a lot more
> >> refactoring, since you have to remove every # for the variable across
> the
> >> class and replace it with `this`. Failing to do so in just 1 instance
> >> creates a bug. The same drawback applies for privatizing a public
> variable,
> >> in reverse.
> >>
> >> Besides which as an instance variable I want to learn `this` as the
> access
> >> prefix. I don't want to have to learn 2 different access prefixes, one
> for
> >> public and one for private. Access control in code only has one real
> >> material advantage: simplifying the public interface of a class by
> hiding
> >> factors that have no use from outside it. This is not big enough of an
> >> advantage to introduce a new access prefix, which can lead to a
> plethora of
> >> bugs due to confusion and/or publicization/privatization transitions
> during
> >> the evolution of one's system.
> >>
> >>
> >> On Fri, 12 Jan 2018, 1:22 am Isiah Meadows, 
> >> wrote:
> >>>
> >>> Inline
> >>>
> >>> -
> >>>
> >>> Isiah Meadows
> >>> m...@isiahmeadows.com
> >>>
> >>> Looking for web consulting? Or a new website?
> >>> Send me an email and we can get started.
> >>> www.isiahmeadows.com
> >>>
> >>> On Thu, Jan 11, 2018 at 2:10 PM, Brandon Andrews
> >>>  wrote:
> >>> >
> >>> > That is a very useful document. I guess I haven't opened the proposal
> >>> > in a while.
> >>> >
> >>> >
> >>> > He puts a lot of stress on preserving encapsulation where as I was
> >>> > planning on relying on a type system to optionally provide that
> feature.
> >>> > That is given a dynamically typed variable accessing privates would
> probably
> >>> > be allowed. (Statically typed variables would detect and not allow
> that kind
> >>> > of like a more strict usage).
> >>>
> >>> The issue with leveraging static typing is that JS has never been a
> >>> statically typed language. Also, private fields are generally
> >>> something you shouldn't need static types to detect - even without the
> >>> sigil, it *is* in fact possible to require something like `private
> >>> foo` as a declaration and alter property lookup within classes to
> >>> check for local private names (for class instances) before public
> >>> ones. (Decided to create a GH issue out of this:
> >>> https://github.com/tc39/proposal-class-fields/issues/69)
> >>>
> >>> > I think the inheritance and using private names as keys are decent
> >>> > arguments. That said I'm personally not against allowing inherited
> classes
> >>> > access to their base class private members though. That is private
> acting
> >>> > like protected in C++ I think is fine for ECMAScript. Am I alone in
> being
> >>> > fine with that behavior? I'm kind of leaning toward:
> >>> > https://github.com/tc39/proposal-private-fields/issues/14#
> issuecomment-216348883
> >>> > that syntax for a true private class scope variable.
> >>>
> >>> Note: not even Java allows subclasses to access superclasses' private
> >>> fields.
> >>>
> >>> >
> >>> > The key name conflict seems niche outside of key based data
> structures.
> >>> > I wrote an ORM system before and just used a key called "internal"
> to hold
> >>> > data in the past to get around a similar conflict. The # sounds like
> a
> >>> > similar workaround when required but allows everything to not be
> hidden in a
> >>> > nested object which is nice.
> >>> >
> >>> > Are "protected" class fields a thing in this discussion at all? Or is
> >>> > the idea to use or 

Re: Markdown Documents of ES8

2018-01-07 Thread Logan Smyth
The easiest version of the spec to read is probably the HTML version at
https://www.ecma-international.org/ecma-262/8.0/. There isn't a markdown
version to look at. The spec is maintained in
https://github.com/tc39/ecma262/blob/master/spec.html as HTML markup with
some custom elements.

On Sun, Jan 7, 2018 at 2:33 PM, Timothy Liu  wrote:

> Dear Community:
>
>
>
> Can anybody point me to the markdown format document of ES 2017?
>
> Recently I’m preparing to write an introduction level book for ES 2017,
> and I want to read the standard cautiously first.
>
>
>
> Best Regards,
>
> Tim
>
> ___
> 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: How it feels to learn JavaScript in 2016

2017-11-26 Thread Logan Smyth
`typeof null` is `"object"` for entirely historical implementation reasons,
not because things that don't fit the existing primitive list are
automatically `object`. Adding a new typeof `symbol` doesn't change a
precedent, because there was no such precedent. I understand that it's not
what you want, but that doesn't make it the wrong choice for the language.

If Symbols had been made typeof `"object"`, we'd have way more people on
here complaining about the exact opposite expectation that code like this
would work, where they assumed that `object` meant something that could
have properties added to it.
```
function addState(obj) {
  if (typeof obj !== "object" || obj === null) throw new Error("State can
only be added to objects");
  Object.defineProperty(obj, "state", {value: ""});
}
```
for instance if it were `"object"` instead, this would pass the library's
check and then throw because you can't define properties on a symbol,
instead of the nice error that the library author intended.

Adding additional typeof results also allows developers to write code
defensively. A dev could absolutely write
```
switch(typeof foo) {
  case "undefined":
  case "object":
  case "number":
  case "string":
  case "boolean":
// handle normally
break;
  default:
throw new Error(`Unexpected value with ${typeof foo}`);
}
```
to enforce their assumptions about type, and give the user helpful feedback
if new types are added in the future. If Symbol had been added as
`"object"`, there's is no way for developers to do this. Someone can guess
"maybe a new typeof will be added", but they would be super unlikely to
guess that a new object type would be added that didn't behave like any
other thing with typeof `"object".

At the end of the day, a new data type is always going to break assumptions
made somewhere, independent of whether there is a new `typeof` result or
not, and if that's already the case, adding a new typeof is much more
consistent with the types already in the language because Symbols do not
behave like normal objects.

I can't tell from what you've said so far, is your complaint that a new
`typeof` result was added, or is it that Symbols aren't actual objects? If
the complaint is entirely about `typeof` then I feel like my above comments
mostly make that clear, but if your issue is just that they should have
conceptually been objects, then I don't feel like you've made it clear why
that would be better than a new primitive (independent of typeof).

On Sun, Nov 26, 2017 at 11:54 AM, kai zhu  wrote:

> neither is null really an object, which for all practical purpose is
> treated like a primitive, but the precedent was set to make it an
> object.  symbol changed that precedent.
>
> > typeof: officially subject to extensions.
> we agree to disagree.  my opinion is introducing more types will only
> make things that were simple more complicated.
>
> -kai
>
> On 11/27/17, Alexander Jones  wrote:
> > They’re not even *objects*, let alone regular objects! :)
> >
> > Making every new addition to the language be a subtype of object just
> > creates a worse language. Given the constraints and requirements it was
> the
> > right choice to make symbol a new primitive. Technically it “broke the
> > web”, like literally every new change to the language. But that’s not as
> > black and white as people make it out to be, by using such a catchy
> phrase.
> >
> > typeof: officially subject to extensions.
> >
> > Alex
> >
> > On Sun, 26 Nov 2017 at 01:23, Jordan Harband  wrote:
> >
> >> Except that they're not regular objects; and if they'd done that,
> there'd
> >> just be the same potential problems with code naively written to accept
> >> an
> >> object (since Symbols are primitives, they don't have persistent
> >> properties, for example).
> >>
> >> Code that's written as if things will never change is brittle;
> "paranoid"
> >> code isn't over-engineered, it's simply *engineered* to handle change
> >> robustly.
> >>
> >> On Sat, Nov 25, 2017 at 5:30 PM, kai zhu  wrote:
> >>
> >>> claude, mature nodejs database drivers with frozen business logic for
> >>> stability reasons are examples of libraries that you are asking to
> >>> change whenever tc39 decides to expand typeof's on a whim which may
> >>> break them.
> >>>
> >>> the maintainers of sqlite3 for example have stated its in maintennance
> >>> mode (https://github.com/mapbox/node-sqlite3/issues/870), and all
> >>> commits for the past 2 years have dealt exclusively with its build
> >>> process so it can successfully compile with each nodejs release.
> >>>
> >>> i write database code myself.  what was my reaction to the
> >>> introduction of the 'symbol' typeof?  annoyance at trying to figure
> >>> out what pathological use-case a user might want to pass a 'symbol'
> >>> type to the database.  i imagine mongodb / mysql / sqlite3 maintainers
> >>> are equally annoyed with trying to figure 

Re: How it feels to learn JavaScript in 2016

2017-11-24 Thread Logan Smyth
Kai, that's not what backward-compatibility means though. It doesn't mean
that new code automatically works with older code, it means existing code
doesn't break when used alongside other existing code. Yes, adding new
features to the language means that assumptions made by old code may not
hold when used with new code. There is no way for existing code to break
due to the introduction of a new `typeof` return value, unless there's
actually new code introduced that _uses_ symbols. There is no way in the
world, in the general case, to introduce a change that will never
invalidate assumptions that someone has made at some point in the history
of an entire language. All TC39 can do is entire that new features are
exposed in such a way that assumptions made won't break as they are
currently used.



On Fri, Nov 24, 2017 at 10:09 PM, kai zhu  wrote:

> On 10/28/17, Frederick Stark  wrote:
> > I'd just like to thank TC39 for not breaking compatibility. All the niche
> > old libraries I use that were written in ES5 still work in my ES6+
> projects
> > with no issues.
>
> introducing the new typeof Symbol() === 'symbol' does break backwards
> compatibility with many es5 libraries that default to 'object' type if
> typeof is not 'boolean', 'number', 'string', 'function', or
> 'undefined'.
>
> fortunately symbols are not used by everyday programmers (and rightly
> so), so its rarely encountered by these libraries.  if tc39 did really
> care about backwards-compat, they should've treated it as an 'object'
> type with a Symbol.isSymbol subtype-check like Array.isArray.
>
> this brings up another backwards-compat issue - what's the typeof for
> proposed BigInt / Int64 / Decimal?  i prefer treating them as 'number'
> or 'object' with subtype-checks BigInt.isBigInt et al., but Symbol has
> dangerously broken that precedent.  in general my opinion is tc39
> should freeze the existing set of typeofs (and use subtype-checks) for
> sake of backwards-compat and library/tooling stability.
> ___
> 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: Question of the Day: What about all this asynchrony?

2017-11-07 Thread Logan Smyth
A nit, but that would have to be `for (const move of moves) await
doMoveAsync()`
since the `forEach` callback is a normal function.

On Tue, Nov 7, 2017 at 11:47 AM, Naveen Chawla 
wrote:

> ... that should be `await doMoveAsync()`
>
> On Wed, 8 Nov 2017 at 01:16 Naveen Chawla  wrote:
>
>> async functions create a new promise for you upon every invocation, which
>> you resolve via `await`, but that's all invisible in the background. It's
>> basically:
>>
>> async function doMovesAsync(){
>> moves.forEach(
>>  move=>{
>>   doMoveAsync(); //another async function
>>  }
>> );
>> }
>>
>> ...so you can do regular programming, in async world. This is why I
>> believe it's more powerful than observables, thereby making them redundant.
>>
>> When I say branching into multiple outputs, I do mean creating new data
>> that leaves the original data untouched.
>>
>> On Tue, 7 Nov 2017 at 20:57 Michael Lewis  wrote:
>>
>>> Also, if you've made it this far, I think it's worth mentioning that
>>> these async strings are basically all you need for a realtime file system.
>>>
>>> File("newFile.ext").append(File("fileA"), File("fileB"),
>>> ...).transpile().save();
>>> // --> automatically watches, all inputs (fileA, fileB, etc), caches
>>> unchanged files, reapplies transforms, writes to file...
>>>
>>> Webpack and gulp are basically async plugin systems w/ transforms.
>>> They're just way too complicated.
>>>
>>> Simplify all the things.
>>>
>>> And while we're at it, why not make a realtime version control system?
>>> Not just for files, but for all the things (any data structure inside the
>>> app).  For example, if we have variable strings, could we enable a history
>>> on it?  Instead of branching onto a separate entity/value, could we branch 
>>> *within
>>> *the string itself, so that we have an entire *verrsion tree *for any
>>> value?
>>>
>>> *What are the fundamental data structures in computer science?*
>>> The Boolean, obviously.  The Integer.  The String.
>>>
>>> Why not a realtime boolean?  I suppose that's just a boolean + change
>>> events.  What is a "change event"?  Just an array of functions.  But
>>> JavaScript functions are an abstract concept (compared to processor
>>> instructions).  What do functions look like at the processor level?
>>> They're compiled with all the dependent values, right?  How many processor
>>> ticks does the average line of JavaScript use?
>>>
>>> I feel like all languages could boil down to a very small set of
>>> fundamental data structures, and maybe a slightly larger set of specialized
>>> data structures.
>>>
>>> What are the different types of circuits in a process?  I understand
>>> (roughly) the basic logic gates, but is there specialized circuitry for
>>> specialized data structures?  What if those fundamental data structures
>>> were optimized at the circuitry level?
>>>
>>> What if we can optimize our programs to run as nearly instantly as
>>> possible?  Most scripts are *mostly *instant - at least, there's no
>>> external input.  For any process that's *nearly* instant, couldn't it
>>> actually be instant?  In other words, 1 tick of the processor?  Load up all
>>> the registers with the necessary values, and shine the light down those
>>> transistors/logic gates, so that we arrive at our result, instantly?
>>>
>>> I really feel like this is possible.  Like I mentioned earlier, I've
>>> never compiled a lick of code in my life, and have very little
>>> understanding of those things.  But from my sense of JavaScript, it's far
>>> from instant.  How many processor ticks per line of JavaScript code, on
>>> average?
>>>
>>>
>>>
>>>
>>> Is anyone still listening?
>>>
>>> On Tue, Nov 7, 2017 at 8:47 AM, Michael Lewis  wrote:
>>>
 I'm not experienced in async/await enough to know what "using async
 functions to process [streams]" would look like.

 You would have to create a new promise for every iteration?  Even if
 performance isn't an issue, it just doesn't make sense to me.  It's like,
 you could use `obj.value = "my string"` instead of `var myString = "my
 string"`, and it will work.  And the performance difference is negligible.
 But, it just doesn't make as much sense...

 *Branching vs Mutation*
 The point you bring up regarding "branching the stream into multiple
 outputs" is another fundamental concept in programming (that I'm still
 trying to wrap my head around).  Basically, does an operation (aka a
 method) operate on the original data, or fork/branch, preserving the
 original, and creating a clone to apply the transform to.

 For example, arr.push() manipulates (mutates) the original array, but
 arr.slice() branches, giving you a brand new array, leaving the underlying
 array untouched (immutable).

 This has always been an area of confusion for me.  Which methods 

Re: Can `new` be optional?

2017-11-05 Thread Logan Smyth
> I also don't see how decorators can solve it.

Making to wrapper for class constructor to allow the constructor to
callable would be fairly straightforward, e.g.

```
function callable(cls) {
  function Wrapper(...args) {
return Reflect.construct(cls, args, new.target || cls);
  }
  Object.defineProperty(Wrapper, "name", { value: cls.name });
  Object.setPrototypeOf(Wrapper, cls);
  Wrapper.prototype = cls.prototype;
  return Wrapper;
}

const Example = callable(class Example {});

Example();
```
and thus potentially
```
@callable
class Example {}
```

I know you said "At the cost of non-zero overhead." but it seems like this
would be something engines could optimize more easily than proxies.

> This seems like a really short sighted issue.  Why can't calling a class
just invoke it's constructor?

I think the big question for me when discussing this with people is, is it
more surprising to throw a clear error in these case, or to do something
close but not quite the same as if it were an ES5-style constructor?

```
class Foo {
  constructor() {
this.foo = 4;
  }
}

var obj = {};
var inst = Foo.call(obj);

// what happens?
// obj.foo => 4 or undefined
// inst => obj, new object, or undefined
// inst.foo => 4 or undefined
```
To be consistent with ES6 class semantics it has to be that a new instance
is returned and `obj` is 100% ignored but that are very much not what you'd
get if you replaced the class there with `function Foo(){ this.foo = 4; }`.
Isn't that its own set of confusing changes?

Specifically for "This seems like a really short sighted issue" I'd say
this is the opposite of short-sighted. There's nothing preventing support
for this in the future, but if it got added with a behavior that ended up
confusing people _more_ than not having it at all, then we'd be stuck with
it for good.


On Sun, Nov 5, 2017 at 11:53 AM, J Decker  wrote:

>
>
> On Sun, Nov 5, 2017 at 7:53 AM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> oldie but goldie ?
>>
>> ```js
>> Object.defineProperty(
>>   Function.prototype,
>>   'new',
>>   {
>> configurable: true,
>> value(...args) {
>>   return new this(...args);
>> }
>>   }
>> );
>> ```
>>
>> doesn't make new optional, just moves it, and doesn't apply to 'class'es
> which the OP is saying.
>
>
>>
>>
>>
>>
>> On Sun, Nov 5, 2017 at 11:28 AM, Oriol _ 
>> wrote:
>>
>>> > Why can't `new` be optional?
>>>
>>> When you call a function, you are using the internal [[Call]] method.
>>> When you use the `new` operator, it's the internal [[Construct]] method.
>>>
>>> They are different things, so IMO avoiding `new` when you are
>>> instantiating is bad practice.
>>>
>>>
> Of course it is... with out new, classes throw an exception.
>
> This seems like a really short sighted issue.  Why can't calling a class
> just invoke it's constructor?
>
> I also don't see how decorators can solve it.
>
> Seems just as arbitrary as the underscore proposal not accepting
> underscore trailing a number or before or after a decimal.
>
> Maybe, it would be better to ask 'Why does calling a class throw an
> exception instead of just creating a new instance.
>
>
>> But if you really want to avoid `new` when using ES6 `class` syntax, you
>>> can use proxies, e.g.
>>>
>>> ```js
>>> let MyClass = new Proxy(class MyClass {
>>>   constructor(arg) { this.arg = arg; }
>>> }, {
>>>   apply: (target, thisArg, args) => Reflect.construct(target, args)
>>> });
>>> MyClass(1); // { arg: 1 }
>>> new MyClass(2); // { arg: 2 }
>>> ```
>>>
>>
> At the cost of non-zero overhead.
>
>
>> --Oriol
>>>
>>> ___
>>> 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
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Monkey patching constructors in builtin class hierarchies?

2017-10-24 Thread Logan Smyth
Given that these are constructors that you don't own, adding your own
properties to them seems like an overall ugly approach to me. Why not store
your data separately in a WeakMap and rather than injecting properties onto
existing objects? Then you can initialize the stored data on first access
of the data you want.

On Tue, Oct 24, 2017 at 10:25 AM, /#!/JoePea  wrote:

> Well, I know I can set accessors on a prototype easily, but what I
> mean is, I need each instance of an `Element` to have exactly one
> instance of something right after construction during the same
> synchronous operation.
>
> For example, if we have an application with a bunch of pre-existing
> Elements that do not extend from any classes of mine, I'd like for the
> all to have `foo` properties, so that I can do this:
>
> ```js
> const el = new SomeCustomElementThatWasDefinedCreatedByMe
> console.log(el.foo) // it exists and is specific to the instance, not
> a prototype property
>
> // or
>
> const div = document.createElement('div')
> console.log(div.foo) // it exists and is specific to the instance, not
> a prototype property
> ```
>
> Can this be done?
> /#!/JoePea
>
>
> On Tue, Oct 24, 2017 at 10:19 AM, /#!/JoePea  wrote:
> >> This feels like a problem similar to https://esdiscuss.org/topic/
> block-scoped-prototype-extensions
> >
> > @Boris, even if it were scoped, how do we monkey patch a
> > *constructor*? By the way, for some reason your link to
> > `https://esdiscuss.org/topic/block-scoped-prototype-extensions` posted
> > as `https://esdiscuss.org/topic/block` which is 404. If you can edit
> > it it would help others not to stumble on a broken link.
> >
> >> if that would be possible, then everyone could just monkey patch
> Object, right?
> >
> > But everyone can monkey patch the entire class already, aside from the
> > constructor, by modifying the prototype. Obviously if someone returns
> > something new from the constructor they might break everything, but it
> > will be completely obvious and people then won't do that. The same
> > applies with methods and properties, it is super easy to break entire
> > applications monkey patching methods.
> >
> > ---
> >
> > So suppose I want to "polyfill" a concept. For example, I want all
> > elements to have a new "foo" accessor after they've been constructed.
> > Or for example, suppose `HTMLElement.prototype.style` and
> > `SVGElement.prototype.style` didn't exist yet. How would I patch those
> > in?
> > /#!/JoePea
> >
> >
> > On Tue, Oct 24, 2017 at 10:07 AM, Michał Wadas 
> wrote:
> >> AFAIR DOM classes are not extensible by any means.
> >>
> >>
> >>
> >> On 24 Oct 2017 6:51 pm, "/#!/JoePea"  wrote:
> >>>
> >>> Is it possible to monkey-patch an intermediate constructor of a
> built-in
> >>> subclass?
> >>>
> >>> For example, suppose I want all `Element` instances in a web app to
> have
> >>> new instance properties, is there a way to monkey-patch the Element
> >>> constructor so that when I make a custom element by extending a
> subclass of
> >>> `Element` that the new logic will fire?
> >>>
> >>> For example:
> >>>
> >>> ```js
> >>> // monkey-patch the Element constructor somehow so that it logs
> "patched
> >>> in Element".
> >>>
> >>> // then
> >>> class FooBar extends HTMLElement {}
> >>> customElement.define('foo-bar', FooBar)
> >>> new FooBar // "patched in Element"
> >>> ```
> >>>
> >>> I tried
> >>>
> >>> ```js
> >>> const OldElement = window.Element
> >>>
> >>> window.Element = function Element() {
> >>>   const _this = new OldElement
> >>>   console.log("patched in Element")
> >>>   return _this
> >>> }
> >>>
> >>> window.Element.prototype = OldElement.prototype
> >>> window.Element.prototype.constructor = window.Element
> >>>
> >>> class FooBar extends HTMLElement {}
> >>> customElements.define('f-b', FooBar)
> >>> new FooBar // does not log "patched in Element"
> >>> ```
> >>>
> >>> But when I make a new custom element, constructing it seems to use the
> old
> >>> Element constructor, as if a non-global reference to the original
> >>> constructor is kept inside a module so that modifying the global
> wouldn't
> >>> have any effect.
> >>>
> >>> Is there a way to monkey patch a constructor in the middle of a
> built-in
> >>> prototype chain or to otherwise inject construction logic to base
> classes of
> >>> existing class hierarchies?
> >>>
> >>>
> >>> /#!/JoePea
> >>>
> >>> ___
> >>> 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: State of Decorators

2017-09-06 Thread Logan Smyth
Keep in mind that the available implementations don't necessarily reflect
the state of the spec, and that they are maintained two independent groups.

None of the current implementations reflect the current state of the spec,
which has changed a lot over the last years. Babel for instance is also a
project maintained entirely by volunteers, and it's only in the last couple
months that someone has come forward with the time and energy available to
make progress on implementing the new version of the spec. Incidentally
this will also probably break all your existing code until new versions of
the decorators you use are written to support the new spec, so remember
that you're very much relying on an experimental feature.

As for supporting it in more places in the syntax, the more more places it
has to support, the more work that will have to be done. Keeping function
and such as things to be approached later means the current spec can
iterate more quickly. It's hard to both iterate quickly and also support a
broad feature set.

On Wed, Sep 6, 2017 at 11:28 AM, Matthew Robb 
wrote:

> Hello all!
>
> Today it struck me that the usefulness and prevalence of Decorators in my
> React applications has been actively climbing and this feels to be at odds
> with the rate of progression within the committee. To me it is quickly
> rising as the most influential feature to the way I write code. At the end
> of the day my code is considerably cleaner, more declarative, and more
> composable.
>
> I am curious as to why this feature is not one of the top discussed or
> actively developed proposals in the pipeline? In the current form it's
> already proving to be so useful and would be more so if it were supported
> in more places (e.g. on functions or plain object properties).
>
> Any insight into this would be great, thank you!
>
> ___
> 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: throwing/breaking inside a for-of loop does not call iterator.throw()

2017-08-23 Thread Logan Smyth
As far as I know, `.throw` exists as a way to inject behavior into an
in-progress iterator. See in https://tc39.github.io/ecma262/#table-54 for
"throw"

> Invoking this method notifies the Iterator object that the caller has
detected an error condition.

But the key thing is that the spec never calls `.throw` directly. It
defines that `.throw` exists, and it defines how it works with generator
functions, by causing the currently yielded statement to essentially do
`throw err;`. It also ensures that `yield*` properly propagates the throw
behavior through into delegated iterators. Beyond that, it does nothing,
because it doesn't really define what "detected an error condition" means.

The answer to your question, from my point of view anyway, is that it isn't
designed for what you think. Throwing an error inside a loop body is an
error, but it's not an error condition for the iterator itself, it's just
an error condition for the loop body. The only time `.throw` runs is if
something in your code itself calls it.


On Wed, Aug 23, 2017 at 1:40 PM, Marius Gundersen 
wrote:

> This is something I stumbled across while looking into the for-of-with
> (aka continue-with/break-with). It seems like throwing inside a for-of loop
> does not call the iterators throw method, it calls the return method and it
> seems to disregard the result of the method. For eample:
>
> ```js
> var gen = () => ({
>   x:0,
>   [Symbol.iterator](){
> return this;
>   },
>   next(p){
> console.log('next', p, this.x);
> return {done: false, value: this.x++};
>   },
>   return(p){
> console.log('return', p);
> return {done: false, value: 'return'};
>   },
>   throw(p){
> console.log('throw', p);
> return {done: false, value: 'throw'};
>   }
> });
>
> for(const g of gen()){ throw 'test' }
> // next undefined 0
> // return undefined
> ```
>
> Shouldn't it call the throw method on the iterator, and then use the
> return value to determine if it will actually return from the loop or not?
> This would be useful for generators, which can catch the error and deal
> with it, and continue to yield values even after throw and return have been
> called:
>
> ```
> function* gen() {
>   while(true) {
> try {
>yield 42;
> } catch(e) {
>   console.log('Error caught!');
> }
>   }
> }
>
> var g = gen();
> g.next();
> // { value: 42, done: false }
> g.throw('Something went wrong');
> // "Error caught!"
> // { value: 42, done: false }
> ```
>
> Unfortunately this example behaves differently if you try to loop over
> gen() in a for-of loop
>
> ___
> 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: Re: Defer expression

2017-08-17 Thread Logan Smyth
`setTimeout` it is defined in the HTML spec,
https://www.w3.org/TR/html5/single-page.html#timers, not the ECMA spec. The
ECMA spec has no concept of time-based delays at all, promise-based or
otherwise.

On Wed, Aug 16, 2017 at 11:03 PM, Naveen Chawla 
wrote:

> An in built `Promise` version of `setTimeout` would be cool:
> `Promise.delay()` and `Promise.delay(500)`
>
> On Thu, 17 Aug 2017, 7:37 a.m. kai zhu  wrote:
>
>> setTimeout is still the best solution in my mind.  none of the promise
>> or async code examples presented are as immediately obvious as
>> setTimeout that the code is to self-run at a later time (and you don't
>> need the 1ms argument).
>>
>> ```js
>> // self-comment that this code will self-run
>> // after the main script in a reasonably immediate fashion
>> setTimeout(function () {
>> // deferred code
>> })
>> ```
>>
>>
>>
>>
>> On 8/17/17, Matthew Robb  wrote:
>> > I think this will actually get you what you're after:
>> >
>> > (async function () {
>> >
>> > await null;
>> > // Deferred code here
>> >
>> > })()
>> >
>> >
>> > On Aug 16, 2017 5:46 PM, "Darien Valentine" 
>> wrote:
>> >
>> > @logan ah, oops, that was an (incorrect) assumption about the proposed
>> > behavior on my part
>> >
>> > ___
>> > 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
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Defer expression

2017-08-16 Thread Logan Smyth
`Promise.try` calls its callback synchronously like `new Promise` does, so
it would not be a substitute for this case.

On Wed, Aug 16, 2017 at 1:29 PM, Darien Valentine 
wrote:

> Deferring can mean different things, but generally `then` covers this well
> (specifically, pushing execution of something to the end of the current
> task).
>
> Promise.resolve().then(stuffToDefer);
>
> I think there is a proposal for `Promise.try(stuffToDefer)`, which would
> eliminate the need for the `resolve` bit.
>
> ___
> 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: @strict class decorator

2017-08-07 Thread Logan Smyth
Not necessarily 100% what you're going for, but you can get an error for
this behavior if you use `Object.preventExtensions()` on the class, e.g.

```
class Person {
  name;
  constructor() {
Object.preventExtensions(this);
  }
}
```

Currently because of an edge-case in Babel 6's class fields, every property
would need an initializer value, but that will be fixed in Babel 7. You can
see an example here:
https://babeljs.io/repl/#?babili=false=true=false=stage-2===false=false_lz=EQVwzgpgBGAuBOBLAxrYBuAUJ5AbAhmGFAAoTxgD2AdlAN6ZRTX4C20AvFAMxZPI048EKkrwAFAEp6jJlADyAIwBWEVADoADvAgA3CNVgBRAB6wDYRIPGwAFojCT0UWQF9M7nINhRN5KrRc1BAA7qT-NFJYfhQ06vgA5pxQAEwA7OhAA=false=false=false=false

As for the IDE errors, it doesn't seem like `@strict` would be enough,
because there are plenty of dynamic ways that you could pass class
constructors or instance objects around that would cause an IDE to lose
track of what objects to look at. This is the type of problem that Flowtype
and Typescript already aim to solve, since the type annotations and
inference allow them to track what types go where. They also already
provide nice IDE errors for just this situation:

*
https://www.typescriptlang.org/play/index.html#src=%0D%0Aexport%20class%20Person%7B%0D%0A%20%20%20%20name%3B%0D%0A%7D%0D%0A%0D%0Aconst%20person%20%3D%20new%20Person()%3B%0D%0Aperson.age%20%3D%2027%3B
*
https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAodBTAHgBzgJwBcwBjGAQwGdKwAFDfSuAOwG9UxOxnyBbDANyoAvuhItKxHAybMwAXm4Yk9RiwAUASiHS1zAHTkA5hgVgATAHYBQA

Given the limitations of type inference without an explicit typechecker, it
doesn't seem like an annotation like `@strict` could be powerful enough to
be useful for an IDE usecase. And for the non-IDE usecase,
`Object.preventExtensions` seems to do what you want already.

On Mon, Aug 7, 2017 at 10:14 PM, Naveen Chawla 
wrote:

> So here it is, the holy grail of allowing classes to have fixed
> definitions...
>
> OK what do I mean?
>
> suppose
>
> ```
> @strict
> export class Person{
> name;
> }
> ```
>
> is followed by
>
> ```
> const person = new Person();
> person.age = 27;
> ```
>
> I would like to see the IDE flag it as " "age" is not a property in strict
> class "Person" "
>
> This reminds the developer to then add age as a property, thereby ensuring
> every instance of the class always has full autocomplete, quick property
> renaming etc. across the project, for all properties added to it. For large
> projects with multiple developers this can also have the benefit of
> ensuring that all properties added to each instance are necessarily
> documented in one place, instead of checking whether someone has
> dynamically added a property somewhere.
>
> I would expect this example to throw a runtime exception like @readonly
> does. I don't think that's a problem because I think the IDE would inform
> much sooner. But I'm open to the idea of the runtime allowing it, since the
> real benefit for me is during development. Maybe instead a `@strictDev`
> decorator for that behavior, not sure.
>
> Support?
>
> ___
> 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: Re: Array.prototype.toObjectByProperty( element=>element.property )

2017-08-07 Thread Logan Smyth
> Object entries() is another strange case. Iterating over Object.keys with
key=> leaves myObject[key] to access the value, whereas iterating over
Object.entries with entry=> requires entry[0] and entry[1] which seems more
verbose for access, and less readable! So do you know why this was
introduced?

Keep in mind that the pair syntax plays quite nicely with destructuring, so
assuming the iteration you're describing is something like

```
for (const key of Object.keys(myObject)) {
  const value = myObject[key];

  // do stuff
}
```

I at least think it's much more readable to do

```
for (const [key, value] of Object.entries(myObject)) {

  // do stuff
}
```

> Array entries() - it's really unclear why this would ever be used, do you
have any idea?

The same is nice for iterating arrays when you need the index

```
for (const [i, value] of ['one', 'two', 'three', 'four'].entries()) {

  // do stuff
}
```

> Imagine the mapping of an array passed into a function (or a reduce),
repeated in code for several arrays that need caching for quick access -
obviously you would expect that to be factored out into a
`toObjectByProperty` function in code, right? That's what I'm talking
about. Now imagine that transition function offered by iterable - an extra
dependency useful across multiple projects is gone. It's only nice. Isn't
it?

Generally at least for me I've transitioned to using Map objects for this
type of lookup. It's slightly longer to use `.get`, but at least for me it
hasn't been particularly troublesome. There are certainly performance
arguments to be made for polyfilled implementations, but that will only
decrease over time.


On Mon, Aug 7, 2017 at 2:41 PM, Naveen Chawla  wrote:

> Hi Darien!
>
> Very interesting!
>
> Set.entries() is interesting - it has [value, value] with the
> justification (according to MDN) "to keep the API similar to the Map
> object".
>
> Array entries() - it's really unclear why this would ever be used, do you
> have any idea?
>
> Object entries() is another strange case. Iterating over Object.keys with
> key=> leaves myObject[key] to access the value, whereas iterating over
> Object.entries with entry=> requires entry[0] and entry[1] which seems more
> verbose for access, and less readable! So do you know why this was
> introduced?
>
> All seem motivated by Map. And I think the pattern is unhealthy, for the
> reasons given before.
>
> Sometimes we need to look at how code looks out there in production, to
> appreciate the benefits of a language feature. Imagine the mapping of an
> array passed into a function (or a reduce), repeated in code for several
> arrays that need caching for quick access - obviously you would expect that
> to be factored out into a `toObjectByProperty` function in code, right?
> That's what I'm talking about. Now imagine that transition function offered
> by iterable - an extra dependency useful across multiple projects is gone.
> It's only nice. Isn't it?
>
> On Tue, 8 Aug 2017 at 02:26 Darien Valentine 
> wrote:
>
>> > The concept of using a 2-element array to represent a key and value is
>> unique to Maps
>>
>> The entries pattern is not unique to `Map` — it’s also used by
>> `Object.entries`, `Set.entries`, and `Array.entries` — e.g.
>>
>> for (const [ index, member ] of array.entries()) ...
>>
>> A bit tangential, but in the case of `Map`, it’s perhaps notable that the
>> contract for "entry" is not "an array of two and only two members". It is
>> "any object at all", with the implied expectation that you’d want
>> properties keyed by "0" and "1" defined on it in order for it to be useful.
>>
>> Regardless of one’s thoughts on `Map` (which I use quite a bit
>> personally), the "entries" pattern is well established in ES. (I’d also
>> point out that adding a method for composition from entries does not
>> preclude supporting other approaches.)
>>
>> On Mon, Aug 7, 2017 at 4:54 PM, Darien Valentine 
>> wrote:
>>
>>> Sorry, meant to reply on-list there!
>>>
>>> On Mon, Aug 7, 2017 at 4:54 PM, Darien Valentine 
>>> wrote:
>>>
 > The concept of using a 2-element array to represent a key and value
 is unique to Maps

 The entries pattern is not unique to `Map` — it’s also used by
 `Object.entries`, `Set.entries`, and `Array.entries` — e.g.

 for (const [ index, member ] of array.entries()) ...

 A bit tangential, but in the case of `Map`, it’s perhaps notable that
 the contract for "entry" is not "an array of two and only two members". It
 is "any object at all", with the implied expectation that you’d want
 properties keyed by "0" and "1" defined on it in order for it to be useful.

 Regardless of one’s thoughts on `Map` (which I use quite a bit
 personally), the "entries" pattern is well established in ES.



 On Mon, Aug 7, 2017 at 3:24 PM, Naveen Chawla 

Re: import.meta and TC39 process as a whole

2017-08-05 Thread Logan Smyth
e execution context stack; moduleCxt is now the
> running execution context.
> - Let importMeta be ObjectCreate(null).
> - Let importMetaValues be ! HostGetImportMetaProperties(module).
> - For each Record {[[Key]], [[Value]]} p that is an element of
> importMetaValues,
> - Perform ! CreateDataProperty(importMeta, p.[[Key]], p.[[Value]]).
> - Perform ! HostFinalizeImportMeta(importMeta, module).
> - Set module.[[ImportMeta]] to importMeta.
> - Let result be the result of evaluating module.[[ECMAScriptCode]].
> - Suspend moduleCxt and remove it from the execution context stack.
> - Resume the context that is now on the top of the execution context stack
> as the running execution context.
> - Return Completion(result).
>
> etc.
>
>
> On Sat, 05 Aug 2017 at 23:50 Logan Smyth  <logan+smyth+%3cloganfsm...@gmail.com%3E>> wrote:
>
>> > The thing is, I clearly provide arguments in favour of my opinion.
>> >
>> > We now have:
>> > - keywords that are just keywords, really (typeof, case, break, etc.)
>> > ...
>>
>> Totally fair. I understand that's where your coming from.
>>
>> > How can adding “properties” to semantically fundamentally different
>> things elegant? Or increasing the number of extremely context-dependent
>> things? Or overriding existing keywords with new and exceedingly confusing
>> behaviours?
>>
>> This is an argument for literally never changing the language. New things
>> always seem confusing at first, then you learn and move on.
>>
>> > Rght. Because import.meta is not a magically-populated
>> not-quite-global variable. Oh. Wait. That’s *exactly* what it is.
>>
>> `Introspect` is a variable with well-defined existing behavior as a
>> variable. `import` is not a variable, it has no meaning when used as a
>> value until the spec assigns it a behavior. That is the point I'm trying to
>> get across. Is it less than ideal? Yeah, having `module` as a keyword would
>> be perfect, but we have to work within the bounds of the language that we
>> have.
>>
>> > Even though it’s worse. import is a not-really-a-function-not-real
>> ly-an-object-not-really-a-static-not-really-a-dynamic-keyword which is
>> clearly far worse than a properly defined API.
>>
>> What is a properly defined API for this case? Access to `.meta` needs to
>> be able to know what module you are inside of. It needs some kind of
>> context that ties it to the file that is asking for metadata. Within the
>> existing behavior of the language, we can't just make a new global
>> object like `Symbol` or `Reflect` because it has no way to know what file
>> is asking for metadata.
>>
>> The options are either:
>>
>> * Add new syntax to expose the per-module-specific information, like
>> `import.meta`, which cannot conflict with any existing code.
>> * Co-opt existing property-access behavior to make it behave differently
>> from how it would in other contexts, like `Introspect.context`. It would
>> either have to introduce an entirely new keyword, which as I mentioned is a
>> breaking change, or it would have to fundamentally override the behavior of
>> accessing a property on an object to allow the object to know what module
>> the property was accessed from.
>>
>> Since new keywords are out the window, I guess it could be said that the
>> argument here are two sides, one arguing for more syntax to keep the
>> execution model simple (import.meta) vs keeping the syntax simple at the
>> expense of making the runtime behavior of the code more complex by changing
>> how property access works.
>>
>> I fall on the side of syntax because changing the behavior of property
>> access to expose the current file seems massively more complex and seems
>> much more likely to me to confuse people.
>>
>>
>> On Sat, Aug 5, 2017 at 2:29 PM, Jordan Harband <ljh...@gmail.com> wrote:
>>
>>> > There’s no code anywhere which doesn’t have an object called Symbol
>>> invoked with `new Symbol()`?
>>> Any such code would either have a local `Symbol`, would have defined a
>>> global `Symbol` that shadowed any pre-defined one (including the new global
>>> in ES6), or would have thrown a ReferenceError or TypeError. Adding
>>> `Symbol` won't break any of that code (because the code that threw was
>>> already broken).
>>>
>>> On Sat, Aug 5, 2017 at 2:20 PM, Dmitrii Dimandt <dmit...@dmitriid.com>
>>> wrote:
>>>
>>>> > [Reflect] Not a breaking change because adding a new global isn't new
>>

Re: import.meta and TC39 process as a whole

2017-08-05 Thread Logan Smyth
at are just keywords, really (typeof, case, break, etc.)
>> - keywords that are just keywords, but don’t even exist in a language.
>> They are reserved for future use in various contexts: always reserved, only
>> in strict mode, only in module code etc. (enum, public, private, await
>> etc.). May never be used and may possibly be removed, as some keywords have
>> been (int, byte, char etc.)
>> - literals that are basically keywords (null, true, false)
>> - non-keywords that are for all intents and purposes keywords (eval,
>> arguments)
>> - keywords that look like objects (because they have additional
>> properties) which are not objects (new with new.target)
>> - keywords that look like functions (because they are invoked like
>> functions and return values like functions) which are not functions (import
>> and import())
>> - keywords that look like objects *and* functions but are neither (import
>> and import() and import.meta)
>>
>> It gets even worse. Because “metaproperties” are not just attached to
>> keywords. They are attached to keywords which have *fundamentally different
>> semantics* in the language:
>> - `new` is an operator[2], it gets `new.target`
>> -  A function is a callable object [3], and it gets a `function.sent`
>> - import is … I don’t know what import is. It gets transformed into a
>> separate, made-just-for-import CallExpression and then it gets an
>> `import.meta` on top of that (as a hardcoded “metaproperty”).
>>
>> All of the above are basic facts about the language as it exists now. How
>> can adding “properties” to semantically fundamentally different things
>> elegant? Or increasing the number of extremely context-dependent things? Or
>> overriding existing keywords with new and exceedingly confusing behaviours?
>>
>> > > So there’s really *nothing* stopping you from designing a proper
>> System/Module/Loader/Introspect/Avocado or any subset thereof instead of
>> slapping “metaproperties” on everything in sight :)
>> >
>> > I don't think anyone has claimed that `import.meta` is meant as a
>> replacement for these. We still need a loader spec
>>
>> and a System spec and an Introspect spec, and ... That is why all these
>> random additions to vastly different things in the language look like
>> ad-hoc shortsighted solutions with no respect for the language or its
>> evolution. “We need a thing, we have nowhere to put this thing, let’s add
>> this thing to a keyword, because new.target (bad design) has opened a door
>> for us”.
>>
>> > I'd _much_ rather have a static syntactically-defined way to access
>> that information over a magically-populated not-quite-global variable like
>> `Introspect.context.sent`.
>>
>> Rght. Because import.meta is not a magically-populated
>> not-quite-global variable. Oh. Wait. That’s *exactly* what it is.
>>
>> Even though it’s worse. import is a not-really-a-function-not-real
>> ly-an-object-not-really-a-static-not-really-a-dynamic-keyword which is
>> clearly far worse than a properly defined API.
>>
>>
>> On Sat, 05 Aug 2017 at 22:37 Logan Smyth > <logan+smyth+%3cloganfsm...@gmail.com%3E>> wrote:
>>
>>> `await` could be added because there is no case in existing code where
>>> `await ` would have been valid code, so it is
>>> backward-compatible. The same applies for all of the meta-property
>>> proposals. The same is not true for `Introspect.context.module`. It's not
>>> just a question of it a given construct could be made to behave the way you
>>> want, it's also a question of it it would be compatible with existing code.
>>>
>>> > Introduced in ECMASCRIPT 2015: Reflect is a built-in object that
>>> provides methods for interceptable JavaScript operations.
>>>
>>> Not a breaking change because adding a new global isn't new syntax, it's
>>> just a new variable that exists and essentially can't break much.
>>>
>>> > Introduced in ECMASCRIPT 2015: The Symbol() function returns a value
>>> of type symbol, has static properties that expose several members of
>>> built-in objects, has static methods that expose the global symbol
>>> registry, and resembles a built-in object class but is incomplete as a
>>> constructor because it does not support the syntax "new Symbol()”.
>>>
>>> Not a breaking change because this constructor did not exist before.
>>>
>>> > ECMAScript 5 introduced: yield, let
>>>
>>> Not a breaking change because those two can only occ

Re: rest getters and setters (sorry, __noSuchMethod__ again)

2017-07-28 Thread Logan Smyth
I almost mentioned that last time, alas. You have a bug in your proxy `get`
handler. It should be:
```
get(target, name, receiver) {
if (name[0] === '$') return target.getItem(name.substr(1));

return Reflect.get(target, name, receiver);
}
```
The third argument `receiver` being the important part here.
`Reflect.get(target, name, receiver)` is the correct reproduction of the
default non-proxy `get` behavior. `target[name]` is close, but loses
information, causing the bad behavior you are seeing. `target` is the
actual target initially passed to `new Proxy`, while `receiver` is the
object that was actually used to access the property, which is the actual
proxy object in this case.

Updated fiddle: https://jsfiddle.net/2dgefd9d/2/

On Fri, Jul 28, 2017 at 5:37 PM, Tobias Buschor <tobias.busc...@shwups.ch>
wrote:

> wow, you are right!
>
> But this does not work.
> It returns "undefined"
>
> ```
> class items {
> // ...
> get item3(){
> return this.$3;
> }
> }
> ```
>
> ```
> myItems = new items();
> console.log( myItems.item3 );
> ```
>
> see https://jsfiddle.net/2dgefd9d/1/
>
> I see, the getter is called on the object itself and not on the proxy
>
>
>
>
>
>
>
>
>
>
>
> 2017-07-29 2:05 GMT+02:00 Logan Smyth <loganfsm...@gmail.com>:
>
>> > but i can not act like this inside the Object, because i am not
>> working with the Proxy
>>
>> You're not quite taking into account the behavior of `this` in JS. `this`
>> is set at call-time, so when you do
>>
>> ```
>> class items {
>> // ...
>>
>> getItem3(){
>> return this.$3;
>> }
>> }
>> ```
>>
>> `this` depends on how `getItem3` was called. In your case if you do
>>
>> ```
>> myItems = new items();
>> myItems.getItem3();
>> ```
>> `this` will be `myItems` because that is how you have called it, meaning
>> that `getItems3()` will behave just like if you had done `myItems.$3`.
>>
>> Your code works as expected in this Fiddle: https://jsfiddle.net/2
>> dgefd9d/
>>
>> On Fri, Jul 28, 2017 at 4:48 PM, Tobias Buschor <tobias.busc...@shwups.ch
>> > wrote:
>>
>>> I realy like the possibility to react to dynamic properties, like what
>>> you can do with Proxies.
>>> But Proxies are not the (my) perfect solution.
>>>
>>>
>>> ```
>>> class items {
>>> constructor() {
>>> return new Proxy(this, {
>>> get(target, name) {
>>> if (name[0] === '$') return
>>> target.getItem(name.substr(1)).value;
>>> return target[name];
>>> }
>>> });
>>> }
>>> getItem(id) {
>>> return this._item[id];
>>> }
>>> }
>>>
>>> myItems = new items(); // [1]
>>> myItems.$1
>>> ```
>>>
>>> [1] this direct returns a Proxy for the newly created Object, ok..
>>> i can do "myItems.$3" instead of "myItems.getItem(4)";
>>>
>>>
>>> but i can not act like this inside the Object, because i am not working
>>> with the Proxy
>>>
>>> ```
>>> class items {
>>> getItem3(){
>>> return this.$3;
>>> }
>>> }
>>> ```
>>>
>>> I have to do this instead...
>>>
>>> ```
>>> class items {
>>> getItem3(){
>>> return this.getItem(3);
>>> }
>>> }
>>> ```
>>>
>>> What about something like getters and setters for the rest (undefined
>>> properties)?
>>>
>>> ```
>>> class items {
>>> get...(name){
>>> if (name[0] === '$') return this.getItem(name.substr(1)).value;
>>> }
>>> set...(name, value){
>>> // implement setter for unknown
>>> }
>>> }
>>> ```
>>>
>>>
>>> Maybe a stupid idea and certainly not thought through.
>>> But what do you think?
>>>
>>>
>>>
>>>
>>>
>>>
>>> ___
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>
>
> --
> Freundliche Grüsse
> Tobias Buschor
>
> shwups GmbH
> Unterlindenberg 206
> 9427 Wolfhalden
>
> +41 76 321 23 21 <+41%2076%20321%2023%2021>
> shwups.ch
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: rest getters and setters (sorry, __noSuchMethod__ again)

2017-07-28 Thread Logan Smyth
> but i can not act like this inside the Object, because i am not working
with the Proxy

You're not quite taking into account the behavior of `this` in JS. `this`
is set at call-time, so when you do

```
class items {
// ...

getItem3(){
return this.$3;
}
}
```

`this` depends on how `getItem3` was called. In your case if you do

```
myItems = new items();
myItems.getItem3();
```
`this` will be `myItems` because that is how you have called it, meaning
that `getItems3()` will behave just like if you had done `myItems.$3`.

Your code works as expected in this Fiddle: https://jsfiddle.net/2dgefd9d/

On Fri, Jul 28, 2017 at 4:48 PM, Tobias Buschor 
wrote:

> I realy like the possibility to react to dynamic properties, like what you
> can do with Proxies.
> But Proxies are not the (my) perfect solution.
>
>
> ```
> class items {
> constructor() {
> return new Proxy(this, {
> get(target, name) {
> if (name[0] === '$') return target.getItem(name.substr(1))
> .value;
> return target[name];
> }
> });
> }
> getItem(id) {
> return this._item[id];
> }
> }
>
> myItems = new items(); // [1]
> myItems.$1
> ```
>
> [1] this direct returns a Proxy for the newly created Object, ok..
> i can do "myItems.$3" instead of "myItems.getItem(4)";
>
>
> but i can not act like this inside the Object, because i am not working
> with the Proxy
>
> ```
> class items {
> getItem3(){
> return this.$3;
> }
> }
> ```
>
> I have to do this instead...
>
> ```
> class items {
> getItem3(){
> return this.getItem(3);
> }
> }
> ```
>
> What about something like getters and setters for the rest (undefined
> properties)?
>
> ```
> class items {
> get...(name){
> if (name[0] === '$') return this.getItem(name.substr(1)).value;
> }
> set...(name, value){
> // implement setter for unknown
> }
> }
> ```
>
>
> Maybe a stupid idea and certainly not thought through.
> But what do you think?
>
>
>
>
>
>
> ___
> 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: Support underscores in numbers

2017-07-26 Thread Logan Smyth
There is currently an active proposal for this:
https://github.com/tc39/proposal-numeric-separator

On Wed, Jul 26, 2017 at 1:47 PM, Alexander Craggs <
alexan...@debenclipper.com> wrote:

> Large number are hard to read in JavaScript, is 2384923842 over a
> billion?  Or just several hundred million.  One solution to this some
> languages have used is to allow underscores within numbers. You can
> immediately recognise 2_384_923_842 is a number in the billions, rather
> than millions.
>
> It would be nice to have such delimiters in large numbers in JavaScript as
> well, and I don't think it would be breaking.
>
> ___
> 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: Inline variable dereferencing of object field names

2017-07-23 Thread Logan Smyth
Assuming in your first example you meant

query.$pull[team] = userId;

not

query[team] = userId;

then your second example is already valid a ES6 computed property and does
exactly what you appear to be looking for.

On Sun, Jul 23, 2017 at 8:15 PM, Sebastian Malton 
wrote:

> When creating objects I think that having some notation to make the
> following easier to read
>
> let query = {
> $pull: {}
> };
> query[team] = userId;
>
> I was thinking of borrowing from the above notation and doing the
> following:
>
> let query = {
> $pull: {
> [team]: userId
> }
> };
>
> ___
> 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: Array.prototype.tap

2017-07-16 Thread Logan Smyth
You could always hack it and use the third argument :D

```
var tap = f => (v, i, arr) => {
  if (i === arr.length - 1) f(arr);

  return v;
};
```

Fine for debugging at least, but not necessarily your overall goal.

On Sun, Jul 16, 2017 at 11:20 AM, Eli White  wrote:

> That leads to a different result. Map is called once for every item in the
> array.
>
> ```
> const tap = f => x => {
>   f(x);
>   return x;
> }
>
> [1, 2, 3]
>   .map(num => num * 2)
>   .map(tap(console.log.bind(console)))
>   .reduce((a, b) => a + b);
> ```
>
> Results in:
>
> ```
> 2
> 4
> 6
> ```
>
> Whereas
>
> ```
> [1, 2, 3]
>   .map(num => num * 2)
>   .tap(console.log.bind(console));
>   .reduce((a, b) => a + b);
> ```
>
> would result in
>
> ```
> [2, 4, 6]
> ```
>
> This is what makes it hard about being a userland function. Tap enables
> the developer to act on the *entire* array, not individual items.
>
> On Sun, Jul 16, 2017 at 11:10 AM, Elie Rotenberg 
> wrote:
>
>> Sorry I meant:
>>
>> const tap = f => x => {
>>   f(x);
>>   return x;
>> }
>>
>>
>> Elie ROTENBERG
>> Directeur général adjoint
>> elie.rotenb...@webedia-group.com
>> 336 89 29 98 19
>> twitter elierotenberg  facebook elie.rotenberg  skype elie.rotenberg
>> github elierotenberg
>> 2, rue Paul Vaillant Couturier - CS 60102 - 92532 Levallois-Perret Cedex
>> - T: 33 811 69 41 42
>>
>>
>> On Sun, Jul 16, 2017 at 8:09 PM, Elie Rotenberg 
>> wrote:
>>
>>> I think the most common use of this pattern would be debugging, and in
>>> this context you don't really care to use a little helper and
>>> Array.prototype.map, eg:
>>>
>>> const tap = f => ...args => {
>>>   f(...args);
>>>   return x;
>>> };
>>>
>>> [1, 2, 3]
>>>   .map(num => num * 2)
>>>   .map(tap(console.log.bind(console)));
>>>   .reduce((a, b) => a + b);
>>>
>>>
>>> On Sun, Jul 16, 2017 at 8:00 PM, Eli White  wrote:
>>>
 I'd like to propose a `.tap` method on the Array prototype. I was able
 to find some previous discussion here but it was off the main topic and
 seemed to die out: https://mail.mozilla.org/
 pipermail/es-discuss/2015-October/044454.html

 A tap method enables the user to inspect an array in the chain.

 For example, inspection:

 If you have a chain like this:

 ```
 [1, 2, 3]
   .map(num => num * 2)
   .reduce((a, b) => a + b);
 ```

 When you want to see what the value of the array is between the map and
 reduce, you would typically do this:

 ```
 const value = [1, 2, 3]
   .map(num => num * 2);

 console.log(value);

 value.reduce((a, b) => a + b);
 ```

 With `.tap`, you'd be able to do this:

 ```
 [1, 2, 3]
   .map(num => num * 2)
   .tap(console.log.bind(console));
   .reduce((a, b) => a + b);
 ```

 `.tap` would be called once, passed the entire array as the first
 argument to the callback, and would return the array after the callback was
 finished.

 This isn't something that can cleanly be done with a user-land function
 since it would have to wrap the chain, or replace all of the chained
 functions like underscore does.

 An example of wrapping the chain:

 ```
 myTap(
   (
 [1, 2, 3]
   .map(num => num * 2)
   ),
   console.log.bind(console);
 )
 .reduce((a, b) => a + b);
 ```

 ___
 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: Pipe operator for JavaScript

2017-07-11 Thread Logan Smyth
There's been talk of this before here and in
https://github.com/gilbert/es-pipeline-operator among other places. Most
recently this was posted, which sounds like promising progress:
https://github.com/gilbert/es-pipeline-operator/issues/33#issuecomment-306986211

On Tue, Jul 11, 2017 at 1:02 PM, David White 
wrote:

> Piping is useful when composing many small pure functions together, one
> problem with this is the evaluation needs to be read from the inner most
> expression value in reverse to the outer most function call. Given the
> following statement we can see that it would be read as 'call math round
> then call math square then pass in PI', whereas the order of execution is
> in reverse.
>
> ```javascript
> const myNumber = Math.round(Math.sqrt(Math.PI));
> ```
>
> Unix has long provided a piping mechanism to achieve that, for example:
> `ps aux | grep node`, as well as F# and the Elixir programming language,
> both provide the `|>` pipe greater-than operator which is very readable.
>
> My proposal would be to use the slightly more verbose `|>` pipe-greater
> than syntax, it provides a convenient direction of travel for the
> expression on the left side, into the expression on the right, F# also
> provides a `<|`, which pipes in the opposite direction though I’ve not
> really seen very good use cases for this operator.
>
> ```javascript
> const myNumber = Math.PI |> Math.sqrt |> Math.round;
> ```
>
> The left side of the operator should always be a primitive data type or
> data structure, these could be any of the following: `Boolean`, `Null`,
> `undefined`, `Number`, `String`, `Symbol` or `Object`. Since functions are
> standard objects they can be passed in as the initial value, as long as the
> function on the right handles the calling on that function.
>
> It also provides a way to either log, process, or do anything with the
> data from the last expression on the left at various stages of the
> execution without adding additional brackets in and around the calls, for
> example.
>
> ```javascript
> function logger (callback) {
>   return function (value) {
> callback(value);
> return value;
>   };
> }
>
> Math.PI
>   |> logger(console.log);
>   |> Math.sqrt
>   |> logger(console.log);
>   |> Math.round
>   |> logger(console.log);
> ```
>
> While a slightly contrived example as we certainly wouldn't write code
> that looks like:
>
> ```javascript
> logger(Math.round(logger(Math.sqrt(logger(Math.PI);
> ```
>
> We would instead assign to variables at each stage of execution:
>
> ```javascript
> const PI = Math.PI;
> logger(PI);
>
> const squaredPI = Math.sqrt(PI);
> logger(squaredPI);
>
> const roundedSquaredPI = Math.round(squaredPI);
> logger(roundedSquaredPI);
> ```
>
> However with this clarity we have unfortunately had to create additional
> constants within this lexical block, whereas simple value passing between
> pure functions provides a very clean and readable approach and allows
> easier updates in the future if we wanted to add additional processing
> within the chain, for example Express middleware composition.
>
> Would love to hear some thoughts on this?
>
> David
>
> * [F# pipe operator](https://docs.microsoft.com/en-gb/dotnet/
> fsharp/language-reference/functions/index#function-
> composition-and-pipelining)
> * [Elixir pipe operator](https://elixir-lang.org/getting-started/
> enumerables-and-streams.html#the-pipe-operator)
> * [Unix pipeline](https://en.wikipedia.org/wiki/Pipeline_(Unix))
>
> ___
> 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: Block scoped prototype extensions

2017-07-05 Thread Logan Smyth
This seems like a difficult thing to do because the prototype chain is only
objects, so mutating them for the context of a single scope isn't easily
done. A few cases come to mind as extremely confusing:

* If you override the prototype in a scope then pass the object to another
function inside the block, does it stay overridden when passed? What if you
_want_ to pass it as a normal array? Does that mean it needs to change the
prototype back to default when calling the function, then change it back to
your override again after?
* What if something captures a reference to the object and then the block
ends? Does every usage of that object in the captured scope then need to
re-mutate the object then change it back again? If not, this means using
this behavior in callbacks and such isn't possible.

This approach encourages a huge amount of mutation, and it seems like it
would be incredibly confusing for average users to have objects changing
behavior out from under them.

On Wed, Jul 5, 2017 at 11:24 AM, kdex  wrote:

> One way to solve this might currently include extending `Array` and
> overriding`indexOf` in a derived class to reflect the `Option` behavior
> you're
> after.
>
> On Wednesday, July 5, 2017 8:10:05 PM CEST Boris Cherny wrote:
> > Hey guys,
> >
> > What would it take to get block scoped prototype extensions into
> JavaScript?
> > I’m curious to get some thoughts before I write a proposal.
> >
> > The use case is similar to Scala’s block scoped implicits. In my
> application
> > code I want Array.prototype.indexOf to return an Option, rather
> > than number | -1. If I patch Array’s prototype directly, it will break
> > other libraries in my project. It would be nice to have a way to extend
> the
> > prototype for just a block, or just a file.
> >
> > Would a combination of block-scoped imports (maybe dynamic imports, to
> patch
> > the prototype) and some sort of onExitBlock hook (to unpatch the
> prototype)
> > be enough to implement this? Has anyone else thought about this sort of
> > feature?
> >
> > Boris
> > ___
> > 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: Expected function parameter scoping behavioor

2017-05-09 Thread Logan Smyth
Perfect, thanks Allen, now I see the part that I was misreading. I didn't
recognize that the only bindings that would be recreated and shadowed in
the new environment were those that had explicitly been redeclared in the
body, I was thinking `varNames` included the parameter names, which is
clearly wrong. So in my examples, the addition of a `var arg;` into the
function body, causes the behavior I was referencing. That's an interesting
edge case.

Thanks!

On Tue, May 9, 2017 at 1:19 PM, Allen Wirfs-Brock <al...@wirfs-brock.com>
wrote:

> You misunderstand.  The two scope design is all about preventing closures
> from referencing variables declared within the body of the functions.  See
> https://github.com/tc39/tc39-notes/blob/master/es6/2013-
> 09/default-arguments.pdf for the motivation for this design. (but be
> aware that there are probably some subtle differences between the final
> specified design and what this deck describes.
>
> In you to test cases, `arg` is not declared within the body of `fn` so
> there is no duplicate binding for it.  Things would be different if you had
> a `var` or `function` declaration for `arg` within the body.
>
> Allen
>
> On May 9, 2017, at 12:40 PM, Logan Smyth <loganfsm...@gmail.com> wrote:
>
> Hey all,
> We're currently exploring some changes to Babel's behavior for function
> parameter default scoping, and I was hoping to validate my understanding of
> the spec, because my reading of the spec does not conform to Chrome or FF's
> behavior. Alternatively if you know bugs for those engines for this, let me
> know.
>
> My understanding from https://tc39.github.io/ec
> ma262/#sec-functiondeclarationinstantiation step #27 is that if function
> parameters contain any expressions, the function body is shifted to run in
> a declarative environment separately from the params. Per #27.f.i.4.a, the
> initial values of the params are copied from from the param environment
> into the function body environment, at initial execution time.
>
> Given that, I'd expect cases such as
> ```
> (function fn(arg, setValue = function () { arg = "a string" }) {
>   setValue();
>
>   return arg;
> })("initial")
> ```
> to return `initial`, because the `arg` binding being mutated by `setValue`
> is not tied to the `arg` binding that the function returns, as the
> `"initial"` value would have been copied into the function body binding
> before `setValue` ran.
>
> Is my understanding there correct?
>
> Similarly I'd have expected
> ```
> (function fn(arg, getValue = function () { return arg; }) {
>
>   arg = "new value";
>
>   return getValue();
> })("initial")
> ```
>
> to return `"initial"` because it is returning the binding value from the
> declarative environment in the function params and accessed by `getValue`
> is not the same environment being mutated by the assignment to `arg1`.
>
> Is my understanding correct, or is there something I'm misunderstanding?
>
> Thanks!
> ___
> 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


Expected function parameter scoping behavioor

2017-05-09 Thread Logan Smyth
Hey all,
We're currently exploring some changes to Babel's behavior for function
parameter default scoping, and I was hoping to validate my understanding of
the spec, because my reading of the spec does not conform to Chrome or FF's
behavior. Alternatively if you know bugs for those engines for this, let me
know.

My understanding from
https://tc39.github.io/ecma262/#sec-functiondeclarationinstantiation step
#27 is that if function parameters contain any expressions, the function
body is shifted to run in a declarative environment separately from the
params. Per #27.f.i.4.a, the initial values of the params are copied from
from the param environment into the function body environment, at initial
execution time.

Given that, I'd expect cases such as
```
(function fn(arg, setValue = function () { arg = "a string" }) {
  setValue();

  return arg;
})("initial")
```
to return `initial`, because the `arg` binding being mutated by `setValue`
is not tied to the `arg` binding that the function returns, as the
`"initial"` value would have been copied into the function body binding
before `setValue` ran.

Is my understanding there correct?

Similarly I'd have expected
```
(function fn(arg, getValue = function () { return arg; }) {

  arg = "new value";

  return getValue();
})("initial")
```

to return `"initial"` because it is returning the binding value from the
declarative environment in the function params and accessed by `getValue`
is not the same environment being mutated by the assignment to `arg1`.

Is my understanding correct, or is there something I'm misunderstanding?

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


Re: [Idea] Bind operator as some sort of property acessor

2017-03-07 Thread Logan Smyth
Unless I'm misunderstanding what you are looking for, I believe the current
proposal accounts for this as `::arr.push` with no expression before the
`::`.

Logan

On Tue, Mar 7, 2017 at 4:33 PM, Augusto Moura 
wrote:

> Before I open any suggestion for my ideia in the [bind-operator](//
> github.com/tc39/proposal-bind-operator) proposal, I like to know you
> guys' opinion about, and if even it is in the scope of the current proposal.
>
> There are moments when we want to export instances methods binded with
> their objects, like `num.toFixed.bind (num)`, most of the time to be used
> as high order functions. With the current proposal the best we can get is
> `num::num.toFixed`, what seems a bit weird and counterintuitive.
>
> For example, let's say that for an unknow reason we want to copy a array
> to another using the `push` method. There are a few ways:
> ``` .javascript
> const unary = fun => a => fun(a);
> const arr = [];
>
>
> // With arrow functions
> [1, 2, 3, 4].map(n => arr.push(n));
>
>
> // With binding
> [1, 2, 3].map(unary(arr.push.bind(arr)));
> ```
>
> And again, the best way of doing this with the current proposal is
> something like:
> ``` .javascript
> [1, 2, 3].map(unary(arr::arr.push));
> ```
>
> My idea, similar to double colon operator in Java 8, is that the
> expression `foo::bar` translates to: access `bar` in `foo`, if it is a
> function, returns the function binded to foo.
>
> So:
> ``` .javascript
> // The two expressions below produce the same function
> foo::bar;
> foo.bar.bind(foo);
>
> // So in our example instead of using something like
> [1, 2, 3].map(arr::arr.push);
> // we can use
> [1, 2, 3].map(arr::push);
> ```
>
> And yeah, it just decreases one word. However imagine the symbol as
> acessor instead of a operator, leaves the things really less confusing in
> my opinion.
>
> It can be useful for React applications too:
> ```.javascript
> class Button extends React.Component {
>   alertText() {
> alert(this.props.text);
>   }
>
>   render() {
> // Instead of `this::this.alertText`
> return ;
>   }
> }
> ```
>
> Imo, my idea has a different motivation e use case than the current
> proposal and because of that, needs to be splitted with the original. We
> can discuss other symbols than the `::`, but I personally think that it
> fits perfectly and make some neat code when composing high order functions.
>
> --
> Augusto B. Moura
>
> ___
> 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: Would it be possible to add “await on first use” to the language?

2017-02-23 Thread Logan Smyth
So you'd be imagining something that would create a variable that would
automatically await when accessed, like
```
async function makePizza(sauceType = 'red') {

  await const dough  = makeDough();
  await const sauce  = makeSauce(sauceType);
  await const cheese = grateCheese(sauce.determineCheese());

  dough.add(sauce);
  dough.add(cheese);

  return dough;
}
```
that would ensure the value is available before accessing them?

On Thu, Feb 23, 2017 at 9:18 PM, Šime Vidas  wrote:

> To clarify, the idea is to declare and kick off all the concurrent tasks
> upfront (using local variables and the ‘lazy await’ keyword), and then just
> continue writing the rest of the code ‘as if all the promises are
> resolved’. The async function automagically pauses whenever needed, so it’s
> no longer necessary to insert await operators throughout the code.
>
> I admit, this is wishful thinking. I’m just waiting for someone to tell me
> that it’s not feasible or that it would lead to some very bad code patterns
> :)
>
> On Fri, Feb 24, 2017 at 3:51 AM, Domenic Denicola  wrote:
>
>> We already have that feature in the language: it’s called await. Just
>> rewrite the example like so, instead of using /* pause to await x */
>> comments:
>>
>> async function makePizza(sauceType = 'red') {
>>   let dough  = makeDough();
>>   let sauce  = await makeSauce(sauceType);
>>   let cheese = grateCheese(sauce.determineCheese());
>>
>>   dough = await dough;
>>   dough.add(sauce);
>>   dough.add(await cheese);
>>
>>   return dough;
>> }
>>
>> This way, instead of random punctuation like the "." operator causing
>> your program to await... it's the actual await keyword.
>>
>>
>
> ___
> 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: Written Proposal for "package" Keyword for ES20XX Imports

2017-02-22 Thread Logan Smyth
> So it sounds like this TDZ error would be at runtime as opposed to
compile-time

Correct, since `extends`, computed properties, and decorators all require
runtime behavior, class declarations are initialized a runtime when
execution reaches them, unlike function declarations, where initialization
can be hoisted.

> would imply the ES6 spec does not truly support circular dependencies

ES6 modules have no explicit handling of circular dependencies. What they
do to approach this problem is have imported values reference the current
value of the exported variable, rather than the value at the time the
import was evaluated. The common problem with circular dependencies in
CommonJS is that when you call `require`, the exported value might not have
been assigned yet. Because ES6 modules expose live access to the current
value, you don't need to worry about that edge case.

This does not however free you from ensuring that your code initializes all
values in the proper order. In your example, the code is executed like
```
// app.js
console.log("B's reference to A", A);

class B extends A {
  constructor() {
super();
  }
}

console.log("A's reference to B", B);

class A {
  constructor() {
  }
}

var a = new A();
var b = new B();
```
because of the way the imports in your snippet are ordered. As is clear,
you are trying to extend class `A` before the class declaration has
executed. Since initialization of block-scoped variables is not hoisted,
`class B extends A` will throw because `A` is uninitialized.

> Do you have a link to where this is referenced?

The TDZ behavior is the standard behavior of block-scoped values. There is
no special logic around this for imports.

> Babel is not entirely incorrect

Babel's behavior essentially treats `class A {}` like `var A = class A {}`,
hence the `undefined` value. That is not entirely correct, but the ordering
of the imports is correct. There are cases where Babel is limited in
implementing ES6's semantics 100%, but they are all around the behavior of
live re-exports like `export * from 'foo';`.

On Wed, Feb 22, 2017 at 1:03 PM, Greg McLeod <cle...@gmail.com> wrote:

> I'll point out that Babel doesn't follow spec perfectly because it can't
>> transpile the bindings correctly in the case of synchronously executed code
>> with circular dependencies. That's a CommonJS limitation that Babel can't
>> work around any more than it already does.
>
>
> @Isiah Is that so? Babel is leading the charge in terms of transpilers
> right now, so that's unfortunate. Anyway I did some quick Googling and
> found a couple of things related to the subject:
>
> https://github.com/webpack/webpack/issues/1788
> https://esdiscuss.org/topic/how-to-solve-this-basic-es6-modu
> le-circular-dependency-problem
>
> While it's evident people have been encountering this for quite some time,
> it seems like the solutions up until now have been mostly workarounds. My
> hope is that a "package" keyword could tackle this kind of thing at more of
> a holistic level for bundled applications.
>
> What does the *spec* say should happen in that situation? (You've clearly
>> been into it in some detail.) As opposed to what Babel does, since of
>> course Babel while excellent is working with some limitations...?
>
>
> @T.J. Good question, see below my response to Logan
>
> It would be a TDZ error, rather than `undefined`, in a real implementation
>> of block scoping + ES6 modules. The ordering still means that `A` won't
>> exist when `class B extends A` runs.
>
>
> @Logan So it sounds like this TDZ error would be at runtime as opposed to
> compile-time, correct? Do you have a link to where this is referenced? Both
> cases would imply the ES6 spec does not truly support circular
> dependencies, and that Babel is not entirely incorrect
>
>
> On Wed, Feb 22, 2017 at 1:18 PM, Logan Smyth <loganfsm...@gmail.com>
> wrote:
>
>> > What does the *spec* say should happen in that situation?
>>
>> It would be a TDZ error, rather than `undefined`, in a real
>> implementation of block scoping + ES6 modules. The ordering still means
>> that `A` won't exist when `class B extends A` runs.
>>
>> On Wed, Feb 22, 2017 at 10:00 AM, T.J. Crowder <
>> tj.crow...@farsightsoftware.com> wrote:
>>
>>> On Wed, Feb 22, 2017 at 5:50 PM, Isiah Meadows <isiahmead...@gmail.com>
>>> wrote:
>>>
>>>> I'll point out that Babel doesn't follow spec perfectly because it
>>>> can't transpile the bindings correctly in the case of synchronously
>>>> executed code with circular dependencies. That's a CommonJS limitation that
>>>> Babel can't work around any more than it already does.
>>>>
>>> I w

Re: Written Proposal for "package" Keyword for ES20XX Imports

2017-02-22 Thread Logan Smyth
> What does the *spec* say should happen in that situation?

It would be a TDZ error, rather than `undefined`, in a real implementation
of block scoping + ES6 modules. The ordering still means that `A` won't
exist when `class B extends A` runs.

On Wed, Feb 22, 2017 at 10:00 AM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Wed, Feb 22, 2017 at 5:50 PM, Isiah Meadows 
> wrote:
>
>> I'll point out that Babel doesn't follow spec perfectly because it can't
>> transpile the bindings correctly in the case of synchronously executed code
>> with circular dependencies. That's a CommonJS limitation that Babel can't
>> work around any more than it already does.
>>
> I was wondering about that. Greg, re your example where you said:
>
> In the latest Babel the above code fails to run on the first line of
>> app.js (at the time it attempts to execute `_inherits(B, _A);`.). This is
>> because "A" is undefined in module b.js due to the circular dependency. In
>> this case Babel basically executed code in the incorrect order for this to
>> be able to work.
>
>
> What does the *spec* say should happen in that situation? (You've clearly
> been into it in some detail.) As opposed to what Babel does, since of
> course Babel while excellent is working with some limitations...?
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Written Proposal for "package" Keyword for ES20XX Imports

2017-02-21 Thread Logan Smyth
Fair enough. Is the idea that class declarations would be lazy-initialized
somehow then? It seems like the runtime behavior of class declarations
would make things difficult. What is responsible for knowing that the class
`A` needs to be initialized before `class B extends A {}`? What if the
declaration is using runtime behavior like `class B extends doThing(A) {}`?



On Tue, Feb 21, 2017 at 11:48 AM, Greg McLeod <cle...@gmail.com> wrote:

> @Logan: Oh I see what you mean, I suppose I was thinking about it in a
> different way. I do know in ES6 the import keywords are always hoisted to
> the top, so it should be a given that the modules will be "resolved"
> already as a consequence of that. But there is no guarantee that all of the
> modules are linked successfully, namely in the edge cases of inheritance.
>
> Consider the following
>
> ```js
> // app.js
> import A from "./a.js";
> import B from "./b.js";
>
> var a = new A();
> var b = new B();
>
> // a.js
> import B from "./b.js";
>
> console.log("A's reference to B", B);
>
> export default class A {
>   constructor() {
>   }
> }
>
> // b.js
> import A from "./a.js";
>
> console.log("B's reference to A", A);
>
> export default class B extends A {
>   constructor() {
> super();
>   }
> }
> ```
>
> In the latest Babel the above code fails to run on the first line of
> app.js (at the time it attempts to execute `_inherits(B, _A);`.). This is
> because "A" is undefined in module b.js due to the circular dependency. In
> this case Babel basically executed code in the incorrect order for this to
> be able to work. The package keyword avoids this by creating a hoist-like
> behavior for classes that are inherited, which is safe to do given the
> proposed limitations in the top-level scope
>
> I should note that circular dependencies like this are (hopefully) not too
> common, but one coming from another language might expect this to work
> based on how ES6 imports are described. I think the behavior of the package
> keyword could be much more transparent about what it's capable of.
>
>
>
> On Tue, Feb 21, 2017 at 1:56 PM, Logan Smyth <loganfsm...@gmail.com>
> wrote:
>
>> I don't have tons of comments on the proposal as a whole, but I do think
>> there may be confusion about ES6 imports. Imports are resolved and
>> processed and modules linked before any execution of the module body takes
>> place. I can't tell from your description if you are reading that
>> differently.
>>
>> On Tue, Feb 21, 2017 at 10:48 AM, Greg McLeod <cle...@gmail.com> wrote:
>>
>>> Thanks Ryan. I think there would be a bit of an issue with introducing
>>> dictionary support alone in that it does not provide a new way for the
>>> language to define where modules actually live in the application itself as
>>> opposed to the file system. This misses out on the benefits the package
>>> keyword could provide. "package" should impose some limitations on the
>>> top-most scope of a module to facilitate the ability to define the packages
>>> before actually executing a module's body.
>>>
>>> To elaborate, one of the biggest benefits I'd like to emphasize is the
>>> complete isolation of dependency resolution and actual module body
>>> execution.
>>>
>>> The package keyword in my proposal would allow you to arbitrarily say
>>> "here's the complete structure of my app, all dependencies already
>>> resolved" and subsequently take action on it after it has been fully loaded
>>> into memory in its entirety. Augmenting existing import syntax cannot allow
>>> this since the core body of each module is being executed amidst the
>>> dependency graph being resolved as each "import" is encountered by the
>>> interpreter.
>>>
>>>
>>> On Tue, Feb 21, 2017 at 12:52 PM, Ryan Birmingham <
>>> rainventi...@gmail.com> wrote:
>>>
>>>> I like the idea you're working from here, it seems to partially
>>>> resemble header files. I'm not sure if a package keyword is needed though;
>>>> couldn't you accomplish the same thing with just adding dictionary support
>>>> and an optional alias parameter to import/export?
>>>>
>>>> -Ryan Birmingham
>>>>
>>>> On 21 February 2017 at 12:27, Greg McLeod <cle...@gmail.com> wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> Back in 2015 I was working on a proposal for the 

Re: Written Proposal for "package" Keyword for ES20XX Imports

2017-02-21 Thread Logan Smyth
I don't have tons of comments on the proposal as a whole, but I do think
there may be confusion about ES6 imports. Imports are resolved and
processed and modules linked before any execution of the module body takes
place. I can't tell from your description if you are reading that
differently.

On Tue, Feb 21, 2017 at 10:48 AM, Greg McLeod  wrote:

> Thanks Ryan. I think there would be a bit of an issue with introducing
> dictionary support alone in that it does not provide a new way for the
> language to define where modules actually live in the application itself as
> opposed to the file system. This misses out on the benefits the package
> keyword could provide. "package" should impose some limitations on the
> top-most scope of a module to facilitate the ability to define the packages
> before actually executing a module's body.
>
> To elaborate, one of the biggest benefits I'd like to emphasize is the
> complete isolation of dependency resolution and actual module body
> execution.
>
> The package keyword in my proposal would allow you to arbitrarily say
> "here's the complete structure of my app, all dependencies already
> resolved" and subsequently take action on it after it has been fully loaded
> into memory in its entirety. Augmenting existing import syntax cannot allow
> this since the core body of each module is being executed amidst the
> dependency graph being resolved as each "import" is encountered by the
> interpreter.
>
>
> On Tue, Feb 21, 2017 at 12:52 PM, Ryan Birmingham 
> wrote:
>
>> I like the idea you're working from here, it seems to partially resemble
>> header files. I'm not sure if a package keyword is needed though; couldn't
>> you accomplish the same thing with just adding dictionary support and an
>> optional alias parameter to import/export?
>>
>> -Ryan Birmingham
>>
>> On 21 February 2017 at 12:27, Greg McLeod  wrote:
>>
>>> Hi all,
>>>
>>> Back in 2015 I was working on a proposal for the "package" keyword, but
>>> stopped prematurely as ES6/ES2015 had already been shipped. Since then I've
>>> been occasionally iterating on it anyway in order to flesh out my ideas
>>> with how it could fit with the new import syntax. I wanted to share with
>>> the mailing list to get some feedback on it, as well as help facilitate
>>> some of the discussion regarding future import syntax.
>>>
>>> Proposal can be found here:
>>> https://gist.github.com/Cleod9/7f73017905d124210ec8
>>>
>>> I should note that a lot of this is derived from an ActionScript to
>>> JavaScript proof-of-concept transpiler I wrote a few years back. (Live
>>> demo: https://as3js.org/demo/ ). I believe this type of package
>>> syntax/behavior has already been possible since ES5, although I have yet to
>>> find any proposals for the keyword that resemble that of battle-tested
>>> languages like Java/C#.
>>>
>>> I think there are a lot of time-saving qualities that packages could
>>> provide for bundled JS applications we have yet to explore, and it could
>>> even open the door to a JS standard library. Even if this doesn't go
>>> anywhere I certainly hope by making this proposal public it will be a
>>> useful for reference for what is possible in the current state of affairs.
>>>
>>> Any feedback would be greatly appreciated!
>>>
>>> Greg
>>>
>>> P.S. Screen-cap of a potential IDE future with packages:
>>> http://i.imgur.com/D5EGNUN.gifv
>>>
>>>
>>> ___
>>> 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: Why can't we `let s = super`?

2017-02-17 Thread Logan Smyth
`super()` right now is a special syntactic feature, just like the new
proposed `import()` and such. To have `super` behave like a variable and be
consistent, `super.foo()` would also then be accessing a property on that
variable, instead of calling a method from the parent constructor
prototype. Then a whole new approach would be needed for parent class
access.


On Fri, Feb 17, 2017 at 7:45 PM, /#!/JoePea  wrote:

> Why can't we store a reference to `super`? It seems counterintuitive and
> prevents possible things like
>
> ```js
> function metaStuff(sup) {
>   // do something else with super or with `this`
> }
>
> class Bar extends Foo {
>   constructor() {
> let s = super
> s()
> metaStuff(s)
>   }
> }
> ```
>
>
> */#!/*JoePea
>
> ___
> 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: Accesssing ES6 class constructor function

2017-01-05 Thread Logan Smyth
> The enforcement seems pointless to me

So we're all on the same page, this restriction exists because it means
`class` syntax can extend builtin types like `Map`, `Set`, `Array` and
`Error` and such, which cannot be extended (with correct functionality
anyway) in standard ES5. By delaying initialization of `this`, it allows
the constructor to drill all the way to the base class, which gets to
instantiate the correct type of object. To have `this` be initialized up
front, there would need to be some other mechanism in place to instantiate
the correct type of base object.

I feel your pain though, I ran into similar issues when updating our
codebase to ES6 classes, though I was able to work around it for our
specific usecase by having a base class handle hooking into things.

On Thu, Jan 5, 2017 at 1:30 PM, Don Griffin  wrote:

> Hi James,
>
> I too was surprised and disappointed with this restriction on constructors.
>
> The enforcement seems pointless to me, because there are valid patterns
> such as DI or multiple-inheritance where the JS run-time cannot know how a
> framework is trying to accomplish the construction sequence.
>
> This is really counter to the general philosophy of JS (imho) and more
> akin to static languages like Java or C#... over there meta programming
> (MP) happens in very different ways, but JS had previously made this task
> simple... sadly this kind of thing starts to make MP harder at every step.
>
> I don't hold much hope that this will be relaxed but it should be. :(
>
> Best,
> Don
> --
> Don Griffin
> Director of Engineering
> Sencha, Inc.
> https://www.sencha.com/
>
> On Thu, Jan 5, 2017 at 1:21 PM, James Treworgy  wrote:
>
>> > Can you clarify what prevents it from being made to work?
>>
>> The fundamental feature difference (continuing to think about this!) is
>> that with ES5 constructors, I can create an instance of something from an
>> abitrary constructor provided to me, and inject properties that will be
>> available to it *at contruction time.* The basic operation of the container
>> might be like this
>>
>> ```js
>> function createInstance(Cotr, args /* array */) {
>> function F() {
>>// this is dynamic in reality but simple example of injecting
>> something...
>>this.logger = new Logger();
>>
>>var instance = Cotr.apply(this, args)
>>return instance; // in case Cotr returns something
>> }
>> F.prototype = Cotr.prototype;
>> return new F();
>> }
>> ```
>>
>> So the Cotr can refer to "this.logger" in the constructor. I don't think
>> there's a way to do this with dynamic class inheritance since you always
>> have to call super() before you can assign any properties in a constructor.
>>
>> This isn't a dealkiller for the tool overall - I can constructor
>> injection instead:
>>
>> ```js
>> class Thing
>> static _inject = [Logger]
>> constructor(deps, ...args) {
>> // deps = { logger: Logger, dep2: Dep2, ... }
>> Object.assign(this, deps) // or however you want to make them
>> available
>> }
>> }
>> ```
>> This will work fine with the dynamic subclass pattern. it just was nice
>> to have everything done by the framework and get rid of boilerplate, but
>> this also has benefits of classes working without the DI container. :) I'm
>> bringing this into an ES6 project for the first time so I can live with a
>> different pattern.
>>
>>
>> On Thu, Jan 5, 2017 at 1:55 PM, T.J. Crowder <
>> tj.crow...@farsightsoftware.com> wrote:
>>
>>> On Thu, Jan 5, 2017 at 5:31 PM, James Treworgy 
>>> wrote:
>>>
>>> I can't address your questions about "why" (I wasn't plugged into the
>>> discussions around it), but addressing this:
>>>
>>> > This has come into play lately for me, as an DI container we use that
>>> > does exactly this doesn't work with ES6 classes (and as far as I can
>>> > tell, there's no way to make it work, other than having devs no longer
>>> > use class syntax).
>>>
>>> Can you clarify what prevents it from being made to work? I'm probably
>>> missing the point you're making there. For instance, this does some
>>> brain-dead DI (injecting an argument in the constructor) by dynamically
>>> extending the class:
>>>
>>> ```js
>>> // The class we'll do DI on
>>> class Original {
>>> constructor($foo) {
>>> this.foo = $foo;
>>> }
>>> run(num) {
>>> const result = this.foo.fooMethod(num);
>>> console.log(`num is ${num}, result is ${result}`);
>>> }
>>> }
>>>
>>> // Brain-dead di function
>>> const di = (cls, Foo) => {
>>> const o = {
>>> [cls.name]: class extends cls {
>>> constructor(...args) {
>>> super(new Foo(), ...args);
>>> }
>>> }
>>> };
>>> return o[cls.name];
>>> };
>>>
>>> // Ues a class that's been DI'd
>>> const use = Original => {
>>> new Original().run(42);
>>> };
>>>
>>> // Use it in dev
>>> use(di(Original, class 

Re: Why are class getters/setters non-enumerable?

2016-10-08 Thread Logan Smyth
FYI,
```
const xDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'x')
xDesc.enumerable = true
Object.defineProperty(XYZValues.prototype, 'x', xDesc)

const yDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'y')
yDesc.enumerable = true
Object.defineProperty(XYZValues.prototype, 'y', yDesc)

const zDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'z')
zDesc.enumerable = true
Object.defineProperty(XYZValues.prototype, 'z', zDesc)
```

can be done with

```
Object.defineProperty(XYZValues.prototype, 'x', {enumerable: true})
Object.defineProperty(XYZValues.prototype, 'y', {enumerable: true})
Object.defineProperty(XYZValues.prototype, 'z', {enumerable: true})
```

or even

```
['x', 'y', 'z'].forEach(prop => Object.defineProperty(XYZValues.prototype,
prop, {enumerable: true}))
```

> Why are accessors non-enumerable when (to end user who use the properties
to access values) they are used in the exact same way that "properties"
are? It seems that they should be enumerable because whether or not they
are "accessors" is not the end user's concern, they merely access the
"property"

Even if they were enumerable, there are still differences. The properties
aren't `own` properties for instance, they exist on the class prototype,
not on the instance itself. You'd run into similar problems with any
library that doesn't traverse beyond `own` keys, like `Object.assign`, even
with enumerability.

To me, your assertion that they are supposed to be interchangeable is the
problem. If they need to be a perfect replacement for standard data
properties in the constructor, your best bet would be to define them in the
constructor as enumerable own getter/setter properties just like the data
properties would have been.




On Sat, Oct 8, 2016 at 4:14 PM, /#!/JoePea  wrote:

> I've ran into this bug due to non-enumerable accessors:
> https://github.com/tweenjs/tween.js/issues/267
>
> The problem is that Tween.js does not detect the getters/setters in a
> for..in loop.
>
> The solution I came up with is ugly, re-defining the descriptors to be
> enumerable, as demonstrated below. Is there a better way? Why are accessors
> non-enumerable when (to end user who use the properties to access values)
> they are used in the exact same way that "properties" are? It seems that
> they should be enumerable because whether or not they are "accessors" is
> not the end user's concern, they merely access the "property"...
>
> ```js
> class XYZValues {
> constructor(x = 0, y = 0, z = 0) {
> this._x = x
> this._y = y
> this._z = z
> }
>
> onChanged() {}
>
> set x(value) {
> this._x = value
> this.onChanged()
> }
> get x() { return this._x }
>
> set y(value) {
> this._y = value
> this.onChanged()
> }
> get y() { return this._y }
>
> set z(value) {
> this._z = value
> this.onChanged()
> }
> get z() { return this._z }
> }
>
> const xDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'x')
> xDesc.enumerable = true
> Object.defineProperty(XYZValues.prototype, 'x', xDesc)
>
> const yDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'y')
> yDesc.enumerable = true
> Object.defineProperty(XYZValues.prototype, 'y', yDesc)
>
> const zDesc = Object.getOwnPropertyDescriptor(XYZValues.prototype, 'z')
> zDesc.enumerable = true
> Object.defineProperty(XYZValues.prototype, 'z', zDesc)
>
> export {XYZValues as default}
> ```
>
>
> */#!/*JoePea
>
> ___
> 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: Array tail destructuring

2016-10-03 Thread Logan Smyth
FYI there's also some previous discussion on this here for those
interested:
https://mail.mozilla.org/pipermail/es-discuss/2015-October/044306.html
https://esdiscuss.org/topic/rest-parameters

On Mon, Oct 3, 2016 at 3:05 PM, Olivier Lalonde  wrote:

> > I think Olivier's point is that there is no way to know when you should
> stop iterating in the case of `[...a]` either - hence the two cases are
> equivalently problematic, if at all. Pulling the last element out *when*
> the iteration stops is a different concern IMO which seems trivial to solve:
>
> Correct.
>
> > The ...a just indicates that you need to pull on the iterator being
> assigned to the destructuring pattern, and store the results that aren't
> claimed by other parts of the destructuring pattern into "a".
>
> Yes, exactly. I'd understand the issue better if "a" had to be an
> arbitrary iterable but AFAICT it's alway an array and the RHS iterable
> always needs to be fully iterated regardless of whether "[...a, last]"
> syntax is supported or not.
>
>
> On Mon, Oct 3, 2016 at 2:54 PM, Tab Atkins Jr. 
> wrote:
>
>> On Sun, Oct 2, 2016 at 2:11 AM, Caitlin Potter 
>> wrote:
>> > On Oct 2, 2016, at 10:50 AM, Awal Garg  wrote:
>> >> On Oct 2, 2016, at 9:30 AM, Olivier Lalonde 
>> wrote:
>> >>> So what's the problem with `[...a, last]` that `[...a]` doesn't have?
>> I
>> >>> still don't get it.
>> >>
>> >> Since you don’t know when the iterator produced for `…a` will
>> terminate,
>> >> there’s no way to know when you need to stop iterating `…a` and move
>> onto
>> >> the next item `last`.
>> >
>> > That statement is factually incorrect. There is a simple criteria to
>> know
>> > when to terminate the iteration for a final rest element, which is when
>> the
>> > iterator returns a result object with "done": true.
>> >
>> > There is no condition to determine when to switch from a non-final rest
>> > element to some other element. That is a problem which needs to be
>> > addressed.
>>
>> I'm similarly confused - there's no need to "determine when to
>> switch"; we don't evaluate things in different contexts or anything.
>> It just requires storage equal to the number of post-rest arguments;
>> when you do hit the end, the things you're holding onto get assigned
>> to the post-rest variable names.  This is all done internally with a
>> freshly-produced array; I don't *think* the timing of array-appending
>> is even observable, so you shouldn't be able to tell that an item is
>> appended only after later items are pulled from the source iterator.
>>
>> I'm similarly confused by the wording you're using, tho, which
>> suggests there may be a deeper communication mismatch - there's no
>> "iterator produced for `...a`".  The ...a just indicates that you need
>> to pull on the iterator being assigned to the destructuring pattern,
>> and store the results that aren't claimed by other parts of the
>> destructuring pattern into "a".
>>
>> ~TJ
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
>
> --
> - Oli
>
> Oli Lalonde
> http://www.syskall.com <-- connect with me!
>
> ___
> 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: How to solve this basic ES6-module circular dependency problem?

2016-08-23 Thread Logan Smyth
be available until the `C` module itself was
> evaluated, so I was expecting for there to be an `undefined` error when
> `initC` was called before the `C` module was evaluated.
>
> You say that
>
> > which means you can import and call a function declaration from any
> module, even if that module hasn't started the `Evaluation` phase yet, the
> same way it'd work with other cases of hoisting, where execution hasn't
> reached the function declaration, but it is available early.
>
> Which makes sense based on what I see happening, but it seems strange
> because it means that the scope of the module (as far as hoisting is
> concerned) is not the module itself, but rather some outer scope that wraps
> *all* the modules that import a given symbol.
>
> You said,
>
> > the same way it'd work with other cases of hoisting, where execution
> hasn't reached the function declaration, but it is available early.
>
> Pre-ES6 "hoisting" in javascript happens on boundaries set by `function`s,
> and I thought that modules would be similar to function bodies, and
> therefore I thought that hoisting would be limited to within a module and
> did not expect hoisting to go beyond the module boundary to some scope that
> encompasses multiple modules. That to me is a different type of "hoisting"
> than what I know from pre-ES6 JavaScript's function-scope hoisting so it
> isn't necessarily the "same way it'd work with other cases of hoisting";
> there is definitely some ES6-module-specific stuff happening that is a
> little different from pre-ES6 function-scope hoisting. (sidenote: I've
> asked the awesome Axel of 2ality to add these useful details to his
> articles.)
>
> If I use the `var` method as you proposed (which is working in my Babel
> env), should I expect that method to always work in any theoretical
> 100%-implemented-to-spec ES6 environment, not just in Babel?
>
> If so, then this may be one of the rare cases of "when we'd want to
> actually use `var` instead of `let`" besides for cases when we want pre-ES6
> hoisting which I think should be generally avoided in order to make code
> less error-prone and easier to understand. This behavior would have been
> nearly-impossible to know about without the knowledge gained from this
> conversation (or from reading the spec in depth which can be difficult).
>
>
>
> */#!/*JoePea
>
> On Tue, Aug 16, 2016 at 10:48 AM, Logan Smyth <loganfsm...@gmail.com>
> wrote:
>
>> > Your `initC` solution is working in Meteor (Babel + Reify) and
>> Webpack+Babel, but the `initC` logic seems to run twice, as if there are
>> two C variables instead of one. The following code is based on yours, and
>> the `console.log('initC!!!')` statement unexpectedly executes twice, and
>> you'll see output like this:
>>
>> Damn, that's a Babel bug with the block scoping logic. That said, as in
>> my example, that needs to be `var C;` anyway, `let` would throw (in an
>> environment with working TDZ anyway). Changing it to `var` also stops the
>> duplicate printing.
>>
>> > I'm also not sure how `initC` can be defined when it is called in the
>> B module, which is evaluated before C and A. The evaluation order is B, C,
>> A (depth first). Does the `initC` function get hoisted into a scope common
>> with all three modules? That is the only way that would seem to explain it,
>> but that seems to go against the intuition I had that each module had it's
>> own module scope (as if it were wrapped inside a `function() {}`, and
>> therefore I thought the `initC` function would be hoisted within the C
>> module, and that with B being evaluated first I thought an "undefined"
>> error would be thrown when it tried to execute `initC` (but that is not
>> happening!). How is it that `initC` can be available to the B module before
>> C is evaluated?
>>
>> There are two separate pieces to executing a module, `Instantiation`, and
>> `Evaluation`, which are what comes into play here. When you tell a JS
>> environment to execute a file, it will instantiate every ES6 module in
>> dependency graph before beginning to execute _any_ of the modules. Babel
>> does its best to simulate this behavior, though it's not perfect at it. One
>> of the things that happens during module instantiation is that hoisted
>> declarations are initialized, which means you can import and call a
>> function declaration from any module, even if that module hasn't started
>> the `Evaluation` phase yet, the same way it'd work with other cases of
>> hoisting, where execution hasn't reached the function declaration, but it
>> is available early.

Re: How to solve this basic ES6-module circular dependency problem?

2016-08-16 Thread Logan Smyth
rt {B as default}
> ```
>
> ```js
> // --- Module C
>
> import A from './A'
> import B from './B'
>
> console.log('module C')
> let C
>
> export function initC(){
> if (C) return
>
> console.log('initC!!!')
>
> C = class C {
> constructor() {
> // this may run later, after all three modules are evaluated,
> or
> // possibly never.
> console.log(A)
> console.log(B)
> }
> }
> }
>
> initC()
>
> export {C as default}
> ```
>
> */#!/*JoePea
>
> On Thu, Aug 11, 2016 at 10:26 AM, Logan Smyth <loganfsm...@gmail.com>
> wrote:
>
>> Keep in mind `let A = A;` is a TDZ error in any real ES6 environment.
>>
>> The example I posted works properly with Babel's live-binding
>> implementation and should require less repetition. What were your thoughts
>> on it?
>>
>> On Thu, Aug 11, 2016 at 12:23 AM, /#!/JoePea <j...@trusktr.io> wrote:
>>
>>> Alright, so I believe I have found the solution. It is not possible to
>>> guarantee a certain module evaluation order, but using some clever (but
>>> tedious) conditional checking I believe the problem is solved (with two
>>> caveats listed after):
>>>
>>> ```js
>>> // --- Entrypoint
>>> import A from './A'
>>> console.log('Entrypoint', new A)
>>> ```
>>>
>>> ```js
>>> // --- Module A
>>>
>>> import C from './C'
>>> import {setUpB} from './B'
>>>
>>> let A
>>>
>>> export
>>> function setUpA(C) {
>>>
>>> if (!A) {
>>> A = class A extends C {
>>> // ...
>>> }
>>> }
>>>
>>> }
>>>
>>> if (setUpA && C) setUpA(C)
>>> if (setUpB && C) setUpB(C)
>>>
>>> export {A as default}
>>> ```
>>>
>>> ```js
>>> // --- Module B
>>>
>>> import C from './C'
>>> import {setUpA} from './A'
>>>
>>> let B
>>>
>>> export
>>> function setUpB(C) {
>>>
>>> if (!B) {
>>> B = class B extends C {
>>> // ...
>>> }
>>> }
>>>
>>> }
>>>
>>> if (setUpA && C) setUpA(C)
>>> if (setUpB && C) setUpB(C)
>>>
>>> export {B as default}
>>> ```
>>>
>>> ```js
>>> // --- Module C
>>>
>>> import A, {setUpA} from './A'
>>> import B, {setUpB} from './B'
>>>
>>> class C {
>>> constructor() {
>>> // this may run later, after all three modules are evaluated, or
>>> // possibly never.
>>> console.log(A)
>>> console.log(B)
>>> }
>>> }
>>>
>>> if (setUpA && C) setUpA(C)
>>> if (setUpB && C) setUpB(C)
>>>
>>> export {C as default}
>>> ```
>>>
>>> The caveat is that this fails in both Babel environments and in Rollup.
>>> For it to work in Babel environments, `let A` and `let B` have to be
>>> changed to `let A = A` and `let B = B`, as per the [fault in Babel's
>>> ES2015-to-CommonJS implementation](https://github
>>> .com/meteor/meteor/issues/7621#issuecomment-238992688) pointed out by
>>> Ben Newman. And it fails in Rollup because Rollup [isn't really creating
>>> live bindings](https://github.com/rollup/rollup/issues/845), which is
>>> fine in most cases, but doesn't work with these circular dependencies. The
>>> Rollup output does not create the C reference before it is ever used in the
>>> first pair of conditional checks, unlike what (I think) would happen with
>>> real live bindings (please correct me if wrong). To understand what I mean
>>> in the case of Rollup, just run `if (FOO) console.log(FOO)` in your
>>> console, and you'll get an error because FOO is not defined. Had the
>>> bindings been live, then FOO *would* be defined.
>>>
>>>
>>>
>>> */#!/*JoePea
>>>
>>> On Wed, Aug 10, 2016 at 5:04 PM, /#!/JoePea <j...@trusktr.io> wrote:
>>>
>>>> I found a solution that works in environments compiled by Babel, using
>>>> the [workaround suggested by Ben Newman](https://github.com/met
>>>> eor/meteor/issues/7621#issuecomment-238992688):
>>>>
>>>> ```js
>>

Re: How to solve this basic ES6-module circular dependency problem?

2016-08-11 Thread Logan Smyth
Keep in mind `let A = A;` is a TDZ error in any real ES6 environment.

The example I posted works properly with Babel's live-binding
implementation and should require less repetition. What were your thoughts
on it?

On Thu, Aug 11, 2016 at 12:23 AM, /#!/JoePea  wrote:

> Alright, so I believe I have found the solution. It is not possible to
> guarantee a certain module evaluation order, but using some clever (but
> tedious) conditional checking I believe the problem is solved (with two
> caveats listed after):
>
> ```js
> // --- Entrypoint
> import A from './A'
> console.log('Entrypoint', new A)
> ```
>
> ```js
> // --- Module A
>
> import C from './C'
> import {setUpB} from './B'
>
> let A
>
> export
> function setUpA(C) {
>
> if (!A) {
> A = class A extends C {
> // ...
> }
> }
>
> }
>
> if (setUpA && C) setUpA(C)
> if (setUpB && C) setUpB(C)
>
> export {A as default}
> ```
>
> ```js
> // --- Module B
>
> import C from './C'
> import {setUpA} from './A'
>
> let B
>
> export
> function setUpB(C) {
>
> if (!B) {
> B = class B extends C {
> // ...
> }
> }
>
> }
>
> if (setUpA && C) setUpA(C)
> if (setUpB && C) setUpB(C)
>
> export {B as default}
> ```
>
> ```js
> // --- Module C
>
> import A, {setUpA} from './A'
> import B, {setUpB} from './B'
>
> class C {
> constructor() {
> // this may run later, after all three modules are evaluated, or
> // possibly never.
> console.log(A)
> console.log(B)
> }
> }
>
> if (setUpA && C) setUpA(C)
> if (setUpB && C) setUpB(C)
>
> export {C as default}
> ```
>
> The caveat is that this fails in both Babel environments and in Rollup.
> For it to work in Babel environments, `let A` and `let B` have to be
> changed to `let A = A` and `let B = B`, as per the [fault in Babel's
> ES2015-to-CommonJS implementation](https://github.com/meteor/meteor/
> issues/7621#issuecomment-238992688) pointed out by Ben Newman. And it
> fails in Rollup because Rollup [isn't really creating live bindings](
> https://github.com/rollup/rollup/issues/845), which is fine in most
> cases, but doesn't work with these circular dependencies. The Rollup output
> does not create the C reference before it is ever used in the first pair of
> conditional checks, unlike what (I think) would happen with real live
> bindings (please correct me if wrong). To understand what I mean in the
> case of Rollup, just run `if (FOO) console.log(FOO)` in your console, and
> you'll get an error because FOO is not defined. Had the bindings been live,
> then FOO *would* be defined.
>
>
>
> */#!/*JoePea
>
> On Wed, Aug 10, 2016 at 5:04 PM, /#!/JoePea  wrote:
>
>> I found a solution that works in environments compiled by Babel, using
>> the [workaround suggested by Ben Newman](https://github.com/met
>> eor/meteor/issues/7621#issuecomment-238992688):
>>
>> ```js
>> // --- Module A
>>
>> import C from './C'
>>
>> let A = A // @benjamn's workaround applied
>>
>> export
>> function setUpA(C) {
>>
>> A = class A extends C {
>> // ...
>> }
>>
>> }
>>
>> export {A as default}
>> ```
>>
>> ```js
>> // --- Module B
>>
>> import C from './C'
>>
>> let B = B // @benjamn's workaround applied
>>
>> export
>> function setUpB(C) {
>>
>> B = class B extends C {
>> // ...
>> }
>>
>> }
>>
>> export {B as default}
>> ```
>>
>> ```js
>> // --- Module C
>>
>> import A, {setUpA} from './A'
>> import B, {setUpB} from './B'
>>
>> let C = class C {
>> constructor() {
>> // this may run later, after all three modules are evaluated, or
>> // possibly never.
>> console.log(A)
>> console.log(B)
>> }
>> }
>>
>> setUpA(C)
>> setUpB(C)
>>
>> export {C as default}
>> ```
>>
>> ```js
>> // --- Entrypoint
>>
>> import A from './A'
>> console.log('Entrypoint', new A) // runs the console.logs in the C
>> constructor.
>> ```
>>
>>
>> Although that works in my environment which is compiled from ES6 modules
>> to CommonJS by Babel, it [doesn't work in Rollup.js](http://goo.gl/PXXBKI),
>> and may not work in other ES6 module implementations.
>>
>> Is there some solution that will theoretically work in any ES6 module
>> environment?
>>
>> */#!/*JoePea
>>
>
>
> ___
> 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: How to solve this basic ES6-module circular dependency problem?

2016-08-10 Thread Logan Smyth
You could also swap that around to simplify the logic in the individual
classes, e.g.

```
// --- Module A

import C, {initC} from './c';

initC();

console.log('Module A', C)

class A extends C {
// ...
}

export {A as default}
```

then export that function to force-initialize the `C` variable.
```
// --- Module C

import A from './a'
import B from './b'

var C;

export function initC(){
if (C) return;

C = class C {
constructor() {
// this may run later, after all three modules are evaluated, or
// possibly never.
console.log(A)
console.log(B)
}
}
}

initC();

export {C as default};
```

So all the individual classes have to do is call the `initC` function to
ensure `C` has been properly initialized, then go from there. Note the
usage of `var` here is also critical since `let` would throw a TDZ error.

On Wed, Aug 10, 2016 at 5:04 PM, /#!/JoePea  wrote:

> I found a solution that works in environments compiled by Babel, using the
> [workaround suggested by Ben Newman](https://github.com/met
> eor/meteor/issues/7621#issuecomment-238992688):
>
> ```js
> // --- Module A
>
> import C from './C'
>
> let A = A // @benjamn's workaround applied
>
> export
> function setUpA(C) {
>
> A = class A extends C {
> // ...
> }
>
> }
>
> export {A as default}
> ```
>
> ```js
> // --- Module B
>
> import C from './C'
>
> let B = B // @benjamn's workaround applied
>
> export
> function setUpB(C) {
>
> B = class B extends C {
> // ...
> }
>
> }
>
> export {B as default}
> ```
>
> ```js
> // --- Module C
>
> import A, {setUpA} from './A'
> import B, {setUpB} from './B'
>
> let C = class C {
> constructor() {
> // this may run later, after all three modules are evaluated, or
> // possibly never.
> console.log(A)
> console.log(B)
> }
> }
>
> setUpA(C)
> setUpB(C)
>
> export {C as default}
> ```
>
> ```js
> // --- Entrypoint
>
> import A from './A'
> console.log('Entrypoint', new A) // runs the console.logs in the C
> constructor.
> ```
>
>
> Although that works in my environment which is compiled from ES6 modules
> to CommonJS by Babel, it [doesn't work in Rollup.js](http://goo.gl/PXXBKI),
> and may not work in other ES6 module implementations.
>
> Is there some solution that will theoretically work in any ES6 module
> environment?
>
> */#!/*JoePea
>
> ___
> 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: The `super` keyword doesn't work as it should?

2016-07-20 Thread Logan Smyth
Joe, yes sorry, my mistake. `a` should have `__proto__: b`, and `b` should
have `__proto__: c` in my example, that's what I get for not validating it
better. Each could `return` but since `a.method` was the only one I called,
it was the only one I put the `return` in.

On Wed, Jul 20, 2016 at 3:27 AM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> For implementation sake, this is a quick'n'dirty approach that brings a
> dynamically resolved `super` to any object or prototype:
> https://gist.github.com/WebReflection/ee4695c107339e039878b02afb90dc0d
>
> Usage example:
> ```js
> function A() {
>   console.log(this.constructor.name);
> }
> A.prototype.method = function () {
>   console.log('method from ' + this.constructor.name);
> };
>
> function B() {
>   this.super();
>   console.log(this.constructor.name);
> }
> B.prototype = Object.create(A.prototype, {constructor: {value: B}});
> withSuperContext(B.prototype).method = function () {
>   this.super.method();
>   console.log('method from ' + this.constructor.name);
> };
>
> function C() {
>   this.super();
>   console.log(this.constructor.name);
> }
> C.prototype = withSuperContext(
>   Object.create(B.prototype, {constructor: {value: C}})
> );
> C.prototype.method = function () {
>   this.super.method();
>   console.log('method from ' + this.constructor.name);
> };
>
> var c = new C;
> // will log
> // A
> // B
> // C
>
> c.method();
> // method from A
> // method from B
> // method from C
>
> ```
>
> Best Regards
>
>
> On Wed, Jul 20, 2016 at 9:06 AM, medikoo 
> wrote:
>
>> Joe, see this post:
>>
>> http://mozilla.6506.n7.nabble.com/Making-quot-super-quot-work-outside-a-literal-td90457.html#a90551
>>
>> There are some explanations there on  why super was implemented as
>> something
>> /static/ and not /dynamic/
>>
>>
>>
>> --
>> View this message in context:
>> http://mozilla.6506.n7.nabble.com/The-super-keyword-doesn-t-work-as-it-should-tp357032p357113.html
>> Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at
>> Nabble.com.
>> ___
>> 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: The `super` keyword doesn't work as it should?

2016-07-19 Thread Logan Smyth
Joe, it seems like you've focused on `super ===
Object.getPrototypeOf(this)` as the overall ideal without considering the
issues with it. I've tried to put together a few counterexamples below. Say
you have a base set up like this:

```
var a = {
  prop: null,
  method(){
this.prop = 4;

// super.method();
// vs
// Object.getPrototypeOf(this).method.call(this);

return this.prop;
  },
};
var b = {
  __proto__: a,
  method: function(){
this.prop = 5;

// super.method();
// vs
// Object.getPrototypeOf(this).method.call(this);
  },
};
var c = {
__proto__: b,
method: function(){
this.prop = 6;
},
};
```

In this example, `super.method()` will work fine, and `a.method() === 6`
because each super call will reassign `this.prop`, where `this === a`.

`Object.getPrototypeOf(this)` has one main core issue here, which is that
we are doing `.call(this);`, meaning that when `a.method()` is called and
subsequently calls `b.method`, `this === a`, not `this === b` inside
`b.method`. This means that when `b` attempts to call _its_ super class, it
has no way of finding `c`, because `this === a` and
`Object.getProtoypeOf(this) === b`, not `c`. This leads to the infinite
recursion case that Bergi mentioned.

The only way for this to work, given your proposal, would be to call
`b.method` with `this === b` instead of `this === a`, e.g. `
Object.getPrototypeOf(this).method.call(Object.getPrototypeOf(this));`, but
that would mean that operations happening inside `b.method`, like the
`this.prop = 5;` would be assigning a property on the wrong object (`b`),
instead of the `a` object, leading to `a.method() === 4`.

ES6 solves this by looking up the parent prototype using the
`[[HomeObject]]` as the root instead of `this`, where `[[HomeObject]]` is
essentially the object that the function was attached to syntactically. The
issue is that a standalone function has no object that it is attached to.
This means that usage of `super.foo` ends up being restricted to only
functions written with method syntax, where they are attached clearly to a
specific object.

On Tue, Jul 19, 2016 at 3:13 AM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> `super === Object.getPrototypeOf(this)` also doesn't work with multiple
> inheritance.
>
> If interested, it has been solved dynamically in this good'ol library:
> https://github.com/WebReflection/es-class#es6-ready
>
> Regards
>
> On Tue, Jul 19, 2016 at 11:03 AM, /#!/JoePea  wrote:
>
>> Hi Bergi, yes, so the object that `super` references would work like
>> `this`, where the value is determined at runtime instead of in a
>> declaration. Basically, `super === Object.getPrototypeOf(this)` would
>> actually be true in my examples. It may be due to ["extra overhead"](
>> http://disq.us/p/1a56gxj) that `[[HomeObject]]` is only defined during
>> declaration, but that is at the huge expense of making the language less
>> intuitive and also more difficult to work with in some cases (for example,
>> in designing a multiple-inheritance scheme).
>>
>> It would simply be great for super to just work as expected in the
>> examples I gave, which would mean that super would work in tandem and
>> intuitively with the various ways in which we can create
>> objects-extending-objects in JS.
>>
>> Good news is that making the necessary change to `super` in ES8 or later
>> is completely backwards compatible with how it currently works.
>>
>> I wonder what the performance problems are and if they can be solved.
>>
>> */#!/*JoePea
>>
>> On Mon, Jul 18, 2016 at 2:46 PM, Bergi  wrote:
>>
>>> /#!/JoePea wrote:
>>>
>>> Why can't `super` simply be a shortcut
 for "look up the prototype of the object that the method is called on,
 then
 find the `.constructor` property and call it on `this`"? That seems to
 be
 simple.

>>>
>>> Simple, yes, and broken in the case of multi-level inheritance:
>>> ```
>>> const x = Object.assign(Object.create({
>>> method() {
>>> console.log("parent");
>>> }
>>> }), {
>>> method() {
>>> console.log("child");
>>> Object.getPrototypeOf(this).method(); // super.method()
>>> }
>>> });
>>> x.method(); // works as expected
>>>
>>> const y = Object.create(x);
>>> y.method(); // infinite loop/stack overflow
>>> ```
>>> A `super` query must not depend on `this` (only), it must statically
>>> resolve the object on which the called method is defined.
>>>
>>> In constructors, using the prototype of the currenctly called
>>> constructor for `super()` works well, but you'd need to use
>>> `Object.setPrototype` as there is currently no declarative way other than
>>> `class`es to define functions with custom prototypes.
>>>
>>> In methods, there would need to be a way to populate the [[HomeObject]]
>>> other than declaring the method as part of a class/object literal.
>>>
>>> Kind regards,
>>>  Bergi
>>> 

Re: Redefining a let variable inside a for loop scope doesn't work?

2016-07-14 Thread Logan Smyth
I think you may be misunderstanding that error. `for (let n of foo){ }`
does create an `n` value inside the loop. The issue isn't that `n` doesn't
exist inside the loop, it's that `n` has already been shadowed by the time
`n.a` is evaluated, meaning you're accessing `.a` of an uninitialized
binding.

In a little bit of a handwavy example, you could think of

```
let n = {a:[1,2,3]}
for (let n of n.a) {
  console.log(n);
}
```
expanding out kind of like this:

```
let n = {a:[1,2,3]};

let _iterable;
{
  _iterable = n.a;

  // Shadow 'n' so the line above here will always error out because 'n' is
uninitialized.
  let n;
}
for (var _value of _iterable) {
  let n = _value;

  console.log(n);
}
```

So the `let n;` shadows the outer `let n = {a: [1,2,3]};` when evaluating
`n.a`, resulting in a TDZ error.

You can see this behavior of the `for` head defined in
http://www.ecma-international.org/ecma-262/7.0/#sec-runtime-semantics-forin-div-ofheadevaluation-tdznames-expr-iterationkind,
where the usage of `let` in the head causes step 2 of loop head evaluation
to create a special new environment that specifically exists during the
execution of the `n.a` expression.


On Thu, Jul 14, 2016 at 1:36 PM, Blake Regalia 
wrote:

> `let n of n.a` is inside the `function` scope, not the `for` scope (look
> at the brackets). This is invalid/terrible-practice because `n` is already
> defined, and you are trying to use `let` to declare a new variable even
> though it already exists in the same scope.
>
>
>  - Blake
>
> On Thu, Jul 14, 2016 at 1:26 PM, /#!/JoePea  wrote:
>
>> The following examples are very confusing, and throw an error that `n` is
>> undefined:
>>
>> ```js
>> function go(n){
>>   for (let n of n.a) {
>> console.log(n);
>>   }
>> }
>>
>> go({a:[1,2,3]});
>> ```
>>
>> ```js
>> let n = {a:[1,2,3]}
>> for (let n of n.a) {
>>   console.log(n);
>> }
>> ```
>>
>> Why does the `let n` in the for loop not create a new variable inside the
>> for loop scope? This seems to go against the intuitive expectation of using
>> `let`, which is to make variable scoping more clear and less error-prone,
>> so it seems that one would expect the above examples to create a new
>> variable `n` inside the scope.
>>
>> Why is this not the case? Is it by design, and if so why?
>>
>>
>> */#!/*JoePea
>>
>> ___
>> 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: Ambiguity with default exports and live bindings?

2016-07-06 Thread Logan Smyth
>From the code perspective, changing the value of `A` will not update the
value of the export, but it's not quite that it's not live, it's that
you're not exporting what you think you're exporting.

```
export default A;
```

is essentially short for

```
const fakeInaccessibleVariable = A;
export {fakeInaccessibleVariable as default};
```

Changing the value of the `A` binding at a later time has no effect on the
exported value because it won't change the value if the inaccessible
variable.

In the spec this variable is referred to as `*default*` (note the `*`s in
the name mean it's not possible to have a program with that as a variable
name, making collisions with a variable impossible). This is because
`export default A;` falls into the same category as `export default 123;`,
where you are exporting an arbitrary value as the default. In the case of
`export default A;` you are exporting the value of `A` at the time that the
`export default` expression is evaluated. In the spec this is the format
`export default [lookahead ∉ { function, class }]
AssignmentExpression[In];` You can see this syntax construct's behavior
defined in the last block in
http://www.ecma-international.org/ecma-262/7.0/#sec-exports-runtime-semantics-evaluation
.

On Wed, Jul 6, 2016 at 3:02 PM, /#!/JoePea  wrote:

> Is it true one of the following does not create a live binding?
>
> ```js
> let A = 123
> export default A // not a live binding?
> ```
>
> compared to
>
> ```js
> let A = 123
> export {A as default} // live binding?
> ```
>
> If so, this seems like large source for unexpected behavior when people
> create modules. I can imagine people easily overlooking the difference and
> expecting live bindings in both cases (this already happened to me).
>
>
> */#!/*JoePea
>
> ___
> 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: exports at the top of the file

2016-06-06 Thread Logan Smyth
>
> ```js
> export default myConst;
> const myConst = {};
> ```
> would throw because when the export is evaluated


Correct, if you wanted to export `myConst` as the default without that
issue, you'd want to do

```
export {myConst as default};
const myConst = {};
```
to declaratively expose the binding under the default name, without
requiring the value be available at the time.

The key thing to remember with exports is that they are all processed
before the JS has even begin executing, and as you saw, are no-ops at
execution time, aside from `export default myConst` which is essentially
sugar for

```
const _hiddenBinding = myConst;
export {_hiddenBinding as default};
```

where the fact that a default binding exists is known at parse time. Only
the value of the export is assigned at evaluation time.

```js
> export {myConst};
> const myConst = {};
> ```


This is not an issue. Export declarations define mappings of module-local
binding names, to publicly exposed export names, and that is all, they do
not access the value in any way on their own. It's possible that if you had
some circular dependencies in your code, something could access `myConst`
before it had been initialized, and that would result in a TDZ error the
same way any other attempt to access the value would.


On Mon, Jun 6, 2016 at 9:39 PM, Raul-Sebastian Mihăilă <
raul.miha...@gmail.com> wrote:

> Douglas Crockford said that eventually JSLint would require exports at the
> top of the file. However I think there are some issues.
>
> If my understanding is correct,
>
> ```js
> export default myConst;
> const myConst = {};
> ```
>
> would throw because when the export is evaluated, in step 2 of the
> Evaluation algorithm applied to the ExportDeclaration: export default
> AssignmentExpression; production (
> https://tc39.github.io/ecma262/#sec-exports-runtime-semantics-evaluation),
> the value of the assignment expression is retrieved, which should cause an
> error because the binding has not yet been initialized.
>
> I'm not sure what should happen if myConst was exported with an
> ExportClause.
>
> ```js
> export {myConst};
> const myConst = {};
> ```
>
> In this case, the Evaluation algorithm just returns a normal completion.
> But I think that it depends on when myConst is indirectly accessed in the
> importing modules. If it's accessed before `const myConst` is evaluated,
> then I believe it would be uninitialized and would throw. Otherwise, it
> would work.
>
> Is my understanding correct? Thanks!
>
> ___
> 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: Subclassing native class and instanceof operator

2016-05-31 Thread Logan Smyth
The correct spec behavior is to return an instance of `MyError`. Step 7 in
your example is not equivalent to calling `Error` without `new`, which
seems to be your assumption. The `newTarget` parameter passed to
`Construct` is used to determine the prototype of the final object, and in
this context `newTarget` would be `MyError`.

Babel does not support extending builtins by default because it is
difficult to transpile properly and would add more boilerplate in all class
cases, even those which do not require logic to handle native extension. If
you need builtin extension support, the only way at the moment is to
explicitly enable it via a plugin like
https://www.npmjs.com/package/babel-plugin-transform-builtin-extend

On Mon, May 30, 2016 at 11:56 PM, Gray Zhang  wrote:

> I know NodeJS outputs `true` in this case, but my problem is from the spec
> it seems `false` is the correct result, or am I missing some chapters in
> spec?
>
> Jordan Harband 于2016年5月31日周二 下午2:47写道:
>
>> In which engine did you try this? Please refer to
>> http://kangax.github.io/compat-table/es6/ under "Subclassing" to see if
>> your browser supports subclassing builtins yet.
>>
>> On Mon, May 30, 2016 at 11:32 PM, Gray Zhang  wrote:
>>
>>> Recently I encountered an issue about subclassing Error and instance
>>> operator, my simplified code is:
>>>
>>> ```
>>> class MyError extends Error {
>>>   constructor() {
>>> super('my error');
>>>   }
>>> }
>>>
>>> let error = new MyError();
>>> console.log(error instanceof MyError);
>>> console.log(error.constructor);
>>> ```
>>>
>>> Surprisingly the output is `false` and `function Error() { [native code]
>>> }`
>>>
>>> I dived into the ECMAScript 2015 spec and find the behavior is correct,
>>> chapter 12.3.5.1 says:
>>> SuperCall : super Arguments
>>>
>>>1. Let *newTarget* be GetNewTarget
>>>
>>> 
>>>().
>>>2. If *newTarget* is *undefined*, throw a *ReferenceError* exception.
>>>3. Let *func* be GetSuperConstructor
>>>
>>> 
>>>().
>>>4. ReturnIfAbrupt
>>>
>>> 
>>>(*func*).
>>>5. Let *argList* be ArgumentListEvaluation of *Arguments*.
>>>6. ReturnIfAbrupt
>>>
>>> 
>>>(*argList*).
>>>7. Let *result* be Construct
>>>
>>>(*func*, *argList*, *newTarget*).
>>>8. ReturnIfAbrupt
>>>
>>> 
>>>(*result*).
>>>9. Let *thisER* be GetThisEnvironment
>>>
>>> (
>>>).
>>>10. Return *thisER*.BindThisValue
>>>
>>> 
>>>(*result*).
>>>
>>> Since Error can be called as a function without new operator, the result
>>> of step 7 is an error instance rather than undefined, so this error
>>> instance becomes `this` value of `thisER` and then returned as the result
>>> of new MyError constructor.
>>>
>>> The problem is, the spec also said "The Error constructor is designed to
>>> be subclassable." so I think instanceof should work correctly on
>>> subclasses, however it fails now.
>>>
>>> This also comes to Map, Set, Array and Object constructors.
>>>
>>> Babel 6.7.7 has the correct behavior which fails on instanceof operator
>>> but it really introduces some troubles, is this by design and how could I
>>> avoid such issues?
>>>
>>> ___
>>> 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: Import wildcards

2016-05-29 Thread Logan Smyth
I think my biggest issue with this is that it seems like a solution in
search of a problem. I can kind of see that you might end up with a setup
where common property prefixes are common in the case of config files where
you want many config options in one file. However, in the vast majority of
JS code, modules, scoping, and objects exist to provide a namespacing
already, making common prefixes extra work with little gain.

Having an import syntax aimed at allowing prefix-based imports solves what
could likely be solved more cleanly using the existing syntax combine with
changes to the structure of the data being exported.

You could for instance have specific sub-files for individual config
namespaces.

import * as API from 'config/api';
API.USERNAME;
API.TOKEN;

or if you want to keep everything in the same file, why not use an object
to create the namespace,

export const API = {
USERNAME: '',
TOKEN: '',
};

with

import {API} from 'config';
API.USERNAME;
API.TOKEN;





On Sun, May 29, 2016 at 1:01 PM, Maël Nison  wrote:

> I might be wrong, but the export * from '...'
>  syntax
> seems to re-export every symbol from a given module, effectively exporting
> indirectly those symbols (since you need to parse the imported module to
> know which symbols will be available). This syntax is quite valuable for
> configuration files, since you can "export *" from a base configuration,
> then overwrite specific symbols by using the usual "export MY_SYMBOL"
> syntax.
>
> Le sam. 28 mai 2016 à 17:06, Matthew Robb  a
> écrit :
>
>> Not exactly. To export a binding it must be declared in scope somewhere
>> which means it's statically analyzable within a given file.
>> On May 28, 2016 9:49 AM, "Maël Nison"  wrote:
>>
>>> I see, but unless I'm mistaken, the same issue occurs with the export *
>>> from '...' syntax, right ?
>>>
>>> Le ven. 27 mai 2016 à 16:06, Kevin Smith  a
>>> écrit :
>>>
 With this syntax, you would not be able to statically tell whether a
 particular variable name (e.g. API_FOO) is bound to a module import,
 without also analyzing the dependencies (and perhaps their dependencies).
 These considerations killed the original "import all" syntax.  (`import *
 from 'foobar'`);

 If repitition is an issue, use the namespace import form.

 import * as constants from 'config';


 On Fri, May 27, 2016 at 10:00 AM Maël Nison 
 wrote:

> Hi,
>
> In about every project I have, I write a file or two with this form:
>
> export let API_USERNAME = `name`
> export let API_TOKEN = `token`
> // etc
>
> Most of the time, when I need one of those variables somewhere, I also
> need the other. It might be burdensome, since I end up with something
> similar to this:
>
> import { API_USERNAME } from 'config';
> import { API_TOKEN } from 'config';
> // etc
>
> Of course, I can import all of these token in a single line, but it
> doesn't help readability when there is a lot of entries (we all know that
> configuration files always end up with a fair number of variables - and
> let's not talk about parsers and similar). Plus, it's not very fun to
> explicitely write all these names when I just want to tell the engine that
> I will need everything similar, pretty please.
>
> Now as for the request: what would you think about adding a new syntax
> -nothing too fancy- to import all the symbols that match a *static 
> *pattern?
> In the spirit of the `export * from ...` syntax, I feel like the following
> could be interesting:
>
> import { API_* } from 'config';
>
> As for the bad part: there really isn't, actually. This syntax is
> familiar with every developer that used globing before, and gives just
> enough insight to someone looking at the source code to understand that a
> variable named `API_SOMETHING` has been imported from a parent module.
> Linters would also be able to help in this regard, since they would just
> have to blacklist declaring variables that would conflict with an import
> prefix.
>
> Any thoughts ?
>
> ___
> 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
>
>
___
es-discuss 

Re: Ignoring arguments

2016-05-29 Thread Logan Smyth
```
function fn(...[a, b, c, ...rest]){}
```
is mostly no different than
```
function fn(...args){
let [a, b, c, ...rest] = args;
}
```

This wasn't officially allowed in ES2015, where only an Identifier was
allowed as a rest param target in arguments, but the behavior has since
been expanded to cover this case in ES2016:
https://github.com/tc39/ecma262/commit/d322357e6be95bc4bd3e03f5944a736aac55fa50

Not that I think this example is particularly readable :)

On Sun, May 29, 2016 at 10:36 AM, Renki Ivanko 
wrote:

> It works in V8 at least, so I assumed it's correct.
>
> On Sun, May 29, 2016 at 8:29 PM, Bob Myers  wrote:
>
>> I'm quite sure this syntax is invalid.
>>
>>
>> On Sun, May 29, 2016 at 9:36 PM, Renki Ivanko 
>> wrote:
>>
>>> You can already do it like this:
>>>
>>> ```js
>>> ((...[,,foo]) => foo)(1, 2, 3) // -> 3
>>> ```
>>>
>>>
>>> R. 
>>>
>>> On Sun, May 29, 2016 at 6:53 PM, Cyril Auburtin <
>>> cyril.aubur...@gmail.com> wrote:
>>>
 Similarly to:

 `var [,x,,y] = [1,2,3,4,5,6];`

 I think it could be interesting to let a field empty in function
 arguments

 `[1,2,3,4].map( (,i) => i )`, `Array.from({length:10}, (,i) => i )`

 `function test(a,,b) { }`

 (but that would alter the current parsing, that doesn't allow it)

 Currently I often use `_` as a way to mark ignored fields, but when
 there are more than 1 you need another identifier. A standard way would be
 interesting rather

>>>
>>
>
> ___
> 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: Is it possible to define an array iterator that adjusts to your for-of syntax?

2016-05-22 Thread Logan Smyth
It is not possible to detect this.

```
for (let [i, elem] of arr){
```

is no different that than

```
for (let pair of arr){
  let [i, elem] = pair;
```

You are destructuring the result of an iterator, and the initialization of
the iterator is independent from the initialization of the destructuring
pattern.



On Sun, May 22, 2016 at 10:55 AM, Šime Vidas  wrote:

> Say I have an array over which I need to iterate multiple times, but I
> need the index value only some of the time. Is it possible to create a
> custom iterator which auto-detects when I need the index and feeds me
> entries() instead of values() in those cases? For example:
>
> array[Symbol.iterator] = /* some magic here */
>
> for (let elem of array) { /* values() iterator is used automatically */ }
> for (let [i, elem] of array) { /* entries() iterator is used automatically
> */ }
>
>
> ___
> 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: Class and Property Initialization

2016-03-19 Thread Logan Smyth
Bradley, looks like you have a typo and should be using the `this` argument
you pass to `exec` rather than `this` in the arrow?

```
class B extends A {
  constructor() {
super(inst => {
  inst.b = 2;
});
  }
}
```

On Fri, Mar 18, 2016 at 8:27 AM, Bradley Meck 
wrote:

> In my own code I tend to do the constructor/executor pattern:
>
> ```
> class A {
>   constructor(exec) {
> this.a = 1;
> exec(this);
> Object.freeze(this);
>   }
> }
> class B extends A {
>   constructor() {
> super(() => {
>   this.b = 2;
> });
>   }
> }
> ```
>
> And it works out pretty well.
>
> On Fri, Mar 18, 2016 at 11:25 AM, kdex  wrote:
>
>> Another way that allowed you to use `new` on both base and derived
>> classes would be something like this:
>>
>> ```js
>> "use strict";
>> function sealInstance(bool) {
>> if (bool) {
>> Object.seal(this);
>> }
>> }
>> class Base {
>> x = 1;
>> constructor(seal = true) {
>> sealInstance(seal);
>> }
>> }
>> class Derived extends Base {
>> y = 2;
>> constructor(seal = true) {
>> super(false);
>> sealInstance(seal);
>> }
>> }
>> let b = new Base(); // Base class can be instantiated with sealing
>> let d = new Derived(); // Derived class can be instantiated with sealing
>> ```
>>
>> Not a particular esthetic way, but it doesn't break `new` and transpiles
>> without private fields.
>> (It will make your constructor signatures a little ugly, though.)
>>
>>
>> On 18.03.2016 16:10, Michael Theriot wrote:
>>
>> Try this... It will only seal if calling new. The subclasses will still
>> need to seal though.
>>
>> ```js
>> class Test {
>>   constructor() {
>> this.x = 1;
>> if(new.target === Test) {
>>   Object.seal(this);
>> }
>>   }
>> }
>> ```
>>
>> On Fri, Mar 18, 2016 at 9:57 AM, Brian Barnes  wrote:
>>
>>> Great, glad to hear that's coming!  I think sealing is a fine solution,
>>> it'll do what I want and doesn't cause fits for the engine makers.
>>>
>>> That said, it has one problem -- base classes.  You can't seal them
>>> because the constructor in the extended class would fail (I tried it) and
>>> so the base classes would always have to remain  unsealed which means you
>>> either (1) understand that or (2) always use an extended class if you care
>>> for level of code safety.
>>>
>>> [>] Brian
>>>
>>>
>>> On 3/18/2016 11:50 AM, kdex wrote:
>>>
 Brian, Your first example isn't too far from ES2017. Leave away the
 `let`s and seal it, and you got:

 ```js
 "use strict";
 class Test {
  x = 1;
  y = 2;
  constructor() {
  Object.seal(this);
  this.z = 3; // TypeError
  }
 }
 ```
 You can already use this using transpilers (at least babel supports it).

 On 18.03.2016 15:39, Brian Barnes wrote:

> Ugh, well, I guess I typed a lot of stuff for nothing!  And by the
> look of their experiment, what I wanted was actually one of the major
> blockers.
>
> It seems classes will really need a more standard type of syntax (non
> static) before you could actually achieve this, and might be a bridge
> too far for javascript:
>
> class test
> {
> let x=1;
> let y=2;
> constructor() {}
> func() { this.z=2; }// syntax error
> }
>
> Though it could be kind of faked by some kind of reverse hoisting,
> i.e., rebuilding the code inside the engine:
>
> class test
> {
> constructor()
> {
> this.x=1;
> this.y=2;
> // stuff that was in the constructor
> Object.seal(this);
> }
> ...
> }
>
> [>] Brian
>
> On 3/18/2016 10:04 AM, Sébastien Doeraene wrote:
>
>> Hi,
>>
>> The Strong Mode experiment was canceled:
>> https://groups.google.com/forum/#!topic/strengthen-js/ojj3TDxbHpQ
>>
>> Cheers,
>> Sébastien
>>
>> On Fri, Mar 18, 2016 at 3:59 PM, kdex < k...@kdex.de
>> > wrote:
>>
>> Already considered and to be implemented via strong mode IIRC.
>>
>> On 18.03.2016 14:36, Brian Barnes wrote:
>>
>> I know properties on classes are getting a look over for the
>> next iteration (last I checked) and I understand javascript is
>> obviously a different language then other oo languages with a
>> different foundation, but I bring this up for it's usage in
>> producing stricter code that reduces errors and is easier to
>> analyze.  A vote for this if anybody considered it!
>>
>> class Test
>> {
>>
>> constructor()
>> {
>>this.x=1;
>> }
>>
>> func1()
>> {
>>this.y=2;
>> 

Re: Has the bind operator been revoked from proposal?

2016-03-05 Thread Logan Smyth
The main page is only proposals >= Stage 1. All of the Stage 0 proposals
are on a separate page:
https://github.com/tc39/ecma262/blob/master/stage0.md

On Sat, Mar 5, 2016 at 11:26 AM, JD Isaacks  wrote:

> Looking here: https://github.com/tc39/ecma262
>
> I no longer see the bind `::` operator listed. Does that mean it is no
> longer being proposed? Or is that list incomplete? If the latter, is there
> anywhere that lists a complete list of proposals?
>
> ___
> 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: Object.prototype.forIn

2016-03-04 Thread Logan Smyth
Edwin, the original example loop explicitly checks `obj.hasOwnProperty(key)`,
so properties in the prototype chain are not an issue here.

On Fri, Mar 4, 2016 at 1:04 PM, Edwin Reynoso  wrote:

> Sorry guys but this is very wrong, for in, loops through all properties
> even the ones inherited from all prototypes, while Object.keys() and
> Object.entries() do not. They are indeed very different
>
> On Fri, Mar 4, 2016 at 1:45 PM Langdon  wrote:
>
>> Ahhh, nothing.  I never think about destructuring.  Thanks!
>>
>> On Fri, Mar 4, 2016 at 1:41 PM, Caitlin Potter 
>> wrote:
>>
>>> > Object.entries does look nice, but 2 arguments is more straightforward
>>> than a passing around a pair.
>>>
>>> What’s the problem with `for (let [key, value] of Object.entries(obj)) {
>>> …. }`
>>>
>>> > As well (and perhaps more importantly), temporarily building an array
>>> of arrays so we can forEach it, seems way less efficient than forIn
>>> is/would be.
>>>
>>> You might be surprised — If the pair never reaches geriatric status (old
>>> generation/tenured space, etc), it could be allocated and cleaned up
>>> relatively quickly.
>>>
>>> On Mar 4, 2016, at 1:28 PM, Langdon  wrote:
>>>
>>> My gripe with Object.keys is that it requires a closure to use
>>> effectively.
>>>
>>> Object.entries does look nice, but 2 arguments is more straightforward
>>> than a passing around a pair.
>>>
>>> As well (and perhaps more importantly), temporarily building an array of
>>> arrays so we can forEach it, seems way less efficient than forIn is/would
>>> be.
>>>
>>> On Fri, Mar 4, 2016 at 1:20 PM, Isiah Meadows 
>>> wrote:
>>>
 Yeah, and those effectively nullify this, anyways.

 On Fri, Mar 4, 2016, 12:55 Simon Blackwell 
 wrote:

> Not sure of the rationale; however, it looks like Chrome now supports
> something similar natively:
>
>
>
>
> https://twitter.com/malyw/status/704972953029623808?utm_source=javascriptweekly_medium=email
>
>
>
> *From:* es-discuss [mailto:es-discuss-boun...@mozilla.org] *On Behalf
> Of *Langdon
> *Sent:* Friday, March 4, 2016 11:22 AM
> *To:* es-discuss@mozilla.org
> *Subject:* Object.prototype.forIn
>
>
>
> My apologies if this has been discussed before (I have to imagine it
> has, but couldn't find anything).
>
>
>
> Why isn't there a `forIn` method on Object natively?
>
>
>
> Something that simply wraps this all-to-common code:
>
>
>
> var key;
>
>
>
> for (key in obj) {
>
>   if (obj.hasOwnProperty(key) === true) {
>
> ...
>
>   }
>
> }
>
>
>
> Example: https://jsfiddle.net/langdonx/d4Lph13u/
>
>
>
> TIA,
>
> Langdon
> ___
> 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
>>
> --
> Thanks
> - Edwin
>
> ___
> 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: Object.prototype.forIn

2016-03-04 Thread Logan Smyth
You can already achieve this in ES5 with

```
Object.keys(obj).forEach(key => {

});
```

or in ES6 with

```
var key;
for (key of Object.keys(obj)){

}
```

And with the new proposal, you'll also have `Object.values` for values and
`Object.entries` for key/value pairs:
https://github.com/tc39/proposal-object-values-entries

On Fri, Mar 4, 2016 at 8:22 AM, Langdon  wrote:

> My apologies if this has been discussed before (I have to imagine it has,
> but couldn't find anything).
>
> Why isn't there a `forIn` method on Object natively?
>
> Something that simply wraps this all-to-common code:
>
>
> var key;
>
> for (key in obj) {
>   if (obj.hasOwnProperty(key) === true) {
> ...
>   }
> }
>
> Example: https://jsfiddle.net/langdonx/d4Lph13u/
>
> TIA,
> Langdon
>
> ___
> 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: Assignments to SuperProperty are confusing and may be useless

2016-02-19 Thread Logan Smyth
Assignment to a super properly definitely has its uses, in the same way
that calling a super method does, though definitely less common. Consider
an example where a subclass wants to override a parent class's accessor
property:

```
class Parent {
  get prop(){
return this._prop;
  }
  set prop(val){
this._prop = val;
  }
}

class Child extends Parent {
  get prop(){
return super.prop.slice('prefix'.length);
  }
  set prop(val){
super.prop = 'prefix' + val;
  }
}

```

Unless the child class wants to (and is able to) duplicate the parent
classes logic, or manually trigger the parent getter and setter functions,
assigning to the super accessor is the only approach.

On Fri, Feb 19, 2016 at 7:20 PM, ziyunfei <446240...@qq.com> wrote:

> Today I saw a V8 test case [1] which took me a long time to figure out why
> it runs like this:
>
> class Test {
>   m() {
> super.length = 10;// `super.length' here has the same effect as
> `this.length'
> console.log(super.length);// but `super.length' here is
> `Test.prototype.__proto__.length' (i.e. `Object.prototype.length') which
> still remains `undefined'
>   }
> }
> var array = [];
> Test.prototype.m.call(array);
> assertEquals(10, array.length);
>
> This syntax is so confusing and I couldn't think of any real use case for
> it, so should we make `SuperProperty = AssignmentExpression' an early error?
>
> Also, I found an old es-bug thread [2] discussed about this.
>
> [1]
> https://chromium.googlesource.com/v8/v8/+/77e30f013a221527bb4ab955188aec44f10fee7f/test/mjsunit/es6/classes-super.js
>
> [2] https://bugs.ecmascript.org/show_bug.cgi?id=3246
>
>
>
> ___
> 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: `await null` to stay in the same tick?

2016-02-08 Thread Logan Smyth
Joe, if you have a specific example, feel free to file an issue and I can
take a look. From what I can see,
http://babeljs.io/repl/#?experimental=true=true=false=false=false=%0A%0A(async%20function%20fn()%7B%0A%20%20console.log('start')%0A%20%20Promise.resolve().then(()%20%3D%3E%20console.log('tick'))%3B%0A%20%20await%20null%3B%0A%20%20%0A%20%20console.log('end')%3B%0A%7D)()%3B
would indicate that Babel always defers with Regenerator as well. Better to
have this discussion elsewhere though.

On Mon, Feb 8, 2016 at 7:07 PM, /#!/JoePea  wrote:

> (Or, maybe it's Facebook Regenerator's fault, not Babel's)
>
>
> On Monday, February 8, 2016, /#!/JoePea  wrote:
>
>> Aah, good to know. With Babel this isn't the case, as `await null`
>> doesn't defer, so I was doing `await somethingThatMightBeNull` to possibly
>> defer, but `if (somethingThatMightBeNull) await somethingThatMightBeNull`
>> will be full proof if Babel fixes that.
>>
>> On Sunday, February 7, 2016, Mark S. Miller  wrote:
>>
>>>
>>>
>>> On Sun, Feb 7, 2016 at 1:51 PM, Kris Kowal  wrote:
>>>
 Await yields to the event loop unconditionally. This is useful for
 spreading CPU-bound work across multiple events. You can explicitly await
 conditionally.

 ```
 if (guard) { await guard; }
 ```

>>>
>>> Good example, thanks.
>>>
>>>
>>>

 On Sun, Feb 7, 2016 at 1:39 PM /#!/JoePea  wrote:

> I'm not sure where's the best place to ask, but if I
>
> ```
> await null
> ```
>
> in an async function does that guarantee that the following code will
> execute immediately (control flow will not go anywhere else)?
>
> - Joe
> ___
> 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
>>>
>>
>>
>> --
>> /#!/JoePea
>>
>
>
> --
> /#!/JoePea
>
> ___
> 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: Negative indexes

2016-02-01 Thread Logan Smyth
Felipe, this has been discussed in the other thread that was just linked:
https://esdiscuss.org/topic/javascript-language-feature-idea. `arr[-1]` is
not a workable solution because it could break existing code.

On Mon, Feb 1, 2016 at 4:43 PM, Felipe Nascimento de Moura <
felipenmo...@gmail.com> wrote:

> Yes, that would do what he wants...but I like the idea of using
> ```arr[-1]```, though!!
> It just makes sense, to me!
> Specially if you want to use reversed loops, for example.
>
>
>
> On Mon, Feb 1, 2016 at 5:46 PM C. Scott Ananian 
> wrote:
>
>> `arr.slice(-1)[0]` does what you want, I think.
>>  --scott
>> ​
>> ___
>> 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: Modifying ES6 module exports

2015-12-22 Thread Logan Smyth
The `{}` shouldn't be from Babel, it has handled all circular dependency
cases as far as I'm aware. I'm curious to know what the end cause of this
issue is, but this isn't really the right discussion forum for it. Joe, if
you do end up making a simplified example that can be tested, I'd be happy
to take a look, so feel free to ping me.

On Tue, Dec 22, 2015 at 5:49 PM, Caridy Patino  wrote:

> circular dependencies will work nicely with declarations, not so much with
> expressions because the code has to be evaluated to set those bindings.
> This, of course, is not a problem if you're not invoking some
> initialization when evaluating the body of the module.
>
> all in all, that's what you're experiencing. as for the {}, that's just
> babel.
>
> side note: this has nothing to do with those being default exports, it
> will happen for any export.
>
> /caridy
>
> > On Dec 21, 2015, at 10:25 PM, /#!/JoePea  wrote:
> >
> > I'm curious, what should happen when module A imports the default from
> > module B which imports the default from module A? Should the exported
> > A object exist inside of module B?
> >
> > Here's two modules A and B (simplified from some real code that I
> > have), which have a circular dependency:
> >
> > ```js
> > // A.js
> > import B from './B'
> > let A = window.globalThing
> > export default A
> >
> > // modify the A object adding methods that reference B.
> > ```
> >
> > ```js
> > // B.js
> > import A from './A'
> > let B = new window.OtherThing
> > export default B
> >
> > console.log(A) // an empty object, {}
> >
> > // modify the B object which depends on A existing (not being some
> temporary
> > // object like I get with Webpack) while the module is evaluated.
> > ```
> >
> > When using Webpack, this code fails because the reference to A in B is
> > some empty object. If I import both A and B into main.js, then A is
> > defined as epected:
> >
> > ```js
> > // main.js
> > import A from './A'
> > import B from './B'
> >
> > console.log(A) // An object with a bunch of properties, as expected.
> > ```
> >
> > I can fix my problem by exporting functions to do setup of A and B,
> > and running those functions in main.js, like this:
> >
> > ```js
> > // A.js
> > import B from './B'
> > let A = window.globalThing
> > export default A
> >
> > A.setup = () => {
> >  // modify the A object adding methods that reference B.
> > }
> > ```
> >
> > ```js
> > // B.js
> > import A from './A'
> > let B = new window.OtherThing
> > export default B
> >
> > console.log(A) // an empty object, {}
> >
> > B.setup = () => {
> >  console.log(A) // the expected object!! Why?
> >
> >  // modify the B object which depends on A existing (not being some
> temporary
> >  // object like I get with Webpack) while the module is evaluated.
> > }
> > ```
> >
> > When using Webpack, this code fails because the reference to A in B is
> > just `{}`, some empty object. If I import both A and B into main.js,
> > then A is defined as epected:
> >
> > ```js
> > // main.js
> > import A from './A'
> > import B from './B'
> >
> > A.setup()
> > B.setup()
> >
> > // no more problems!
> >
> > console.log(A) // An object with a bunch of properties, as expected.
> > ```
> >
> > So, if I run the setup for A and B in main.js instead of in the module
> > evaluation, everything works perfectly.
> >
> > This led me to wonder: What is the expected behavior of circular
> > dependencies in ES2015? Have you had this 'empty object' problem
> > before? Is that expected to happen, or might there be a bug in
> > Webpack?
> >
> > I guess the problem makes sense: How can the first method (running
> > relying on module evaluation for setting up A and B exports) work if
> > module B depends on the evaluation of module A which depends on the
> > evaluation of module B?
> > ___
> > 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: Modifying ES6 module exports

2015-12-21 Thread Logan Smyth
To start, an object is definitely not what I'd expect. The core thing to
remember with ES6 modules is that while imports are live bindings, you
still need to write your code in such a way that it has no run-time
circular dependencies.

In your specific examples, you are importing `A` first, which will begin
`B` loading. Since `A` has not finished executing yet, and B will be
attempting to access the the `A` import before the `A.js` file has begin
executing. I'm not 100% sure off the top of my head, but in a real ES6
environment, that would either result in the `A` import being `undefined`,
or attempting to access it would throw a temporal dead zone error due to
you accessing a variable before it has been initialized.

If your `A.js` file comment "// modify the A object adding methods that
reference B." adds those references without actually accessing `B` in any
way, then the solution to your issue (in a real environment anyway) would
be to import `B.js` _first_ so that you do not have circular
initialization-time dependencies.

In this case, are you using Babel's ES6 module syntax transpiling, or
Webpack with another transpiler?


On Mon, Dec 21, 2015 at 7:25 PM, /#!/JoePea  wrote:

> I'm curious, what should happen when module A imports the default from
> module B which imports the default from module A? Should the exported
> A object exist inside of module B?
>
> Here's two modules A and B (simplified from some real code that I
> have), which have a circular dependency:
>
> ```js
> // A.js
> import B from './B'
> let A = window.globalThing
> export default A
>
> // modify the A object adding methods that reference B.
> ```
>
> ```js
> // B.js
> import A from './A'
> let B = new window.OtherThing
> export default B
>
> console.log(A) // an empty object, {}
>
> // modify the B object which depends on A existing (not being some
> temporary
> // object like I get with Webpack) while the module is evaluated.
> ```
>
> When using Webpack, this code fails because the reference to A in B is
> some empty object. If I import both A and B into main.js, then A is
> defined as epected:
>
> ```js
> // main.js
> import A from './A'
> import B from './B'
>
> console.log(A) // An object with a bunch of properties, as expected.
> ```
>
> I can fix my problem by exporting functions to do setup of A and B,
> and running those functions in main.js, like this:
>
> ```js
> // A.js
> import B from './B'
> let A = window.globalThing
> export default A
>
> A.setup = () => {
>   // modify the A object adding methods that reference B.
> }
> ```
>
> ```js
> // B.js
> import A from './A'
> let B = new window.OtherThing
> export default B
>
> console.log(A) // an empty object, {}
>
> B.setup = () => {
>   console.log(A) // the expected object!! Why?
>
>   // modify the B object which depends on A existing (not being some
> temporary
>   // object like I get with Webpack) while the module is evaluated.
> }
> ```
>
> When using Webpack, this code fails because the reference to A in B is
> just `{}`, some empty object. If I import both A and B into main.js,
> then A is defined as epected:
>
> ```js
> // main.js
> import A from './A'
> import B from './B'
>
> A.setup()
> B.setup()
>
> // no more problems!
>
> console.log(A) // An object with a bunch of properties, as expected.
> ```
>
> So, if I run the setup for A and B in main.js instead of in the module
> evaluation, everything works perfectly.
>
> This led me to wonder: What is the expected behavior of circular
> dependencies in ES2015? Have you had this 'empty object' problem
> before? Is that expected to happen, or might there be a bug in
> Webpack?
>
> I guess the problem makes sense: How can the first method (running
> relying on module evaluation for setting up A and B exports) work if
> module B depends on the evaluation of module A which depends on the
> evaluation of module B?
> ___
> 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: `super` and superclass constructor return values

2015-10-16 Thread Logan Smyth
Yup, correct. The value of the `this` binding is initialized to the result
of `[[Construct]]`, which will either be the parent constructor `this`
binding, or the explicitly returned value.

Relevant spec links:
Evaluating `super()`: (12.3.5.1)
http://www.ecma-international.org/ecma-262/6.0/#sec-super-keyword-runtime-semantics-evaluation
Returning a value from a constructor: (9.2.2 step 13.b)
http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-construct-argumentslist-newtarget


On Fri, Oct 16, 2015 at 2:24 PM, Eric Faust  wrote:

> Hi Isiah,
>
> My understanding is that this should log "true". Class constructors may
> return any object they wish, and needn't return instances of the class.
>
> Hopefully, this will allow you to simplify.
>
> Thanks,
>
> Eric
>
> On Fri, Oct 16, 2015 at 2:02 PM, Isiah Meadows 
> wrote:
>
>> What should `this` be in class `B`? The value of `object` or an instance
>> of `B`? It's an edge case, but could simplify my code a little if it's the
>> former.
>>
>> ```js
>> const object = {}
>>
>> class A {
>>   constructor() {
>> return object
>>   }
>> }
>>
>> class B extends A {
>>   constructor() {
>> super()
>> console.log(this === object)
>>   }
>> }
>> ```
>>
>> ___
>> 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: Exporting Symbols

2015-10-15 Thread Logan Smyth
The main issue is that modules are statically analysable and
imports/exports are processed before the module executes, and the behavior
of a symbol is by definition a runtime thing. Until the code executes,
there would be no symbol object, and there would be no way to know what
thing was being imported imported / exported.

The primary benefit of symbols is that they are unique, and cannot collide
unless you have a reference to them. Module exports have full control over
their names and don't have the same collision issues that objects and
classes generally do. What is the benefit you are hoping to get from
exposing these values on symbols instead of string keys?



On Thu, Oct 15, 2015 at 12:14 AM, Francisco Tolmasky 
wrote:

> Not sure if it isn’t the case, but it seems the only way to export symbols
> right now is:
>
> ```js
> export default { [Symbol(“something”)]: blah }
> ```
>
> It would be nice if “symbol literals” could somehow be supported. In
> particular, I can imagine this sort of thing becoming common:
>
> export { “5.4” as Symbol(“version”) }
>
> Or, even better (but harder since its now more expression):
>
> import VersionSymbol from “symbols"
> export { “5.4” as VersionSymbol }
>
> I’m currently writing an API where there are expected methods stored in
> symbols, but this forces exporting one default object instead of being able
> to lay them out individual.
>
> Thanks,
>
> Francisco
>
> --
> Francisco Tolmasky
> www.tolmasky.com
> tolma...@gmail.com
>
> ___
> 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: String.substitute

2015-08-12 Thread Logan Smyth
Template literals evaluate to simple strings, there is no way to pass a
reference to an un-evaluated template literal. The function method is the
only way. Programmatically

```
String.substitute({ year: 2015}, `Last year was ${year-1}`);
```

is identical to

```
var str = `Last year was ${year-1}`
String.substitute({ year: 2015}, str);
```

How would it ever know that it was supposed to skip evaluating the template
string first before calling the function?


On Wed, Aug 12, 2015 at 7:55 AM, Edwin Reynoso eor...@gmail.com wrote:

 With `String.substitute()` you'd still be able to evaluate expressions,
 it's kind of like changing scope, or passing an object to use for scoped
 variables, which is not possible:

 ```JS
 substitute({ year: 2015 }, 'Last year was year ${year-1}'); // Will throw
 an error
 ```

 You can't evaluate with your function

 With `String.substitute()` you would be able to:

 ```JS
 String.substitute({ year: 2015}, `Last year was ${year-1}`);
 ```

 You also miss **New Lines** which is another thing template literals
 solved, so yes you could just add `\n` but that's the point of why template
 literals take care of that for you

 On Wed, Aug 12, 2015 at 10:49 AM, Elie Rotenberg e...@rotenberg.io
 wrote:

 ```
 function substitute(obj, str) {
   return str.replace(/\${([^}]*)}/g, (m, p) = obj[p]);
 }

 substitute({ year: 2015 }, 'This is year ${year}'); // === 'This is year
 2015'
 ```


 On Wed, Aug 12, 2015 at 4:42 PM, Nathaniel Higgins n...@nath.is wrote:

 Am I being naive or could this just be written in user space?

 Sent from my iPhone

 On 12 Aug 2015, at 15:31, Edwin Reynoso eor...@gmail.com wrote:

 Yes of course, still requires 1.Destructuring, and making a function for
 each type of string to return. Defeats the purpose.

 I'd have to make different functions for each template:

 ```JS
 const yearTemplate = ({ year }) = `This year is ${year}`;

 const ageTemplate = ({ age}) = `I'm ${age} yrs old`;
 ```

 Compare to:

 ```JS
 let yearSentence = String.substitute({ year: 2015}, `This year is
 ${year}`);
 let ageSentence = String.substitute({ age:100 }, `I'm ${age} yrs old`);
 ```

 On Wed, Aug 12, 2015 at 10:19 AM, Claude Pache claude.pa...@gmail.com
 wrote:


  Le 12 août 2015 à 15:41, Edwin Reynoso eor...@gmail.com a écrit :
 
  Could we make the following possible, I can't seem to think of a way
 to do it, since template literals are evaluated with the current scope,
 also tried with `eval` but shouldn't even use that at all:
 
  ```JS
  String.substitute( { year: 2015 }, `This year is ${year}` ); //
 Returns This year is 2015
  ```
 
  Yes I'm aware I could do the following:
 
  ```JS
  var obj = { year:2015 }
 
  `This year is ${obj.year}`
  ```
 
  The point is to get rid of the part where I reference `obj` all the
 time.
 
  I could just use destructuring:
 
  ```JS
  var { year } = { year: 2015 }
 
  `This year is ${year}`
  ```
 
  So yes destructuring takes care of most of this just fine, but the
 point is to have a template literal evaluate as a pass reference and not
 right away.
 
  You can't make your own function and pass in a template literal
 that's not evaluated when passed as a reference, I'm not sure if anyone
 will actually want this but me. Please let me know. Thanks

 There is a general trick for deferring evaluation (of a template
 literal or of anything else): enclosing it in a function.

 ```js
 const myTemplate = ({ year }) = `This year is ${year}`

 myTemplate({ year: 2015 })
 ```

 —Claude


 ___
 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


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


Re: String.substitute

2015-08-12 Thread Logan Smyth

 Could be possible to pass a string with  instead of \`\`


At that point, you are implementing a templating language that happens to
match up syntactically with template literals. You'd also then be moving
parsing of the template to runtime instead of compile time, which will slow
things down. It would also only be possible to implement using `eval`.

You can certainly do that, but it doesn't seem like something that should
be included in the language. It's no different from using Handlebars or
Mustache at that point. The primary benefit of template literals is that
they have access to variables in-scope, which seems to be what you are
trying to avoid.

On Wed, Aug 12, 2015 at 8:19 AM, Edwin Reynoso eor...@gmail.com wrote:

 @logan that's an interesting thought, which is why I posted this for
 discussion, Thinking of that, I'm kind of doubting most will like the
 function to only be able to take the literal instead as a variable because
 that's just messing with the way Javascript itself.

 Could be possible to pass a string with  instead of \`\`

 ```JS
 String.substitute({year: 2015}, This year is ${year});
 ```

 Which is giving javascript a way to allow writing a Template Literal
 without evaluating by using  instead of \`\`

 @Tab atkin

 Your still making a function yourself. You may ask what's wrong with that?

 Well then I'd say what's the point of `ES6` having `Hi.includes(H)`
 when we could of just did:

 ```JS
 function includes(str, included) {
   return str.indexOf(included)  -1;
 }
 ```

 On Wed, Aug 12, 2015 at 11:08 AM, Tab Atkins Jr. jackalm...@gmail.com
 wrote:

 On Wed, Aug 12, 2015 at 7:31 AM, Edwin Reynoso eor...@gmail.com wrote:
  Yes of course, still requires 1.Destructuring, and making a function for
  each type of string to return. Defeats the purpose.
 
  I'd have to make different functions for each template:
 
  ```JS
  const yearTemplate = ({ year }) = `This year is ${year}`;
 
  const ageTemplate = ({ age}) = `I'm ${age} yrs old`;
  ```
 
  Compare to:
 
  ```JS
  let yearSentence = String.substitute({ year: 2015}, `This year is
 ${year}`);
  let ageSentence = String.substitute({ age:100 }, `I'm ${age} yrs old`);
  ```

 let yearSentence = ({year:2015}=`This year is ${year}`)();

 should work, or

 let yearSentence = (year=`This year is ${year}`)(2015);

 You don't *have* to save the templates in variables. You can just call
 them immediately.

 ~TJ



 ___
 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: Cancelable promises proposal

2015-08-05 Thread Logan Smyth
Given your example of

```
let done = query.done;
done.then(updateView).then(log, logAbort);
done.ignore(updateView);
```

The core of my complaint comes down to control flow. To demonstrate, let's
convert this to a co generator so it's readable like sync code.

```
co(function*(){
  try {
let result = yield query.done;
let update = yield updateView(result);
log(update);
  } catch(err){
logAbort(err);
  }
});
```

What you are asking for seems like a way to halt execution of the function,
without ever returning from the function, or executing either branch of the
try/catch. In synchronous code the only way to achieve this would be
`while(true){}`, which is terrible. There isn't really a world where I'd
expect that code to execute neither side, because promises are
fundamentally about chaining data together, not about listening for events.

Instead you might write your code like

```
let ignore = false;
let done = query.done;
done.then(result = ignore ? undefined : updateView(result).then(log,
logAbort));
ignore = true;
```
Your code is skipped, like you wanted, but the outer promise still resolves
eventually.


As for the duplicate handler question, imagine this:

```
let counter = 0;
function fn(){
  return ++counter;
}

let original = Promise.resolve();
let result;
for (let i = 0; i  10; i++){
  result = original.then(fn);
}
result.then(output = console.log(output));
```

the result is `10` because `result` was the 10th promise and then the 10th
execution of `fn`. If the same promise were returned constantly, then this
would instead print `1`.



On Tue, Aug 4, 2015 at 9:06 PM, Glen Huang curvedm...@gmail.com wrote:

 Are there some example use-cases where being able to `.ignore` is
 preferable to having the promise reject?


 The purpose of .ignore() is to let promises show disinterest, by
 disinterest, i mean the situation that whatever happens to that promise, it
 shouldn't be observable to the callbacks. Making that promise pending
 forever is the correct way to do that IMO. Rejecting the promise means the
 callback is still interested in the rejecting case.

 I can't really see a case where you'd want to disconnect a promise handler
 without informing promises farther down the chain


 If you want to inform promises farther down the chain, you shouldn't
 disconnect the handler, you should let that aborted reason flow down the
 chain.

 Also to your question about adding multiple handlers, if that handler has
 side-effects, then it would definitely cause bugs if the same promise were
 returned for multiple calls to `.then` with the same callback.


 Are you talking about passing the same callback combination to .then()
 returns the same promise? Would you provide an example where it can cause
 bugs? I guessed it's dangerous, but not sure how it could fail. But let's
 say it causes bug, do you think .ignore() disconnecting all same callbacks
 in the current promise could cause bug too? Or it could behave
 counter-intuitively? I'm only using returning the same promise as a
 guidance on designing how ignore() works, .then() doesn't really have to
 behave that way.

 Finally, here is an example to demonstrate the use case.

 Given

 ```js
 let query = queryDB(sql);
 let updateView = data = render(data);
 let log = data = console.log(data);
 let logAbort = err = {
   if (err instanceof AbortError) console.error(reason);
   throw err;
 };
 ```

 Let's say you want to abort the query, but log the abortion in a child
 promise:

 ```js
 query.done.then(updateView).then(log, logAbort);
 query.abort();
 ```

 Or if you want to show disinterest that the query is irrelevant now:

 ```js
 let done = query.done;
 done.then(updateView).then(log, logAbort);
 done.ignore(updateView);
 ```

 Does this answer you question?

 On Aug 5, 2015, at 10:51 AM, Logan Smyth loganfsm...@gmail.com wrote:

 Glen, sorry if this has been covered in other discussions, but it's not
 clear to me so I wanted to ask. Are there some example use-cases where
 being able to `.ignore` is preferable to having the promise reject? Promise
 chains are about defining flows of data and I can't really see a case where
 you'd want to disconnect a promise handler without informing promises
 farther down the chain, like your `.then(log)` in your example. To me
 anyway, the proposed `.ignore` seems like it adds boat-loads of complexity
 with unclear goals.

 Also to your question about adding multiple handlers, if that handler has
 side-effects, then it would definitely cause bugs if the same promise were
 returned for multiple calls to `.then` with the same callback.


 On Tue, Aug 4, 2015 at 5:32 PM, Glen Huang curvedm...@gmail.com wrote:


 On Aug 4, 2015, at 1:32 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 only promises that has passed through their initialization the callback
 would be cancelable,and this could be reflected through a `.cancelable`
 property


 That's precisely the problem. When you made a mistake

Re: Cancelable promises proposal

2015-08-04 Thread Logan Smyth
Glen, sorry if this has been covered in other discussions, but it's not
clear to me so I wanted to ask. Are there some example use-cases where
being able to `.ignore` is preferable to having the promise reject? Promise
chains are about defining flows of data and I can't really see a case where
you'd want to disconnect a promise handler without informing promises
farther down the chain, like your `.then(log)` in your example. To me
anyway, the proposed `.ignore` seems like it adds boat-loads of complexity
with unclear goals.

Also to your question about adding multiple handlers, if that handler has
side-effects, then it would definitely cause bugs if the same promise were
returned for multiple calls to `.then` with the same callback.


On Tue, Aug 4, 2015 at 5:32 PM, Glen Huang curvedm...@gmail.com wrote:


 On Aug 4, 2015, at 1:32 PM, Andrea Giammarchi andrea.giammar...@gmail.com
 wrote:

 only promises that has passed through their initialization the callback
 would be cancelable,and this could be reflected through a `.cancelable`
 property


 That's precisely the problem. When you made a mistake and thought a
 function should have the ability to abort, you wouldn't reflect
 that `.cancelable` property, you would simply call abort(). Passing a
 different object makes this less likely to happen since it's not thenable.


 and pragmatists would never find out what should be the behavior once
 aborted 'cause Promise can only reject and never be ignored.


 What do you think of the ignore() method I proposed?

 ___
 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: for statement with index and value

2015-07-13 Thread Logan Smyth
Unfortunately we can't have both

```
for (let value of values){
```

and

```
for (let [index, value] of values){
```

Over all, the first one is the more likely one on a day-to-day basis.

The `[]` are needed because the `for...of` follows the standard rules for
assignment, so it uses standard destructuring, and JS array destructuring
requires `[]`.

```
for (let [index, value] of values.entries()){
```

is essentially is the same as

```
for (let pair of values.entries()){
let [index, value] = pair;
```

As for your last question, `.entries` returns an iterator, so it will not
create a copy of the array.

On Mon, Jul 13, 2015 at 7:43 PM, Tingan Ho tinga...@gmail.com wrote:

 for (let [index, value] of [1, 2, 3].entries())
 console.log(index + :  + value)

 I still think most people will write:

 ```
 for (let value of values) { ... }
 ```
 and then rewrite the whole expression inside the `for-loop` when they find
 out that they need the index too:
 ```
 for (let [index, value] of [1, 2, 3].entries())
 console.log(index + :  + value)
 ```
 `for (let value, index of values) { ... }` is still much easier to type
 than `for (let [index, value] of [1, 2, 3].entries())` and also more
 readable.


 Also, doesn't that makes a copy of the `[1, 2, 3]`?

 --
 Sincerely,

 Tingan Ho
 @tingan87 https://twitter.com/tingan87

 ___
 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: Incompatibility between generators and arrays in the Iterator protocol

2015-06-30 Thread Logan Smyth
The value set when `done: true` is set is not considered part of the
iterated list, which is why you are seeing what you are seeing. The
expected behavior is defined as `done: false` for all yielded values, and
`done: true` when iteration has completed.

That same behavior also applies for `for...of` loops for instance. For
example, see 13.7.5.13
http://www.ecma-international.org/ecma-262/6.0/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
#5c,
as soon as 'done' becomes 'true' the loop exits, the returned value is
ignored. Also the same can also be seen in Array.from in 22.1.2.1
http://www.ecma-international.org/ecma-262/6.0/#sec-array.from #6.g.iv

On Tue, Jun 30, 2015 at 11:13 AM, Tim Jansen m...@tjansen.de wrote:

 Hi,

 I am working on a collections library that supports the Iterable/Iterator
 protocol, but I ran into a stumbling block: the iterator protocol seems to
 work differently for arrays and generator functions. Array iterators set
 'done' to true *after* the last element, but function generators set 'done'
 to true *on* the last element.

 Is this incompatibility intentional, or or just an implementation issue in
 the browsers (tested on FF38 and Chrome 43)? I wasn't able to find any
 information on this. The ES6 draft from April '15 doesn't define when
 exactly 'done' is set.


 Code example:

 var a = ['a', 'b'];

 var itA = a[Symbol.iterator];

 itA.next();   // {value: 'a', done: false}

 itA.next();   // {value: 'b', done: false} !!

 itA.next();   // {value: undefined, done: true}


 function* b() {

   yield 'a';

   return 'b';

 }

 var itB = a[Symbol.iterator];

 itB.next();   // {value: 'a', done: false}

 itB.next();   // {value: 'b', done: true} !!!

 itB.next();   // {value: undefined, done: true}

 The difference is in the second invocation of next(), which returns true
 for generator functions. That protocol makes it impossible for me to
 support both generator functions and array iterators with the same
 implementation - at least if I want to support 'undefined' as a valid value
 in collections. I wouldn't be able to differentiate between an empty list
 ([]) and a list containing undefined ([undefined]).


 Thanks,

 Tim




 ___
 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: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Logan Smyth
To clarify things, since I don't think it's been made abundantly clear, the
example that Sebastian gave would work in a standard ES6 environment,
correct? It is only if the callback were executed synchronously that the
exception would be thrown since the `this` binding has not yet been
initialized?
Transpilers however have elected to prevent this to err on the side of
ensuring that invalid ES6 allowed through because adding runtime checking
for the `this` binding would be difficult?



On Tue, Jun 2, 2015 at 7:37 PM, Brendan Eich bren...@mozilla.org wrote:

 With best intentions I must say that you are overreacting. The
 subject-line code (h/t Mark Miller for pointing me at it!) in context of
 the superclass constructor uses `this` before `super` has returned. That's
 a no-no for pretty-good reason.

 If you have a better alternative design, we needed it last month. As
 things stand, this is a thing to learn, with a workaround. What's the big
 deal?

 /be


 Matthew Robb wrote:

 If I thought I could make any money then I would most definitely bet that
 the changes made to classes that are at the root of this problem will be
 the undoing of es classes and I find myself feeling more and more like
 avoiding them is the easiest thing to do.

 This use-case is a perfect example of something that is EXTREMELY
 unexpected which is funny because the changes are supposed to be supporting
 subclassing of built-ins.

 Very disheartened :(


 - Matthew Robb

 On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me mailto:
 d...@domenic.me wrote:

 Hmm I am pretty sure Babel et al. are correct here in not allowing
 this. The super call needs to *finish* before you can use `this`.
 Chrome also works this way.

 The correct workaround is

 ```js
 let resolve, reject;
 super((a, b) = {
   resolve = a;
   reject = b;
 });

 // use this
 ```


 ___
 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