Search code examples
javascriptfunctional-programminglispramda.jsmit-scheme

How to translate code from Lisp (MIT Schema) into JavaScript using Ramda?


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))

into JavaScript (using Ramda).

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. a).

Is there any way to avoid these functions? Or is there another better way of doing this in JavaScript (maybe even without Rambda)?

I would like to avoid statements such as if, for and switch.

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);

Which complicates a and b, since they will always have to be called (see a() + 1).

EDIT:

For some reason the last code where I define a and b as functions doesn't work 🤔


Solution

  • Ramda is auto curried, so you can invoke the function with some of the parameters, and get a new function back. For example:

    const { pipe, cond, gt, lt, T, always, identity, multiply } = R
    
    const a = 3
    const b = 3 + 1
    
    const fn = (a) => pipe(
      cond([
        [gt(a), always(a)],
        [lt(a), identity],
        [T, always(-1)]
      ]),
      multiply(a + 1)
    )
    
    const result = fn(a)(b)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>