0

I'm implementing the game Tic Tac Toe/Naughts and Crosses in a functional programming style and have stumbled across a hurdle with curried functions.

I have a reoccurring pattern of functions in the form func(width, height, index) which I then wish to curry, binding width and height and leaving curriedFunc(index).

However the problem arises when I have functions that expect one of these curried functions to be defined at compile-time.

They cannot be defined at compile time, because they need input from the user to then bind the values to the function.

Below is some example code of the pattern I've encountered.

// Board indexes:
//  0 | 1 | 2
// ---+---+---
//  3 | 4 | 5
// ---+---+---
//  6 | 7 | 8

const getRowNumGivenWidth = w => i => Math.floor(i/w);

// I want to be able to declare nextIndexInRowGivenWidth() here, outside of main()
// but getRowNum() needs to be defined beforehand


const main = () => {

  // User input:
  const width = 3;

  // ...


  const getRowNum = getRowNumGivenWidth(width);

  const nextIndexInRowGivenWidth = width => currentIndex => {
    const rowNum = getRowNum(currentIndex);
    const nextIndex = currentIndex + 1;

    if (getRowNum(nextIndex) != rowNum)
      result = nextIndex - width;
    else
      result = nextIndex;

    return result;
  };


  const nextIndexInRow = nextIndexInRowGivenWidth(width);

  const board = [0, 1, 2, 3, 4, 5, 6, 7, 8];

  board.map(x => console.log(x, " -> ", nextIndexInRow(x)));

  // ...

}

main();

The only way I can think of solving this is to pass the curried function as an argument (to nextIndexInRowGivenWidth() in this example).

However I don't think this is ideal as if a function requires a few similarly curried functions at run-time, it quickly becomes unwieldy to define and curry said function.

The ideal solution would be if I could somehow make the binding of the values dynamic, suppose I could put the declaration getRowNum = getRowNumGivenWidth(width); before main(). This way I could call something like getRowNum(someInt) to initialise getRowNum() which I could then use in other functions that are already expecting it to be defined.

As this is a reoccurring pattern in my code, I was wondering if there is a design pattern to achieve this.

3
  • 1
    There is no compile time. Nor is it at all clear why you're wrapping your code in a 'main' function. You can also create functions anytime and you can always use .bind to partially apply parameters. It's not really clear what you're asking here. Commented May 25, 2018 at 14:36
  • Apologies, I mistakenly used "compile-time" to refer to "before program execution". The main() was just to indicate the entry point of the code and how the functions would be called. It does seem like .bind can achieve what I'm trying to do, but is it a functional construct? Commented May 25, 2018 at 15:50
  • "Is it a functional construct" isn't that putting the cart before the horse? Does it lead to easier code reuse? Easy to maintain? Read? Although .bind is frequently used OO-style to manually set the this pointer, it can also be used in FP to partially apply: const add = (x, y) => x + y; const add3 = add.bind(null, 3); const five = add3(2); Commented May 25, 2018 at 16:14

1 Answer 1

2

I think you are looking for

const getRowNumGivenWidth = w => i => Math.floor(i/w);

const nextIndexInRowGivenWidth = width => {
  const getRowNum = getRowNumGivenWidth(width);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  return currentIndex => {
    const nextIndex = currentIndex + 1;

    if (getRowNum(nextIndex) != getRowNum(currentIndex))
      return nextIndex - width;
    else
      return nextIndex;
  };
};

const main = () => {
  // User input:
  const width = 3;
  const nextIndexInRow = nextIndexInRowGivenWidth(width);

  // ...
}

Alternatively, you could define that nextIndexInRowGiven… function not with the width as the first curried parameter, but with getRowNum itself as the parameter:

const getRowNumGivenWidth = w => i => Math.floor(i/w);

const nextIndexInRowGivenRowNumGetter = getRowNum => currentIndex => {
  const nextIndex = currentIndex + 1;

  if (getRowNum(nextIndex) != getRowNum(currentIndex))
    return nextIndex - width;
  else
    return nextIndex;
};

const main = () => {
  // User input:
  const width = 3;
  const nextIndexInRow = nextIndexInRowGivenRowNumGetter(getRowNumGivenWidth(width));

  // ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I like both ideas. I think the first will be more beneficial in this situation because it's more likely that many of the smaller functions will be bound to width and height specifically. In the second method, it becomes unruly if many functions are required to be passed in, which may be a possibility as the code grows. Using the first method you could have a function f(w, h, i) and then bind all the smaller functions inside as they all rely on w and h.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.