I'm currently teaching myself functional programming.
I'm trying to translate the following:
(define a 3) (define b (+ a 1)) (* (cond ((> a b) a) ((< a b) b) (else -1)) (+ a 1))
One could use nested ternaries, but I like to using the
cond function from Ramda. Here is what I did:
const a = 3; const b = 3 + 1; cond([[() => a > b, () => a], [() => a < b, () => b], [T, () => -1]])() * (a + 1)
The problem I have with this is that I had to use these functions (e.g.
() => 3) instead of just their value (e.g.
I would like to avoid statements such as
An alternative way to solve this would be using:
import gt from "ramda/src/gt"; import lt from "ramda/src/lt"; const a = () => 3; const b = () => a() + 1; cond([[gt(a, b), a], [lt(a, b), b], [T, () => -1]])() * (a() + 1);
b, since they will always have to be called (see
a() + 1).
For some reason the last code where I define
b as functions doesn't work ????
I think you're working under a bit of a misapprehension.
cond is designed to give you a function. It's really not designed for creating a scalar value for an expression. Of course it can do so, simply by immediately calling the function it generates. But that's not the point of it. Moreover, it really is not meant for calling with nullary functions (except in the case of passing
T for the default condition.). Again, you can do so, but it's working against the grain of the tool.
Although Ramda takes inspiration from both LISP-style and ML-style functional languages, and although I am personally more a fan of the former, Ramda is closer to the ML world, especially to Haskell. So the main activity it is meant to support is to build functions by composing other functions.
If I were to solve this problem, I probably wouldn't use any Ramda whatsoever, choosing something like this:
const larger = (a, b) => (a > b) ? a : (b > a) ? b : -1 const foo = (a, b) => (a + 1) * larger(a, b) foo(3, 4) //=> 16 foo(6, 3) //=> 42 foo(3, 3) //=> -4
Or, if I didn't need to reuse
larger, I might inline it like this:
const foo = (a, b) => (a + 1) * ((a > b) ? a : (b > a) ? b : -1)
Of course I can write this in Ramda, and in a point-free fashion:
const larger = cond([[gt, unapply(head)], [lt, unapply(last)], [T, always(-1)]]) const foo = converge(multiply, [inc, larger])
Or again, I might inline
larger, or replace
But none of these options is as readable as the original. Ramda adds nothing here that I can see. Note that I am a big fan of Ramda; I started the library and am one of its principle authors. But I don't think it should be used for every problem.