DEV Community

Discussion on: Writing If Statements with the Ternary Operator

Collapse
 
peerreynders profile image
peerreynders • Edited

In my view the insight that is missing in this article is the key difference between both conditional constructs:

  • An if statement is - well, a statement.
  • The ternary operator is part of an expression.

So what?

  • An if statement routes the flow of execution - based on the outcome of the condition, program execution is routed to a specific conditional block of statements.

  • A ternary has to produce value - so a ternary expression will always have to have two possible outcomes (values). (BTW - what else returns a value: a function).

If you have an imperative programming style you will be thinking and programming in statements. As such you will default to if statements (me - programming C decades ago and going "yech" every-time I came across a ternary).

Once you start using a functional language (say Erlang, OCaml, Haskell, Elixir, Clojure, etc.) statements go out the window (even Rust, though imperative, is largely expression-based). You have to deal with everything in terms of expressions producing values (not statements mutating values; PLOP - Place-Oriented Programming) because expressions - just like functions - take some values as inputs and produce a new value. There is no if statement - only conditional expressions.

Scheme is in JavaScript's history which is evidenced by its function-oriented nature so while it isn't possible to dump statements entirely (they have their uses 😏) one can develop a more expression-based style - and using ternaries (with tuples and destructuring assignments) is a big part of that.

// ...

function categorize(ch) {
  return 'a' <= ch && ch <= 'z'
    ? CHAR_CATEGORY.LowerCase
    : 'A' <= ch && ch <= 'Z'
    ? CHAR_CATEGORY.UpperCase
    : SEPARATORS.includes(ch)
    ? CHAR_CATEGORY.Delimiter
    : CHAR_CATEGORY.Other;
}

const isAlphabetic = (c) =>
  c === CHAR_CATEGORY.LowerCase || c === CHAR_CATEGORY.UpperCase;

function reducer([last, acronym], ch) {
  const current = categorize(ch);
  return (last === CHAR_CATEGORY.LowerCase &&
    current === CHAR_CATEGORY.UpperCase) ||
    (last === CHAR_CATEGORY.Delimiter && isAlphabetic(current))
    ? [current, acronym + ch.toUpperCase()]
    : [current, acronym];
}

// beginning of phrase is equivalent to a "delimiter"
const INIT_COLLECT = Object.freeze([CHAR_CATEGORY.Delimiter, '']);

function acronym(phrase) {
  const [_last, result] = phrase.split('').reduce(reducer, INIT_COLLECT);
  return result;
}
Enter fullscreen mode Exit fullscreen mode