HN2new | past | comments | ask | show | jobs | submitlogin

This is the equivalent without a do expression.

    const func = (() => {
      let result; // cache
      return () => {
        if (result === undefined) {
          result = someComputation();
        }
        return result;
      }
    })();
You could write it without the immediately invoked arrow funciton or a do expression if `result` is in the same scope as `func`

    let result;
    const func = () => {
      if (result === undefined) {
        result = someComputation();
      } 
      return result;
    }
Result is in the same scope as func, inviting anyone to read from or write to it.

In all three examples `func` is assigned a zero argument function. That function returns the result of calling `someComputation`, but it stores the value in `result`. If `result` is not undefined `func` returns `result`. `func` is a cached, memoized, or lazy-loaded version of someComputation.

A do expression will return the last evaluated expression in it's scope, in this example that expression is `() => {...}`, not `return` because the inner anonymous function wasn't called.

---

I think a clearer demonstration of do expressions is an assigning switch or ifelse

    const value = do {
      switch (someString) {
        case 'Monday':
          0;
          break;
        case 'Tuesday':
          1;
          break;
        ...
      }
    }

    const other = do {
      if (isPrime(n)) {
        'prime'
      } else if (isOdd(n)) {
        'odd'
      } else {
        'even'
      }
    }


Oh, your examples are better. Except for the break on the functional switch (that is weird again), they are how it should be done.

Is the example on the article wrong? A functional "if" shouldn't accept just one side of the branch, a functional switch shouldn't accept a "break", and although it's not absurd that a functional code block accepts a "return", it is not usual.


the break is part of a switch/case though?

https://www.w3schools.com/js/js_switch.asp


The switch example seems odd to me, since in that case getting rid of the `do` expression and using returns turns out to be shorter than futzing around with breaks.

  const value = (() => {
   switch (someString) {
     case 'Monday':
       return 0;
     case 'Tuesday':
       return 1;
     ...
    }
  })();


To me this is a code smell, the function would be better off being a named function like getStatusString(n)

    function getStatusString(n) {
      if(isPrime(n)) {
        return 'prime';
      } 
      if(isOdd(n)) {
        return 'odd';
      }
      return 'even';
    } 
Much easier to read, understand and maintain than an inline monster. No need to add complicated new language constructs for simple situations.....


I agree, these are contrived examples, but I know that I have reached for inline logic many times in my career. To me another code smell is a scope with too many variables and do expressions are a tool to reduce the scope of variables. Refactoring to named functions will introduce another named variables.

Javascript doesn't have private modules so moving logic to helper functions in util modules doesn't reduce scope bloat.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: