Re: Proposal: Property Accessor Function Shorthand

2019-12-09 Thread Tab Atkins Jr.
On Sat, Dec 7, 2019 at 2:01 PM  wrote:
>> I do find it surprising that property access isn't addressed there,
>> but it seems like it was likely just overlooked - it has no mention in
>> the repo, in the open issues, or even in the closed issues or any of
>> the open or closed pull requests.
>
> Actually, they do seem to address it here as a non-goal:
> https://github.com/tc39/proposal-partial-application#support-for-receiver-placeholder
>
> If we had that, then we wouldn’t need a specific syntax for property 
> accessors. However, arrow functions are already pretty compact, so I don’t 
> feel a strong desire for this `receiver placeholder` syntax or something like 
> Kotlin’s `it`. I know the same logic applies to a `property accessor` 
> proposal, but accessing properties in JS is extremely common and in my 
> opinion, deserving of a syntax shorthand.

Yes, in general, unfortunately, the partial-application proposal
doesn't help with partially applying operators (note in their examples
that they explicitly use an add() function, since you couldn't use +
with it). You'd have to jump to the competing pipeline proposal for
that; `+>#.foo` is the shortest way to spell it there.

I agree that `x=>x.foo` is a very small syntax tax to pay to create an
accessor function; I haven't found it problematic to do so in my own
coding.

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


Re: function invocation with just commas for explicit undefined optional arguments in the middle

2019-10-29 Thread Tab Atkins Jr.
On Tue, Oct 29, 2019 at 9:06 AM manuelbarzi  wrote:
> ```
> fun('a', 'b',, 'd',, 'f')
> ```

While this does technically match up with arrays, I find the the array
behavior unreadable and unintuitive (especially with the exception for
the final comma), and I'd prefer that syntax quirk not spread to other
list-like syntax constructs.

Passing `undefined` is simply and easy enough; if it's too long you
can shave off three characters by spelling it `void 0`. Or put a `var
_;` at the top of your script and use that.

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


Re: Conditional await, anyone?

2019-10-14 Thread Tab Atkins Jr.
On Sat, Oct 12, 2019 at 7:19 AM Andrea Giammarchi
 wrote:
> in order to work, `await` must be executed in an async scope/context (either 
> top level or within a closure).
>
> In such case, either somebody is awaiting the result of that `async` 
> execution, or the order doesn't matter.

That's definitely not true. I gave you an explicit example where the
order differs. That example code is realistic if you're using the
async call for side-effects only (and thus don't care about the
returned promise), or if you're storing the returned promise in a
variable so you can pass it to one of the promise combinators later.
In either of these cases the order of execution between the sync and
async code can definitely matter.

> The following two examples produce indeed the very same result:
>
> ```js
> (async () => { return 1; })().then(console.log);
> console.log(2);
>
> (async () => { return await 1; })().then(console.log);
> console.log(2);
> ```

In both of these cases, you're doing no additional work after the
"maybe async" point. That is the exact part that moves in execution
order between the two cases, so obviously you won't see any
difference.  Here's a slightly altered version that shows off the
difference:

```js
(async () => { 1; console.log("async"); return 3; })().then(console.log);
console.log(2);

(async () => { await 1; console.log("async"); return 3; })().then(console.log);
console.log(2);
```

In the first you'll log "async", "2", "3". In the second you'll log
"2", "async", "3".

> As summary: the proposal was to help engines be faster when it's possible, 
> but devs are confused by the syntax, and maybeat the end there wouldn't be as 
> many benefits compared to the apparent confusion this proposal would add.

You still seem to be misunderstanding what the execution order
difference is about. Nobody's confused about the syntax; it's clear
enough. It just does bad, confusing things as you've presented it.

As I said in earlier message, there *is* a way to eliminate the
execution-order difference (making it so the only difference would be
the number of microtasks when your function awaits *multiple* sync
values), which I thought you'd come up with at some point, but I'm
pretty sure it was just me misunderstanding what you'd said.

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


Re: Re: Modify Promise.all() to accept an Object as a parameter

2019-10-14 Thread Tab Atkins Jr.
On Fri, Oct 11, 2019 at 9:53 PM Jacob Bloom  wrote:
> What about special handling for Maps? Maybe something like
>
> ```
> const requests = new Map();
> requests.set('reqA', fetch('...'));
> requests.set('reqB', fetch('...'));
> const responses = await Promise.all(requests);
> console.log(
>   responses.get('reqA'),
>   responses.get('reqB'),
> );
> ```
>
> ...which would continue to fail for most objects and would encourage
> using Map over POJOs for map-like data structures. (Since Maps are
> iterable, this may break some existing code but I doubt it)

Hm. Since the functor instance over Maps is just the values, and
Promise.all is just a special-cased traverse, I think this makes sense
to me:

Map> => Promise>

I'm fine with this living in another method name, tho.

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


Re: Conditional await, anyone?

2019-10-11 Thread Tab Atkins Jr.
On Fri, Oct 11, 2019 at 1:15 AM Andrea Giammarchi
 wrote:
> Again, the `await?` is sugar for the following:
>
> ```js
> const value = await? callback();
>
> // as sugar for
> let value = callback();
> if ('then' in value)
>   value = await value;
> ```

Okay, so that has the "you can't predict execution order any more"
problem. But that's not consistent with what you said in "otherwise
schedule a single microtask if none has been scheduled already, or
queue this result to the previous scheduled one", which implies a
different desugaring:

```js
let value = callback();
if('then' in value || thisFunctionHasntAwaitedYet)
  value = await value;
```

*This* desugaring has a consistent execution order, and still meets
your goal of "don't add a bunch of microtask checkpoints for
synchronous values".

Put another way, this `await?` is equivalent to `await` *if* you're
still in the "synchronously execute until you hit the first await"
phase of executing an async function; but it's equivalent to your
simpler desugaring ("await only if this is a thenable") after that.

> but since I've stated already I have no interest anymore in this proposal, we 
> can also stop explaining to each others things we know already.

I'm fine if you want to drop it, but we're not explaining things we
already know to each other. At least one of us is confused about
what's being proposed. And the altered desugaring I give up above at
least has a chance of happening; the only issue might be the
observability of how many microtasks get scheduled. If that's not a
problem, it might be possible to suggest this as an actual change to
how `await` works.

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


Re: Conditional await, anyone?

2019-10-10 Thread Tab Atkins Jr.
On Wed, Oct 9, 2019 at 11:17 PM Andrea Giammarchi
 wrote:
> > What's the order of the logs?
>
> Exactly the same, as the `await?` is inevitably inside an `async` function 
> which would grant a single microtask instead of N.

I think you're misreading my example?  Check this out:
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/7271

```html


function one() {
  oneAsync();
  w("one A");
}
async function oneAsync() {
  await Promise.resolve();
  w("one B");
}

function two() {
  twoAsync();
  w("two A");
}

async function twoAsync() {
  // await? true;
  w("two B");
}

one();
two();

```

This script logs:

```
log: one A
log: two B
log: two A
log: one B
```

A and B are logged in different order depends on whether there's an
`await` creating a microtask checkpoint or not. `await? true` won't
create a microtask checkpoint, so you'll get the two() behavior,
printing B then A. `await? Promise.resolve(true)` will create one, so
you'll get the one() behavior, printing A then B.

> If `maybeAsync` returns twice non promises results, there is only one 
> microtask within the async `tasks` function, that would linearly collect all 
> non promises, so that above example could have 1, 2, max 4 microtasks, 
> instead of always 4
> .
> To explain `await?` in steps:
>
>   * is the awaited value a promise? schedule microtask
>   * otherwise schedule a single microtask if none has been scheduled already, 
> or queue this result to the previous scheduled one
>
> This would grant same linear order and save time.

Ah, your earlier posts didn't say that `await? nonPromise` *would*
schedule a microtask in some cases! That does change things.  Hm, I
wonder if this is observably different from the current behavior?

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


Re: Conditional await, anyone?

2019-10-09 Thread Tab Atkins Jr.
On Wed, Oct 9, 2019 at 12:08 AM Andrea Giammarchi
 wrote:
> I don't know why this went in a completely unrelated direction so ... I'll 
> try to explain again what is `await?` about.

Nah, we got it. Our complaint was still about the semantics.

> ```js
> const value = await? callback();
>
> // as sugar for
> let value = callback();
> if ('then' in value)
>   value = await value;
> ```
>
> The order is guaranteed and linear in every case, so that nothing actually 
> change logically speaking, and the hint would be about performance, 'cause 
> engines don't apparently optimize non-promise based cases.

Expand that code so there's a caller:

```js
function one() {
  two();
  console.log("one");
}
async function two() {
  await? maybeAsync();
  console.log("two");
}
```

What's the order of the logs?

If maybeAsync() is synchronous, then one() calls two(), two() calls
maybeAsync() which returns immediately, and it continues to log "two"
before ending and returning execution to one(), which then logs "one"
and ends.

If maybeAsync() returns a promise, then one() calls two(), two calls
maybeAsync() then freezes while it waits for the promise to resolve,
returning execution to one(). Since one() isn't awaiting the promise
returned by two(), it just immediately continues and logs "one" then
ends. At some point later in execution, the maybeAsync() promise
resolves, two() unfreezes, then it logs "two".

So no, the order is not guaranteed. It's unpredictable and depends on
whether the function being await?'d returns a promise or not. If you
don't know what maybeAsync() returns, you won't be able to predict
your own execution flow, which is dangerous and a very likely source
of bugs.

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


Re: Conditional await, anyone?

2019-10-08 Thread Tab Atkins Jr.
I'm not sure I understand the intended use-case here.  If the author
knows the function they're calling is async, they can use `await`
normally. If they know it's not async, they can avoid `await`
altogether. If they have no idea whether it's async or not, that means
they just don't understand what the function is returning, which
sounds like a really bad thing that they should fix?  And in that
case, as Gus says, `await?`'s semantics would do some confusing things
to execution order, making the line after the `await?` either run
*before* or *after* the calling code, depending on whether the await'd
value was a promise or not.

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


Re: Optional chaining syntax but with the "mice" operator ?

2019-09-06 Thread Tab Atkins Jr.
On Fri, Sep 6, 2019 at 8:04 AM Andrea Giammarchi
 wrote:
> Indeed I'm not super convinced myself about the "branching issue" 'cause 
> `const result = this?.is?.branching?.already` and all I am proposing is to 
> hint the syntax where to stop in case something else fails down the line, as 
> in `const result = this.?.is is not reached, there is a certain point to keep going (which is, example, 
> checking that `result !== this`)

Important distinction there is that ?. only "branches" between the
intended type and undefined, not between two arbitrary types. The
cognitive load between those two is significantly different.

In particular, you can't *do* anything with undefined, so
`foo?.bar.baz` has pretty unambiguous semantics - you don't think you
might be accessing the .baz property of undefined, because that
clearly doesn't exist.

That's not the case with mouse, where it's not clear, at least to me,
whether `foohttps://mail.mozilla.org/listinfo/es-discuss


Re: Optional chaining syntax but with the "mice" operator ?

2019-09-05 Thread Tab Atkins Jr.
On Thu, Sep 5, 2019 at 2:39 PM Andrea Giammarchi
 wrote:
>
> This is basically a solution to a common problem we have these days, where 
> modules published in the wild might have a `default` property, to support ESM 
> logic, or not.
>
> ```js
> // current optional chaining logic
> const imported = exported?.default ?? exported;
>
> // my "mice operator" proposal
> const imported = exported ```
>
> Semantically speaking, not only ` points at its previous value in case the chaining didn't work.
>
> Beside the basic example, the "mice operator" might save CPU cycles when it 
> comes to involving more complex expressions, i.e.
>
> ```js
> // current "solution"
> const thing = require('thing')?.default ?? require('thing');
>
> // mice operator
> const thing = require('thing') ```
>
> This is also easily tranpilable, so kinda a no-brainer for modern dev tools 
> to bring in.
>
> TL;DR specially for cases where an accessed property should fallback to its 
> source, this operator might save both typing and CPU time whenever it's 
> needed.

I find it a rather curious pattern, that I'd never seen before! Is it
used in anything besides this ESM-compat thing you're talking about?

(Saving CPU cycles is not a convincing argument; it's trivial to write
such a line over two declarations and avoid any expensive
recomputations.)

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


Re: Proposal: `String.prototype.codePointCount`

2019-08-08 Thread Tab Atkins Jr.
On Thu, Aug 8, 2019 at 2:45 AM Claude Pache  wrote:
> In fact, for my purpose, I have no reason to impose a limit for a precise 
> number of *code points* (as opposed to other possible definitions of “length” 
> such as *UTF-16 code units* or *grapheme clusters*). Technically, I am 
> usually limited by the size of a column in the database, for which the “size” 
> corresponds typically to the number of bytes in a UTF-8 encoded string. From 
> a user point-of-view, the number of “characters” is better approximated by 
> the number of grapheme clusters. None of those two notions of “length” 
> correspond to the number of code points.

Yup, code points, while a useful specification concept to work with,
are in fact very rarely what you actually need to care about for
anything in real use-cases! Bytes or grapheme clusters are almost
always what you want.

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


Re: Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal)

2019-03-10 Thread Tab Atkins Jr.
On Sat, Mar 9, 2019 at 11:10 AM Felipe Nascimento de Moura
 wrote:
>
> Personally, I don't think it would be THAT useful...
> but...I think there is something behind this proposal that makes sense.
>
> I do believe it could be useful for developers to have an easier access to 
> number parts or characteristics.
> Perhaps something like:
>
> const i = 1234.567;

Can you provide a scenario in which these would do something useful,
such that it would be worth adding them over just using the math
operations that already exist?

> console.log( i.float ); // 567

i % 1

(If you really wanted this as an integer, it's not well-founded; .567
isn't exactly representable as a double, so JS doesn't know that you
"meant" it to have only three digits after the decimal point, and thus
want 567 as the answer. You'll instead get some very very large
integer that *starts with* 567, followed by a bunch of zeros, followed
by some randomish digits at the end.)

> console.log( i.abs ); // 1234

Math.trunc(i)

> console.log( i.thousands ); // 1

Math.trunc(i / 1000)

> console.log( i.million ); // 0

Math.trunc(i / 1e6)

> console.log( i.hundred ); // 2

Math.trunc(i / 100) % 10

> console.log( i.hundreds ); // 12

Math.trunc(i / 100)

> console.log( i.ten ); // 2

Math.trunc(i / 10) % 10

> console.log( i.tens ); // 123

Math.trunc(i / 10)

> console.log( i.tenth ); // 5

Math.trunc(i % 1 * 10) % 10

> console.log( i.tenths ); // 5

Math.trunc(i % 1 * 10)

> console.log( i.hundredth ); // 6

Math.trunc(i % 1 * 100) % 10

> console.log( i.hundredths ); // 56

Math.trunc(i % 1 * 100)


Some of these are easy to remember and use; others take some thinking
to deploy. But the question is still "what would someone use this
information for?", such that the benefit to developers is worth the
cost to all parties involved (spec writers, implementors, testers, and
then developers having to navigate a larger stdlib).

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


Re: add stage4 constraint - ease-of-minification

2019-02-12 Thread Tab Atkins Jr.
On Tue, Feb 12, 2019 at 7:44 AM kai zhu  wrote:
> i think there’s an industry-painpoint (at least from my experience), of 
> resistance adopting es6+ features because legacy-toolchains cannot be easily 
> retooled to minify them.
>
> i’m not sure the best way to address this problem? i favor requiring 2 
> independent minifiers to be able to handle a stage3-proposal before 
> advancement (indicating retooling is feasible), but that may be 
> overly-restrictive to some folks.

Can you expand on what you mean by this, or provide an example of a
feature that can't be "easily minified"?

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


Re: De-structuring array arguments

2019-01-17 Thread Tab Atkins Jr.
On Thu, Jan 17, 2019 at 1:36 PM Jordan Harband  wrote:
> I'm not sure what you mean, that should certainly be possible today. In node, 
> I get this:
>
> ```
> function foo ([a, b] = [1, 2]) { return [a, b]; }
> foo([2, 3]) // [2, 3]
> foo() // [1, 2]
> ```

Yup, and you get the same in browsers. It definitely works today.

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


Re: Proposal: Placeholder operator

2019-01-11 Thread Tab Atkins Jr.
On Fri, Jan 11, 2019 at 6:42 AM Sultan  wrote:
> >empty space with a comma?
>
> I think that only works with trailing params. For example this is not 
> possible:
>
> const foo = (a,  , c) => {}

It doesn't even "work" with trailing params. Function arglists can
*contain* a trailing comma, it's just ignored and does nothing. `const
foo = (a, b, )=>a+b` still has a .length == 2, and `(a, b, ,)=>a+b` is
just invalid syntax. The trailing comma is just allowed so you can
format a long arglist onto separate lines, and don't have to remember
that the last argument doesn't have a comma.

> >Today, you can write: const foo = (a, b, _) => {}
>
> However that does throw with:
>
> const foo = (a, _, _) => {}

Yup, I've run into that problem before, and had to hack around by
using `_1` for the second ignored arg. It's rare/niche enough that I'm
not sure it's worth solving, but I do acknowledge it as an annoyance.

> >You can already write: const [ , setState] = useState(0)
>
> Thanks i forgot about that.

Yeah, using holes *works*, but it's definitely harder to read than using _.

And the fact that the last trailing , does *not* create a hole isn't
relevant for destructuring, but it would be relevant and confusing for
function-arity if we allowed holes in arglists. That is,
`[1,2,].length` returns 2 list, while `[1,2,,].length` returns 3. If
we get pattern-matching and array literals can do strict length
checking, it would also become relevant and confusing. (But that's
several stacked "if"s!)

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


Re: New Proposal: Number.range (Yes, range again)

2018-11-28 Thread Tab Atkins Jr.
I end up writing a range function in virtually every project I use, so
yeah, I think this is worthwhile.

My own preferences, based on Python precedence:

Number.range(end) === Number.range(0, end, 1)
Number.range(start, end) === Number.range(start, end, Math.sign(end-start))
Number.range(start, end, step) => {
  if start < end && step > 0: yield all (start + k*step), for k from 0
to infinity, less than end
  elif start > end && step < 0: yield all (start + k*step), for k from
0 to infinity, greater than end
  else: yield nothing
}

So:
* [...Number.range(5)] evaluates to [0, 1, 2, 3, 4]
* [...Number.range(0)] evaluates to []
* [...Number.range(-5)] evaluates to []
* [...Number.range(1, -3)] evaluates to [1, 0, -1, -2]
* [...Number.range(-3, 1)] evaluates to [-3, -2, -1, 0]
* [...Number.range(1, 1)] evaluates to []
* [...Number.range(0, 10, 5)] evaluates to [0, 5]
* [...Number.range(0, 10, -5)] evaluates to []

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


Re: New Proposal: Placeholder syntax

2018-11-28 Thread Tab Atkins Jr.
Aside from the fact that this "placeholder" proposal addresses the
"receiver" and "operator" cases that partial-application explicitly
omits, the two proposals are exactly identical. They're not
"complementary", they're the same thing, just making a different
decision wrt complexity of some of the syntax cases.

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


Re: deprecate .add/removeEventListener(...) in pro of .on/off(...)

2018-11-28 Thread Tab Atkins Jr.
Jordan meant that DOM isn't part of the JS standard. ^_^ So yeah, not
relevant to this list.
On Wed, Nov 28, 2018 at 11:39 AM Isiah Meadows  wrote:
>
> It *is* part of the DOM itself:
> https://dom.spec.whatwg.org/#interface-eventtarget. Doesn't make this
> any more on-topic here, though.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> On Wed, Nov 28, 2018 at 2:37 PM Jordan Harband  wrote:
> >
> > Neither of these methods, nor the DOM itself, are part of the JS language 
> > standard - you might be thinking of the HTML standard.
> >
> > On Wed, Nov 28, 2018 at 11:28 AM manuelbarzi  wrote:
> >>
> >> make it shorter, simpler and more handy
> >>
> >> deprecate this
> >> ```
> >> EventTarget.addEventListener(...)
> >> EventTarget.removeEventListener(...)
> >> ```
> >>
> >> in pro of
> >> ```
> >> EventTarget.on(...)
> >> EventTarget.off(...)
> >> ```
> >>
> >> make it easier, more intuitive and more readable
> >> ```
> >> button.on(‘click’, e => ...)
> >> form.on('submit', e => ...)
> >> document.on('DOMContentLoaded', () => ...)
> >> ...
> >> ```
> >>
> >> (and reduce code length)
> >> ___
> >> 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: Arrow methods

2018-11-16 Thread Tab Atkins Jr.
On Fri, Nov 16, 2018 at 12:42 PM Sultan  wrote:
>
> Consistency and sugar. Changing from arrow and non-arrow method is a diff 
> between `=>` where:
>
> foo() {} mirrors foo: function () {}
> foo() => {} mirrors foo: () => {}

Yes, but note that the first one *actually contains sugar* - it lets
you omit a decent chunk of characters (at bare minimum, nine) and puts
the name next to the arg-list again, like how normal functions look.

The second lets you omit exactly one character. It also makes it look
*more* like a named function declaration, while arrow functions are
always name-less, so it's not helping you return to a "normal" form
either.

> Also the "this" reference in the second variant is not the class instance i.e 
> it is part of the shared prototype.
>
> It has an added reach in usefulness when you consider nested classes:
>
> class A {
>   foo() {
> return class B {
>   bar() => {
> return this // refers to instance A
>   }
> }
>   }
> }
>
> This is not possible today without creating a self-like variable for bar to 
> reference A's instance; Which is one of the points arrow functions addressed.

Instance methods that don't refer to the instance are definitely the
exception, not the rule. Reading this code, I would *absolutely*
expect on first and probably second glances for `this` to be referring
to the B instance, not the A instance. Binding A's `this` to a
different name is actually a readability *aid* in this circumstance,
unlike the many cases that arrow functions were designed to replace.

This looks to me like a decent argument *against* the suggestion. :/

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


Re: Proposal: `maxDepth` on objects

2018-10-22 Thread Tab Atkins Jr.
On Mon, Oct 22, 2018 at 2:42 AM Rob Ede  wrote:
> Calculating this on plain objects could be a O(1) operation:
>
> Empty objects are initialized with maxDepth 0 and are set to 1 when a 
> primitive property is added.
> If an object property is added the maxDepth is set to 1 + 
> maxDepth(newObjectProperty)`instead of it being calculated Ïevery time 
> .maxDepth is accessed (much like how Array#length works).

That's not enough. Any time you add/change/remove a property that
would alter the depth of an object, you also need to update the depth
of every *parent* object containing it.

This isn't "actually" O(1) - it's O(1) on *access*, but only because
it's amortized the cost over every mutation instead. We don't
generally consider that trade-off worthwhile, particularly for things
like this that would have fairly specialized/limited use-cases in the
first place.

(Plus, it still doesn't answer what the depth is of an object with a
cyclic reference.)

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


Re: Why isn't `Promise.all()` overloaded?

2018-08-10 Thread Tab Atkins Jr.
On Fri, Aug 10, 2018 at 2:30 PM Jacob Pratt  wrote:
> This is potentially a very simple question, `Promise.all()` takes a single 
> iterable as a parameter. Is there any particularly reason it wasn't 
> overloaded to allow passing multiple parameters (and use `...arguments`)? Of 
> course, the only difference is the creation of an array, but it is an array 
> that doesn't need to be created.

API complexity - Promise.all()'s promise resolves to an array of
resolved values. How would multiple input iterables be reflected here?
Just concatenated together? More straightforward and predictable to
just ask the user to concatenate things on the input side.

Also, Promise.all(), following the example of other promise methods,
doesn't require the values in the input array to be promises; it just
Promise.resolve()'s all of them, so you can pass in non-Promise values
as well.  With a "multiple input arguments" API shape, it's less clear
that `Promise.all("foo", "bar")` is wrong, for instance (it would
treat each of them as a 3-element array of characters).  With the
current design you usually have to put in a literal [], so it's easier
to remember the API shape.

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


Re: !Re: proposal: Object Members

2018-08-03 Thread Tab Atkins Jr.
On Fri, Aug 3, 2018 at 2:33 PM Ranando King  wrote:
>
> A side thought:
>
> If a language reserving certain words, even to the point of generating error 
> messages related to using them under certain circumstances, doesn't 
> constitute at least part of a justification for using them, then why do 
> languages so often reserve keywords for future use? Isn't precisely the case 
> with `private`, `protected`, `public`, and `package` (and `class` prior to 
> ES6). Weren't they all holdovers from the fact that the syntax for ES was 
> mostly borrowed from Java, and kept in reserve just in case the concepts 
> behind these keywords became language features?
>
> If that's not the case, then there's no point in keeping these (or indeed 
> any) keywords in reserve.

Yes, they were reserved because they were the Java reserved keywords,
with the intention that we might add more Java features later in the
langauge's evolution. That has no bearing on their use today.

Unreserving them wouldn't provide much benefit now. But keeping them
reserved still doesn't mean we have any particular need to use them.

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


Re: es-discuss Digest, Vol 135, Issue 48

2018-05-23 Thread Tab Atkins Jr.
On Wed, May 23, 2018 at 1:05 PM, Jordan Harband  wrote:
> `array.push(...sources)`, not sure why we'd need "append".

>From the original email (a bit buried and hard to find due to broken
threading, admittedly):

> Has anyone ever suggested Array.prototype.append as an Array.prototype.push 
> which returns the array itself?

The point is x.append(y) returning x, whereas x.push(y) returns y.

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


Re: Proposal: Add a global Infinitesimal property

2018-05-14 Thread Tab Atkins Jr.
On Sat, May 12, 2018 at 9:49 AM, Abdul Shabazz  wrote:
> As polar opposite to Infinity, Number.POSITIVE_INFINITY, the Infinitesimal
> should be a smallest representable value greater than 0. Perhaps someone
> else could propose why this would be useful.

Please stop suggesting things that you don't even think are useful.
Feature proposals, on their own, are not useful for a standards body;
there are an infinity of features we *could* add. What we need is
*problems you're having*, and then possibly a suggested new feature to
help solve that problem.  Without the problem we have no reason to
think that adding the feature would help anyone, so there's no reason
to add it.

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


Re: Re: Proposal: Array.prototype.shuffle (Fisher-Yates)

2018-04-29 Thread Tab Atkins Jr.
On Sun, Apr 29, 2018 at 4:31 PM, J Decker  wrote:
> I can see that's certainly something that can be gotten wrong; the in-place
> sort is kind-of nice; but you end up hitting most numbers twice, and with a
> longer array (say a set of 75 bingo balls) you can move the same number
> multiple times.
> which gives numbers at the end a higher chance of being at the start when
> all is done; and almost guaranteed to not be at the end.

This is true of a "naive" in-place shuffle, which draws the "item to
be placed at the end" from the full array, rather than from just the
unshuffled portion. But the proper Fisher-Yates algorithm does not
have this bias, and gives a proper unbiased sort, as shown by a
multitude of links across the web, many of which can be found in the
SO answers linked from earlier in this thread.

> And then to shuffle, for each number in the array, assign a random number;
> hang in a binary tree from least to most; then gather the tree back out.

While this shuffling method (assign a random number to each value,
then sort by that) also works and is unbiased, it takes O(nlogn) time,
and may, as you note for your implementation, have significant space
costs as well.  Fisher-Yates is a faster (linear-time, bounded by the
cost of generating N random numbers) and more space-efficient unbiased
algorithm.

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


Re: Re: Proposal: Array.prototype.shuffle (Fisher-Yates)

2018-04-29 Thread Tab Atkins Jr.
On Sun, Apr 29, 2018 at 10:01 AM, Isiah Meadows  wrote:
> I think this would be better suited for a library function rather than
> a language feature. I could see this also being useful also for
> randomized displays, but that's about it. And I'm not sure what an
> engine could provide here that a library couldn't - you can't really
> get much faster than what's in the language (minus bounds checking,
> but the likely frequent cache misses will eclipse that greatly), and
> it's not unlocking any real new possibilities.

Yes, this is very easily doable in userland, and a built-in will have
little if any speed benefit.

The point, tho, is that this is (a) a relatively common operation, and
(b) very, very easy to do *wrong*, as demonstrated by the SO link.
Thus it's a reasonable candidate for inclusion as a built-in anyway,
to avoid the footgun of trying to do it yourself and screwing it up.

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


Re: Proposal: Allow Promise callbacks to be removed

2018-04-23 Thread Tab Atkins Jr.
On Mon, Apr 23, 2018 at 10:56 AM, Oliver Dunk  wrote:
> My proposal is that we add a way of removing a particular callback, or all 
> callbacks, from a Promise. This is different to cancelling a Promise and 
> would instead happen if you want the operation to continue but are no longer 
> interested in running a function when the Promise is resolved or rejected.
>
> This would be implemented in two ways. The first I believe to be most useful, 
> and the second is a sort of “sub-proposal”, that I would be happy to leave 
> out:
>
> 1. A new `Promise.prototype.clear()` method. This would remove all callbacks 
> currently added to a Promise.

This is almost certainly a no-go - it's a huge capability leak. If
Alice has attached a .then() callback to a promise, Bob shouldn't be
able to cancel that without Alice's permission.

> 2. A `Promise.prototype.clear(promise)` method, which takes the Promise 
> returned when `Promise.prototype.then()` or `Promise.prototype.catch()` was 
> called. This would remove that specific callback leaving any others. I don’t 
> know if another argument would make better sense here? Maybe an identifier to 
> the one used in `clearInterval()`.
>
> The use case that I see for this is for a Promise equivalent to 
> `EventTarget.removeEventListener()`.

Possible, but seems unnecessary. In EventTarget, the listener is
attached *forever*, because there's no limit to how many times the
event can fire. Removing a listener is thus a useful feature, to
prevent listeners from stacking up infinitely.

For a promise, tho, the callback is one-and-done; after it resolves,
the callback is released and can be collected.  There's no strong
memory-related reason to "cancel" a promise callback; if you need that
functionality on your own, you can just have the callback close over a
boolean, and check the boolean once it resolves and either continue or
return immediately.  This would only be a few lines to write a helper
function for.

As others have stated, it also makes the semantics of the returned
promise from .then() unclear. A forever-pending promise is a possible
resolution, but it feels a bit awkward.

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


Re: [strawman] Symbol.thenable proposal

2018-04-16 Thread Tab Atkins Jr.
On Fri, Apr 13, 2018 at 6:00 PM, Isiah Meadows  wrote:
> I can't remember where, but I recall seeing this discussed elsewhere
> (maybe in the TC39 meeting notes?) and the conclusion was basically
> ¯\_(ツ)_/¯. I'm not convinced myself it's actually worth the extra
> symbol just to make something not considered a thenable - all these
> Promise libraries have been able to get away with it for this long;
> what makes ES promises any different here? (Dynamic import is probably
> the only possible case I can think of short certain proxies in terms
> of things that could be considered thenables but shouldn't always.)

Having a reserved property key is a big footgun; you *can't* reliably
resolve a promise to an arbitrary object, because if the object
happens to have a "then" key, it'll try to recursively resolve it.

Userland may "get away with it" because "then" isn't a common key, but
it's still a hassle, same as how __proto__ being a special key in JS
causes problems with JSON usage - it's rare, but not unknown, and
problematic because it's an obvious layering violation.

> Worst case, you can just return a value that happens to have a promise
> in a property, like in `{value: somePromise}` - nobody resolves that
> except `co` IIRC.

Note that this isn't about nesting promises (or even promise-likes)
without recursive resolution, it's about nesting *thenables* into a
promise without (attempted) recursive resolution, which is a much
larger conceptual class: the presence of a "then" property says
absolutely nothing about the type of an object. We've just been making
a statistical judgement about the posterior probability of an object
being promise-like based on the presence of a particular key, which is
very dubious.

I'm still strongly of the opinion that we messed this up; the reason
we went with thenables was because it's how userland did it, and they
were working under the constraints of a proliferation of promise-likes
and the difficulty of userland type-testing; real Promise usage
promulgated much quicker than the pessimistic estimates, tho, making
the relative trade-off of "free" compatibility with promise-likes vs
the layering violation of reserving a property name on every object
forever much less favorable.  We should have instead relied on the
actual Promise type, with a Symbol escape-hatch opting a userland
object into being a promise-like.  Doing the reverse and letting
objects opt *out* of being treated as promise-like is probably the
most we can do at this point, unfortunately. Generic data-handling
will just have to manually add such a Symbol to objects they're
resolving to, which sucks but is better than the alternative of always
using a wrapper object.

(Note that having a "strictResolve" method won't help; it might
prevent the precise promise you construct from recursing into the
object, but if you then resolve *another* promise to that promise,
it'll go ahead and try to recurse again.  Maybe strictResolve() could
auto-add the "I'm not a promise-like" symbol to the object it resolves
to? That would be a bit more ergonomic for generic handling.)

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


Re: EcmaScript Proposal - Promised functions

2018-04-12 Thread Tab Atkins Jr.
On Thu, Apr 12, 2018 at 9:07 AM, Luiz Felipe Frazão Gonçalves
 wrote:
> One new proposal for EcmaScript.
>
> Promised Functions
>
> Like async/await, the promised functions would be preceded by a keyword. In
> the case, promised, it would change the default behavior of the function,
> making it behave as a promise.
>
> I will use as an example a classic sleep function:
>
> function sleep(forHowLong) {
>   return new Promise((resolve, reject) => {
> setTimeout(function() {
>   resolve();
>
>   /**
>* For reject:
>*
>* reject(Error('Some error'));
>*/
> }, forHowLong);
>   });
> }
>
> I think to avoid the huge amount of callbacks, there should be a syntax
> similar to this:

Some of these callbacks aren't necessary:

function sleep(forHowLong) {
  return new Promise(resolve=>setTimeout(resolve, forHowLong));
}

Tho even if you do use all the same callbacks, just formatting it
properly helps:

function sleep(forHowLong) {
  return new Promise(resolve=>setTimeout(_=>resolve(), forHowLong));
}

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


Re: partial spread syntax

2018-03-25 Thread Tab Atkins Jr.
On Sun, Mar 25, 2018 at 6:20 PM, 月の影 <19511...@qq.com> wrote:
> Sometimes I got a infinity iterable sequences, I may want a partial spreed
> syntax. `...iterableObject{from, to}`
>
> For example:
>
> ```js
> function *fibonacci() {
> let a = 0, b = 1
> while(1) {
> [a, b] = [b, a + b]
> yield a
> }
> }
>
> console.log([...fibonacci(){3, 5}]) // [3, 5, 8]
> ```
>
> For a finite list, it is similar to [...list].slice(from, to)
>
> ```js
> const arr1 = [1, 2, 3, 4],
> arr2 = [5, 6, 7, 8]
>
> console.log([...arr1{2}, ...arr2{1}])  // 3, 4, 6, 7, 8
> ```

This seems to be well-served by a simple library function right now:

```
function take(n, iter) {
  if(n <= 0) return;
  for(let item of iter) {
yield item;
if(n-- <= 0) return;
  }
}

function drop(n, iter) {
  iter = iter[Symbol.iterator];
  for(let i = 0; i < n; i++) {
iter.next();
  }
  yield* iter;
}

function subiter(start, end, iter) {
  return take(end-start+1, drop(start, iter));
}

console.log([...subiter(3, 5, fibonacci())]);
```

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


Re: Operator for Currying

2018-03-22 Thread Tab Atkins Jr.
While I love currying in many languages, I have some reservations
about it being generally useful enough in JS to be worth adding syntax
for.

1. Currying isn't friendly with variadic functions (that is, optional
arguments) - you can't tell when the function has consumed "enough"
arguments to finally resolve itself unless you predefine the arity.
2. Currying isn't friendly with JS's style of named arguments (passing
an option bag) - no clue how to solve this even with workarounds?

Partial application, whether via a dedicated syntax or as part of the
smart-mix pipeline syntax, gives you *most* of the benefits of
currying while solving these issues: 1, the partially-evaluated
function will fully evaluate as soon as you call it, with whatever
arguments you've given it (unless you explicitly partially-evaluate
again); 2, with object-rest, you can spread a later options object
into your partially-filled in options object, and then pass that to
the underlying function.

```
// variadic example with pipeline function
const threeOrMore = +> Math.max(3, ...);
// and you can partially-eval again to fill in more options without "finishing":
const moreLimitations = +> threeOrMore(newLimit, ...);`

// option-bag example with arrow function
const someOptions = (arg, moreOpts) => optUsingFunction(arg, 1, 2,
{foo: bar, ...moreOpts});
// or with pipeline function:
const someOptions = +> optUsingFunction(#, 1, 2, {foo:bar, ...##});
```

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


Re: Expanding Object Shorthand

2018-03-16 Thread Tab Atkins Jr.
On Fri, Mar 16, 2018 at 1:58 PM, Sebastian Malton  wrote:
> Yes that is possible but what if you want to do the following?
>
> ```
> var a = {
> b: B.b,
> c: B.c,
> d: B.d,
> e: B.e
> };
> ```
>
> Would it not be easier to do the following?
>
> ```
> var a = {
> { b, c, d, e }: B
> };
> ```

It's shorter to write, sure. But we can come up with special-purpose
ways to shorten code all day.

This proposal is not consistent with the existing shorthand syntax, or
the object-destructuring syntax it also somewhat resembles. It's
unique, while looking very similar to existing syntax, and for a
relatively small case (extracting a subset of the properties of an
object into another object, with the same key names).  That's usually
not a recipe for success. :(

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


Re: Expanding Object Shorthand

2018-03-16 Thread Tab Atkins Jr.
On Fri, Mar 16, 2018 at 1:30 PM, Sebastian Malton  wrote:
> Hello currently the following is a possible way to define an object.
>
> ```
> var d = { a, b, c };
> ```
>
> But this only works if the fields are already variables.
>
> So if you wanted to select some fields from an object within you have to use
> temp variables, reference the field by name but without the temporary
> variables, or use some immediately called functions which is messy.

You can just use ordinary object-creation syntax.  The syntax you're
referencing is a shorthand, specifically for the limited, but common,
case where you want to add a field with the same name as a variable.
Like:

> So I propose the following syntax:
>
> ```
> var d = {
> a,
> b,
> { c }: e
> };
> ```
>
> Here d will have the fields [a, b, c] and the values are the variable a,
> variable b, and value e.c.

You can just write:

```
var d = {
  a,
  b,
  c: e.c
};
```

(Assuming that's what you meant, and not `c.e` for the last field's value.)

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


Re: Re: Explainer/Spec: Smart pipelines

2018-03-11 Thread Tab Atkins Jr.
On Sun, Mar 11, 2018 at 4:44 PM, Tab Atkins Jr. <jackalm...@gmail.com> wrote:
> On Sun, Mar 11, 2018 at 2:36 PM, Peter Jaszkowiak <p.jasz...@gmail.com> wrote:
>>> optionally preceded by `new` or `await`
>>
>> This seems very arbitrary and _not_ forwards-compatible.
>
> I agree with arbitrary, tho I think new/await ends up being
> reasonable.  What part of it do you think isn't forwards-compatible?
> Afaict, we can definitely add new bare-style forms in the future, as
> attempts to use them today would be a syntax error.

Actually, I'd like to elaborate here, as I think the inclusion of
new/await is actually very important for understanding the motivations
of bare style as JS has proposed, versus the "arbitrary topic-less
expression that evaluates to a function" form that Dan's original has.

Ultimately, bare style is just a syntax nicety.  Anything you can
write in bare style (either one), you can write in topic style with a
few more characters; it adds no additional power.  As such, we should
think about it in terms of what it allows vs what it disallows, and
how useful each category would be.

In Dan's "arbitrary expression" form, you get:
1. easy pipelining of variables holding functions: `x |> foo |> bar`
2. easy pipelining of point-free expressions, or auto-curried
functions: `x |> flip(foo)` or `xs |> filter(pred)`

You do *not* get:
3. easy construction of new objects: `x |> new Foo` will call `Foo()`
and then try to call the result with x, when you probably wanted it to
call `new Foo(x)`; you need to instead write `x |> new Foo(#)`
4. easy awaiting of function results - `x |> await bar` will await the
bar variable and then try to call the result with x, when you probably
wanted it to call `await bar(x)`; you need to instead write `x |>
await bar(#)` or `x |> bar |> await #`
5. easy method calls!!!: `x |> foo.bar` pulls `bar` off of `foo`, then
calls it with `x`, *without* `foo` being bound to `this`! You probably
wanted it to call `foo.bar(x)`, so you instead you need to write `x |>
foo.bar(#)`

JS's bare-form, on the other hand, gets you 1, 3, 4, and 5, and only
misses out on 2; you need to write `xs |> filter(pred)(#)` or `xs |>
filter(pred, #)` instead, depending on how the function is defined.  I
think that cases 3/4/5 are dramatically more important and common than
case 2.

What's worse, in the "arbitrary expression" form, if you accidentally
leave off the #, you get a *runtime* error (hopefully) when your
expression is misinterpreted, and have to track down why something is
acting weird. (And each of the three possible mistakes acts weird in a
unique way - an object constructed without its argument, or a promise
showing up unexpectedly, or `this` being `undefined` unexpectedly.)

In JS's form, if you leave off the # you get a *syntax* error
immediately, pointing you straight to where the problem is.

So overall I think JS's bare-form is *very* well motivated and
shouldn't be changed. ^_^

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


Re: Re: Explainer/Spec: Smart pipelines

2018-03-11 Thread Tab Atkins Jr.
On Sun, Mar 11, 2018 at 2:36 PM, Peter Jaszkowiak  wrote:
>> To clarify: The way that bare style and topic style are distinguished are
>> not by the absence/presence of a topic reference. Bare style has a simple
>> and strict syntax: any identifiers, separated by `.`s, optionally preceded
>> by `new` or `await`.
>
> So `x['hello']` would not be valid? Seems pretty inconsistent. I think that
> checking for the lexical topic token would be simpler and easier for
> developers.

I strongly disagree - I thing JS's approach is a large improvement
over the previous pipeline proposal, for two reasons.

1. As they already stated, it helps avoid accidental mis-types, like
`x |> f()` when you meant `x |> f` - you get an early syntax error
instead.
2. It *purposely prevents* point-free shenanigans, where you might
type `x |> f()` on purpose, *intending* f() to resolve to a function
that is then called with x.  Instead you have to write `x |> f()(#)`,
which has a much clearer intent, as it's written exactly how you'd
call it if you wrote it out without the pipeline.  More importantly,
imo, it makes point-free stuff like `flip` or the like pointless (uh,
no pun intended) - instead of doing abstract manipulations of the
argument lists, you can just call the function normally, with # put
where you want.

>> Any pipeline body that does not fulfill that simple and strict syntax is
>> in topic style. However, any pipeline body that is in topic style also must
>> contain a topic reference, or else it is an early syntax error. `x |> f()`
>> is in topic style; it is also an early syntax error, because it is a
>> topic-style pipeline that does not use the topic reference.
>
> This seems to not support auto-currying functions. For instance,
> **lodash/fp** has auto-currying functions which take an iteratee as the
> first argument:
>
> ```js
> // `lodash/fp/filter` is iteratee-first data-last:
> // (iteratee, collection)
> var compact = fp.filter(Boolean);
> compact(['a', null, 'c']);
> // ➜ ['a', 'c']
> ```
>
> So someone might want to do something like the following to utilize this
> behavior:
>
> ```js
> ['a', null, 'c'] |> fs.filter(Boolean)
> ```

This works just fine, you just need to explicitly call it like:

```
['a', null, 'c'] |> fs.filter(Boolean)(#)
```

>> optionally preceded by `new` or `await`
>
> This seems very arbitrary and _not_ forwards-compatible.

I agree with arbitrary, tho I think new/await ends up being
reasonable.  What part of it do you think isn't forwards-compatible?
Afaict, we can definitely add new bare-style forms in the future, as
attempts to use them today would be a syntax error.

> By only allowing identifiers, you're requiring people to create unnecessary
> intermittent variables. I propose that you allow any expression on the
> right-hand side of the pipe operator, and decide whether it's in topic style
> or bare style based on the inclusion of the lexical topic token. Your
> argument that making it very restrictive reduced cognitive burden doesn't
> make sense to me at all, as remembering what is and isn't allowed is more
> difficult than just remembering "if it doesn't have the token, it will call
> the function specified by the expression with the argument of the result of
> the previous step in the pipeline".

There is never a need to create intervening variables, you just need
to use topic style.

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


Re: Proposal: then operator for easier promise manipulation

2018-03-03 Thread Tab Atkins Jr.
On Sat, Mar 3, 2018 at 1:04 AM, Bryant Petersen  wrote:
> The purpose of `await` is to allow synchronous execution within an
> async function.
>
> The purpose of `then` is to make it easier to manipulate the promises
> as if they were normal values. It is much closer to
> `Promise.prototype.then` than to `await`, since it does not prevent
> the statements following it from execution. For this reason it doesn't
> need to be in an async function.
>
> The synchronous nature of `await` can be annoying when you have
> multiple promise-creating expressions that you want to run in
> parallel. You have to run the expressions first, keep track of the
> promises they evaluate to, and then use `await` on those promises.
> `Promise.all` helps in this endeavor, but it prevents you from putting
> expressions exactly where you want them to be.
>
> Consider the following:
> ```js
> const pets = (await getDogs()).concat(await getCats())
> ```
> This would not be ideal if you want `getDogs` and `getCats` to start
> off in parallel. So you need to do something like this:
> ```js
> const [dogs, cats] = await Promise.all([getDogs(), getCats()])
> const pets = dogs.concat(cats)
> ```
> With `then` it could be done like so:
> ```js
> const pets = await (then getDogs()).concat(then getCats())
> ```

I'm not sure how you're able to continue running code after the first
"then". The `.concat` part is a property lookup on the first value,
which can run arbitrary code - what object does that code operate on?
How do you get to the point of even noticing that there's an argument
to the function that also needs to be then'd?

I *think* the only way to get this to work would be to do a pre-parse
over the function, looking for "then" expressions, and collect them
all together into an implicit "await Promise.all(...)", effectively
run at the beginning of the function when you execute it "for real".
(Kinda similar to `var` hoisting, which implicitly puts a lot of `var
x = undefined;` statements at the top of your function.) How this
squares away with the possibility of a later "then" actually depending
on the value of an earlier "then" expression, or on a value outside of
the "then" expressions, is unclear.

Using Promise.all() to avoid synchronously waiting on each promise
one-by-one is a little awkward sometimes, but it gives you obvious,
well-defined semantics, which this doesn't appear to have.

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


Re: Proposal: Map#assign

2018-01-18 Thread Tab Atkins Jr.
On Thu, Jan 18, 2018 at 11:25 AM, Peter Jaszkowiak  wrote:
> Isn't there a proposal for `Map#setAll`? That would fulfill the other use
> case.

Or, stealing naming from Python, Map#update.  (I've asked for this in
the past and would be very happy to see it.)

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


Re: Re: Allow specify numbers with suffixes

2017-12-13 Thread Tab Atkins Jr.
On Tue, Dec 12, 2017 at 6:38 PM, Darien Valentine  wrote:
> The runtime version seems likely to create more confusion than not, too. The
> example you gave — `10px + 1em` — demonstrates how that might go. One might
> expect that to work because css’s `calc` can do it. But the browser knows
> what the current value of `em` for the node in question is. Even if it
> somehow knew what the contextual relationship between px and em was, it’s
> not clear to me what that’s actually supposed to evaluate to.

Right. It turns out that we have an answer to that now!
(drafts.css-houdini.org/css-typed-om) But any solution that didn't
allow us to write that sort of thing and get a CSSNumericValue out of
it would be pretty incomplete.

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


Re: Array.prototype.mapOn method

2017-10-27 Thread Tab Atkins Jr.
On Fri, Oct 27, 2017 at 8:17 AM, Peter Jaszkowiak  wrote:
>
> Actually flatMap isn't even needed. My question is, why use this over a 
> normal map with a conditional? It doesn't seem to really save any space.


Right. The example given:

```
exampleArray.mapOn(Math.sqrt, Number.isInteger); // [1, 1.414, 3, "A",
"B", "C"];
```

can be written with today's code as just:

```
exampleArray.map(x=>Number.isInteger(x) ? Math.sqrt(x) : x);
```

You're paying only a tiny handful of additional characters for this.

-

And in any case, specializing this use-case to Array.map only isn't
too great. This sort of "conditionally call this function" ability
would be useful more generally, with something like:

```
function onlyIf(cond, func) {
  return (...x)=>cond(...x) ? func(...x) : x;
}
exampleArray.map(onlyIf(Number.isInteger, Math.sqrt));
```

Feel free to write this into your own code.  (Or get super-fancy and
put it on Function.prototype, so you can write
`.map(Math.sqrt.onlyIf(Number.isInteger))` ^_^)

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


Re: Make comma at the end of line optional

2017-09-13 Thread Tab Atkins Jr.
I believe Bob was engaging in reductio ad absurdum, Isiah. ^_^

On Wed, Sep 13, 2017 at 11:51 AM, Isiah Meadows  wrote:
> What about...
>
> - variable (var)
>
> - donuts (do)
>
> - forest (for)
>
> - awaiter (await, module-specific)
>
> - async (https://github.com/caolan/async)
>
> - className (class)
>
> - letters (let)
>
> - constants (const)
>
> Fun fact: all of these are valid, and many of them are relatively common.
> Please consider the ramifications of such a feature before proposing them.
>
> On Wed, Sep 13, 2017, 14:22 Bob Myers  wrote:
>>
>> Personally, I am annoyed by the extra typing required for spaces.
>> I propose that we have a new kind of ASI: automatic SPACE insertion.
>>
>> For instance, you could then write
>>
>> ```js
>> functionfoobar(){return42;}
>> ```js
>>
>>
>>
>>
>> On Wed, Sep 13, 2017 at 11:25 PM, Naveen Chawla 
>> wrote:
>>>
>>> `x`  `[y]` would be invalid syntax, right?
>>> So
>>> ```js
>>> x
>>> [y]
>>> ```
>>> would automatically insert a comma in the case of a function call
>>> arguments list, right?
>>
>> ___
>> 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: Make comma at the end of line optional

2017-09-12 Thread Tab Atkins Jr.
On Tue, Sep 12, 2017 at 1:49 PM, Алексей  wrote:
> Think of it from a different way: if there would be no ',' how would you
> react on the idea of adding it? Peaty sour every one would decide that would
> be a complete nonsense.

This sort of hypothetical isn't useful; you're not proposing switching
over to *solely* comma-less, you're proposing a *mixture* of comma and
comma-less being allowed.  That has very different ergonomics than
either all-comma or all-comma-less.

The hypothetical comma-less language would also have made many
different syntax decisions over the years to accommodate that, which
current JS has *not* made.  This causes the sorts of problems that
Claude/etc have pointed out.

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


Re: super return

2017-08-28 Thread Tab Atkins Jr.
On Mon, Aug 28, 2017 at 1:27 PM, Sebastian Malton  wrote:
> This could be done but I see a few problems with it:
>
> 1. Though it does make ending from some functions like forEach able to be 
> done it does not all returning from other functions like map or sort

map() and forEach() have exactly the same signatures for their
callbacks; you can definitely do the same thing in both of them.

You're right about sort(), but returning early from a sort() call
seems like a really small niche; I think it's the sort of thing you'll
only do in an error situation, in which case throwing is the correct
way to handle it.  (On the other hand, returning early from a
forEach() can be due to perfectly normal reasons, the same sorts of
things that cause you to `break` from a loop.)

> 2. It does not directly allow the returning of values but this might be 
> rectified by having it be a function that you call and when it calls it stops 
> any further calls and then returns the first parameter past

It's the outer function's responsibility to return appropriate values.
A map() call that didn't return an array would cause a lot of
problems; a forEach call that returned something meaningful would be
weird. In either case, it's a bad code smell to try and override what
the outer function is doing.  If you're stopping because of an error,
and so whatever the function is trying to do isn't relevant anymore,
you should throw an error instead.

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


Re: super return

2017-08-28 Thread Tab Atkins Jr.
On Mon, Aug 28, 2017 at 12:29 PM, Sebastian Malton
 wrote:
> I have seen some people want to modify some of the array prototype
> functions, especially forEach, so that returning from them returns a value.
> However, I have also seems that this could break things since in some cases,
> again forEach, the return value in explicitly defined.
>
> Thus I propose the new syntax `super return` and any other positive number
> of supers. This syntax is currently not valid in any scenario and with the
> current meaning of super seems, to me at least, relativity easy to
> understand.
>
> The outcome of this basically means "return from current context up one
> level and then return from there".
>
> A current method of doing this is by using try / catch but it is not ideal.
> Using the above method I believe that it would be able to be better
> optimized.

This has been suggested in the past, by adding a fourth argument to
the callback signature passing an opaque "halt" value. Returning the
halt value would end execution of the looping function prematurely.
No reason to add new syntax for this, plus hooks for userland to take
advantage of it, when we can just use something that userland could
adopt *today*.

(As an added bonus, it would make the callback arguments be Element,
Index, Collection, Halt, finally spelling out Brendan's full last
name. ^_^)

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


Re: Re: Defer expression

2017-08-17 Thread Tab Atkins Jr.
On Thu, Aug 17, 2017 at 12:12 PM, Matthew Robb  wrote:
> Honestly have there been any proposals for something like `do async { // can
> await here  }` which would produce a promise in the enclosing scope

Do-expressions haven't advanced in general yet, but if/when they do,
this seems like it might be reasonable. It's just sugar for the
`Promise.resolve().then(()=>{...})` expression, right?

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


Re: an operator for ignoring any exceptions

2017-08-02 Thread Tab Atkins Jr.
On Wed, Aug 2, 2017 at 3:45 AM, T.J. Crowder
 wrote:
> On Wed, Aug 2, 2017 at 4:58 AM, Sheng TIAN  wrote:
>> Is there any proposal for an one unary operator for ignoring any
>> exceptions.
>>
>> (I have not search out any related threads. But it is useful IMO,
>> so I'm wondering if this had been discussed.)
>
> In general, a thorough search before posting is your best course.
>
> To the idea: I join the chorus saying that making it easy to ignore errors
> is generally not a good idea. And reusing `try` for something that
> suppresses exceptions implicitly is separately not a good idea in my view.

Agree. Note that the similar operator (`try!(...)`) in Rust does not
*suppress* errors, but rather just simplifies handling of the error
(in Rust, expressed using a Result object); if an error is returned it
immediately returns from the outer function with the Result object;
otherwise it evaluates to the (unwrapped from the Result object)
success value.  This is closer to the try expression you bring up,
just with some slightly more opinionated handling.

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


Re: Return value of forEach

2017-07-24 Thread Tab Atkins Jr.
On Mon, Jul 24, 2017 at 3:31 PM, T.J. Crowder
<tj.crow...@farsightsoftware.com> wrote:
> On Mon, Jul 24, 2017 at 9:58 PM, Tab Atkins Jr. <jackalm...@gmail.com>
> wrote:
>> In general, functions returning undefined are *often* safe to switch
>> to returning a more useful value
>
> I think we'd struggle to prove it could be done safely. For instance, we'd
> have to differentiate between all the places that did something like this:
>
> ```js
> someDataPromise().then(data => data.forEach(entry => console.log(entry)));
> ```
>
> ...that *do* and *do not* rely on the fact that promise resolves with
> `undefined`. (The above does not.)
>
> Hopefully, ones that do are few and far between. But webscale is massive,
> "few and far between" can be an unacceptably high number.
>
> If there were an appetite for `Array.prototype.each`, I'd like to address
> not just the return value but other issues with `Array.prototype.forEach` as
> well (like step value, per-iteration updates of the index, stopping early
> [using `some` or `every` is sometimes perfect, other times semantically
> misleading]). I have some thoughts on doing that while retaining runtime
> efficiency for the common case and code simplicity. But I doubt the appetite
> is there.

Yeah, thus the "often". ^_^  It's been done a few times in DOM land
iirc.  Relying on a promise to resolve to undefined is probably quite
rare; it would mean that you're explicitly testing for undefined on
the far end.  Much more likely, in situations like that, is just
ignoring the resolution value, in which case switching it to an Array
is fine.

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


Re: Re: Add an easier method for slicing and stepping strings and arrays

2017-07-24 Thread Tab Atkins Jr.
On Sun, Jul 23, 2017 at 12:36 AM, Darien Valentine
 wrote:
> Here are some related threads from the past:
>
> https://esdiscuss.org/topic/negative-indices-for-arrays
> https://esdiscuss.org/topic/array-slice-syntax
> https://esdiscuss.org/topic/javascript-language-feature-idea
>
> I think I’ve seen it mentioned a few other times too.
>
> The `arr[-1]` syntax is a non-starter I’m afraid, cause it’s just property
> access. An array can already have a property with the key "-1".
>
> Personally I’d find it weird for slicing to be singled out for special
> syntax. It’s just a method. However I’d agree that it’s quite awkward to do
> things like `arr[arr.length - 1]` or `arr.slice().pop()` etc to access from
> the right. I think in one of those threads someone proposed a method like
> `Array.prototype.nth()` which would accept negative indices, though this
> creates an odd asymmetry since (presumably) we would not want to use -0 for
> the last index.

Yeah, -1 is the last index; it just does one round of "underflow" basically.

> In general I think the functionality you’re describing could be useful but
> that it could be served better by adding methods rather than syntax.

Agreed. Slicing via Array#slice() can likely be extended to allow
negative indexes, and even a third argument for steps to match Python
(yay for the -1 step value, to get a slice in reverse!).  Adding an
nth() that just takes a single positive or negative index would be
nice.  That we still have to do `arr[arr.length -1]` is barbaric. ^_^

(Only downside of negative indexes is that, when using it on
iterators, you have to consume the entire iterator before you can
return the desired value.)

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


Re: Return value of forEach

2017-07-24 Thread Tab Atkins Jr.
On Sun, Jul 23, 2017 at 6:53 AM, Naveen Chawla  wrote:
> Does anybody have any opinion on a new Array.prototype.each method that does
> the same as forEach but returns the array, thereby allowing chaining with
> sort, map, filter etc., while also preserving backwards compatibility?

In general, functions returning undefined are *often* safe to switch
to returning a more useful value; this is one of the recommended
patterns for upgrading DOM code that uses callbacks to using promises
instead.  We should pursue that first.  ^_^

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


Re: A twist on functional operatorsr

2017-07-17 Thread Tab Atkins Jr.
On Fri, Jul 14, 2017 at 8:11 PM, Bob Myers  wrote:
> The proposal to write `arr.reduce((+))`, with `(+)` as an alternative to
> `(a, b) => a + b` is admirably concise, but syntactically challenging. I
> propose an alternative which is slightly less compact, but hopefully more
> implementable and general.
>
> The idea is a new form of function we'll call a "pound function", written as
> `#{ }`, Within the body, parameters are available as `#0`, `#1`, etc. Thus,
> the example about would be written as
>
> ```js
> arr.reduce(#{#0 + #1})
> ```

This is incredibly close to `arr.reduce((x,y)=>x+y)`.  They're even
both 10 characters (tho yours is 8 character if you remove the
whitespace around the `+`, like I did with the arrow function).

I don't think one can reasonably justify adding more syntax (and
eating another useful ASCII glyph) just to reduce some types of arrow
functions by a few more characters; arrow functions are already
incredibly compact.

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


Re: Roman numeral support in Number type

2017-07-11 Thread Tab Atkins Jr.
On Thu, Jul 6, 2017 at 11:29 PM, kdex  wrote:
> Turns out the largest representable number is 39,
> but this might be implementation-specific.

Avoiding the more unusual characters is why CSS's roman-numeral
list-numbering scheme
 is only
defined up to 3999 - that lets us stick with ASCII.

(I agree in general that this should be handled by i18n or by a
userland library; there's nowhere near enough call to do this to
justify it being in JS core, imo.)

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


Re: setTimeoutAt(cb, date)

2017-07-11 Thread Tab Atkins Jr.
On Sat, Jul 8, 2017 at 12:58 PM, Isiah Meadows  wrote:
> Previous discussion:
> https://esdiscuss.org/topic/standardize-global-settimeout-etc

That thread is not relevant to the question at hand.  That linked
thread is talking about moving the definition of setTimeout() from DOM
to ES; this thread is talking about letting setTimeout() take a Date
object instead of a numeric delay argument, and run at that given
date.

(Unless you were trying to say that, as sorta concluded in the linked
thread, this is a DOM issue rather than an ES issue. In which case,
okay, but you could have been a lot more direct. ^_^)

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


Re: Intercepting sets on array-like objects

2017-06-09 Thread Tab Atkins Jr.
On Fri, Jun 9, 2017 at 2:07 PM, Domenic Denicola  wrote:
> I'm not really sure how you're expecting to get an answer "according to
> TC39."

I was told by Anne in

to "go back to TC39 I suppose and say you really want to do typed
arrays again".  (And in messages preceding/following that, Anne
implies that his pushback on the idea is motivated by historical TC39
dislike for this approach.) I'm doing precisely that.

> One member had replied and given his suggestion. I don't think it's a
> good one for new APIs; I think new APIs should use arrays and not type check
> on sets but at processing time. I'm sure there will be many other opinions
> from other TC39 members.

"Don't type-check things that look like arrays" means carving out a
special one-off shape in web APIs - every single property set or
method call in WebIDL typechecks the values. What makes "things that
look like arrays" special in this regard?  I can't avoid typechecking
- why should specs have to do bespoke typechecking in their functions
that *accept* these object, versus every other type of object in the
platform that is automatically type-happy?

Drilling in deeper: *fixed length* "things that look like arrays" can
have type-checking in WebIDL no problem, you just have to define the
names in prose, due to a legacy limitation of the WebIDL syntax. This
allows users to do `obj[1] = val;` and get a TypeError thrown when it
mismatches, exactly like they'd get with `obj.foo = val`. What makes
fixed-length different from dynamic-length "things that look like an
array"?  There's no semantic/usability difference between these cases;
it's purely an accidental artifact of the particular way JS handles
the [] syntax.

This is not good API design. Platform objects can mimic every other JS
object; there's no user-understandable reason why they should be
different in this one particular case.



Digging back a bit to try and find what TC39 opinion Anne was
referring to, I instead found this 2009 thread

which might be what he is remembering (it mentions FileList and
DOMTokenList), where TC39 members were pretty uniformly supportive of
an "integer property catch-all" (explicitly suggested by Maciej in
)
so that platform APIs could do non-live Array-likes.

Did something change in the intervening 8 years? If so, what, and why?
 (This was the second result in my mail archives for "indexed getter",
so I don't think I'm cherrypicking this thread either.)

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


Re: Intercepting sets on array-like objects

2017-06-09 Thread Tab Atkins Jr.
On Fri, Jun 9, 2017 at 1:57 PM, Adam Klein <ad...@chromium.org> wrote:
> On Thu, Jun 8, 2017 at 11:32 AM, Tab Atkins Jr. <jackalm...@gmail.com>
> wrote:
>> Note that if we don't get some variant of this functionality, these
>> APIs will instead do one of:
>>
>> * just using Proxies (already defined in WebIDL)
>
>
> When you say "Proxies" here, I believe you're referring to the "indexed
> properties" feature of WebIDL
> (https://heycam.github.io/webidl/#idl-indexed-properties). This seems like
> the right mechanism to use, from a WebIDL spec, to get the behavior you
> desire. In Chromium/V8, this doesn't actually use Proxies under the hood (we
> have something called "indexed property handlers", see the API at
> https://cs.chromium.org/chromium/src/v8/include/v8.h?rcl=ff98ddca4a1770c2868d44f1cdfe1d4656363f30=5781),
> but it's definitely implementable using Proxies.

Correct.

WebIDL's indexed getters/setters would fulfill my use-case *exactly*.
If that's okay to use, per TC39 consensus, then awesome!

However, in <https://github.com/heycam/webidl/issues/345#issuecomment-300734048>
Anne says:

> [When] we discussed those kind of approaches with TC39, they told us not
> to and to just use Array. It wasn't just about [], it was also about FileList,
> NodeList, etc. And the problem with those was not that they did not have
> enough methods like Array, it was that they required a proxy.

Thus my confusion/consternation.

If this is incorrect, and indexed getters/setters are indeed fine to
use in new APIs, then we can close this thread "no change" and I can
go away happy. ^_^

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


Intercepting sets on array-like objects

2017-06-08 Thread Tab Atkins Jr.
Heya!  As part of designing the CSS Typed OM
, we've ended up with at
three (so far) places where we want an interface that represents a
list of values:

* CSSUnparsedValue
,
representing alternating unparsed strings and variable references in a
property
* CSSNumericArray
,
representing the n-ary arguments of sum/product/min/max operations
* CSSTransformValue
,
representing a list of transform functions

The most natural way to represent these is as an Array, so authors can
get all the Array methods, use `val[i]` syntax, etc.  However, doing
so means we lose the ability to type-check sets to the values.

In general, type-checking is an important part of APIs defined in
WebIDL.  Any set to a property on an object is automatically
type-checked, any arguments to methods are automatically type-checked,
etc.  By building this into WebIDL, it removes the need for a lot of
annoying boilerplate on the part of spec authors, and more
importantly, removes the possibility that spec authors will forget to
typecheck at all, or will typecheck in incorrect or weird bespoke
ways.  Every API responds in exactly the same way when you pass the
wrong type of object, and that's a Good Thing for both users and
implementors.

And so, it would be great to have the same ability to typecheck these
Array-likes in the Typed OM.

Naively, this requires a Proxy, so we can intercept uses of the []
syntax.  However, we don't need all the rest of the Proxy
functionality, just this one intercept - a setter function, just for
`obj[foo]` rather than `obj.foo`.  Further, Typed Arrays already have
*precisely* the functionality I'd like to use - they intercept setting
using [], and convert it into the appropriate type of number.  AWB
also proposed adding exactly this hook in the past (I think it was
called "Array reformation" or something?).

Thoughts?

Note that if we don't get some variant of this functionality, these
APIs will instead do one of:

* just using Proxies (already defined in WebIDL)
* using .get()/.set() functions with integer arguments to badly emulate arrays
* just relying on iterator/constructor, so users have to convert the
object to an Array, fiddle with it, then construct a brand new object

And whichever I end up with, I'll be advocating that as the Standard
WebIDL Way to do array-likes, so we can finally have some consistency.

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


Re: Nonconstructors

2017-04-28 Thread Tab Atkins Jr.
On Mon, Apr 24, 2017 at 10:53 PM, Raul-Sebastian Mihăilă
<raul.miha...@gmail.com> wrote:
> On Tue, Apr 25, 2017 at 12:15 AM, Tab Atkins Jr. <jackalm...@gmail.com>
> wrote:
>>
>>
>> The obvious question is, why do you want to use `this`?
>>
>> ~TJ
>
>
>
> For cases such as a debounce function:
>
> ```js
>   const debounce = (func, delay) => {
> let timeout;
>
> return function (...args) {
>   clearTimeout(timeout);
>
>   timeout = setTimeout(() => {
> func.apply(this, args);
>   }, delay);
> };
>   };
> ```
>
> If func is using `this` the resulted function (returned by `debounce`)
> should pass its `this`.
> Another case is related to form fields. Let's say a form field is an object
> with a `validate` method. I provide a `createValidator` function to the user
> that accepts multiple functions in order to call them 1 by 1 until one of
> them returns an error. The result of `createValidator` is a function that
> then becomes the value of the field's `validate` method (which the user will
> call in order to validate the field). So the function will want to use
> `this` because it will forward it to the functions provided by the user.
> This is expected because the function will be called as a method of the
> field object.

Ah, these use-cases are reasonable.

In that case, then, yeah, checking `new.target` seems to be the way
you want to go. That's explicitly what it was defined to do:

if(new.target) throw "Foo() must not be called with new";

There's no shorter way to do this; all the shorter methods rely on the
function clearly existing as a method, syntactically.

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


Re: Nonconstructors

2017-04-24 Thread Tab Atkins Jr.
On Mon, Apr 24, 2017 at 1:42 PM, Raul-Sebastian Mihăilă
 wrote:
> I have a dilemma. I like how typically the built-in methods are not
> constructors (like Array.prototype.forEach). I have cases in which I'm
> creating a function in which I want to use `this` but I would like the
> function to not be constructible. There are ways of doing this:
> - checking new.target - but you have to check and the last time I checked
> uglifyjs was failing because of it.
> - ({function() { ... }}).function - but this requires creating an object
> every time, so it's ugly.
>
> It would probably be too much to add a new kind of function definition, but
> I was wondering if anybody ever cared about this kind of things. For
> instance, would people usually expect frameworks/libaries or Javascript
> itself to not make functions constructible if they're not meant to be?

The obvious question is, why do you want to use `this`?

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


Re: How come resolving a settled Promise doesn't throw?

2017-02-28 Thread Tab Atkins Jr.
On Tue, Feb 28, 2017 at 10:12 AM, /#!/JoePea  wrote:
> f.e.
>
> ```js
> let resolve
> let p = new Promise(r => resolve = r)
>
> resolve(5) //  resolves the promise.
> resolve(4) // noop (in Chrome), but why not throw an error?
> ```
>
> I only tested in Chrome, and I'm assuming it follows spec, but I could be
> wrong.
>
> I'm asking because it seems that throwing an error will prevent shots in the
> foot, so that code doesn't assume that resolving on an already resolved
> Promise worked, although it didn't. It seems like it can lead to unexpected
> failures.

That's correct behavior, yes.  In general, it's because the internal
state of a promise is meant to be unobservable unless you're
specifically listening to it.

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


Re: Enable async/await to work on functions that don't just return promises.

2017-02-27 Thread Tab Atkins Jr.
On Mon, Feb 27, 2017 at 12:41 AM, Isiah Meadows  wrote:
> May I add one more thing: the main topic this was about is adapting
> non-standard async APIs (like Node's error-first callback idiom) to the land
> of promises. Async functions and iterators are incredibly useful when you're
> dealing with just promises, especially consuming them, but this is about
> creating promise adapters, not consuming promises.

You don't need to change the behavior of core syntax to make
Node-style error-first callbacks work.  That's easily done by
libraries, which have existed in Node-land for quite a while, and can
automatically convert functions that take Node-style callbacks into
functions that return promises.

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


Re: Array Comprehensions

2017-02-06 Thread Tab Atkins Jr.
On Mon, Feb 6, 2017 at 9:47 AM, Gil Tayar  wrote:
> Forgive me if I'm wrong, but the double-for comprehension (e.g. [for (i of
> numbers) for (j of letters) i + j]) can't be easily expressed in JS because
> there's no flatMap.

Correct. (Which is why we need to add it.)

Aside: double-for in array comprehensions is only Pythonic in very
simple cases; it's usually quite hard to read.  The functional version
is somewhat better imo:

numbers.flatMap(i => letters.map(j => i+j));

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


Re: Ranges

2016-12-13 Thread Tab Atkins Jr.
On Tue, Dec 13, 2016 at 3:07 AM, Hikaru Nakashima
 wrote:
> My idia is as follows:
>
> ```
> [1..5]  //-> [1,2,3,4,5]
>
> (1..5)   //-> iterate 1, 2, 3, 4, 5
>
>
> [1..Infinity]  // -> TypeError because n > 2**32-1
>
> (1..Infinity)  // -> valid iterator
> ```

As Andy just explained in the previous message, that doesn't work.  In
particular, `[1..end]` is equivalent to `[(1).end]`, which is a
perfectly valid expression that creates a length-1 array containing
the value of the "end" property from a Number wrapper auto-constructed
around 1.  (Which happens to be undefined, unless you do shenanigans.)

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


Re: expanding comments proposal

2016-10-21 Thread Tab Atkins Jr.
On Fri, Oct 21, 2016 at 3:20 PM, Gert Cuykens  wrote:
> First I would like to see if we can agree on the term superset. Like
> the question is typescript a superset of ES? As you pointed out there
> are many comment like solutions like jsdoc or like your pep 484
> suggestion. But then a superset get narrowed down to // and /**/ which
> is fine but that means typescript doesn't come close as a super set
> and can never be used in jsbin directly for example.

Supersets have more stuff than the base.  Anything that's a superset
syntax-wise will never be usable in places that expect base grammar;
the extra stuff will be a syntax error.

> So the big question is can we agree on a superset that stretches the
> boundaries so that typescript would fall under that category. If for
> example certain typescript syntax is too brought I can ask the
> typescript community if they can adjust their compiler in the future
> that is compatible with the Ecma superset specifications.

Can you actually explain what you're asking for, with specifics?  So
far all i can divine is that you want JS to allow some
TypeScript-specific syntax (and treat it as comments?), but I don't
know *what* syntax you're asking for.  All you've done so far is
provide TypeScript snippets for us to look at.

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


Re: expanding comments proposal

2016-10-21 Thread Tab Atkins Jr.
On Fri, Oct 21, 2016 at 2:46 PM, Gert Cuykens  wrote:
> Exactly, here is a concrete ES2015 example
> http://jsbin.com/ruqekam/edit?html,output Now just add a simple
> typescript type to any of the variables and notice everything breaks.
> If ES2015 would be smart enough to ignore the typings I can use a
> simple jsbin to share my code with others without any transpiling. I
> want to avoid making this a typescript specific thing but just want to
> point out that Ecma262 can be made more flexible to allow some supper
> set syntax that browser vendors can simply ignore but editors like
> vscode can use it for intellisense because it recognizes the extra
> syntax as typescript for example.

Okay, so it *sounds* like your proposal is that ES allow the
TypeScript syntax of writing variables declarations as "name:type",
and treat the :type part as a comment?

If you're interested in "typing that look like comments", you can do
that today; Python2 defines a reasonable syntax in Pep 484
.

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


Re: Proposal: add an option to omit prototype of objects created by JSON.parse()

2016-10-06 Thread Tab Atkins Jr.
On Thu, Oct 6, 2016 at 12:50 PM, Rick Waldron  wrote:
> var o = JSON.parse('{}');
> Object.setPrototypeOf(o, null);

That's not remotely correct, as it does nothing for anything other
than the top object.  (And it breaks things if the top-level value
isn't an object.)

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


Re: Array tail destructuring

2016-10-04 Thread Tab Atkins Jr.
On Mon, Oct 3, 2016 at 8:06 PM, Caitlin Potter <caitpotte...@gmail.com> wrote:
>> On Oct 3, 2016, at 10:54 PM, Tab Atkins Jr. <jackalm...@gmail.com> wrote:
>>> On Sun, Oct 2, 2016 at 2:11 AM, Caitlin Potter <caitpotte...@gmail.com> 
>>> wrote:
>>>> On Oct 2, 2016, at 10:50 AM, Awal Garg <awalg...@gmail.com> wrote:
>>>>> On Oct 2, 2016, at 9:30 AM, Olivier Lalonde <olalo...@gmail.com> 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".
>
> "I'm similarly confused about your assertion that this idea needs to avoid a 
> halting problem, because here's a way around this problem, not suggested by 
> anyone else, with a non-negligible cost, so there"?
>
> Really? I'm asking how they would alter IteratorBindingInitialization. It's 
> not rocket science, but it's important for the discussion.

Right, the details are important, but there's clearly no need to
predict future behavior to achieve it; you can do this sort of thing
in userland already.

> Also, this behaviour differs observably from the current behaviour, I 
> believe. Consider:
>
> ```
> try {
>   var [...x, y, z] = 
> } catch (e) {
>   console.log(y); // initialized?
> }
> ```
>
> I'm fairly sure currently (ignoring the non-final rest element) everything 
> would be bound except for `z`. But in this idea, it sounds like it wouldn't 
> be.
>
> So, another thing to deal with, I guess

Ah, yes, so it is observable, good catch.  Yes, the only reasonable
way to do this is to have an N-element delay in assigning, where N is
the number of post-rest arguments, and then only assign the final N
arguments when the end of the iterator is hit.  So in this case, both
y and z would be uninitialized; the algo would be holding onto one
pending element (to be assigned to y if the next pull returns a
{done:true}) and the throw prevents it from doing that assignment.

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


Re: Array tail destructuring

2016-10-03 Thread Tab Atkins Jr.
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


Re: Support () => {}() syntax?

2016-09-30 Thread Tab Atkins Jr.
On Fri, Sep 30, 2016 at 7:23 AM, Allen Wirfs-Brock
 wrote:
> On Sep 30, 2016 6:10 AM, Kevin Smith  wrote:
>> Ideally there will be an `async` version of do expressions, which evaluate
>> to a promise:
>>
>> ```
>> let promise = async do {
>>   await something();
>> };
>> ```
>>
>> (BTW, if we get such a thing, we might not really need
>> top-level-module-await...)
>
> +1 !!

Aw dang, yeah, I really like that. (Obviously the example given is
trivial, as just calling something() directly would give the exact
same result, but being able to do more complicated stuff with the
result means inline promise-chaining without having to asyncify your
whole function!)

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


Re: Syntax Proposal: Anonymous Arguments

2016-09-28 Thread Tab Atkins Jr.
On Fri, Sep 23, 2016 at 10:38 AM, Kenneth Powers  wrote:
> I have a proposal for new syntax in ES inspired by the placeholder syntax in
> Scala Functions.
>
> Essentially, the idea would be to allow anonymous arguments. The most simple
> example would be a function which takes one argument (as far as the
> programmer is concerned):
>
> [1, 2, 3].map(@ + 1)
>
> This would be the same thing as:
>
> [1, 2, 3].map(n => n + 1)
>
> Just like in Scala, an anonymous function is created. This concept can be
> further extended in ES:
>
> [1, 2, 3].reduce(@0 + @1, 0)
>
> Which would be the same thing as:
>
>[1, 2, 3].reduce((sum, n) => sum + n, 0)
>
> Thoughts?

While I like really concise callbacks for simple cases like this, the
win over arrow functions is *so tiny* here.  map(@+1) vs map(x=>x+1)
is *3 characters* different; map(@0+@1) vs map((x,y)=>x+y) is 5.
Having to learn a new syntax for tiny functions that only gains an
extremely miniscule benefit in terms of code size is an extremely hard
sell.

Compound this with the fact that the @ glyph is already spoken for,
and you have an extreme uphill battle to deal with.

I suggest just living with the few extra characters that arrow
functions impose, and being happy we no longer have to type out
"function ... { return }". ^_^

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


Re: Function constants for Identity and No-op

2016-08-10 Thread Tab Atkins Jr.
On Wed, Aug 10, 2016 at 7:25 AM, Eli Perelman  wrote:
> Now obviously it would be trivial for me to declare these constants in
> userland code like I already do, e.g. `const NOOP = () => {}`, but in
> projects where it's needed in several files, I'll have to put that in a
> module or re-declare everywhere. This is not a huge inconvenience but
> something that could easily allocated for in the language.

Mark's argument (which I agree with) is that `x=>x` and `()=>{}` are
good *spellings* of "identity function" and "noop function".  It's
immediately obvious what they do; `obj.doCallback(()=>{})` is about as
easy to understand as `obj.doCallback(Function.noop)`.  The ID
function is even simpler - `obj.map(x=>x)` reads *extremely* well to
me, equal or better than `obj.map(Function.id)`. If we were to reserve
"id" and "noop" as bare global variables, I might agree that those
were even better, but that's clearly out of the question.

~TJ
___
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-09 Thread Tab Atkins Jr.
On Tue, Aug 9, 2016 at 4:00 PM, /#!/JoePea  wrote:
> True, and so that's why I'm wondering if the module system can see that it
> can satisfy all module requirements if it simply evaluates module C first,
> followed by A or B in any order. It is easy for us humans to see that. It
> would be nice for the module system to see that as well (I'm not sure if
> that is spec'd or not).

That knowledge requires, at minimum, evaluating the rest of each
module, beyond what is expressed in the `import` statements.  That's
assuming there's no dynamic trickery going on that would invalidate
whatever assumptions it can draw from surface-level analysis.

Because of this, only the `import` statements are declaratively
available to the module system to work with.  Based on that, it
definitely can't make any ordering assumptions; all it knows is that A
imports C, B imports C, and C imports both A and B, making a circular
import.

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


Re: Operating with arbitrary timezones

2016-08-05 Thread Tab Atkins Jr.
On Fri, Aug 5, 2016 at 1:59 PM, Kris Siegel  wrote:
>>  Once you endow them with a timezone offset they cease to represent points
>> in time, but rather more points in space, which adds complexity and
>> liability to any code handling Date objects
>
>
> I would disagree. Time isn't useful without a point in space (space and time
> should be looked at as one thing, not two) and since the Date object tracks
> it internally as UTC it has a default space.

This is incorrect. It tracks a UTC timestamp; the current time as I
write this is 1470432591121 milliseconds since the epoch, and that's
true regardless of where you are on the planet.

Timezones are a *display* concept - they affect how you parse
human-readable strings into timestamps, and how you display a
timestamp as a human-readable string.  This is similar to the
distinction between Unicode values and strings encoded in UTF8.

JS Date objects input/output using the user's local timezone. Luckily,
since Yahoo Mail apparently knows the user's preferred timezone (from
their settings), they can adjust things as appropriate themselves. The
important concept, tho, is that this adjustment is in *how you
parse/display datetimes*, not how you *store* them - storing is done
without any timezone information whatsoever.  It's not *trivial* to do
so (thus the success of libraries like moment.js), but it's at least
easier when you realize that Date objects represent exact points in
time, and timezone (and related things like "start of day") are
display-related only.

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


Re: Why are object initializer methods not usable as constructors?

2016-07-28 Thread Tab Atkins Jr.
On Wed, Jul 27, 2016 at 11:44 AM, /#!/JoePea  wrote:
> What's the good reason that object-initializer methods can't be constructors
> though? I mean, I get that "that's what spec says", but what's the actual
> good reason?

Because they're methods, not functions. The distinction between the
two was merely semantic in ES5, but now it's mechanical, due to
super(); constructing something intended as a method would make
super() behave in confusing and unintuitive ways, so methods just
don't have a constructor any more.

There are several very similar ways you can write your example that do
achieve what you want. As Allen said, you can just use the non-concise
syntax, explicitly typing "function" (or better, "class") for each of
the values.  This is only a few characters more and achieves exactly
what you want.

It's been explained to you already in previous threads why super() is
designed the way it is, and how a dynamic super() would add
significant cost to some situations.  Making this one niche use-case
("I want to define several constructor-only classes inline in an
object initializer") require a few characters less is not a
sufficiently worthwhile benefit for the cost.  Just type the few extra
characters (exactly what you would have typed in ES5, so it's not even
a new imposition), and you'll be fine.

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


Re: Code smell? Iterator prototype has iterator method that returns "this"

2016-07-25 Thread Tab Atkins Jr.
On Mon, Jul 25, 2016 at 4:28 PM, John Lenz  wrote:
> I understand the way it is used, but I don't understand why.   "for-of"
> could have been spec'd to take either an Iterable (an object with an
> [Symbol.iterator] method) or an Iterator.  Or just an Iterable.

Not just for-of, but the whole rest of the world (in particular,
anything that directly consumes iterables) would also have to make
that distinction.  Much easier to just let everyone pretend that an
iterator is iterable, so you can use a common API between the two
types.  (Also, Python already worked this way, and a lot of JS
iterator details were copied from Python originally.)

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


Re: Proposal: Bind Promise Catch to Try/Catch scope

2016-06-21 Thread Tab Atkins Jr.
On Tue, Jun 21, 2016 at 6:15 PM, Todd Hubers  wrote:
> 1. Whether you await or not, the try scope's catch callback [TSCC] should 
> still be captured.

Why? Async code doesn't do anything special for try/catch anywhere
else in the language - what does this proposal do that's worth the
added complexity beyond what just using a Promise and the await/async
keywords can do?

> 2. If there is no use of Promise (for coders own design reasons) the try 
> scope's catch callback [TSCC] should be available

What uses are you thinking of, and why should this be available?

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


Re: Suggestion: Object.symbols

2016-06-15 Thread Tab Atkins Jr.
On Wed, Jun 15, 2016 at 3:54 PM, doodad-js Admin  wrote:
>> I consider all of the 'get some arbitrary subset of properties from an
>> object' use cases obsoleted by `Map`. But maybe I'm missing something
>> obvious or not-so-obvious...?
>
> Objects, obsolete with Map ? “Map” is not meant to replace objects, is it ?

It's meant to replace "objects used as maps". ^_^  That's one of the
major reasons to use Object.keys(), so to justify adding a similar
method for symbol-valued properties, you'd have to present a use-case
that's not better solved by "just use a Map".

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


Re: Array.prototype.includesAll

2016-06-14 Thread Tab Atkins Jr.
On Tue, Jun 14, 2016 at 12:58 PM, Bob Myers  wrote:
> This proposal is so far from something that should go into the base language
> that it makes me choke.
>
> Are you also going to propose that we add `includesNone` and `includesSome`?
> Do you want to include an option to sort the items for efficiency?
> Why do you provide no `fromIndex` parameter?
> Shall we include an option to lowercase before checking for equality?
> How does this relate to the notion of array difference, which is one way to
> accomplish what you want?
>
> Just write a library that does what you want and get on with your life.

This is a grossly inappropriate tone and does not belong on the list.

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


Re: New Set.prototype methods

2016-05-31 Thread Tab Atkins Jr.
On Sun, May 29, 2016 at 6:13 AM, Michał Wadas  wrote:
> I have written proposal for new Set.prototype methods.
>
> https://github.com/Ginden/set-methods
>
> New methods would be:
>
> Set.prototype.filter
> Set.prototype.map
> Set.prototype.some
> Set.prototype.every
> Set.prototype.find
> Set.prototype.union
> Set.prototype.intersect
> Set.isSet
>
>
> TBA:
>
> Set.prototype.difference (or .except)

Yes *please* to all of these.  I've added most of them manually to
Set.prototype on some of my projects.

One additional request in a related vein - Set.prototype.chain - like
.map, but the callback's value is iterated and added to the result
set.  (We need to coordinate this with an identical method on Array;
.chain just seems to be one of the more common names for this
operation in JS-land.)  I use this a *lot* to, for example, expand
items into related terms.

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


Re: Proposal: importing selected chucks of a module into an object

2016-05-24 Thread Tab Atkins Jr.
On Tue, May 24, 2016 at 11:59 AM, Norbert de Langen
 wrote:
> It would be nice to have this option:
>
> ```
> import { parse } as xmlLib from 'xml-lib';
> import { parse } as jsonLib from 'json-lib';
> import { parse } as htmlLib from 'html-lib';
>
> // usage
> xmlLib.parse();
> jsonLib.parse();
> htmlLib.parse();
> ```

This begs the question, tho - why do you only need to import selected
chunks? If you're pulling in the module as a namespace object, how
does having the *rest* of the module available harm you?

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


Re: Get currently destructured object

2016-05-19 Thread Tab Atkins Jr.
On Thu, May 19, 2016 at 8:59 AM, Michał Wadas  wrote:
> Idea:
>
> function foo({bar, *: baz}) {
>
> }
>
> would be equivalent to:
>
> function foo(baz) {
>const bar =  baz.bar;
> }
>
> Rationales:
> - little better IDE support (argument name reveals intention)
> - allows to write more concise code when handling case of getting common
> values and handling whole object optionally
> - improve pattern "use few properties of options object then pass it deeper"
> - allows more expressive module import
> - allows to more concise code when destructuring expression result
>
> import {*: rand, generateRandomInt} from 'fancy-random-module';
> import {*: moment, isMoment} from 'moment';

Other languages with destructing have a more explicit syntax for this
(giving a name to the container as well as its pieces), so that it
works in all the destructuring forms.  In Haskell, for example, it
looks like "baz@{bar}". This is usable with list destructuring, too.

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


Re: Proposal: Switch position of delay and callback in signature of `setTimeout()`

2016-04-25 Thread Tab Atkins Jr.
On Mon, Apr 25, 2016 at 10:43 AM, Oriol Bugzilla
 wrote:
> `setTimeout` is not part of ECMAScript. You should suggest this to WHATWG
> instead.

And I can short-circuit the request: we can't change it.  setTimeout
is an old and heavily-used API, so any change like this is very likely
to be backwards-incompatible.

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


Re: stable sort proposal

2016-03-18 Thread Tab Atkins Jr.
On Tue, Mar 15, 2016 at 8:50 AM, Vic9  wrote:
>> What about the Timsort?
>
> I cannot believe it will be faster on random int array. And TimSort is base 
> on MergeSort and, seems, for it's worst cases it cannot be better than 
> MergeSort.
> I have tried https://github.com/mziccard/node-timsort/ with my old node.js - 
> 0.10.4 and Chrome 49 (win32) - and I see that random int array case is much 
> slower that native in Chrome, and in node.js too if I replace "native" with a 
> function from https://github.com/v8/v8/blob/master/src/js/array.js .
>
> Perhaps, implementers will want to leave the behaviour of 
> `array.sort(comparefn)` as it was for backward compatiblity.

There's no back-compat impact for switching to a stable sort; since
you can't depend on the ordering of an unstable sort in the first
place, changing that order (to stable) is fine.  (Most likely it'll
*fix* pages that are currently sometimes broken in small ways because
they assume stability.)  It's just potentially a minor speed drop.

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


Re: stable sort proposal

2016-03-18 Thread Tab Atkins Jr.
On Fri, Mar 18, 2016 at 3:57 PM, Waldemar Horwat <walde...@google.com> wrote:
> On 03/18/2016 11:10, Tab Atkins Jr. wrote:
>>
>> If you're planning on pessimistically assuming that legacy
>> implementations use an unstable sort for Array#sort(), then testing
>> for the presence of Array#fastSort() (and assuming that when it
>> appears the Array#sort is stable) is exactly as useful as testing for
>> the presence of Array#stableSort (and assuming that when it appears
>> the Array#sort is unstable/fast).  So, polyfilling isn't a reason to
>> prefer one default vs the other.
>
> That makes no sense.  The presence of fastSort does not indicate that sort
> is stable.

I'm confused.  Did you miss some context here?  No UA currently
provides an Array#fastSort.  We'd only do so if the method was added
to the spec; such a method would only be added to the spec if we also
changed the spec to require Array#sort to be stable.

So yes, the presence of Array#fastSort is a positive signal for
Array#sort being stable.  Just like the presence of Array#stableSort
is a positive signal for Array#sort *not* being stable.  Exception
proves the rule, etc.

> The approach of sometimes using "sort" for unstable sort and sometimes for
> stable sort would cause too much confusion.  Which sort are you getting when
> you call sort?  If you want a sort that's guaranteed stable, call
> stableSort.

Again, in the context that I was replying to, we're talking about a
polyfill.  Said polyfill would ensure that legacy implementations got
a stable sort filled in for Array#sort.

> The argument that stable sort should have the shorter name doesn't hold much
> water either.  C++ defines sorts named sort and stable_sort (as well as a
> few others) just fine.  sort is by far the more popular one (by a factor of
> 20!) because most applications don't actually care about stability.

Or because most people reach for the familiar short name by default.
Usability directly impacts use, and most coders are familiar with only
a small fraction of the standard library.  I'd bet quite a lot of
applications actually *do* care about stability, but such situations
only crop up rarely in practice, and so they're just occasionally
buggy.

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


Re: stable sort proposal

2016-03-14 Thread Tab Atkins Jr.
On Fri, Mar 11, 2016 at 8:17 PM, Isiah Meadows  wrote:
> In my honest opinion, there's not much reason to just require the sort to be
> stable. Some engines have done this in the past, and the spec technically
> allows it. At this point, stable sorts are about as fast as unstable ones,
> both in theory and practice (wasn't the case 10 years ago IIRC).

I think you meant "to not just require", yes?  As in, you think the
spec *should* require .sort() to be stable?

On Sun, Mar 13, 2016 at 12:23 PM, Vic9  wrote:
> Stable sort is useful sometimes, but it is possible to implement it in js.

Most things in the JS standard library are possible in userland code,
so that's not a useful rebuttal to anything by itself.  The question
is whether it's worth requiring that the standard sort be stable.
Stable sort is never *bad* - there are no use-cases where a stable
sort gives the wrong answer while an unstable sort is correct, but the
opposite is definitely true.  The only question is how much
slower/more expensiver stable sorting is than unstable sorting, and
whether that cost is sufficient to outweigh the usefulness of a stable
sort.

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


Re: es7 proposal/polyfill?: base Map/WeakMap off Proxy + Weak References

2016-02-19 Thread Tab Atkins Jr.
On Fri, Feb 19, 2016 at 12:59 PM, Boris Zbarsky  wrote:
> On 2/19/16 3:50 PM, Coroutines wrote:
>> Side discussion: Why does Javascript have this limitation? - what I
>> view as a limitation?  You'd think this could be supported without
>> breaking older JS..
>
> I don't see how it could.  I'll bet $50 someone out there is using
> obj[location] for example.

Yes, relying on the stringification behavior is very common.
Absolutely no way to change it at this point without something like
AWB's (abandoned) Object Model Reformation proposal

that would allow changing the behavior of [].

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


Re: Any reason why __proto__ is not a well known symbol?

2016-02-15 Thread Tab Atkins Jr.
On Mon, Feb 15, 2016 at 9:14 PM, Coroutines <corouti...@gmail.com> wrote:
> On Mon, Feb 15, 2016 at 8:51 PM, Tab Atkins Jr. <jackalm...@gmail.com> wrote:
>> It was specified before symbols existed, and all implementations do it
>> as a string property.  If we were reinventing it today it would either
>> be a symbol or something in the MOP, but are hands are tied by legacy.
>>
>>> Being that it was not formally spec'd it shouldn't have broke backwards
>>> compatibility either.
>>
>> Backwards compat has nothing to do with specs, and everything to do
>> with existing implementations.  Multiple implementations agreed on
>> __proto__, so our choice was either to leave it unstandardized or spec
>> what the browsers did.
>
> Is there a migration to make it a Symbol in ES7?  (ignorant question?)

There's a lot of code in the wild that uses __proto__ and depends on
it.  We can't remove it until/unless that changes (it won't, at least
not in the near future), and while we have __proto__, there's no
reason to have anything else.

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


Re: Any reason why __proto__ is not a well known symbol?

2016-02-15 Thread Tab Atkins Jr.
On Mon, Feb 15, 2016 at 8:34 PM, JD Isaacks  wrote:
> I know ES2015 formally made the `__proto__` property a way to access/set an
> object's internal `[[Prototype]]` property.
>
> Is there any reason why this wasn't spec'd as a well known symbol such as
> `@@__proto__`. It just seems like it would line up well with other modifiers
> like `@@iterator`, `@@species`, etc.

It was specified before symbols existed, and all implementations do it
as a string property.  If we were reinventing it today it would either
be a symbol or something in the MOP, but are hands are tied by legacy.

> Being that it was not formally spec'd it shouldn't have broke backwards
> compatibility either.

Backwards compat has nothing to do with specs, and everything to do
with existing implementations.  Multiple implementations agreed on
__proto__, so our choice was either to leave it unstandardized or spec
what the browsers did.

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


Re: monadic extension to do-notation

2016-02-09 Thread Tab Atkins Jr.
On Sun, Feb 7, 2016 at 9:07 AM, Raphael Mu  wrote:
> The ES Promise is an instance of Monad, a property that implies a much more
> concise and expressive syntax for using Promise, by exploiting its monadic
> properties. I've seen a lot of people complain about Promises having too
> clumsy a syntax, and likewise for async/await.

As others have said, ES Promise is monad-like, but not actually a
monad, because it flattens too much.  That said, it's close enough for
most purposes.

> We now have the do-notation proposal
> (http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions), and
> monadic assignment would fit well into the syntax.

I assume you're reading this as being similar to do-notation in
Haskell?  The resemblance stops at the keyword - the do-notation in ES
is just a way of converting a statement (or multiple) into an
expression.  Do-notation in Haskell is specifically and explicitly
sugar for nested bind calls.  Conflating them will likely just lead to
sadness (Rick offers an example with a syntax conflict).

In any case, arrow functions actually make nested binds not too bad in JS:

let finalPromise =
  promiseA.then( x =>
  promiseB.then( y => {
  let c = f(a,b);
  g(a, b, c);
}));

Except for the fact that you need to track the parens/curlies you
used, so you can close them at the end, this hews pretty close to
Haskell's do-notation.

As an added benefit, you get support for
functors/applicatives/tranversables/etc for free, by using .map/etc
instead of .then (/.flatMap/.bind, for the general monad).  Also,
being able to customize the function used is nice for JS-as-it-exists,
because we don't have a rich ecosystem of monadic/etc classes that use
a common syntax yet: Promises use .then, Arrays have a proposal to add
.flatMap, JS Fantasy Land uses .chain, etc.

> The extension would allow use of `<-` within a do-expression for binding
> Promise values to variables, and the computation would behave most similarly
> to the Either monad in Haskell (in the following code, if promiseA or
> promiseB reject, the result of the entire expression would be a rejected
> Promise).

Even if we added explicit support for something like this, there'd be
no reason to specialize it to Promises.  It would just desugar to
nested binds, same as Haskell.

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


Re: Using 'this' in default parameters

2016-02-09 Thread Tab Atkins Jr.
On Sun, Jan 31, 2016 at 3:59 PM, Bergi  wrote:
> Jason Orendorff wrote:
>> On Fri, Jan 29, 2016 at 8:14 AM, ` Mystery .  wrote:
>>> IMHO I don't think the default parameters should be evaluated within the
>>> context of the function being called, at least not while it's outside of
>>> function body's region.. Is there a specific reason to do that, or
>>> it's
>>> just a design preference?
>>
>> Sure, there is a reason: it's about how defaults are used.
>>
>> Most defaults are probably constants or empty objects. Those don't
>> need to refer to any variables at all, so we can set them aside.
>
> Well, primitive-valued constants are fine. But if you have an empty object
> constant, which is statically attached to the function instance instead of
> being re-evaluated at every call, that would surely cause enough havoc
> already :-)

I was about to send almost this exact reply. ^_^  This is actually
*very* important, and can't be set aside - Python got it wrong, which
is why if you want an argument to default to an empty list, for
example, you have to do:

def foo(bar=None):
  # or any sentinel value, but None is almost always usable
  if bar is None:
bar = []
  ...

Otherwise you get a single array created at function definition time
and shared by all calls that default that parameter. ^_^  JS made the
right ergonomic decision for this, but of course some use-cases are
negatively affected in the trade-off, but none of them are made
impossible, or even difficult, as several people in this thread have
shown.

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


Re: JavaScript Language feature Idea

2016-02-09 Thread Tab Atkins Jr.
On Tue, Feb 2, 2016 at 12:15 PM, Jonas Sicking  wrote:
> On Mon, Jan 25, 2016 at 12:38 PM, Andrea Giammarchi
>  wrote:
>> FWIW `.at` works for me. Anything really, as long as `Symbol.last` won't
>> even be proposed :D
>
> If we name it `.item` that would mean that a whole bunch of DOM
> classes could be replaced with plain JS Arrays.
>
> For example FileList, MessagePortList, DOMRectList, TouchList, etc.
>
> It would also mean API compatibility with a whole lot of more APIs,
> like NodeList, DOMTokenList and CSSValueList. While we couldn't
> replace these with actual Arrays (for varying reasons), we'd end up
> with classes that have more API surface in common.

I love a good bird-killing stone. ^_^  Let's do this!

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


Re: Promises as Cancelation Tokens

2016-01-04 Thread Tab Atkins Jr.
On Mon, Jan 4, 2016 at 9:01 AM, Domenic Denicola  wrote:
> From: Kevin Smith [mailto:zenpars...@gmail.com]
>
>> And what's the deal, is it canceled or cancelled?  : )
>
> This is kind of the worst. Previous discussion at 
> https://github.com/promises-aplus/cancellation-spec/issues/4.
>
> Data seems to favor cancelled:
>
> - 
> https://books.google.com/ngrams/graph?content=canceled%2Ccancelled_start=1800_end=2020=15=3=_url=t1%3B%2Ccanceled%3B%2Cc0%3B.t1%3B%2Ccancelled%3B%2Cc0
> - http://www.google.com/trends/explore#q=cancelled%2C%20canceled=q
> - http://www.googlefight.com/canceled-vs-cancelled.php

The best approach in cases like this is to avoid the word altogether.
The fact that there's confusion at all means people will mess it up
and get annoyed, even if there's a "winner" in overall usage.

On Mon, Jan 4, 2016 at 9:36 AM, Kevin Smith  wrote:
>> I am also unsure when .whenCanceled is necessary
>
> Maybe in the case where you have a promise-returning function and you want
> to reject the returned promise upon cancellation.
>
> function delayWithCancel(ms, cancelToken) {
>   return new Promise((resolve, reject) => {
> setTimeout(resolve, ms);
> cancelToken.whenCancelled(reject);
>   });
> }

Yes, forcing people to poll an attribute of a Promise-like thing is
kinda ridic. ^_^

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


Re: Reflection to know if executed within a generator/async ?

2015-12-08 Thread Tab Atkins Jr.
On Tue, Dec 8, 2015 at 9:44 AM, Andrea Giammarchi
 wrote:
> yup, that's what my library does as well. I thought Bergi meant in absolute.

I can't speak for Bergi, but yeah, I assume he was talking about a
function returning a promise or not based on something other than
overloads, such as the value of certain arguments, or the syntactic
location in a greater expression.

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


Re: Reflection to know if executed within a generator/async ?

2015-12-08 Thread Tab Atkins Jr.
On Sun, Dec 6, 2015 at 10:48 PM, Andrea Giammarchi
 wrote:
> However, I'm curious to know about this "Functions that sometimes return
> promises and sometimes not are already known to be an antipattern" because I
> have a library that does that in somehow explicit way (if you pass a
> callback it doesn't return  a promise, it invokes such callback once
> resolved) and it works without any real-world problem.

This pattern is fine; different overloads of a function are basically
different functions, and we're using this pattern in the web platform
in a few places to "update" some CB-using APIs to Promises.  As long
as the function previously returned void and took the CB last, we can
do it.

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


Re: Map literal

2015-11-28 Thread Tab Atkins Jr.
On Thu, Oct 29, 2015 at 6:23 PM, Alexander Jones  wrote:
> I don't think borrowing object notation is a good idea. What exactly does
>
> ```
> const myMap = Map#{
> get foo() { return 100; },
> set foo(v) {}
> constructor() {}
> };
> ```
>
> mean?
>
> Honestly, a very significant portion of the use cases I have for *actual
> maps* don't involve string keys. So to borrow object notation and have to
> constantly write keys in [] is pretty naff:
>
> ```
> const describe = Dict#{
> [1]: "one",
> [[1, 2]]: "array of 1 and 2",
> [null]: "the null value",
> }; // please no!
> ```
>
> If it makes people feel too weird to have comma separated, colon split
> key-value pairs within curlies that *don't* parse like POJSOs, we could have
> completely non-ambiguous parse with normal parentheses, I think?
>
> ```
> const describe = Dict#(
> 1: "one",
> [1, 2]: "array of 1 and 2",
> null: "the null value",
> );
> ```
>
> That might limit confusion while giving a syntactically clean way to define
> maps. Let's consider that a future mapping type like Dict compares
> non-primitive keys by abstract value instead of by reference identity. There
> are *tonnes* of nice use cases that open up that are taken for granted in
> other languages and other classes like Immutable.Map - we're not there yet
> with ES6 built-ins, so perhaps people might not yet appreciate the value of
> this.
>
> To reiterate a previous point, object property access with a statically
> defined string key is idiomatically written `obj.foo`, so it makes sense for
> symmetry to have `foo` appear as a bareword in a literal defining `obj =
> {foo: 42}`. For most mapping-type classes this symmetry simply does not
> apply, and frankly neither should it.
>
> Also, I specifically suggested that the consumed value is an ArrayIterator
> rather than an Array, because I feel having an intermediate Array around is
> placing too high an importance on the humble Array. If the implementation
> really wants an Array to work on internally, they can simply call
> `Array.from` with little cost. But if they want an Immutable.List they can
> have that instead without ever seeing an actual Array. (The Symbol.fromHash
> method is just Symbol.literalOf as I called it - same thing, modulo
> bikeshed.)

I strongly agree with a lot of the points here, and think they suggest
the OP's suggestion was generalized in slightly the wrong way.
Producing a Map literal is indeed too specific to justify syntax, but
what's suggested is not a special way of calling some constructors,
but *a literal syntax for 2-value iterators*.

We have a literal syntax for 1-value iterators: just use an Array.
It's lightweight (2 chars + 1 char per item), and typos in the syntax
are caught at compile time.  Our existing literal syntax for 2-value
iterators (an array of length-2 arrays) fails at both of these: it's
heavyweight (4 chars + 4 chars per item), and typos in the syntax are
only caught at runtime, when it's actually iterated over.

Having a lightweight, compile-time-checked 2-value iterator literal
that desugars to an N×2 Array (or ArrayIterator) fixes all these
problems, and makes it easy to write Map literals, Immutable.Dict
literals, or anything else.  Using the hash-paren syntax suggested
above:

```
let m =  Map(#(1: "one", [1, 2]: "array of 1 and 2", null: "the null value"));
```

There's no need to invent a new function-calling syntax or add a new
well-known symbol to anything. It Just Works™ as long as the function
you pass it to expects a 2-value iterator.

(From other languages, there doesn't appear to be any call for N×3
literals or anything higher

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


Re: Map literal

2015-10-27 Thread Tab Atkins Jr.
On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones  wrote:
> I agree this is pretty important. Using actual maps really frees up a lot of
> complexity, but the syntax is cumbersome to say the least.
>
> Whatever the decided syntax, bare words as string keys is a really bad idea
> IMO. The key syntax should be parsed as an expression, like the values are,
> and like they are in basically every other language.
>
> Another outstanding issue is that we might want the syntax for
> `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves deficiency
> $x, $y and $z. I'd say introducing a special syntax for `Map` right now is
> not ideal.

Currently, the "extensible literal syntax" for this isn't that bad:

const bar = 43;
const map = Immutable.Map([["foo", 42], [bar, 44]]);

It's a little more verbose because the entries have to be surrounded
by [], but hey.

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


Re: Swift style syntax

2015-10-16 Thread Tab Atkins Jr.
On Thu, Oct 15, 2015 at 11:12 PM, Isiah Meadows  wrote:
> I like the idea, but could the function names be made a little
> shorter? I'd like to at least save some characters on it. Example:
> `(a, b) => a > b` is 15 characters, where `Math.greaterThan` is 16.
>
> For comparison, I also have equivalent versions for the colon-preceded 
> operators
>
> Here's some naming ideas I have:
[snip]

At that point, though, the use of the Math namespace starts getting
weird.  Equality and Logical aren't mathematical; Bitwise mostly isn't
either.  (It can sometimes be used to do mathy things, like using
shift to mul/div by a power of 2, but that's not its core purpose.)

Put them on a new Op namespace object, or into an Op built-in module.
Even shorter, and clearer!

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


Re: Reflect.getDefaultParameterValues

2015-10-06 Thread Tab Atkins Jr.
On Mon, Oct 5, 2015 at 9:00 AM, Benjamin Gruenbaum  wrote:
> Well, I've personally thought about building a small pattern matching
> library using the syntax, but that's hardly a general use case:
>
> ```js
> match(
> (x = 1) => doFoo(...)
> (x = {y : 3}) => doBar(...)
> ```

That's just syntax punning/abuse, not a real use-case. ^_^

> However, there are several use cases people mention. Here are the first
> twofrom questions asking for this on StackOverflow in other languages:
>
>  - Exposing functions in a module over a JSON API. If the caller omits
> certain function arguments, return a specific error that names the specific
> function argument that was omitted. If a client omits an argument, but
> there's a default provided in the function signature, I want to use that
> default.

I'm confused.  If the argument defaulted or not?  If it's defaulted,
omitting it isn't an error.  If omitting it is an error, then there's
no default, by definition.

>  - Building an ORM that uses the default values in the database and returns
> correct error messages when an insert of a default value failed.

What about that requires the knowledge of the defaulted value, rather
than just the argument value?  I *might* see a use-case here for
knowing *whether or not the argument was defaulted*, so you can output
a more helpful error message (saying that the default is wrong, rather
than saying the passed value is wrong), but knowing the default value
doesn't help there (unless it's a unique sentinel value, which defeats
the point of default values in the first place).

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


Re: rest parameters

2015-10-02 Thread Tab Atkins Jr.
On Fri, Oct 2, 2015 at 12:09 PM, Steve Fink  wrote:
> I don't know, but I can speculate. It's not at all obvious how ...args in
> the middle should behave: what if you have two rest arguments? Is that
> forbidden, or is one greedy? What if one of the trailing parameters has a
> default value? Also, iiuc the spec treats "undefined" the same as
> "nonexistent" in most places. So what should your function do when passed
> (1, 2, 3, undefined)?
>
> In short, it seems like a hairball of complexity for no real gain.

Yes, this has been discussed in the past, and issues like what you
brought up are the reason we've rejected it.  There's lots of
ambiguous situations, no clear answer for most (any?) of them, and the
benefit is minimal.

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


Re: rest parameters

2015-10-02 Thread Tab Atkins Jr.
On Fri, Oct 2, 2015 at 3:00 PM, Michaël Rouges  wrote:
> For the undefined case, it isn't unexistent...
>
> ```JavaScript
> void function () {
>  console.log(arguments.length); // 3
> }(1, 2, undefined);
> ```
>
> Then, I don't see how it may be ambiguous...

Again, this has been discussed in the past.  It would be useful for
you to look it up in the archives and find the previous discussion.

A few examples of the ambiguity:

function f1(...a, b, c) {print arguments}
f1(1) // ([], 1, undefined) or ([], undefined, 1) ?

function f2(...a, b="default") {print arguments}
f2(1) // ([], 1) or ([1], "default") ?

function f3(a, b, ...c, d, e) {print arguments)
f3(1,2,3) // (1, 2, [], 3, undefined) or (1, 2, [], undefined, 3) or
(1, undefined, [], 2, 3) or something else?

With the rest param limited to being at the end, it's clear how to
answer questions similar to these - you just assign arguments
normally, and then if there are any left over, they get packed up in
the rest param.

When arguments can follow the rest param, it's not clear how to do it.
You can't just ignore the rest param, assign args, and then take the
leftovers, because the rest param needs to take from the middle.
You're clearly grabbing from "each end" and then if there's any left
in the middle, you pack them into the rest param, but how to do so?
That's the essence of the f1 and f3 ambiguities.  And optional
arguments (f2) are similarly difficult - should they "grab" more
strongly than the rest param?

You can come up with answers to these questions.  What you can't do is
come up with answers that are *obviously correct*.  This is why I'm
not aware of any language that allows this syntax.

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


Re: Alternative to Promise

2015-09-30 Thread Tab Atkins Jr.
On Tue, Sep 29, 2015 at 10:51 PM, 韩冬  wrote:
> ES6 Promise is great,  i just want to share my thoughts on dealing with
> callback hell issue with a different approach here.
> I’m been try to port ConT monad from haskell to javascript these days, after
> some work, i believe we can have a much simpler alternative to Promise, read
> this introduction to my approach please:
>
> http://winterland1989.github.io/Action.js/
>
> I’m not saying it’s better than Promise, but it’s much simpler and easier
> IMO, any peer are welcomed!

Promises already exist and are implemented in most browsers already.
They won't be replaced; anything which hopes to occupy a similar niche
needs to justify how it is sufficiently useful to be worth having two
similar-but-not-identical things in the standard library.  There's
always going to be decisions that could have been made slightly
differently, and which would make things more convenient for
particular use-cases, but that doesn't, by itself, justify the cost of
adding to the standard library.

Likely anything new will want to fit into the General Theory of
Reactivity .

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


Re: Alternative to Promise

2015-09-30 Thread Tab Atkins Jr.
On Wed, Sep 30, 2015 at 5:18 PM, 韩冬  wrote:
> Yes, i understand it’s too late to revise Promise design, my random thought 
> are:
>
> 1. Why we put Promise into language?

Because it exposes useful functionality.  I recommend reading some of
the Promise explainers that exist for lots of examples.

> Promise are complex state machine, there can be so many variations, each 
> implementation have different performance characteristic, which one should be 
> built into language?

There's only one variation that's standard, and every browser is or
will soon be implementing that one.

The "state machine" isn't complex.  "unresolved" goes to either
"resolved to another promise", "fulfilled", or "rejected".  "resolved
to another promise" eventually turns into "fulfilled" or "rejected".
Or, of course, hangs, which "unresolved" can also do.

> 2. Why we don’t look for continuation based implementation at the first place?

Continuations are a different concept, and don't address what we were
trying to solve when adopting promises.

> Lisp, haskell or even some transpiled to js language like elm use 
> continuation solve callbacks already, why didn’t port them?
> Now we invent a complex state machine based solution, a lot of people will 
> creating them everytime using an `async` without understand the cost.

Those languages often also have Promises, or Futures, or Tasks, or one
of the other closely-related names and concepts.

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


Re: Alternative to Promise

2015-09-30 Thread Tab Atkins Jr.
On Wed, Sep 30, 2015 at 5:46 PM, 韩冬  wrote:
> Now take a look at even a very simple Promise library Q form its design 
> document: https://github.com/kriskowal/q/blob/v1/design/q7.js
>
>> The "state machine" isn't complex.  "unresolved" goes to either
>> "resolved to another promise", "fulfilled", or "rejected".  "resolved
>> to another promise" eventually turns into "fulfilled" or "rejected".
>> Or, of course, hangs, which "unresolved" can also do.
>
> With all these state transition added, it’s quiet complex to me to figure out 
> how does it work, i have to go back and read the design process from 1 to 7.
> Should we expect future js programmers just use it, or understand it before 
> use it?

If you think what I said above, in your quote, is complex, then I
really can't help you.

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


  1   2   3   4   5   6   >