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


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

Understanding &&

Started byAndrew Poulos <ap_prog@hotmail.com>
First post2021-04-16 14:30 +1000
Last post2021-04-19 23:13 +0100
Articles 20 on this page of 44 — 7 participants

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


Contents

  Understanding && Andrew Poulos <ap_prog@hotmail.com> - 2021-04-16 14:30 +1000
    Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-16 11:00 +0100
    Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-16 11:17 +0000
      Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-16 16:09 +0100
        Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-16 15:26 +0000
          Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-16 21:09 +0100
            Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-16 21:06 +0000
              Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-17 02:01 +0100
                Re: Understanding && The Natural Philosopher <tnp@invalid.invalid> - 2021-04-17 08:33 +0100
                Re: Understanding && John G Harris <niam@jghnorth.org.uk.invalid> - 2021-04-17 12:06 +0100
                  Re: Understanding && The Natural Philosopher <tnp@invalid.invalid> - 2021-04-17 14:13 +0100
                  Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-17 15:50 +0100
                Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-17 15:21 +0000
                  Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-17 23:46 +0100
                    Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-17 23:46 +0000
                      Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-18 23:59 +0100
                        Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-19 13:56 +0000
                          Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-19 23:08 +0100
                            Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-19 22:52 +0000
                              Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-20 01:23 +0100
                                Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-20 01:08 +0000
                Re: Understanding && Arno Welzel <usenet@arnowelzel.de> - 2021-04-18 00:49 +0200
                  Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-18 17:26 +0100
            Re: Understanding && Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-04-17 17:05 +0200
              Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-17 23:04 +0100
                Re: Understanding && Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-04-18 00:48 +0200
                  Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-18 17:13 +0100
                    Re: Understanding && Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-04-19 21:58 +0200
              Re: Understanding && John G Harris <niam@jghnorth.org.uk.invalid> - 2021-04-18 18:20 +0100
            Re: Understanding && Arno Welzel <usenet@arnowelzel.de> - 2021-04-18 00:40 +0200
              Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-18 00:14 +0100
                Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-18 00:01 +0000
                  Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-18 17:44 +0100
                    Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-18 17:51 +0000
                Re: Understanding && Arno Welzel <usenet@arnowelzel.de> - 2021-04-19 13:41 +0200
                  Re: Understanding && John G Harris <niam@jghnorth.org.uk.invalid> - 2021-04-19 15:02 +0100
                    Re: Understanding && The Natural Philosopher <tnp@invalid.invalid> - 2021-04-20 17:40 +0100
                      Re: Understanding && John G Harris <niam@jghnorth.org.uk.invalid> - 2021-04-20 18:19 +0100
                        Re: Understanding && The Natural Philosopher <tnp@invalid.invalid> - 2021-04-21 10:11 +0100
                          Re: Understanding && John G Harris <niam@jghnorth.org.uk.invalid> - 2021-04-21 19:46 +0100
                            Re: Understanding && The Natural Philosopher <tnp@invalid.invalid> - 2021-04-22 13:48 +0100
                  Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-19 21:28 +0100
                    Re: Understanding && Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-04-19 21:56 +0000
                      Re: Understanding && Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-04-19 23:13 +0100

Page 1 of 3  [1] 2 3  Next page →


#39949 — Understanding &&

FromAndrew Poulos <ap_prog@hotmail.com>
Date2021-04-16 14:30 +1000
SubjectUnderstanding &&
Message-ID<U_CdnQWSXulHj-T9nZ2dnUU7-evNnZ2d@westnet.com.au>
I've been looking at moveable.js
<https://daybrush.com/moveable/release/latest/doc/index.html>
when I noticed this (fragment of) code:

on("resize", ({ target, width, height, dist, delta, clientX, clientY }) => {
   delta[0] && (target.style.width = `${width}px`);
})

I don't understand what the double ampersand in
   delta[0] && (target.style.width = `${width}px`);
is doing.

Does it mean that if delta[0] is falsey then the width of target is set? 
That is
if (!delta[0]) target.style.width = `${width}px`;
?

Andrew Poulos

[toc] | [next] | [standalone]


#39950

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-16 11:00 +0100
Message-ID<878s5ift1o.fsf@bsb.me.uk>
In reply to#39949
Andrew Poulos <ap_prog@hotmail.com> writes:

> I've been looking at moveable.js
> <https://daybrush.com/moveable/release/latest/doc/index.html>
> when I noticed this (fragment of) code:
>
> on("resize", ({ target, width, height, dist, delta, clientX, clientY }) => {
>   delta[0] && (target.style.width = `${width}px`);
> })
>
> I don't understand what the double ampersand in
>   delta[0] && (target.style.width = `${width}px`);
> is doing.
>
> Does it mean that if delta[0] is falsey then the width of target is
> set? That is if (!delta[0]) target.style.width = `${width}px`; ?

It's the other way round.  In x && y, only if x is "truthy" must y be
evaluated.  When x is false, the whole expression must be false and the
language guarantees that the right-hand operand won't be evaluated.

The same (with the appropriate switch between truth and falsehood) is
true for ||.  There is also the much newer ?? operator that evaluates
and returns the right-hand operand only when the left operand is
null or undefined (sometimes called "nullish").

Such operators are often said to have "short circuit" evaluation.

-- 
Ben.

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


#39951

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-16 11:17 +0000
Message-ID<slrns7ishn.4j8.jon+usenet@raven.unequivocal.eu>
In reply to#39949
On 2021-04-16, Andrew Poulos <ap_prog@hotmail.com> wrote:
> I've been looking at moveable.js
><https://daybrush.com/moveable/release/latest/doc/index.html>
> when I noticed this (fragment of) code:
>
> on("resize", ({ target, width, height, dist, delta, clientX, clientY }) => {
>    delta[0] && (target.style.width = `${width}px`);
> })
>
> I don't understand what the double ampersand in
>    delta[0] && (target.style.width = `${width}px`);
> is doing.
>
> Does it mean that if delta[0] is falsey then the width of target is set? 
> That is
> if (!delta[0]) target.style.width = `${width}px`;
> ?

"a && b" evaluates "a", and if it is a value that is considered "false"
returns that value, otherwise it evaluates and returns "b". So if "a"
is false, "b" is never looked at at all. So the execution flow is
equivalent to:

  if (a) b

(Note also that assignments such as "b = c" are considered an
expression - whose value is "c".)

You most often see this sort of thing in JavaScript that was
automatically generated by a compiler (either because the original
source was in something else like TypeScript or a more modern version
of JavaScript or because the author wanted to compress/minify the
script), but human beings are also quite capable of writing hard-to-read
code like this.

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


#39952

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-16 16:09 +0100
Message-ID<87wnt2e06e.fsf@bsb.me.uk>
In reply to#39951
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> You most often see this sort of thing in JavaScript that was
> automatically generated by a compiler (either because the original
> source was in something else like TypeScript or a more modern version
> of JavaScript or because the author wanted to compress/minify the
> script), but human beings are also quite capable of writing hard-to-read
> code like this.

Is that specifically when the right-hand operand is an assignment
expression?  I don't find that hard to read but then I'm used to
assignment being and expression so it seems like a natural extension of
the more frequently seen uses of &&.

-- 
Ben.

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


#39953

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-16 15:26 +0000
Message-ID<slrns7jb5v.4j8.jon+usenet@raven.unequivocal.eu>
In reply to#39952
On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>> You most often see this sort of thing in JavaScript that was
>> automatically generated by a compiler (either because the original
>> source was in something else like TypeScript or a more modern version
>> of JavaScript or because the author wanted to compress/minify the
>> script), but human beings are also quite capable of writing hard-to-read
>> code like this.
>
> Is that specifically when the right-hand operand is an assignment
> expression?  I don't find that hard to read but then I'm used to
> assignment being and expression so it seems like a natural extension of
> the more frequently seen uses of &&.

I mean where it's an expression being abused as a control flow mechanism.

The example here:

  delta[0] && (target.style.width = `${width}px`);

is harder to read than, and isn't even shorter than:

  if (delta[0]) target.style.width = `${width}px`;

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


#39954

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-16 21:09 +0100
Message-ID<87mttydm95.fsf@bsb.me.uk>
In reply to#39953
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>> You most often see this sort of thing in JavaScript that was
>>> automatically generated by a compiler (either because the original
>>> source was in something else like TypeScript or a more modern version
>>> of JavaScript or because the author wanted to compress/minify the
>>> script), but human beings are also quite capable of writing hard-to-read
>>> code like this.
>>
>> Is that specifically when the right-hand operand is an assignment
>> expression?  I don't find that hard to read but then I'm used to
>> assignment being and expression so it seems like a natural extension of
>> the more frequently seen uses of &&.
>
> I mean where it's an expression being abused as a control flow
> mechanism.

If readability is not the problem I'm not sure what constitutes abuse.
Is it just a rule of yours to keep these two things entirely separate?
Maybe some uses are acceptable and don't constitute abuse?  Is any
reliance on short-circuit evaluation in an expression an abuse?  If so,
does that extend to '??' and '?.'?  (That's not easy to make clear in
typing but I hope you know what I mean.)

I only suggested that assignment might be where it crosses the line for
you because I think that's where the line is for a lot of people, but it
sounds like go further than that.

I go the other way.  Statements (most of them at least) are just wasted
expression opportunities.  It's less noticeable in ECMAScript, than in
many other languages, but it still bugs me every now and then.

-- 
Ben.

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


#39955

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-16 21:06 +0000
Message-ID<slrns7jv2m.4j8.jon+usenet@raven.unequivocal.eu>
In reply to#39954
On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>> On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>>> You most often see this sort of thing in JavaScript that was
>>>> automatically generated by a compiler (either because the original
>>>> source was in something else like TypeScript or a more modern version
>>>> of JavaScript or because the author wanted to compress/minify the
>>>> script), but human beings are also quite capable of writing hard-to-read
>>>> code like this.
>>>
>>> Is that specifically when the right-hand operand is an assignment
>>> expression?  I don't find that hard to read but then I'm used to
>>> assignment being and expression so it seems like a natural extension of
>>> the more frequently seen uses of &&.
>>
>> I mean where it's an expression being abused as a control flow
>> mechanism.
>
> If readability is not the problem I'm not sure what constitutes abuse.

You snipped the next lines of my post where I said that readability
*is* the problem.

> Is it just a rule of yours to keep these two things entirely separate?

It's not a rule of mine, it seems to be a rule of almost everyone.

> Maybe some uses are acceptable and don't constitute abuse?  Is any
> reliance on short-circuit evaluation in an expression an abuse?

No, of course not. I think it's "abuse" because it's written to look
like an expression but it isn't, really - we don't care about its
result, we only care about its side-effects.

Having said that, you might have a case where you did something like
this:

  a = b && (c = d)

and that would probably be even worse!

> I only suggested that assignment might be where it crosses the line for
> you because I think that's where the line is for a lot of people, but it
> sounds like go further than that.

Maybe it is there. Fundamentally the issue is that if you're going to
sacrifice readability, you'd better be getting something good in return. 
In the case we're talking about some readability has been sacrificed and
we've gained absolutely nothing in return - the code isn't shorter, or
neater, and it doesn't run faster.

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


#39956

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-17 02:01 +0100
Message-ID<87o8edd8qk.fsf@bsb.me.uk>
In reply to#39955
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>> On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>>>> You most often see this sort of thing in JavaScript that was
>>>>> automatically generated by a compiler (either because the original
>>>>> source was in something else like TypeScript or a more modern version
>>>>> of JavaScript or because the author wanted to compress/minify the
>>>>> script), but human beings are also quite capable of writing hard-to-read
>>>>> code like this.
>>>>
>>>> Is that specifically when the right-hand operand is an assignment
>>>> expression?  I don't find that hard to read but then I'm used to
>>>> assignment being and expression so it seems like a natural extension of
>>>> the more frequently seen uses of &&.
>>>
>>> I mean where it's an expression being abused as a control flow
>>> mechanism.
>>
>> If readability is not the problem I'm not sure what constitutes abuse.
>
> You snipped the next lines of my post where I said that readability
> *is* the problem.

Oh, sorry.  The fact that you didn't address my questions about
readability made me think you were now making a broader point.  If you
don't mind, can say if the problems you have with its readability is
down to there being an assignment on the right, or is it with any use of
&& that relies on the short-circuit evaluation.

>> Is it just a rule of yours to keep these two things entirely separate?
>
> It's not a rule of mine, it seems to be a rule of almost everyone.

The trouble is that a non-trivial number of languages have this form,
and I've seen it used quite widely.  But maybe most of the uses don't
rise to your standard of abuse.  I've not come across the rule, but then
it's a long time since I worked anywhere that had rules about
programming.

>> Maybe some uses are acceptable and don't constitute abuse?  Is any
>> reliance on short-circuit evaluation in an expression an abuse?
>
> No, of course not. I think it's "abuse" because it's written to look
> like an expression but it isn't, really - we don't care about its
> result, we only care about its side-effects.

Ah, right.  So the abuse (as you see it) is not exactly the control flow
but using it to control side-effects.

I've seen (and, dare I say, written) code that uses the result.  I
wonder if that absolves the programmer from the charge of abuse:

  return (data = parse_input(file_name))
      && (result = transform(data))
      && write_file(file_name);

<cut>
>> I only suggested that assignment might be where it crosses the line for
>> you because I think that's where the line is for a lot of people, but it
>> sounds like go further than that.
>
> Maybe it is there. Fundamentally the issue is that if you're going to
> sacrifice readability, you'd better be getting something good in return. 
> In the case we're talking about some readability has been sacrificed and
> we've gained absolutely nothing in return - the code isn't shorter, or
> neater, and it doesn't run faster.

I don't have any problem with the readability, in general.  Obviously
you can make unreadable examples, but I not a fan of rules than ban
something because of the potential for abuse.

-- 
Ben.

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


#39957

FromThe Natural Philosopher <tnp@invalid.invalid>
Date2021-04-17 08:33 +0100
Message-ID<s5e30a$2i0$1@dont-email.me>
In reply to#39956
On 17/04/2021 02:01, Ben Bacarisse wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
> 
>> On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>>> On 2021-04-16, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>>>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>>>>> You most often see this sort of thing in JavaScript that was
>>>>>> automatically generated by a compiler (either because the original
>>>>>> source was in something else like TypeScript or a more modern version
>>>>>> of JavaScript or because the author wanted to compress/minify the
>>>>>> script), but human beings are also quite capable of writing hard-to-read
>>>>>> code like this.
>>>>>
>>>>> Is that specifically when the right-hand operand is an assignment
>>>>> expression?  I don't find that hard to read but then I'm used to
>>>>> assignment being and expression so it seems like a natural extension of
>>>>> the more frequently seen uses of &&.
>>>>
>>>> I mean where it's an expression being abused as a control flow
>>>> mechanism.
>>>
>>> If readability is not the problem I'm not sure what constitutes abuse.
>>
>> You snipped the next lines of my post where I said that readability
>> *is* the problem.
> 
> Oh, sorry.  The fact that you didn't address my questions about
> readability made me think you were now making a broader point.  If you
> don't mind, can say if the problems you have with its readability is
> down to there being an assignment on the right, or is it with any use of
> && that relies on the short-circuit evaluation.
> 
>>> Is it just a rule of yours to keep these two things entirely separate?
>>
>> It's not a rule of mine, it seems to be a rule of almost everyone.
> 
> The trouble is that a non-trivial number of languages have this form,
> and I've seen it used quite widely.  But maybe most of the uses don't
> rise to your standard of abuse.  I've not come across the rule, but then
> it's a long time since I worked anywhere that had rules about
> programming.
> 
>>> Maybe some uses are acceptable and don't constitute abuse?  Is any
>>> reliance on short-circuit evaluation in an expression an abuse?
>>
>> No, of course not. I think it's "abuse" because it's written to look
>> like an expression but it isn't, really - we don't care about its
>> result, we only care about its side-effects.
> 
> Ah, right.  So the abuse (as you see it) is not exactly the control flow
> but using it to control side-effects.
> 
> I've seen (and, dare I say, written) code that uses the result.  I
> wonder if that absolves the programmer from the charge of abuse:
> 
>    return (data = parse_input(file_name))
>        && (result = transform(data))
>        && write_file(file_name);
> 
> <cut>
>>> I only suggested that assignment might be where it crosses the line for
>>> you because I think that's where the line is for a lot of people, but it
>>> sounds like go further than that.
>>
>> Maybe it is there. Fundamentally the issue is that if you're going to
>> sacrifice readability, you'd better be getting something good in return.
>> In the case we're talking about some readability has been sacrificed and
>> we've gained absolutely nothing in return - the code isn't shorter, or
>> neater, and it doesn't run faster.
> 
> I don't have any problem with the readability, in general.  Obviously
> you can make unreadable examples, but I not a fan of rules than ban
> something because of the potential for abuse.
> 
U=I can even say why I dont like it.

It mixes up logical comparison with program flow in a single operator.
IF... THEN separates them in an easily read way.
and given modern compiler smarts, terse unintelligible code (like 
rexgexps) simply is unnecessary

-- 
You can get much farther with a kind word and a gun than you can with a 
kind word alone.

Al Capone

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


#39958

FromJohn G Harris <niam@jghnorth.org.uk.invalid>
Date2021-04-17 12:06 +0100
Message-ID<u4gl7gls4sbkvh232rarcd04qr8n7cck43@4ax.com>
In reply to#39956
On Sat, 17 Apr 2021 02:01:55 +0100, Ben Bacarisse
<ben.usenet@bsb.me.uk> wrote:

  <snip>
>If you
>don't mind, can say if the problems you have with its readability is
>down to there being an assignment on the right, or is it with any use of
>&& that relies on the short-circuit evaluation.
  <snip>

Two ways of writing it imply different purposes :

  if A is true then Do B
where the emphasis is on Doing.

  if A is true then it's safe to Evaluate B
where the emphasis is on Evaluating.

When the code is being read in a panic, looking for a bug, it's better
for the purpose to be made as clear as possible.

  John

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


#39959

FromThe Natural Philosopher <tnp@invalid.invalid>
Date2021-04-17 14:13 +0100
Message-ID<s5emua$4h3$1@dont-email.me>
In reply to#39958
On 17/04/2021 12:06, John G Harris wrote:
> On Sat, 17 Apr 2021 02:01:55 +0100, Ben Bacarisse
> <ben.usenet@bsb.me.uk> wrote:
> 
>    <snip>
>> If you
>> don't mind, can say if the problems you have with its readability is
>> down to there being an assignment on the right, or is it with any use of
>> && that relies on the short-circuit evaluation.
>    <snip>
> 
> Two ways of writing it imply different purposes :
> 
>    if A is true then Do B
> where the emphasis is on Doing.
> 
>    if A is true then it's safe to Evaluate B
> where the emphasis is on Evaluating.
> 
> When the code is being read in a panic, looking for a bug, it's better
> for the purpose to be made as clear as possible.
> 
>    John
> 
Exactly.

You can write code to impress other people with, or to be as instantly 
clear to anyone reading it as it is possible to get it.

if A then
x=Y
ELSE
X=Z
is a lot easier to follow than

X=A? Y:Z

for beginner programmers.

as to whether any professional programmer would blink an eye at it 
though is moot.

Again breaking code into functional blocks - subroutines - even though 
they are only called once, is good for readability, and 'inline' is your 
friend, in C...

...dont suppose it exists in JavaScript, maybe doesn't need to.

-- 
When plunder becomes a way of life for a group of men in a society, over 
the course of time they create for themselves a legal system that 
authorizes it and a moral code that glorifies it.

  Frédéric Bastiat

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


#39960

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-17 15:50 +0100
Message-ID<87y2dharsu.fsf@bsb.me.uk>
In reply to#39958
John G Harris <niam@jghnorth.org.uk.invalid> writes:

> On Sat, 17 Apr 2021 02:01:55 +0100, Ben Bacarisse
> <ben.usenet@bsb.me.uk> wrote:
>
>   <snip>
>>If you
>>don't mind, can say if the problems you have with its readability is
>>down to there being an assignment on the right, or is it with any use of
>>&& that relies on the short-circuit evaluation.
>   <snip>
>
> Two ways of writing it imply different purposes :
>
>   if A is true then Do B
> where the emphasis is on Doing.
>
>   if A is true then it's safe to Evaluate B
> where the emphasis is on Evaluating.

Thanks.  I don't find the "do" vs "evaluate" so clear cut, but I get
that you want to keep them separate.  The two get mixed up because
sometimes we want both.  And functions that do things and return values
make sense (to me) on either side of &&.

-- 
Ben.

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


#39962

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-17 15:21 +0000
Message-ID<slrns7lv7n.6lk.jon+usenet@raven.unequivocal.eu>
In reply to#39956
On 2021-04-17, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>> It's not a rule of mine, it seems to be a rule of almost everyone.
>
> The trouble is that a non-trivial number of languages have this form,
> and I've seen it used quite widely.  But maybe most of the uses don't
> rise to your standard of abuse.  I've not come across the rule, but then
> it's a long time since I worked anywhere that had rules about
> programming.

I don't mean as a rule that's written down, I mean as in 99% of
programmers do not write code that looks like this. I don't consciously
have it as a "rule" either except inasmuch as it is a consequence of
"readability matters".

>> No, of course not. I think it's "abuse" because it's written to look
>> like an expression but it isn't, really - we don't care about its
>> result, we only care about its side-effects.
>
> Ah, right.  So the abuse (as you see it) is not exactly the control flow
> but using it to control side-effects.
>
> I've seen (and, dare I say, written) code that uses the result.  I
> wonder if that absolves the programmer from the charge of abuse:
>
>   return (data = parse_input(file_name))
>       && (result = transform(data))
>       && write_file(file_name);

Unlike the original, that's bad enough that I would outright reject it
in a code review.

>> Maybe it is there. Fundamentally the issue is that if you're going to
>> sacrifice readability, you'd better be getting something good in return. 
>> In the case we're talking about some readability has been sacrificed and
>> we've gained absolutely nothing in return - the code isn't shorter, or
>> neater, and it doesn't run faster.
>
> I don't have any problem with the readability, in general.  Obviously
> you can make unreadable examples, but I not a fan of rules than ban
> something because of the potential for abuse.

I haven't suggested anything like that, in fact I explicitly said right
there that what matters is the code quality overall.

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


#39969

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-17 23:46 +0100
Message-ID<87zgxwa5sg.fsf@bsb.me.uk>
In reply to#39962
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> On 2021-04-17, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>> It's not a rule of mine, it seems to be a rule of almost everyone.
>>
>> The trouble is that a non-trivial number of languages have this form,
>> and I've seen it used quite widely.  But maybe most of the uses don't
>> rise to your standard of abuse.  I've not come across the rule, but then
>> it's a long time since I worked anywhere that had rules about
>> programming.
>
> I don't mean as a rule that's written down, I mean as in 99% of
> programmers do not write code that looks like this. I don't consciously
> have it as a "rule" either except inasmuch as it is a consequence of
> "readability matters".

I read too much into some very strong words.

>>> No, of course not. I think it's "abuse" because it's written to look
>>> like an expression but it isn't, really - we don't care about its
>>> result, we only care about its side-effects.
>>
>> Ah, right.  So the abuse (as you see it) is not exactly the control flow
>> but using it to control side-effects.
>>
>> I've seen (and, dare I say, written) code that uses the result.  I
>> wonder if that absolves the programmer from the charge of abuse:
>>
>>   return (data = parse_input(file_name))
>>       && (result = transform(data))
>>       && write_file(file_name);
>
> Unlike the original, that's bad enough that I would outright reject it
> in a code review.

Interesting view.  Thanks.

>>> Maybe it is there. Fundamentally the issue is that if you're going to
>>> sacrifice readability, you'd better be getting something good in return. 
>>> In the case we're talking about some readability has been sacrificed and
>>> we've gained absolutely nothing in return - the code isn't shorter, or
>>> neater, and it doesn't run faster.
>>
>> I don't have any problem with the readability, in general.  Obviously
>> you can make unreadable examples, but I not a fan of rules than ban
>> something because of the potential for abuse.
>
> I haven't suggested anything like that, in fact I explicitly said right
> there that what matters is the code quality overall.

Your view is much more moderate than I thought it was from some of the
words used, but I did get that you were making balanced judgement.  When
I said I don't have a problem with the readability I was suggesting that
nothing is last so there is no need for any balancing gain, but I think
you see readability through the eyes of the least skilled reader who
might have to look at the code.  I find that hard.  How low should one
go...

-- 
Ben.

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


#39973

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-17 23:46 +0000
Message-ID<slrns7msra.6lk.jon+usenet@raven.unequivocal.eu>
In reply to#39969
On 2021-04-17, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>> I don't mean as a rule that's written down, I mean as in 99% of
>> programmers do not write code that looks like this. I don't consciously
>> have it as a "rule" either except inasmuch as it is a consequence of
>> "readability matters".
>
> I read too much into some very strong words.

I did say "abuse", which can be a very strong word in some contexts but
isn't really in when talking about software programming. You introduced
the word "rule".

> Your view is much more moderate than I thought it was from some of the
> words used, but I did get that you were making balanced judgement.  When
> I said I don't have a problem with the readability I was suggesting that
> nothing is last so there is no need for any balancing gain, but I think
> you see readability through the eyes of the least skilled reader who
> might have to look at the code.  I find that hard.  How low should one
> go...

It depends on the context I suppose. Some companies hire expensive DBAs,
so that they can hire cheap programmers. Some companies don't.

I would expect a moderately competent programmer to know immediately
what's going on with something like "a && (b = c)" but at the same time
it would require more intellectual effort expended (I think, for most
people) to verify its correctness than "if (a) b = c", and the
complexity basically goes up exponentially the more branches you put
into the expression.

I use "JavaScript Standard Style", and so I must admit I am sometimes
tempted when I have something like:

  if (complex_expression) complex_conditional

and it doesn't fit on one line, to use:

  complex_expression &&
    complex_conditional

because the linter won't object to that, but it will object to:

  if (complex_expression)
    complex_conditional

but almost always I will end up using instead:

  if (complex_expression) {
    complex_conditional
  }

because it is probably easier for others to read ("others" perhaps
including me a year later...) And by "easier" I don't mean incompetent
programmers can't understand it, I just mean it will take most people
slightly longer to understand / have a slightly higher percentage chance
of being misunderstood.

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


#39980

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-18 23:59 +0100
Message-ID<87mttv42sv.fsf@bsb.me.uk>
In reply to#39973
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> On 2021-04-17, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>> I don't mean as a rule that's written down, I mean as in 99% of
>>> programmers do not write code that looks like this. I don't consciously
>>> have it as a "rule" either except inasmuch as it is a consequence of
>>> "readability matters".
>>
>> I read too much into some very strong words.
>
> I did say "abuse", which can be a very strong word in some contexts but
> isn't really in when talking about software programming. You introduced
> the word "rule".

Oh, please!  I /asked/ if it was a rule as far you were concerned, so,
yes, I typed the word first, but your reply was to claim it was an
almost universal rule.  That's the strong language!

>> Your view is much more moderate than I thought it was from some of the
>> words used, but I did get that you were making balanced judgement.  When
>> I said I don't have a problem with the readability I was suggesting that
>> nothing is last so there is no need for any balancing gain, but I think
>> you see readability through the eyes of the least skilled reader who
>> might have to look at the code.  I find that hard.  How low should one
>> go...
>
> It depends on the context I suppose. Some companies hire expensive DBAs,
> so that they can hire cheap programmers. Some companies don't.
>
> I would expect a moderately competent programmer to know immediately
> what's going on with something like "a && (b = c)" but at the same time
> it would require more intellectual effort expended (I think, for most
> people) to verify its correctness than "if (a) b = c",

Interesting.  I would not have thought so, but I have no data.  Code
verification seems to be a lost art these days so my main reaction is
delight that it's still considered important!

> and the
> complexity basically goes up exponentially the more branches you put
> into the expression.

Ack.   I'm sure that this is true.

> I use "JavaScript Standard Style", and so I must admit I am sometimes
> tempted when I have something like:
>
>   if (complex_expression) complex_conditional
>
> and it doesn't fit on one line, to use:
>
>   complex_expression &&
>     complex_conditional
>
> because the linter won't object to that, but it will object to:
>
>   if (complex_expression)
>     complex_conditional
>
> but almost always I will end up using instead:
>
>   if (complex_expression) {
>     complex_conditional
>   }
>
> because it is probably easier for others to read ("others" perhaps
> including me a year later...) And by "easier" I don't mean incompetent
> programmers can't understand it, I just mean it will take most people
> slightly longer to understand / have a slightly higher percentage chance
> of being misunderstood.

That's another interesting perspective.  When I look back on old code,
it's never things like this that take any time at all.  I often wish
there were a large block comment explaining the algorithm or method
being used, and sometimes I just wish for a comment explaining /why/
count is being set to i + j, but I never lose even a moment over /what/
the code is doing (in the sense of what the syntax means).

Another attraction of '&&' is that it chains in a natural way whereas
'if' nests.  Sometimes (as in the example of mine that you'd reject
immediately) you can negate the tests and use early returns to avoid the
nesting, but I don't like doiing either very much.  There are studies
that have shown that nesting is harder to follow that chaining.

-- 
Ben.

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


#39983

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-19 13:56 +0000
Message-ID<slrns7r30m.6lk.jon+usenet@raven.unequivocal.eu>
In reply to#39980
On 2021-04-18, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>> but almost always I will end up using instead:
>>
>>   if (complex_expression) {
>>     complex_conditional
>>   }
>>
>> because it is probably easier for others to read ("others" perhaps
>> including me a year later...) And by "easier" I don't mean incompetent
>> programmers can't understand it, I just mean it will take most people
>> slightly longer to understand / have a slightly higher percentage chance
>> of being misunderstood.
>
> That's another interesting perspective.  When I look back on old code,
> it's never things like this that take any time at all.  I often wish
> there were a large block comment explaining the algorithm or method
> being used, and sometimes I just wish for a comment explaining /why/
> count is being set to i + j, but I never lose even a moment over /what/
> the code is doing (in the sense of what the syntax means).

Here's a topical conundrum I have right now about readability...
I needed to implement CSS.escape, which node doesn't have built-in:

  https://drafts.csswg.org/cssom/#the-css.escape%28%29-method

Two implementations I have written are shown below. They both do exactly
the same thing. I'd say the first one is *much* more readable. But sadly
it's almost *five times* slower than the second one. So the dilemma is
which one to use...

As an aside, it turns out that (under V8 anyway) the following:

  for (const char of string) { ... }

is much slower than:

  for (let i = 0; i < string.length; i++) {
    const char = string[i]
    ...
  }

which is a bit disappointing given the former is much neater and appears
on the face of it that it should perform better. (And yes I know they
don't do exactly the same thing!)

CSS.escape functions:

  function escape1 (value) {
    const string = String(value)
    if (string === '-') return '\\-'
    return string.replace(/[^-_a-zA-Z\u0080-\uffff]/g, (char, offset) => {
      if (char === '\0') return '\ufffd'
      const digit = /[0-9]/.test(char)
      if (digit && (offset > 1 || !/^[0-9-]/.test(string))) return char
      if (char >= ' ' && char !== '\x7f' && !digit) return '\\' + char
      return '\\' + char.charCodeAt(0).toString(16) + ' '
    })
  }

  function escape2 (value) {
    const string = String(value)
    if (string === '-') return '\\-'
    let output = ''
    for (let offset = 0; offset < string.length; offset++) {
      let char = string[offset]
      if (char === '-' || char === '_' || (char >= 'a' && char <= 'z') ||
          (char >= 'A' && char <= 'Z') || char >= '\x80' ||
          ((char >= '0' && char <= '9') && (offset > 1 || (string[0] !== '-' &&
            (string[0] < '0' || string[0] > '9'))))) {
      } else if (char === '\0') {
        char = '\ufffd'
      } else if (char >= ' ' && char !== '\x7f' && (char < '0' || char > '9')) {
        char = '\\' + char
      } else {
        char = '\\' + char.charCodeAt(0).toString(16) + ' '
      }
      output += char
    }
    return output
  }

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


#39988

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-19 23:08 +0100
Message-ID<87lf9eyljq.fsf@bsb.me.uk>
In reply to#39983
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> On 2021-04-18, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>> but almost always I will end up using instead:
>>>
>>>   if (complex_expression) {
>>>     complex_conditional
>>>   }
>>>
>>> because it is probably easier for others to read ("others" perhaps
>>> including me a year later...) And by "easier" I don't mean incompetent
>>> programmers can't understand it, I just mean it will take most people
>>> slightly longer to understand / have a slightly higher percentage chance
>>> of being misunderstood.
>>
>> That's another interesting perspective.  When I look back on old code,
>> it's never things like this that take any time at all.  I often wish
>> there were a large block comment explaining the algorithm or method
>> being used, and sometimes I just wish for a comment explaining /why/
>> count is being set to i + j, but I never lose even a moment over /what/
>> the code is doing (in the sense of what the syntax means).
>
> Here's a topical conundrum I have right now about readability...
> I needed to implement CSS.escape, which node doesn't have built-in:
>
>   https://drafts.csswg.org/cssom/#the-css.escape%28%29-method
>
> Two implementations I have written are shown below. They both do exactly
> the same thing. I'd say the first one is *much* more readable. But sadly
> it's almost *five times* slower than the second one. So the dilemma is
> which one to use...

How important is the speed?  Five times almost nothing is almost
nothing, so one would have to know how much this code is used and how
slow the slow one is.

But it's an excellent example of what we've been talking about.  I found
your preferred version (the first one) quite hard to verify.  My
difficulty was not due to any language feature that you'd used but came
from the algorithm combining a negative character class and some
positive tests to implement a set of rules that are not written that
way.

> CSS.escape functions:
>
>   function escape1 (value) {
>     const string = String(value)
>     if (string === '-') return '\\-'
>     return string.replace(/[^-_a-zA-Z\u0080-\uffff]/g, (char, offset) => {
>       if (char === '\0') return '\ufffd'
>       const digit = /[0-9]/.test(char)
>       if (digit && (offset > 1 || !/^[0-9-]/.test(string))) return char
>       if (char >= ' ' && char !== '\x7f' && !digit) return '\\' + char
>       return '\\' + char.charCodeAt(0).toString(16) + ' '
>     })
>   }
>
>   function escape2 (value) {
>     const string = String(value)
>     if (string === '-') return '\\-'
>     let output = ''
>     for (let offset = 0; offset < string.length; offset++) {
>       let char = string[offset]
>       if (char === '-' || char === '_' || (char >= 'a' && char <= 'z') ||
>           (char >= 'A' && char <= 'Z') || char >= '\x80' ||
>           ((char >= '0' && char <= '9') && (offset > 1 || (string[0] !== '-' &&
>             (string[0] < '0' || string[0] > '9'))))) {
>       } else if (char === '\0') {
>         char = '\ufffd'
>       } else if (char >= ' ' && char !== '\x7f' && (char < '0' || char > '9')) {
>         char = '\\' + char
>       } else {
>         char = '\\' + char.charCodeAt(0).toString(16) + ' '
>       }
>       output += char
>     }
>     return output
>   }

For me, readability is about how easily can I see that the code is doing
the right thing, and given the specification:

https://drafts.csswg.org/cssom/#serialize-an-identifier

I would write something like this:

  function escape3 (value) {
      const string = String(value)
      return string.replace(/./g, (c, index) => {
          if (c === '\0')
              return '\ufffd'
          if (inRange(c, '\1', '\1f'))
              return escapedAsCodePoint(c)
          if (index === 0 && inRange(c, '0', '9'))
              return escapedAsCodePoint(c)
          if (index === 1 && inRange(c, '0', '9') && string[0] === '-')
              return escapedAsCodePoint(c)
          if (index === 0 && string.length === 1)
              return escaped(c)
          if (c >= '\u0080' || c === '-' || c === '_' ||
              inRange(c, '0', '9') ||
              inRange(c, 'A', 'Z') ||
              inRange(c, 'a', 'z'))
              return c;
          return escaped(c)
      })

      function inRange(c, low, high) {
          return c >= low && c <= high
      }
      function escaped(c) {
          return '\\' + c
      }
      function escapedAsCodePoint(c) {
          return '\\' + c.charCodeAt(0).toString(16) + ' '
      }
  }

and then I'd check to see if I really needed to complicate the tests
and/or pull out special cases to get a more speed.  By the way, the
replace(/./g) is not an important part of what I'm saying.  I used that
method to minimise the differences between our approaches.

When if comes the language features, I would probably write this:

  function escape4 (value) {
      const string = String(value)
      return string.replace(/./g, (c, index) => {
          return c === '\0'             ? '\ufffd'
               : inRange(c, '\1', '\1f') ? escapedAsCodePoint(c)
               : index === 0 &&
                 inRange(c, '0', '9')    ? escapedAsCodePoint(c)
               : index === 1 &&
                 inRange(c, '0', '9') &&
                 string[0] === '-'       ? escapedAsCodePoint(c)
               : index === 0 &&
                 string.length === 1     ? escaped(c)
               : c >= '\u0080' ||
                 c === '-'     ||
                 c === '_'     ||
                 inRange(c, '0', '9') ||
                 inRange(c, 'A', 'Z') ||
                 inRange(c, 'a', 'z')    ? c
               :                           escaped(c)
      })
   
      function inRange(c, low, high) {
          return c >= low && c <= high
      }
      function escaped(c) {
          return '\\' + c
      }
      function escapedAsCodePoint(c) {
          return '\\' + c.charCodeAt(0).toString(16) + ' '
      }
  }

but this is not really my point.  Readability goes much deeper than the
surface constructs.  It's about, as I think you said, how easy the code
is to verify, and that often means how closely it matches the
specification.

If this was hard-line production code, I think I'd include the seven
sentences from the specification as a comment.  That would go a long way
to explaining why the code is written as it is.

(I'm aware that posting code that has not had much testing is offering a
hostage to fortune.  But, if I've made a mistake, I hope my point will
be made by how easily you spot it!)

-- 
Ben.

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


#39990

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-04-19 22:52 +0000
Message-ID<slrns7s2du.6lk.jon+usenet@raven.unequivocal.eu>
In reply to#39988
On 2021-04-19, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>> Here's a topical conundrum I have right now about readability...
>> I needed to implement CSS.escape, which node doesn't have built-in:
>>
>>   https://drafts.csswg.org/cssom/#the-css.escape%28%29-method
>>
>> Two implementations I have written are shown below. They both do exactly
>> the same thing. I'd say the first one is *much* more readable. But sadly
>> it's almost *five times* slower than the second one. So the dilemma is
>> which one to use...
>
> How important is the speed?  Five times almost nothing is almost
> nothing, so one would have to know how much this code is used and how
> slow the slow one is.

Yes, to be fair I will probably go with the one I find more readable
(i.e. the one you find less readable ;-) ) because I can't imagine this
ending up actually taking any measurable amount of the whole program's
execution time. It just does hurt me slightly that it's so much less
efficient. I guess it must be the overhead of calling the anonymous
function.

> But it's an excellent example of what we've been talking about.  I found
> your preferred version (the first one) quite hard to verify.  My
> difficulty was not due to any language feature that you'd used but came
> from the algorithm combining a negative character class and some
> positive tests to implement a set of rules that are not written that
> way.
...
> For me, readability is about how easily can I see that the code is doing
> the right thing, and given the specification:
>
> https://drafts.csswg.org/cssom/#serialize-an-identifier
>
> I would write something like this:
...
> and then I'd check to see if I really needed to complicate the tests
> and/or pull out special cases to get a more speed.  By the way, the
> replace(/./g) is not an important part of what I'm saying.  I used that
> method to minimise the differences between our approaches.
>
> When if comes the language features, I would probably write this:
...
> but this is not really my point.  Readability goes much deeper than the
> surface constructs.  It's about, as I think you said, how easy the code
> is to verify, and that often means how closely it matches the
> specification.
>
> If this was hard-line production code, I think I'd include the seven
> sentences from the specification as a comment.  That would go a long way
> to explaining why the code is written as it is.

That's interesting, because there is an npm package which implements
the function (which I couldn't use for $reasons) and it's written
*exactly* as you describe.

You do of course have a point about following the spec, but to my mind
(and we're deviating considerably from the original topic here) it just
shows how this sort of "specification" is an absolute abomination. Many
of the modern web specifications are similar. They don't tell you what
things mean, they just give random algorithms and you have to work out
the meaning for yourself. They're basically the opposite of a
specification. I had to reverse-engineer the CSSOM spec in order to find
out what it actually meant, in order to write my implementation. If it
was an actual specification, what I just said would be nonsensical.

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


#39991

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-04-20 01:23 +0100
Message-ID<87mtttyfbg.fsf@bsb.me.uk>
In reply to#39990
Jon Ribbens <jon+usenet@unequivocal.eu> writes:

> On 2021-04-19, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Jon Ribbens <jon+usenet@unequivocal.eu> writes:
>>> Here's a topical conundrum I have right now about readability...
>>> I needed to implement CSS.escape, which node doesn't have built-in:
>>>
>>>   https://drafts.csswg.org/cssom/#the-css.escape%28%29-method
>>>
>>> Two implementations I have written are shown below. They both do exactly
>>> the same thing. I'd say the first one is *much* more readable. But sadly
>>> it's almost *five times* slower than the second one. So the dilemma is
>>> which one to use...
>>
>> How important is the speed?  Five times almost nothing is almost
>> nothing, so one would have to know how much this code is used and how
>> slow the slow one is.
>
> Yes, to be fair I will probably go with the one I find more readable
> (i.e. the one you find less readable ;-) ) because I can't imagine this
> ending up actually taking any measurable amount of the whole program's
> execution time. It just does hurt me slightly that it's so much less
> efficient. I guess it must be the overhead of calling the anonymous
> function.

That, and the cost of replacing lots of tiny matches I would think.  I
think most implementations make growing a string more efficient than
doing a mid-string replacement.

For what it's worth, I don't find the factor of 5 that you do, but my
version is *way* slower than either of yours.  That, I think, is because
it matches every character.  (As I said I did that to minimise the
changes.)

If I change the string.replace to a simple for loop, then it matches
your escape2 in performance.

>> But it's an excellent example of what we've been talking about.  I found
>> your preferred version (the first one) quite hard to verify.  My
>> difficulty was not due to any language feature that you'd used but came
>> from the algorithm combining a negative character class and some
>> positive tests to implement a set of rules that are not written that
>> way.
> ...
>> For me, readability is about how easily can I see that the code is doing
>> the right thing, and given the specification:
>>
>> https://drafts.csswg.org/cssom/#serialize-an-identifier
>>
>> I would write something like this:
> ...
>> and then I'd check to see if I really needed to complicate the tests
>> and/or pull out special cases to get a more speed.  By the way, the
>> replace(/./g) is not an important part of what I'm saying.  I used that
>> method to minimise the differences between our approaches.
>>
>> When if comes the language features, I would probably write this:
> ...
>> but this is not really my point.  Readability goes much deeper than the
>> surface constructs.  It's about, as I think you said, how easy the code
>> is to verify, and that often means how closely it matches the
>> specification.
>>
>> If this was hard-line production code, I think I'd include the seven
>> sentences from the specification as a comment.  That would go a long way
>> to explaining why the code is written as it is.
>
> That's interesting, because there is an npm package which implements
> the function (which I couldn't use for $reasons) and it's written
> *exactly* as you describe.

So it does.  The comment is split between the cases but, yes, the same.

> You do of course have a point about following the spec, but to my mind
> (and we're deviating considerably from the original topic here) it just
> shows how this sort of "specification" is an absolute abomination. Many
> of the modern web specifications are similar. They don't tell you what
> things mean, they just give random algorithms and you have to work out
> the meaning for yourself. They're basically the opposite of a
> specification. I had to reverse-engineer the CSSOM spec in order to find
> out what it actually meant, in order to write my implementation. If it
> was an actual specification, what I just said would be nonsensical.

I think concentrating on the term "specification" is slightly
distracting up from the big picture.  I was trying to say that
readability is much deeper than the meaning of the surface syntax.
After all, that can be looked up, but how clearly the code represents
the method used to get the desired result is often the hard part of what
we mean by "readability".

-- 
Ben.

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


Page 1 of 3  [1] 2 3  Next page →

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


csiph-web