-2

To clarify:
This is purely for experimental purposes, to learn the quirks, odds and ends of a new (to me) language. I would of course write it readable if I ever were to share this code with anyone else. :-)


I have a function someFunction(x), and two global variables:

let m = 2;
let e = 5;

Inside the function, I want to check if x == m. If this is true, I'd like to pass m to a side function call (sideFunction(m)), then reassign x to e to complete someFunction.

This does work as expected:

const someFunction = x => {
    if (x == m) {
        sideFunction(m);
        x = e;
    }
    doOtherStuffWith(x);
}

However, I'd like to shorten it, preferably to one line. This is also to understand more about ternaries and/or boolean chaining.

I have tried these two methods:

// Boolean chaining
const someFunction = x => {
    x == m && sideFunction(m) && (function () {x = e})();
    doOtherStuffWith(x);
}

This does not work, presumably because the assignment x = e only applies to the x in the local scope of the inner, anonymous function...?

// Ternary operator
const someFunction = x => {
    x = (x == m && sideFunction(m)) ? e : x;
    doOtherStuffWith(x);
}

This does not work, presumably because sideFunction(m) doesn't actually get called, for some reason...?

How can I fix these to make them work?
Alternatively, are there other, elegant ways to perform this check/call/reassignment without a full multi-line if block?

Thank you very much!

genbatro
  • 146
  • 8
  • 1
    What does `sideFunction` return? Looks like a void function, in which case it would evaluate to `false`... – fredrik Jan 10 '21 at 20:48
  • 2
    "*This does not work, presumably because the assignment x = e only applies to the x in the local scope of the inner, anonymous function...?*" or presumably because `someFunction` returns a falsy value. Likely `undefined` (if it doesn't have an explicit `return`). I don't see what is the need to shorten it. You tried and see where it brought you - how much time and typing did you spend on this question? Does it make up for the few characters you might save? – VLAZ Jan 10 '21 at 20:49
  • 2
    Keeping it short: don't make this one line. – ggorlen Jan 10 '21 at 20:52
  • @fredrik Woah, I didn't even think about that. Thank you! – genbatro Jan 10 '21 at 20:53
  • @VLAZ I'm experimenting to learn how the language work. I would never write it this way in a production environment. :-) Thank you anyway! – genbatro Jan 10 '21 at 20:54
  • There's no need to experiment to know how the language works - just read the specification. It's more reliable... – fredrik Jan 10 '21 at 20:54
  • I did, and always do, read the documentation. Unfortunately, no documentation can cover all use cases. I believe that experimenting, trying and failing will always be a necessary part of learning any language. – genbatro Jan 10 '21 at 21:07

3 Answers3

1

The problem with

x == m && sideFunction(m) && (function () {x = e})();

is that && evaluates left-to-right, and will stop as soon as the first falsey value is found. Unless sideFunction returns something explicitly truthy, the third IIFE:

(function () {x = e})()

will never run, resulting in x never being reassigned.

x is local in that function. If you can get the function to run, it will reassign x as desired.

You could use the comma operator:

x == m && (sideFunction(m), x = e);

Similarly

x = (x == m && sideFunction(m)) ? e : x;

won't work because sideFunction would have to return something truthy for the left side of the conditional to evaluate truthily - otherwise, x will be assigned to x, no change.


All this said - I'd highly recommend not doing any of these. Your first approach is much more readable, and readability is much more important than line conservation.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

You could take a compound expression with a comma operator and do not care about the result value of sideFunction.

const fn = x => (x == m && (sideFunction(m), x = e), doOtherStuffWith(x));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • For the record, this is four (4) characters shorter than what OP has. If we discount the contiguous whitespace. – VLAZ Jan 10 '21 at 20:54
1

The comma operator , can be used to chain expressions and return the last one e.g.,

var x = (1 + 2, 10 + 2, 100 + 2);
x;
//=> 102

We can use it to evaluate sideFunction(m) and return e: (sideFunction(m), e).

Since you always want to execute doOtherStuffWith you only need to work out whether to give it e or the original x:

const someFunction = x => doOtherStuffWith(x == m ? (sideFunction(m), e) : x);
customcommander
  • 17,580
  • 5
  • 58
  • 84