News for hackers. Stuff that matters.
Re:Avoid Else, Return Early (2013) by Waterluvian on Monday March 26, 2018 @08:49AM (#16678426)
JavaScript has the guard operator. It can really clean up your control flow when you know it's a guard operator and not just logical AND.
Re:Avoid Else, Return Early (2013) by timoxley on Monday March 26, 2018 @09:07AM (#16678538)
A big gotcha with `&&` as a guard in JS is that it can return any falsey typed value if you don't coerce the guard to a boolean.

e.g.

    const check(cond) => cond && otherValue
If `cond` is falsey, it returns `cond`.

This means the function could return any of: `false`, `undefined`, `null`, '', `0` or `NaN`.

This is a fairly common issue I see with React + JSX:

    <div>{cond && <SomeComponent />}</div>
If `cond` is `false`, `null`, `undefined` or '', everything will be just fine, but if `cond` happens to be a zero or `NaN`, suddenly you have a weird `0` or `NaN` rendering in your page. Oops.

Low cost, much safer guard:

    const check(cond) => !!cond && otherValue
Re:Avoid Else, Return Early (2013) by sergeykish on Monday March 26, 2018 @04:51PM (#16682469)
Quite interesting. For a moment I've thought it is another JS issue but no. It's React who's strange https://github.com/facebook/react/blob/v0.11.2/src/browser/u... https://github.com/facebook/react/blob/v0.11.2/src/utils/tra...

Same behavior on Ruby:

    def content_markup(children)
      case children
      when String, Numeric
        children
      when NilClass, TrueClass, FalseClass
        return
      else
        # ...
      end
    end

    content_markup 'foo'
    #=> "foo"
    content_markup 0
    #=> 0
    content_markup true
    #=> nil
    content_markup false
    #=> nil
    content_markup nil
    #=> nil
Re:Avoid Else, Return Early (2013) by Waterluvian on Monday March 26, 2018 @09:42AM (#16678758)
Good point. Good example. I imagine it works well in my cases but I haven't come across cases like your example where it breaks down.
Re:Avoid Else, Return Early (2013) by acjohnson55 on Monday March 26, 2018 @10:55AM (#16679343)
...until you do.

That's the problem with antipatterns. It's impossible to remain alert to the edge cases, and then they eventually bite you in production. Better to lint them away. But it's difficult to convince people not to do something really convenient if they haven't gotten bitten yet.

Re:Avoid Else, Return Early (2013) by sgustard on Monday March 26, 2018 @11:14AM (#16679488)
Yes, back when CoffeeScript was in vogue the ? operator handled this case nicely:

  cond? && otherValue
Re:Avoid Else, Return Early (2013) by arghwhat on Monday March 26, 2018 @09:14AM (#16678589)
Logical AND in JavaScript can be used as a guard, by why in the world would you think of it as anything other than a logical AND?

If you start thinking it is a "guard operator", I would think that going down the wrong path, which might promote misunderstanding of the behavior.

Re:Avoid Else, Return Early (2013) by timoxley on Monday March 26, 2018 @01:22PM (#16680639)
> which might promote misunderstanding of the behavior

This isn't a misunderstanding, binary logical operators in JS short-circuit like this by design. I believe && and || returned a boolean value in the past, but were explicitly changed to support this behaviour.

Re:Avoid Else, Return Early (2013) by arghwhat on Tuesday March 27, 2018 @04:37AM (#16686464)
Quoting ECMA-262 First Edition (June 1997), Chapter 11, Section 11 (Binary logical operators)[1]:

    The production LogicalANDExpression : LogicalANDExpression && BitwiseORExpression is evaluated as follows:
    
    1. Evaluate LogicalANDExpression. 
    2. Call GetValue(Result(1)).
    3. Call ToBoolean(Result(2)).
    4. If Result(3) is false, return Result(2).
    5. Evaluate BitwiseORExpression.
    6. Call GetValue((Result(5)).
    7. Return Result(6).
That is, the behavior has always been "If the first expression is false-ish, return the first expression, otherwise return the second expression" ("BitwiseORExpression" is a class of expressions that include a lot of things, including equality operators).

JavaScript does not have any operators that is not explicitly listed in a version of ECMA-262. It would be correct to refer to the construct as a "guard", but incorrect to refer to it as a "guard operator". Calling it "guard operator" also does not promote an understanding of the underlying construct.

1: https://www.ecma-international.org/publications/files/ECMA-S...

Re:Avoid Else, Return Early (2013) by timoxley on Tuesday March 27, 2018 @09:43PM (#16694487)
> the behavior has always been

The ECMA spec only defines Javascript 1.3 and above. See this description for logical operators for Javascript 1.1: https://web.archive.org/web/20060318153542/wp.netscape.com/e...

Re:Avoid Else, Return Early (2013) by arghwhat on Thursday March 29, 2018 @07:45AM (#16706189)
ECMA-262 defines ECMAScript. "JavaScript 1.3" refers to a Netscape-specific language implementation ("Mocha", "LiveScript", "JavaScript"), with version 1.3 being based partially based on ECMA-262 Second Edition. Some of it might still live on in Firefox, but it is certainly not what people refer to as "JavaScript".

Doing some research, it appears that Netscape changed the logical operator behavior in version 1.2 (https://web.archive.org/web/19981202065738if_/http://develop...).

However, they did not highlight this change at all (https://web.archive.org/web/19970630092641fw_/http://develop...), so I suspect it was just a minor cleanup, potentially related to the equality operator change.

As a side-note: Netscape scripting was awful. This was how you casted an object to a Number:

    Number(x) = x;