jskulski jskulski - 8 months ago 39
Javascript Question

Two dimensional array mapping in point free notation?

I'm playing around with functional/tacit style programming, specifically creating the snake game (example of game: http://patorjk.com/games/snake/)

The specific question is that I'm taking an array of strings like:

['2 '],

and wanting to get the list of coordinates in numerical order of the 'value'. In the domain, 0 is the head of the snake, 2 is the tail, the whole thing is the board.

So I built:

var findSnake = function(rendered_board) {
return r.map(function(x) {
return r.map(function (y) {
return {
x: x,
y: y,
val: rendered_board[x][y]
})(r.keys(r.split('', rendered_board[x])));

which gives me back:

[ [ { x: '0', y: '0', val: '2' }, { x: '0', y: '1', val: ' ' } ],
[ { x: '1', y: '0', val: '1' }, { x: '1', y: '1', val: '0' } ] ]

which I can then sort and get my list of coordinates. It works but I have questions on style.

Is there a way to write findSnake in point free style? Is there a more idiomatic approach to this problem?


As expected, this seems far too difficult to turn into a readable points-free solution. I did take a simpler subset of it, just to see what I could do, and that itself was ugly enough that I didn't carry it through.

If we started with this function:

var fn = function(list) {
    return R.map(function(y) {
        return {
            y: y
    }, list);

... which can clearly be recognized as an inner subproblem of the original, then, I can turn it into this monstrosity:

var fn = R.pipe(R.converge(
    R.pipe(R.length, R.repeat('y')), 
), R.map(R.apply(R.createMapEntry)));

(Some intermediate steps are in the REPL)

But considering how this looks in es6, that seems extremely counter-productive:

var fn = R.map(y => ({y});

And that's why I use points-free when it makes sense, but don't try to apply it everywhere.


As of version 0.18, Ramda renamed createMapEntry to objOf made converge a binary function, which means the code above no longer works. Nor does the REPL link, as the REPL has been updated. You can see it now updated in the REPL.