Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #21093 > unrolled thread

Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split()

Started bybrettz9@gmail.com
First post2013-08-28 19:09 -0700
Last post2013-09-01 15:06 +0200
Articles 4 — 3 participants

Back to article view | Back to comp.lang.javascript


Contents

  Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split() brettz9@gmail.com - 2013-08-28 19:09 -0700
    Re: Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split() Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-08-29 10:42 +0200
      Re: Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split() Brett Zamir <brettz9@gmail.com> - 2013-08-31 19:37 -0700
        Proposal for Array.prototype.join() and String.prototype.split() (was: Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split()) Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-09-01 15:06 +0200

#21093 — Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split()

Frombrettz9@gmail.com
Date2013-08-28 19:09 -0700
SubjectProposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split()
Message-ID<563b9f80-1d04-4a54-b581-2e6c2a057833@googlegroups.com>
Per https://gist.github.com/brettz9/6373468 (live at http://brett-zamir.me/tests/proposal-join-split.html ), I have come across a need periodically to do joins and use the same glue surrounding the join. I think it would be handy if one could do:

    ['a', 'b', 'c'].join('|', true); // '|a|b|c|'

Similarly, with split, one may not require the first and last elements of the resulting array, so a corresponding ability to easily strip the first and last elements in the resulting array could also be added.

    '|a|b|c|'.split('|', undefined, true).join(',') // a,b,c

[toc] | [next] | [standalone]


#21094

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-08-29 10:42 +0200
Message-ID<1780396.7rZ4NEZdN2@PointedEars.de>
In reply to#21093
brettz9@gmail.com wrote:

> Per https://gist.github.com/brettz9/6373468 (live at
> http://brett-zamir.me/tests/proposal-join-split.html ), I have come across
> a need periodically to do joins and use the same glue surrounding the
> join. I think it would be handy if one could do:
> 
>     ['a', 'b', 'c'].join('|', true); // '|a|b|c|'

The prevalent opinion appears to be that boolean arguments to determine the 
behavior of a function are not a good idea, summarized in “A (highly 
cohesive) function should do one thing and one thing only.” and GNU's “one 
tool for one purpose”.

<http://programmers.stackexchange.com/questions/147977/is-it-wrong-to-use-a-boolean-parameter-to-determine-behavior>

I, too, have my share of making this mistake.  The more you want to modify 
the behavior of a function, the more you come you tend to come to the 
conclusion that a single options argument of the Object type is the better 
approach.  And there comes a point when you want to write a new function for 
the new behavior instead because you cannot keep the order of the arguments 
in mind.  [My experience shows that functions/methods taking more than a 
handful (5) *positional* arguments (where order matters) are hard to use 
because of that, sometimes even more than 3.]

There is no good reason why one could not write

  "|" + ["a", "b", "c"].join("|") + "|"

instead, using the standard Array.prototype.join() method.  Or, if you are 
concerned about DRY,

  var delim = "|";
  delim + ["a", "b", "c"].join(delim) + delim
 
> Similarly, with split, one may not require the first and last elements of
> the resulting array, so a corresponding ability to easily strip the first
> and last elements in the resulting array could also be added.
> 
>     '|a|b|c|'.split('|', undefined, true).join(',') // a,b,c

Please explain the meaning of the second and third argument passed to your 
proposed modification of the standard String.prototype.split() method.

The same result can be achieved with

  "|a|b|c|".slice(1, -1).split("|")

or

  "|a|b|c|".split("|").slice(1, -1)

so again I do not see the advantage of your proposal here.

[.join(",") is optional if the value of this expression is used in string 
context, as split() returns a reference to an Array instance whose inherited 
toString() method does what .join(",") does.]

I am going to respond to your RegExp.prototype.forEach() suggestion later 
this week.

In general, please

- take your suggestions for the next Edition of ECMAScript to the ES Discuss
  mailing list instead; a so-called “strawman” document may be the outcome:

    <http://wiki.ecmascript.org/doku.php?id=strawman:strawman>

  ECMAScript implementations being dynamic languages, we all have extended
  built-in objects one way or the other before for syntactic sugar.  It is
  not necessarily a good thing to make your use-cases the standard for
  everyone.  The people most likely to give you a proper review with regard
  to that are reading that mailing list.  You want to keep some
  recommendations in mind when doing this:

    <http://wiki.ecmascript.org/doku.php?id=harmony:harmony>

  Also, be aware that the way you are doing it now, the new or changed
  properties are enumerable (show up in for-in iteration), and you cannot
  prevent this from happening in implementations of ES Editions earlier
  than 5 (see Object.defineProperty()).

- post using your real name (you may include your nickname for recognition)

- avoid posting to Usenet using the borken, spammed Google Groups.  Use a
  locally installed newsreader application instead, like KNode, SeaMonkey,
  or Thunderbird.

- always post the minimum of the relevant code *here*.  While a Web
  reference is useful, this is _not_ the Web, and you cannot assume
  people going to your Web site, looking up your code there.

<http://jibbering.com/faq/#posting>
<http://PointedEars.de/faq#posting>

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#21136

FromBrett Zamir <brettz9@gmail.com>
Date2013-08-31 19:37 -0700
Message-ID<45644598-181c-47d4-8ba4-d768f4633a4b@googlegroups.com>
In reply to#21094
On Thursday, August 29, 2013 4:42:06 PM UTC+8, Thomas 'PointedEars' Lahn wrote:
> brettz9@gmail.com wrote:
> 
> 
> 
> > Per https://gist.github.com/brettz9/6373468 (live at
> 
> > http://brett-zamir.me/tests/proposal-join-split.html ), I have come across
> 
> > a need periodically to do joins and use the same glue surrounding the
> 
> > join. I think it would be handy if one could do:
> 
> > 
> 
> >     ['a', 'b', 'c'].join('|', true); // '|a|b|c|'
> 
> 
> 
> The prevalent opinion appears to be that boolean arguments to determine the 
> 
> behavior of a function are not a good idea, summarized in “A (highly 
> 
> cohesive) function should do one thing and one thing only.” and GNU's “one 
> 
> tool for one purpose”.
> 
> 
> 
> <http://programmers.stackexchange.com/questions/147977/is-it-wrong-to-use-a-boolean-parameter-to-determine-behavior>

I tend to agree with the responses favoring practicality though I can understand the desire to take into account popular preferences. But I think when used judiciously, boolean args can be tasteful (e.g., the deep cloning of domNode.cloneNode(true) is not a burden on memory to remember once the method is studied even if it is admittedly not immediately apparently what the boolean means to a complete novice).

> I, too, have my share of making this mistake.  The more you want to modify 
> 
> the behavior of a function, the more you come you tend to come to the 
> 
> conclusion that a single options argument of the Object type is the better 
> 
> approach.  And there comes a point when you want to write a new function for 
> 
> the new behavior instead because you cannot keep the order of the arguments 
> 
> in mind.  [My experience shows that functions/methods taking more than a 
> 
> handful (5) *positional* arguments (where order matters) are hard to use 
> 
> because of that, sometimes even more than 3.]

Agreed.

> There is no good reason why one could not write
> 
> 
> 
>   "|" + ["a", "b", "c"].join("|") + "|"
> 
> 
> 
> instead, using the standard Array.prototype.join() method.  Or, if you are 
> 
> concerned about DRY,

Yes...

> 
>   var delim = "|";
> 
>   delim + ["a", "b", "c"].join(delim) + delim

Yes, I know it can be done this way; but I happen to be a fan of "magic" to provide (readable) terseness and I appreciate the "magic" which has been added to the language along the way also. I don't think that there are likely to be other join-related behaviors that one would wish to add to join()*, so I don't think positional arguments would likely lead to bloat for the future.

*Actually, I can see one other mod to join() that would be useful, though not adding arguments: if join() were to accept a callback for its first argument, I think that would quite helpful since it would further reduce the overhead of "reduce()" when reducing to a string--a fairly common use case I have run into (though the next example is admittedly contrived):

',' + ['a', 'b', 'c'].join(function (item) { // Maybe "prev" could be an (optional) second argument
  return ',' + item.toUpperCase();
}); // ,A,B,C

...as opposed to the DRY-violating:

['a', 'b', 'c'].reduce(function (prev, item) {
  return prev + ',' + item.toUpperCase();
}, ''); // ,A,B,C

My recurring use cases have tended to be within template code where I want to build a string inline in as terse and implementation-detail-free a manner as possible.

> > Similarly, with split, one may not require the first and last elements of
> 
> > the resulting array, so a corresponding ability to easily strip the first
> 
> > and last elements in the resulting array could also be added.
> 
> > 
> 
> >     '|a|b|c|'.split('|', undefined, true).join(',') // a,b,c
> 
> 
> 
> Please explain the meaning of the second and third argument passed to your 
> 
> proposed modification of the standard String.prototype.split() method.

The second argument is the standard second argument, "limit". The third argument is the counter-part to the proposed join() boolean: optionally drop the outer matches (in this case, "|" at the very beginning and very end).

> The same result can be achieved with
> 
> 
> 
>   "|a|b|c|".slice(1, -1).split("|")
> 
> 
> 
> or
> 
> 
> 
>   "|a|b|c|".split("|").slice(1, -1)

I don't like those options for two reasons:

1. I really believe in helping developers avoid implementation details. It is arguably less error prone, it is easier for beginners to grasp, and it makes code easier for veteran programmers to quickly digest as well. Of course, it is not practical to standardize with declarative expressions for every possible need out there, but at least for common cases, it would be helpful.

2. If it were a regular expression returning values of potentially differing lengths, your approach would not work.

> [.join(",") is optional if the value of this expression is used in string 
> 
> context, as split() returns a reference to an Array instance whose inherited 
> 
> toString() method does what .join(",") does.]

Sure. I just wanted to be clear that the expected type was still an array.

> In general, please
> 
> 
> 
> - take your suggestions for the next Edition of ECMAScript to the ES Discuss
> 
>   mailing list instead; a so-called “strawman” document may be the outcome:
> 
> 
> 
>     <http://wiki.ecmascript.org/doku.php?id=strawman:strawman>

Ok, thank you for this and your other recommendations/references.


>   Also, be aware that the way you are doing it now, the new or changed
> 
>   properties are enumerable (show up in for-in iteration), and you cannot
> 
>   prevent this from happening in implementations of ES Editions earlier
> 
>   than 5 (see Object.defineProperty()).

Did you mean to include this or was this just a part of boilerplate? In my code here, I have only redefined existing methods.

> - post using your real name (you may include your nickname for recognition)

Ok, done.

> - avoid posting to Usenet using the borken, spammed Google Groups.  Use a
> 
>   locally installed newsreader application instead, like KNode, SeaMonkey,
> 
>   or Thunderbird.

Is this a strict requirement due to some bad output generated by Google Groups or merely general advice to the user? I don't want to be forced to download a bunch of messages of no interest to me, adding unnecessarily to web traffic for everyone, nor do I wish to wait until I get replies to disable my subscription (and repeat these steps every time I may come around again to make a new post), etc. Your FAQ also links to Google Groups, btw.

> - always post the minimum of the relevant code *here*.  While a Web
> 
>   reference is useful, this is _not_ the Web, and you cannot assume
> 
>   people going to your Web site, looking up your code there.

In this case, there was no need to follow the link, as that was only for extra information or if of interest, with the main thrust being about the proposed API rather than an implementation. I presume we don't need to post any library we may reference unless the code is under discussion. I get the idea though at least for other cases.

Best wishes,
Brett

[toc] | [prev] | [next] | [standalone]


#21137 — Proposal for Array.prototype.join() and String.prototype.split() (was: Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split())

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-09-01 15:06 +0200
SubjectProposal for Array.prototype.join() and String.prototype.split() (was: Proposal for encapsulator boolean 2nd arg for Array.prototype.join() and innerOnly boolean 3rd option for split())
Message-ID<4354949.izIPKcei6W@PointedEars.de>
In reply to#21136
Brett Zamir wrote:

[Fixed quotations]

> […] Thomas 'PointedEars' Lahn wrote:
>> brettz9@gmail.com wrote:
> 
> ',' + ['a', 'b', 'c'].join(function (item) { // Maybe "prev" could be an
> (optional) second argument
>   return ',' + item.toUpperCase();
> }); // ,A,B,C
> 
> ...as opposed to the DRY-violating:
> 
> ['a', 'b', 'c'].reduce(function (prev, item) {
>   return prev + ',' + item.toUpperCase();
> }, ''); // ,A,B,C

  ["", "a", "b", "c"].map(function (item) {
    return item.toUpperCase();
  }).join(",")

or simply

  String(["", "a", "b", "c"]).toUpperCase()

are equivalent.  And again I do not see the use-case.

(JFYI: It is customary to use double-quotes as string delimiter unless 
apostrophes are required or better readable.  They stand out more.)
 
> My recurring use cases have tended to be within template code where I want
> to build a string inline in as terse and implementation-detail-free a
> manner as possible.

In that case I suggest to use a template implementation instead.  I am 
working on one myself, based on Python’s.
 
>> > Similarly, with split, one may not require the first and last elements
>> > of the resulting array, so a corresponding ability to easily strip the
>> > first and last elements in the resulting array could also be added.
>> > 
>> >     '|a|b|c|'.split('|', undefined, true).join(',') // a,b,c
>> 
>> Please explain the meaning of the second and third argument passed to
>> your proposed modification of the standard String.prototype.split()
>> method.
> 
> The second argument is the standard second argument, "limit". The third
> argument is the counter-part to the proposed join() boolean: optionally
> drop the outer matches (in this case, "|" at the very beginning and very
> end).

Probably since I never had a need for it, I was not *consciously* aware of 
the second parameter of String.prototype.split(), which has been introduced 
with ECMAScript Edition 3 (I would assume few people are).  However 
fortunately, the ECMAScript Support Matrix already has the corresponding 
test case, and according to the results that feature can be considered safe.
 
>> The same result can be achieved with
>> 
>>   "|a|b|c|".slice(1, -1).split("|")
>> 
>> or
>> 
>>   "|a|b|c|".split("|").slice(1, -1)
> 
> I don't like those options for two reasons:
> 
> 1. I really believe in helping developers avoid implementation details. It
> is arguably less error prone, it is easier for beginners to grasp, and it
> makes code easier for veteran programmers to quickly digest as well. Of
> course, it is not practical to standardize with declarative expressions
> for every possible need out there, but at least for common cases, it would
> be helpful.

I do not agree with your assessment at all.  New, mostly untested, code is 
more error-prone than old, proved code.  To-be-JIT-compiled user code is 
less efficient than vendors’ precompiled machine code.  Beginners should 
learn the basics, not merely learn how to use a particular library, and they 
should not have to work around its quirks.  Veteran developers are 
accustomed to quickly writing code the standard way, and will be even slower 
to accept other ways than beginners.

That said, I do have written libraries myself (JSX in particular), but I 
have written them mostly on an as-needed basis to simplify decision 
branches, or streamline development across implementation released in 
different times; and as a tool for teaching.  Not merely for syntactic 
sugar.

> 2. If it were a regular expression returning values of potentially
> differing lengths, your approach would not work.

The first variant would not; the second one would, because 
String.prototype.split() can take a regular expression as argument:

  /* ["a", "b", "c"]
  "||||a|||b||c|".split(/\|+/).slice(1, -1)

(since ES 3; now in ES 5.1, §15.5.4.14)

> Ok, thank you for this and your other recommendations/references.

You are welcome.  Also, keep your Subject header field value short as it 
will likely be trimmed for display.  This applies to all electronic 
discussion media.  Note my change of Subject here (the “(was:” part is to be 
removed on replies).
 
>>   Also, be aware that the way you are doing it now, the new or changed
>>   properties are enumerable (show up in for-in iteration), and you cannot
>>   prevent this from happening in implementations of ES Editions earlier
>>   than 5 (see Object.defineProperty()).
> 
> Did you mean to include this or was this just a part of boilerplate?

I mean you should use Object.defineProperty() if available, unless you want 
those properties to be enumerable.  (Now that ES 5.x is reasonably stable, 
it is on my to-do list as well.  One problem to solve is that JScript is 
FUBAR in that regard; you can augment host objects, but not native objects, 
this way.)

> In my code here, I have only redefined existing methods.

That does not matter.  Not all implementations will keep the internal 
[[DontEnum]] or [[Enumerable]] attribute value when you assign a new value 
to a built-in property.
 
>> - avoid posting to Usenet using the borken, spammed Google Groups.  Use a
>>   locally installed newsreader application instead, like KNode,
>>   SeaMonkey, or Thunderbird.
> 
> Is this a strict requirement due to some bad output generated by Google
> Groups or merely general advice to the user?

It is a strong recommendation due to a lot of inappropriate output generated 
by Google Groups (particularly: often full quotes because quotations are 
collapsed only in the Web interface, and the user is not [made] aware of 
that; lines of astronomical lengths due to lack of automatic line break, and 
quotations with interleaved empty lines), and due to it being the source of 
a lot, if not most, of the spam (because the spam filters at Google Groups 
only *hide* the spam *at Google Groups*, they never delete the spam, and 
apparently they could not care less about complaints about spammers).

I for one will think twice before I reply to a posting injected via Google 
Groups.  In fact, usually I filter out all those postings, so I do not read 
them in the first place.

> I don't want to be forced to download a bunch of messages of no interest
> to me,

A newsreader will only download the messages that you select, in the 
newsgroups you subscribed to.  At first it will only download the header of 
the messages of the newsgroups you have subscribed to (but this is 
customizable depending on the application).

> adding unnecessarily to web traffic for everyone,

Again, this is _Usenet_; it is neither the Web, nor necessarily the 
Internet.  You are using a (buggy) interface to Usenet, on the Web which in 
turn runs on top of the Internet infrastructure.

> nor do I wish to wait until I get replies to disable my subscription

A newsgroup subscription in Usenet is not like a mailing list subscription.  
It is merely a choice you make which newsgroups are listed at computer.  
(Google Grooups has muddled the difference there as well.)

> (and repeat these steps every time I may come around again to make a new
> post),

A newsreader will keep a newsgroup in the list of newsgroups you have 
subscribed to until you unsubscribe from it.  RTFM.

> etc. Your FAQ also links to Google Groups, btw.

It is not exactly *my* FAQ (although I have made a few adjustments to the 
original due to the latter being unmaintained), and it has linked and is 
linking to Google Groups as a newsgroup *archive*.  [I can only hope that
you cannot find any endorsement of using Google Groups there (given the 
previous maintainer's predilection for Google Groups, that is a distinct 
possibility).]

>> - always post the minimum of the relevant code *here*.  While a Web
>>   reference is useful, this is _not_ the Web, and you cannot assume
>>   people going to your Web site, looking up your code there.
> 
> In this case, there was no need to follow the link,

Yes, there was.

> […] with the main thrust being about the proposed API rather than an
> implementation.

The API leads to the implementation.  What good is a good API if the 
implementation it leads to is FUBAR?

> I presume we don't need to post any library we may reference unless the
> code is under discussion.

Because one wants to avoid people having to switch media, posting the 
relevant code is prudent, unless its size exceeds certain limits.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web