Suppose a robot that can add sugar cubes to beverages. It has several methods for deciding how many sugars to add, so there must be some code that determines the highest-priority answer.
Each of these have a code demo and comments about their problems in sugars.js:
Strategy | nice code | lazy eval | correct result¹ |
---|---|---|---|
temporary variable | |||
just use || | |||
|| wrap(…) | |||
[ …values ].find() | |||
[ …functions ].reduce() |
¹ Without lazy eval, "correct result" can only be half because gratuitous evaluation of the later expressions might have modified the (meaning of the) result or might have thrown an Error.
var n = (guessFromColor(bev)
?| queryHwdb(bev.idVendor, bev.idProduct)
?| (cfg || false).defaultSugars
?| surpriseMe(bev)
);
- Precedence like
||
- Picks the next value in the chain until it encounters a value
that is defined (
!== undefined
). - Code from sugars.js. More details there.
var n = ( ?| checkAcceptable
: guessFromColor(bev)
: n2u(queryHwdb(bev.idVendor, bev.idProduct))
: (cfg || false).defaultSugars
: surpriseMe(bev)
// Beware: If there was no acceptable value, you still get the last one!
// So better append either a default value, or a last resort:
: test.fail('No acceptable value!')
);
- Precedence like
… ? … : …
- Picks the next value in the chain until it encounters a value for which the decider function returns a truthy value.
- Code from sugars.js. More details there.
I wish I had one. For now the tests use a RegExp-based pseudo-transpiler.
Use a custom decider function.
If it's just about null
, vote a thumbs-up emoji on
issue #4.
- Update: The Null Coalescing proposal seems to be just what you're looking for.
Is this a Safe Navigation Operator?
No. I'd really like to have an SNO in JavaScript as well, but SNO is for diving deep into an object, whereas this proposal is about a decision chain with several unrelated values.
- Update: It's on the horizon.
Then instead let's calclulare the amount of damage your character takes, or how many ads to show before a funny cat video.
Feature creep galore.
(undefined // <- redundant // [1]
?|: pureWhite cloud1() // [2]
?|: colorful cloud2()
?|: colorful cloud3()
?| undefined // <- just to show you can mix them.
?|: (codepoint.odd) cloud4()
?|: (codepoint.odd) cloud5()
?|: (codepoint.even) cloud6()
?|: ((Date.now() % 3) ? codepoint.odd : pureWhite) cloud7()
?|: (codepoint.ascii) cloud8() // [3]
?|: dontBotherMe cloud9() // [4]
?|: colorful auroraBorealis()
?| { error: "Couldn't find any. :-(" }
),
- Precedence of
|?:
is same as|?
|?:
works mostly like|?
but with a custom criterion for the (one) next candidate value.- If you want to avoid the above repetitions, just open a new level or parens for a chain with a custom decider function.
- Code from flakes.js. More details there.
- Custom decider functions get the chain's previous value as 2nd argument. Details: hindsight.js
License: ISC