javascript - Är Ramda ifElse ett effektivt mönster om det abstraherar en ternär operation


Riskabel fråga att ha en åsikt om. Jag arbetar på ett projekt med Ramda.js. Och jag ser många ifElse-anrop i hela koden.

const getEvent = R.ifElse(
  fireable,
  R.always(sendAnalyticsEvent),
  R.always(R.always(undefined))
);

Är det verkligen värt ansträngningen att slå in logik i ett funktionellt villkor på det här sättet? Finns det någon fördel?

Om Ramda i slutändan bara abstraherar en ternär operation och vi returnerar undefined vid falsk match.

Ramdas ifElse

var ifElse = _curry3(function ifElse(condition, onTrue, onFalse) {
  return curryN(Math.max(condition.length, onTrue.length, onFalse.length),
    function _ifElse() {
      return condition.apply(this, arguments) ? onTrue.apply(this, arguments) : onFalse.apply(this, arguments);
    }
  );
});
export default ifElse;

Detta verkar som ett antipattern i FP-världen, att alltid returnera undefined eller i vissa fall null

R.ifElse(hasUrl, promptToShare, R.always(null))

Oavsett den ifrågasatta returvärdet av undefined, skulle det inte vara mer idiomatiskt för ett JavaScript-samhälle att använda ternära operatorer?

hasUrl(urlObject) ? promptToShare() : null

Detta verkar mer kortfattat och läsbart för mig, jag vill omstrukturera. Men detta kan bero på min naivitet i FP-världen.

Svar #1

Flera punkter (ansvarsfriskrivning: jag är en Ramda-författare):

  • Alltför ofta har du rätt. Punkt-fri kod används för mycket när nya användare börjar med FP i Javascript. Jag brukar generellt föreslå att det bara är användbart när det förbättrar läsbarheten.

  • En ifElse-anrop är inte ekvivalent med ett Javascript-villkorsuttryck (ternärt). Det kan dock vara ekvivalent med en lambda-funktion som returnerar värdet av ett ternärt uttryck. Det vill säga, exemplet skulle vara mer som (urlObject) => hasUrl(urlObject) ? promptToShare(urlObject) : null. Vid det här laget är ifElse åtminstone möjligen mer läsbart. Detta leder oss till punkterna från kommentarerna om partiell applicering/currying.

  • Det finns lite anledning jag kan se att använda ifElse med funktioner som har olika signaturer. Det vill säga, om promptToShare inte tar några argument, så hör det antagligen inte hemma i ett anrop till ifElse.

  • Den där getEvent-funktionen ser ganska bisarr ut. Med tanke på att den använder ett namn som sendAnalyticsEvent, gissar jag att den skapar någon bieffekt. Och den andra grenen är en no-op. Även om Ramda-teamet egentligen inte bryr sig om hur du använder biblioteket, är detta inte den typ av funktion vi föreställer oss att användare skapar med det.

  • Jag har sett andra konstiga anrop till ifElse som skickar identitet för en av grenfunktionerna. Dessa bör förmodligen ersättas med when eller unless, vilket definitivt skulle vara mer semantiskt.

Så jag håller med om att ditt exempel inte alls behöver ifElse. Men ifElse och dess motsvarigheter when och unless har sina platser.