jskulski jskulski - 6 months ago 23
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 '],
['10']
]


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])));
})(r.keys(rendered_board));
};


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?

Answer

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.zip, 
    R.pipe(R.length, R.repeat('y')), 
    R.identity
), 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.


Update

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.