Re: try/catch/else
>> On Thu, Feb 8, 2018 at 10:13 AM, Claude Pache>> wrote: >>> >>> What about the following pattern (labelled block + break)? >>> >>> ```js >>> processSuggestions: { >>> let suggestions; >>> try { >>> suggestions = await fetchSuggestions(); >>> } catch (e) { >>> alert('Failed to load suggestions'); >>> break processSuggestions; >>> } >>> showSuggestions(suggestions); >>> } >>> ``` I don't mean to hijack this tread. I'm mostly curious why you opt or even suggest for that over putting it in a function and an early return? Like; ``` function processSuggestions() { let suggestions try { suggestions = await fetchSuggestions(); } catch (e) { return alert('Failed to load suggestions'); } showSuggestions(suggestions); } ``` This is almost identical, especially the way the example was written. I understand the differences, I don't think they're a problem for by far most cases where you'd want this. That said I wouldn't mind seeing try/catch/else/finally because the pattern(s) above still leads to awkward code in the real world. One could bikeshed on how "else" implies the attempt ("try") to have failed rather than succeeded. On the other hand making it try/then/catch/finally is also going to be confusing so whatever :) - peter ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: try/catch/else
I honestly wish engines (read: V8) didn't jave so much issue optimizing that. But yes, it's a very useful pattern. On Thu, Feb 8, 2018, 14:35 Mark Millerwrote: > Hi Claude, that's nice. Whenever I faced this issue I always turned to the > boolean flag variable. But this is strictly better. I expect to use it from > now on. Thanks! > > > On Thu, Feb 8, 2018 at 10:13 AM, Claude Pache > wrote: > >> What about the following pattern (labelled block + break)? >> >> ```js >> processSuggestions: { >> let suggestions; >> try { >> suggestions = await fetchSuggestions(); >> } catch (e) { >> alert('Failed to load suggestions'); >> break processSuggestions; >> } >> showSuggestions(suggestions); >> } >> ``` >> >> —Claude >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > > > -- > Cheers, > --MarkM > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: try/catch/else
Hi Claude, that's nice. Whenever I faced this issue I always turned to the boolean flag variable. But this is strictly better. I expect to use it from now on. Thanks! On Thu, Feb 8, 2018 at 10:13 AM, Claude Pachewrote: > What about the following pattern (labelled block + break)? > > ```js > processSuggestions: { > let suggestions; > try { > suggestions = await fetchSuggestions(); > } catch (e) { > alert('Failed to load suggestions'); > break processSuggestions; > } > showSuggestions(suggestions); > } > ``` > > —Claude > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Suggestion: Infix operators/functions
Time to put infix operators into TypeScript, first, then? On Sat, 3 Feb 2018 at 04:25, kdexwrote: > People in the C++ community have been using overloaded operators since the > 1980's, and I wouldn't say that different semantics for the same operator > have > been a bad idea at all, given that the operator handles completely > different > types (that can and should be statically analyzable). > > I wouldn't even think that these features are abused in the C++ community: > Think vector/matrix operations, for instance. Very expressive stuff. > > Depending on the application, it could be nicer for Array + Array to become > Array(Array, Array) rather than Array(...Array, ...Array). Depends on your > use > case. As for function composition, it's a matter of preference if A + B is > supposed to mean (...args) => A(B(...args)) or rather (...args) => > B(A(...args)). > > My point is, as long as there is a statically analyzable definition for how > operators are supposed to behave for a given set of input types, there's no > reason not to give programmers the ability to provide such definitions. > > But again, these discussions will be much more relevant if proposals such > as > [this one](https://github.com/sirisian/ecmascript-types) are discussed for > standardization at some point. > > On Saturday, February 3, 2018 4:57:34 AM CET Naveen Chawla wrote: > > I don't like the idea of custom operators only because of readability of > > code - it can be different for different pieces of code, and so I think > it > > is a larger surface area for bugs, so I think it would be a net negative. > > > > However, I do like the idea of allowing e.g. `+` to be used intuitively > and > > consistently (i.e. with a fixed meaning) between certain data types that > > are not currently supported, e.g.: > > > > Array + Array (array concatenation) > > Function + Function (function composition) > > > > On Fri, 2 Feb 2018 at 22:02 Michael Haufe > wrote: > > > How would operator precedence work? Would we be restricted to > 2-argument > > > functions only? > > > > > > On Fri, Feb 2, 2018 at 5:55 AM, Thomas Grainger > wrote: > > >> I'm porting this from the TypeScript issue tracker, original from: > > >> https://github.com/Microsoft/TypeScript/issues/2319#issue-60851953 > > >> > > >> Since it's very unlikely that the extension methods will ever be > > >> implemented [in a call-site-rewrite > > >> manner]( > > >> > https://github.com/Microsoft/TypeScript/issues/9#issuecomment-74302592), > > >> please consider adding infix operators to enable writing in functional > > >> style similarly to what can be done in Haskell: > > >> > > >> Monoids > > >> > > >> ```js > > >> > > >> function '+' (left, right) { > > >> > > >>return left.concat(right); > > >> > > >> } > > >> > > >> [1, 2, 3] '+' [4, 5]; // [1, 2, 3, 4, 5] > > >> > > >> ``` > > >> > > >> Monads > > >> > > >> ```js > > >> > > >> function '>>=' (promise, bind) { > > >> > > >>return promise.then(bind); > > >> > > >> } > > >> $.get('/get') '>>=' x => $.post('/save', x + 1) > > >> > > >> ``` > > >> > > >> Functors > > >> > > >> ```js > > >> > > >> function '.' (inner, outer) { > > >> > > >>return function(value: a) : c { > > >> > > >> return outer(inner(value)) > > >> > > >>} > > >> > > >> } > > >> > > >> function f(x) { } > > >> function g(y) { } > > >> (f '.' g)(x); // z > > >> > > >> ``` > > >> > > >> > > >> > > >> Thomas Grainger > > >> > > >> ___ > > >> 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: try/catch/else
What about the following pattern (labelled block + break)? ```js processSuggestions: { let suggestions; try { suggestions = await fetchSuggestions(); } catch (e) { alert('Failed to load suggestions'); break processSuggestions; } showSuggestions(suggestions); } ``` —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: try/catch/else
Sounds good in principle but I think the name is misleading. Actually try/catch/else is the synchronous equivalent of tryFn().then(elseFn, catchFn) but then has other implications (it returns a new promise and the then method actually takes two functions). Calling it then would imply it's equivalent to tryFn().then(thenFn).catch(catchFn) which is actually just the same as the first example, not the try/catch/else. I also think having the else after the catch makes the intention clearer (just like finally comes after catch and else). On Thu, Feb 8, 2018, at 4:20 PM, Michael Luder-Rosefield wrote: > Well, since promise.then(/**blah**/).catch(/**blah**/) is already a > thing, why not stick with that?> > try { > // blah > } then(val) { > // blah > } catch { > // blah > } finally { > // blah > } > > I added `val` to the then since we might want to pass something from > `try` to it, just as promises do. Best way to do that might be for > `try` to act as an expression block and implicitly return the last > thing in it.> > On Thu, 8 Feb 2018 at 14:50 Alan Plumwrote: >> __ >> Hi everyone, >> >> I'm hoping this is the right medium to ask this but I would like to >> propose a language feature called try/catch/else.>> >> Conditional try/catch seems to be all the rage right now but in many >> cases the problem it really wants to solve seems to be code like the >> following:>> >> try { >> const suggestions = await fetchSuggestions(); >> showSuggestions(suggestions); >> } catch (e) { >> alert('Failed to load suggestions'); >> // Oops, we also swallow errors from showSuggestions >> } >> // now do something else >> >> Having a more fine-grained catch wouldn't necessarily help here >> because both functions might throw the same kind of error but what >> we're really interested in is discerning the *source* of the error. >> So instead some people resort to something like this:>> >> let suggestions; >> try { >> suggestions = await fetchSuggestions(); >> } catch (e) { >> alert('Failed to load suggestions'); >> return; >> } >> showSuggestions(suggestions); >> // now do something else - unless we failed to load >> >> Note how we're forced to add a return to explicitly abort the control >> flow. Unlike the change from const to let this isn't something an IDE >> would point out while refactoring, so this actually introduces >> potential for bugs. If we don't actually want to bail out completely >> this often leads to noisy status booleans (e.g. didNotThrow) or error- >> prone checks (e.g. !suggestions is a bug if the async function really >> didn't return anything).>> >> I'm not sure about other languages but Python has a solution for this >> by adding an else clause:>> >> let suggestions; >> try { >> suggestions = await fetchSuggestions(); >> } catch (e) { >> alert('Failed to load suggestions'); >> } else { >> showSuggestions(suggestions); >> } >> // now do something else >> >> The semantics are pretty straightforward: if the try block did not >> throw, the else block is executed next (before the finally block if >> any). If the try block does throw, the else block is ignored (like a >> conditional catch that doesn't match).>> >> I realise there is some ambiguity in using the else keyword for this >> (though I can't think of a meaningful opposite of "catch" either). >> There is also some overlap with conditional try/catch but I think >> this language feature is useful even if conditional try/catch exists.>> >> >> Cheers, >> >> Alan Plum >> ___ >> 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: try/catch/else
Well, since promise.then(/**blah**/).catch(/**blah**/) is already a thing, why not stick with that? try { // blah } then(val) { // blah } catch { // blah } finally { // blah } I added `val` to the then since we might want to pass something from `try` to it, just as promises do. Best way to do that might be for `try` to act as an expression block and implicitly return the last thing in it. On Thu, 8 Feb 2018 at 14:50 Alan Plumwrote: > Hi everyone, > > I'm hoping this is the right medium to ask this but I would like to > propose a language feature called try/catch/else. > > Conditional try/catch seems to be all the rage right now but in many cases > the problem it really wants to solve seems to be code like the following: > > try { > const suggestions = await fetchSuggestions(); > showSuggestions(suggestions); > } catch (e) { > alert('Failed to load suggestions'); > // Oops, we also swallow errors from showSuggestions > } > // now do something else > > Having a more fine-grained catch wouldn't necessarily help here because > both functions might throw the same kind of error but what we're really > interested in is discerning the *source* of the error. So instead some > people resort to something like this: > > let suggestions; > try { > suggestions = await fetchSuggestions(); > } catch (e) { > alert('Failed to load suggestions'); > return; > } > showSuggestions(suggestions); > // now do something else - unless we failed to load > > Note how we're forced to add a return to explicitly abort the control > flow. Unlike the change from const to let this isn't something an IDE would > point out while refactoring, so this actually introduces potential for > bugs. If we don't actually want to bail out completely this often leads to > noisy status booleans (e.g. didNotThrow) or error-prone checks (e.g. > !suggestions is a bug if the async function really didn't return > anything). > > I'm not sure about other languages but Python has a solution for this by > adding an else clause: > > let suggestions; > try { > suggestions = await fetchSuggestions(); > } catch (e) { > alert('Failed to load suggestions'); > } else { > showSuggestions(suggestions); > } > // now do something else > > The semantics are pretty straightforward: if the try block did not throw, > the else block is executed next (before the finally block if any). If the > try block does throw, the else block is ignored (like a conditional catch > that doesn't match). > > I realise there is some ambiguity in using the else keyword for this > (though I can't think of a meaningful opposite of "catch" either). There is > also some overlap with conditional try/catch but I think this language > feature is useful even if conditional try/catch exists. > > > Cheers, > > Alan Plum > ___ > 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
try/catch/else
Hi everyone, I'm hoping this is the right medium to ask this but I would like to propose a language feature called try/catch/else. Conditional try/catch seems to be all the rage right now but in many cases the problem it really wants to solve seems to be code like the following: try { const suggestions = await fetchSuggestions(); showSuggestions(suggestions); } catch (e) { alert('Failed to load suggestions'); // Oops, we also swallow errors from showSuggestions } // now do something else Having a more fine-grained catch wouldn't necessarily help here because both functions might throw the same kind of error but what we're really interested in is discerning the *source* of the error. So instead some people resort to something like this: let suggestions; try { suggestions = await fetchSuggestions(); } catch (e) { alert('Failed to load suggestions'); return; } showSuggestions(suggestions); // now do something else - unless we failed to load Note how we're forced to add a return to explicitly abort the control flow. Unlike the change from const to let this isn't something an IDE would point out while refactoring, so this actually introduces potential for bugs. If we don't actually want to bail out completely this often leads to noisy status booleans (e.g. didNotThrow) or error-prone checks (e.g. !suggestions is a bug if the async function really didn't return anything). I'm not sure about other languages but Python has a solution for this by adding an else clause: let suggestions; try { suggestions = await fetchSuggestions(); } catch (e) { alert('Failed to load suggestions'); } else { showSuggestions(suggestions); } // now do something else The semantics are pretty straightforward: if the try block did not throw, the else block is executed next (before the finally block if any). If the try block does throw, the else block is ignored (like a conditional catch that doesn't match). I realise there is some ambiguity in using the else keyword for this (though I can't think of a meaningful opposite of "catch" either). There is also some overlap with conditional try/catch but I think this language feature is useful even if conditional try/catch exists. Cheers, Alan Plum ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Suggestion: Destructuring object initializer.
It does make one stop and wonder why the group will endlessly entertain trolls debating whether or not ES6 (or ES5) portends the end of civilization as we know it, while relentlessly ignoring literally dozens of similar/identical proposals for property picking, a feature which easily contributes as much to the language at as little cost as many other features such as spread properties. Bob On Thu, Feb 8, 2018 at 4:15 PM, Bob Myerswrote: > This extremely useful feature, which is sometimes called "picking", has > been discussed extensively on the group, but the "thought leaders" (?) who > apparently have the ability to kill a feature by saying "I don't really > think it's that important" have failed to get excited about it, although it > seems to me to be at least as "interesting" (in terms of the unwritten > criteria apparently applied to determine "interesting") as many other > features which are progressing through the ES39 life-cycle, and the nature > of the TC39 governance process, which gives entirely new meaning to the > notion of "design by committee", makes it impossible to find the champion > which is the gating factor for the entire process. > > Bob > > On Thu, Feb 8, 2018 at 3:15 PM, Yeong-u Kim wrote: > >> # Suggestion: Destructuring object initializer. >> >> -- >> >> Destructuring assignment: it extracts values by destructuring an object, >> and assign _them_ to ‘variables.’ I suggest Destructuring object >> initialization syntax; it is similar to Destructuring assignment, except >> that it initializes an object with _the extracted values_. >> >> ```javascript >> const name_info = {"first name": "Yeong-u", "last name": "Kim", nickname: >> "K."}; >> const e = "computed property name"; >> >> const object = { >> name: { >> *{"first name": forename, "last name": surname}: name_info >> }, >> *[a, b, c]: [1, 2, 3], >> *[d]: [4], >> [e]: "This is not part of the syntax" >> *[{"some property name": "new one"}]: [{"some property name": 5}], >> *{gettable: something}: {get gettable() {return Symbol("Using [[Get]]");}} >> }; >> /* >> { >> name: { >> forename: "Yeong-u", >> surname: "Kim" >> }, >> a: 1, >> b: 2, >> c: 3, >> d: 4, >> "computed property name": "This is not part of the syntax", >> "new one": 5, >> something: Symbol(Using [[Get]]) >> } >> */ >> ``` >> >> -- >> >> I would appreciate hearing your opinion on this. >> >> >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Suggestion: a chainable in-place alternative of `Array.prototype.map`.
Already discussed (at the end there's an Array.prototype.each idea that's the same): https://esdiscuss.org/topic/return-value-of-foreach On Thu, 8 Feb 2018 at 14:17 Yeong-u Kimwrote: > # Suggestion: a chainable in-place alternative of `Array.prototype.map`. > > > > -- > > > > I personally do make massive use of `Array.prototype.map` whenever I code > in ECMAScript. However, it often leaves an array waiting for garbage > collection (which makes unnecessary memory use and burdens the garbage > collector) when you no longer need the original array values. In order to > avoid it, you may do this in-place with `Array.prototype.forEach` instead. > But the problem is that it is not chainable unlike `Array.prototype.fill`. > > > > ```javascript > > /// To get ["#apple", "#banana", "#cabbage"] > > > > const tag = name => ('#' + name); > > > > if("Try #1") > > { > > ["apple", "banana", "cabbage"].forEach((n, i, a) => { > > a[i] = tag(n); > > }); // It is not chainable -- returns nothing but `undefined`. > > } > > > > if("Try #2") > > { > > // So we need to declare a variable holds the array in this scope. > > const array = ["apple", "banana", "cabbage"]; > > array.forEach((n, i) => { > > array[i] = tag(n); > > }); // We cannot feed it `tag` directly. > > const result = array; > > } > > > > if("Try #3") > > { > > const result = ["apple", "banana", "cabbage"].map(tag); > > // It looks neat, but does not make use of the existing memory and leaves > ‘garbage.’ > > } > > > > if("Suggestion") > > { > > const result = ["apple", "banana", "cabbage"].update(tag); > > // The array values are modified (updated) by `tag` in-place, > > // and it returns the updated array -- it's chainable. > > } > > ``` > > > > So I suggest `Array.prototype.update` and `TypedArray.prototype.update`. > It is similar to `Array.prototype.map` except for its in-place > modification. It is also similar to `Array.prototype.fill`. > > > > ```javascript > > Array.prototype.update(function callback(currentValue[, index[, array]]) > {..}[, thisArg]) > > ``` > > > > | | fill | map > | update | > > > |-|::|:---:|:--:| > > | Chainable | Yes | Yes > | Yes | > > | In-place modification (a side effect on the original array) | Yes | No > | Yes | > > | Returns a reference to the input (original) array. | Yes | No > | Yes | > > | Ignores holes (empty elements). | No | Yes > | Yes | > > | Makes use of the input (original) array values. | No | Yes > | Yes | > > > > > > How do you think about this suggestion? > > ___ > 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: Suggestion: Destructuring object initializer.
This extremely useful feature, which is sometimes called "picking", has been discussed extensively on the group, but the "thought leaders" (?) who apparently have the ability to kill a feature by saying "I don't really think it's that important" have failed to get excited about it, although it seems to me to be at least as "interesting" (in terms of the unwritten criteria apparently applied to determine "interesting") as many other features which are progressing through the ES39 life-cycle, and the nature of the TC39 governance process, which gives entirely new meaning to the notion of "design by committee", makes it impossible to find the champion which is the gating factor for the entire process. Bob On Thu, Feb 8, 2018 at 3:15 PM, Yeong-u Kimwrote: > # Suggestion: Destructuring object initializer. > > -- > > Destructuring assignment: it extracts values by destructuring an object, > and assign _them_ to ‘variables.’ I suggest Destructuring object > initialization syntax; it is similar to Destructuring assignment, except > that it initializes an object with _the extracted values_. > > ```javascript > const name_info = {"first name": "Yeong-u", "last name": "Kim", nickname: > "K."}; > const e = "computed property name"; > > const object = { > name: { > *{"first name": forename, "last name": surname}: name_info > }, > *[a, b, c]: [1, 2, 3], > *[d]: [4], > [e]: "This is not part of the syntax" > *[{"some property name": "new one"}]: [{"some property name": 5}], > *{gettable: something}: {get gettable() {return Symbol("Using [[Get]]");}} > }; > /* > { > name: { > forename: "Yeong-u", > surname: "Kim" > }, > a: 1, > b: 2, > c: 3, > d: 4, > "computed property name": "This is not part of the syntax", > "new one": 5, > something: Symbol(Using [[Get]]) > } > */ > ``` > > -- > > I would appreciate hearing your opinion on this. > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Suggestion: Destructuring object initializer.
# Suggestion: Destructuring object initializer. -- Destructuring assignment: it extracts values by destructuring an object, and assign _them_ to ‘variables.’ I suggest Destructuring object initialization syntax; it is similar to Destructuring assignment, except that it initializes an object with _the extracted values_. ```javascriptconst name_info = {"first name": "Yeong-u", "last name": "Kim", nickname: "K."};const e = "computed property name"; const object = {name: { *{"first name": forename, "last name": surname}: name_info }, *[a, b, c]: [1, 2, 3], *[d]: [4], [e]: "This is not part of the syntax" *[{"some property name": "new one"}]: [{"some property name": 5}], *{gettable: something}: {get gettable() {return Symbol("Using [[Get]]");}}};/* { name: { forename: "Yeong-u",surname: "Kim" }, a: 1, b: 2, c: 3, d: 4, "computed property name": "This is not part of the syntax", "new one": 5, something: Symbol(Using [[Get]])}*/``` -- I would appreciate hearing your opinion on this. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Suggestion: a chainable in-place alternative of `Array.prototype.map`.
# Suggestion: a chainable in-place alternative of `Array.prototype.map`. -- I personally do make massive use of `Array.prototype.map` whenever I code in ECMAScript. However, it often leaves an array waiting for garbage collection (which makes unnecessary memory use and burdens the garbage collector) when you no longer need the original array values. In order to avoid it, you may do this in-place with `Array.prototype.forEach` instead. But the problem is that it is not chainable unlike `Array.prototype.fill`. ```javascript /// To get ["#apple", "#banana", "#cabbage"] const tag = name = ('#' + name); if("Try #1") { ["apple", "banana", "cabbage"].forEach((n, i, a) = { a[i] = tag(n); }); // It is not chainable -- returns nothing but `undefined`. } if("Try #2") { // So we need to declare a variable holds the array in this scope. const array = ["apple", "banana", "cabbage"]; array.forEach((n, i) = { array[i] = tag(n); }); // We cannot feed it `tag` directly. const result = array; } if("Try #3") { const result = ["apple", "banana", "cabbage"].map(tag); // It looks neat, but does not make use of the existing memory and leaves ‘garbage.’ } if("Suggestion") { const result = ["apple", "banana", "cabbage"].update(tag); // The array values are modified (updated) by `tag` in-place, // and it returns the updated array -- it's chainable. } ``` So I suggest `Array.prototype.update` and `TypedArray.prototype.update`. It is similar to `Array.prototype.map` except for its in-place modification. It is also similar to `Array.prototype.fill`. ```javascript Array.prototype.update(function callback(currentValue[, index[, array]]) {..}[, thisArg]) ``` | | fill | map | update | |-|::|:---:|:--:| | Chainable | Yes | Yes | Yes | | In-place modification (a side effect on the original array) | Yes | No | Yes | | Returns a reference to the input (original) array. | Yes | No | Yes | | Ignores holes (empty elements). | No | Yes | Yes | | Makes use of the input (original) array values. | No | Yes | Yes | How do you think about this suggestion? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss