## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
• Jan 31 2019 22:17
CrossEye commented #2779
• Jan 31 2019 21:04
ArturAralin commented #2779
• Jan 31 2019 20:08
CrossEye commented #2779
• Jan 31 2019 18:56
buzzdecafe commented #2631
• Jan 31 2019 18:09
ArturAralin commented #2779
• Jan 31 2019 16:18
CrossEye commented #2779
• Jan 31 2019 16:10
CrossEye commented #2631
• Jan 31 2019 16:06
CrossEye commented #2777
• Jan 31 2019 14:44
ArturAralin opened #2779
• Jan 31 2019 07:39
inferusvv commented #2631
• Jan 31 2019 03:07
sespinozj commented #2771
• Jan 31 2019 02:33
• Jan 31 2019 02:26
JeffreyChan commented #2777
• Jan 30 2019 14:30
CrossEye closed #2777
• Jan 30 2019 12:13
• Jan 30 2019 01:42
JeffreyChan commented #2777
• Jan 29 2019 21:06
• Jan 29 2019 16:28
CrossEye commented #2777
• Jan 29 2019 15:50
mbostock commented #2772
• Jan 29 2019 15:48
CrossEye commented #2772
Hardy Jones
@joneshf
Given the type (b -> b -> c) -> (a -> b) -> a -> a -> c it almost writes itself.
const on = curry((f, g, x, y) => f(g(x), g(y)));
Since you need a value of type c, you only have one place to get it, the f function. Well, the f function needs two values of type b, and you can only get those from the g function. The g function needs a value of type a, and you have two of those: x, and y. So you be fair and send both values x, and y to g, then send that to f, and your function wrote itself.
Hardy Jones
@joneshf
There's only two other implementations of that function so you've got a 1 in 3 chance of getting it right :)
And once you add in the law on(f, identity) == f you have no other choice for an implementation.
This message was deleted
Jakub Korzeniowski
@kujon
Hi All,
my brain isn't in a good shape today and I got stuck on trying to do the following:
I want something like R.ap, but a variant which is not going to do every permutation, but only apply first function to the first argument in the list, the second function to the second argument in the list, and so on:
R.ap([R.multiply(2), R.add(3)], [1,2]); // => [2, 5]
any ideas?
Hardy Jones
@joneshf
zipWith(curry((f, x) => f(x)), [R.multiply(2), R.add(3)], [1,2])
maybe avoid the curry in this case?
zipWith((f, x) => f(x), [R.multiply(2), R.add(3)], [1,2])
Jakub Korzeniowski
@kujon
that is one glorious solution, much appreciated!
Hardy Jones
@joneshf
Use a data type that encodes this behavior is another possibility.
const ZipArray = xs => ({
toArray: xs,
map(f) {
return ZipArray(R.map(f, xs));
},
ap({toArray: ys}) {
if (xs.length == 0 || ys.length == 0) {
return ZipArray([]);
} else {
const yss = R.tail(ys);
const xss = R.tail(xs);

return ZipArray(R.prepend(x(y), ZipArray(xss).ap(ZipArray(yss)).toArray));
}
},
});

R.ap(ZipArray([R.multiply(2), R.add(3)]), ZipArray([1,2])).toArray //=> [2, 5]
Or I guess you could clean it up...
const ZipArray = xs => ({
toArray: xs,
map(f) {
return ZipArray(R.map(f, xs));
},
ap({toArray: ys}) {
return ZipArray(R.zipWith((f, x) => f(x), xs, ys));
},
});

R.ap(ZipArray([R.multiply(2), R.add(3)]), ZipArray([1,2])).toArray //=> [2, 5]
probably better that way, since tco.
Sean Sartell
@ssartell
Hey everyone, is it possible to do recursion with strictly pointfree style syntax? I'm guessing not, but thought I'd ask here anyways.
David Chambers
@davidchambers
@ssartell, does the Y combinator make this possible?
Scott Christopher
@scott-christopher
var Y = f => (x => f(y => x(x)(y)))(x => f(y => x(x)(y)));
var factorial = Y(go => n => n === 0 ? 1 : n * go(n - 1));
factorial(6); // 720
I'm sure it's probably possible to define the function passed to Y in a points-free fashion, but it wouldn't be pretty.
David Chambers
@davidchambers
@scott-christopher, that's cool!
Scott Christopher
@scott-christopher
Scott Sauyet
@CrossEye
The Y-combinator allows recursion even where the language doesn't explicitly account for it. But it had little to do with being points-free.
There should be no issues doing points-free recursion, but I'm not going to try an example on my phone.
David Chambers
@davidchambers

@CrossEye, have you ever found yourself writing code like this?

const f = R.pipe(
a,
b,
c,
d,
e,
x => f(x),
g,
h
);

I was wondering whether the Y combinator could obviate the need for the lambda.

Scott Sauyet
@CrossEye
I'm afraid it won't.
David Chambers
@davidchambers
No worries. :)
Scott Christopher
@scott-christopher
It's a silly example, but to show that the Y combinator allows for points-free recursion:
var min10 = Y(R.ifElse(R.compose(R.gte(R.__, 10), R.nthArg(1)),
R.nthArg(1),
R.useWith(R.call, [R.identity, R.inc])));

min10(12); // 12
min10(-3); // 10
the use of R.nthArg might be cheating a little, depending on your rules of points-free golf :D
Scott Christopher
@scott-christopher
it does also emphasise that you're probably not going to have something readable by the time you manage to get the recursive function to be points-free.
Scott Sauyet
@CrossEye
Yes, I was once again missing the point. It sounded easy to do recursion points-free until I tried it. Of course is not possible to do naively, but something like the Y-comb would allow it. But as always with the Y-combinator, it feels mostly like a trick. You prove that it can be done, but you don't use it for anything real.
Hardy Jones
@joneshf
function loop() {
return loop;
}
seems pretty free of points
Tobias Pflug
@gilligan
and arguments
;)
craigdallimore @craigdallimore jumps in. Sees Y-Combinator. Jumps out.
Scott Sauyet
@CrossEye
And free of recursion
Tobias Pflug
@gilligan
I just realized that R.or(a,b) is merely a || b and does thus not return true or false as stated in the documentation but a a truthy or falsy value
Scott Sauyet
@CrossEye
@gilligan: if you want to see extended discussions about this, see #1218 and #1335. Perhaps not the most civil debates we've enter held, though.
If you pass booleans, though, you'll get a boolean.
Tobias Pflug
@gilligan
Oh that is a lot to read
;)
I skimmed some of it
Scott Sauyet
@CrossEye
I did say "extended". :smile:
Tobias Pflug
@gilligan
I wonder though- i get that there was resistance against dispatching but wouldn't Boolean( a || b) have made sense?
David Chambers
@davidchambers
I don't think Boolean(a || b) makes sense. One of the properties of (<|>) is that the return value is always one of the inputs. The operation represents a choice between two possibilities. It would not make sense for 0 <|> 1 to evaluate to True. That's my view, at any rate.
Tobias Pflug
@gilligan
but R.or is not in fact the alternative operator
and it does not pretend to be it either
Returns true if one or both of its arguments are true. Returns false if both arguments are false.
Scott Sauyet
@CrossEye
It wasn't about dispatching. I argued that the language's basic behavior is one of its good parts, and that keeping Ramda's behavior close to it was a good idea that didn't interfere with people who wanted to use it as a plain boolean operator.