These are chat archives for ramda/ramda

18th
Sep 2015
Scott Sauyet
@CrossEye
Sep 18 2015 00:09
Sorry, the question was about when g is variadic. That's in good part the point of contention in #1318. And "variadic" isn't really the issue, but rather "polyadic". What happens when g is not unary? Generally Ramda curries the outputs of its functions. But when we do that for compose/pipe, we caused a number of thing that one would expect to work to fail, including the case Hardy Jones describes above.
David Chambers
@davidchambers
Sep 18 2015 00:10
@joneshf-work1 is suggesting that compose/pipe assume all the functions to be unary. I agree with this wholeheartedly.
Scott Sauyet
@CrossEye
Sep 18 2015 00:11
That's too far from the core of JS for me.
David Chambers
@davidchambers
Sep 18 2015 00:11
Yeah, I can understand that.
This is an important enough distinction that it's reasonable for Ramda and Sanctuary to provide differing composition functions.
Scott Sauyet
@CrossEye
Sep 18 2015 00:12
absolutely
But I really do want to figure this out for Ramda, and do one more pass at it, then settle down on changes in this area.
David Chambers
@davidchambers
Sep 18 2015 00:13
At which point it'll be a simple matter of you and @paldepind agreeing on something. ;)
Scott Sauyet
@CrossEye
Sep 18 2015 00:13
"Simple" he says! :wink:
joneshf-work1
@joneshf-work1
Sep 18 2015 00:26
Yeah, peeking into argument arity and whatnot is too complex for me.
harder for me to reason about.
i.e. I haven't been able to figure out how to use pipe yet when I don't want the absolute simplest pipe going on.
Scott Sauyet
@CrossEye
Sep 18 2015 00:28
Understood, but we have to balance between a library that introduces FP concepts into JS with one that works with the grain of JS.
David Chambers
@davidchambers
Sep 18 2015 00:28
Have you tried R.pipe(R.identity, f, g, h)? This should give you the unary-only behaviour you're after.
joneshf-work1
@joneshf-work1
Sep 18 2015 00:29
I've not.
I'll try to remember that next time.
Scott Sauyet
@CrossEye
Sep 18 2015 00:29
Well, I'm trying to revert the change that makes it necessary! :smile:
If you play around with the REPL from v15, you can see pipe as I expect it to work: http://ramdajs.com/repl/?v=0.15.1
joneshf-work1
@joneshf-work1
Sep 18 2015 00:30
@CrossEye totally, I'm just saying that it's not so easy to understand what pipe is currently doing, no matter your background.
Scott Sauyet
@CrossEye
Sep 18 2015 00:31
I agree. I've answered a number of questions in various forums about why pipe/compose are not doing what's expected since that change.
But David's Alice/Bob story demonstrates that there is a decent rationale for the alternative introduced there.
joneshf-work1
@joneshf-work1
Sep 18 2015 00:32
Alice/Bob?
Is that in the issue?
Scott Sauyet
@CrossEye
Sep 18 2015 00:32
I simply prefer the older behavior. And I think it's generally simpler.
Yes, in #1318
joneshf-work1
@joneshf-work1
Sep 18 2015 00:32
ah
joneshf-work1
@joneshf-work1
Sep 18 2015 00:32
I mean, in the grand scheme, it doesn't really make that big a difference. More than likely, it probably makes more sense to not pipe what I was doing.
clearer that way probably.
David Chambers
@davidchambers
Sep 18 2015 00:33
We can have it both ways by simply providing two functions. @CrossEye and I agree on the more complex function which currently lacks a good name, but we don't agree on how the simpler function should behave.
Scott Sauyet
@CrossEye
Sep 18 2015 00:33
No? You still want to curry it? I thought we'd come to agreement there.
David Chambers
@davidchambers
Sep 18 2015 00:34
I think the simple function should assume that all the functions are unary.
Scott Sauyet
@CrossEye
Sep 18 2015 00:34
Damn, thought we'd nailed that one down.
David Chambers
@davidchambers
Sep 18 2015 00:34
I don't mind, though, reverting to the pre-v0.17.0 pipe/compose and adding a unary-only composition function to Sanctuary.
Consider it nailed down.
Scott Sauyet
@CrossEye
Sep 18 2015 00:35
It was what was published in that same comment.
ok
David Chambers
@davidchambers
Sep 18 2015 00:35
It's not my preference, but I don't want to be a blocker.
Reverting to the old behaviour is acceptable to me, though I'd still like to provide the function which lacks a good name in addition.
Scott Sauyet
@CrossEye
Sep 18 2015 00:36
Agreed.
Gotta find a good name.
And I can't remember now how #1260 changed other compose-ish functions. I know there were other changes, and I don't know if the same sorts of issues might crop up there.
But that should be easy to deal with.
My trip overseas is delayed a little, so I'll probably have some time this weekend.

Just notice @paldepind's follow-up to the Alice-and-Bob story, which noted that this is broken:

R.compose(R.flip(R.map)([1,2,3,4]), R.add)(3);

Look familiar? :smile:

joneshf-work1
@joneshf-work1
Sep 18 2015 00:54
:)
Jethro Larson
@jethrolarson
Sep 18 2015 01:26
@raine Tried to use replem "Error: Cannot find module 'chalk'"
David Chambers
@davidchambers
Sep 18 2015 02:06
A colleague threw together a mock O'Reilly book cover:
orielly-ramda.png
Perhaps in two or three years this'll be a real thing.
Shane Keulen
@SeeThruHead
Sep 18 2015 02:09
const multiplyRange1 = R.compose(R.lift(R.multiply(10)), R.range);
const multiplyRange2 = R.compose(R.map(R.multiply(10)), R.range);

console.log(
  multiplyRange1(0, 5),
  multiplyRange2(0, 5));
whats the difference?
Scott Sauyet
@CrossEye
Sep 18 2015 02:18

@SeeThruHead: lift can easily be seen as an abstraction on map. The difference is that it will work on polyadic functions:

R.lift(R.add)([1, 2, 3], [10, 20]); //=> [11, 21, 12, 22, 13, 23]
R.lift(R.add)(Just(35), Just(7)); //=> Just(42)

map only works for unary functions.

hemanth.hm
@hemanth
Sep 18 2015 05:03
@CrossEye Thanks.
My talk went well, it was live streamed, forgot to ping the link, will send the video link later, it was just introducing people to functional javascript with ramda :)
Raine Virta
@raine
Sep 18 2015 06:21
@jethrolarson thanks for the heads up, somehow missed adding that as dependency. fixed it now
Raine Virta
@raine
Sep 18 2015 07:26
This message was deleted
hemanth @hemanth ^ This message was deleted :|
Raine Virta
@raine
Sep 18 2015 07:40
I didn't want to put up a massive retina image :smile:
hemanth.hm
@hemanth
Sep 18 2015 07:41
heh heh np, just pulling your legs ;)
Raine Virta
@raine
Sep 18 2015 07:50
Screen Shot 2015-09-18 at 10.24.18.png
hemanth.hm
@hemanth
Sep 18 2015 09:55
:+1:
hemanth.hm
@hemanth
Sep 18 2015 11:24
@raine I was planning to do a similar one, nice! :)
Martin Algesten
@algesten
Sep 18 2015 11:36
I'm new to fp. in my mind pipe simply takes the output of one func as input to next, which means all funcs must be unary apart from the first, which could be any-ary. it would be totally unsurprising to me if the resulting function is curried to the arity of the first. this sounds like what ramda currently does? I like that.
Raine Virta
@raine
Sep 18 2015 11:50
@algesten intuitively, what would you think R.compose(R.add(1), parseInt)("1") returns?
Martin Algesten
@algesten
Sep 18 2015 12:00
parseInt is not an interesting point in these kind of arguments. it only serves to show that parseInt is surprisingly not unary and not any flaw in compose.
and as a js programmer you sort of have to know about the dangers of parseInt.
Raine Virta
@raine
Sep 18 2015 12:03
functions that take optional arguments are common in JS ecosystem
Martin Algesten
@algesten
Sep 18 2015 12:03
yes. and as a js programmer i need to be aware of which do.
hemanth.hm
@hemanth
Sep 18 2015 17:17
@davidchambers That was a nice mock of O'Reilly, before I even read you message I clicked on the image thinking the book is out! heh heh
David Chambers
@davidchambers
Sep 18 2015 17:21
There's no question as to which animal would be used!
hemanth.hm
@hemanth
Sep 18 2015 17:22
:sheep: indeed ;)
Drew
@dtipson
Sep 18 2015 17:46
Is there a more concise/functional way to implement a sort of bind operation, given a method, and object that's of a type that has that method, and the argument to pass to that method? That is, a more generalizable way to do things like this:
var bind = function(promise,fn){
    return promise.then(fn);
}
Maybe one where the methodname "then" would be the first argument in a curried function that took an object and an argument, (rather than specifically a promise and a function).
Raine Virta
@raine
Sep 18 2015 17:48
dtipson: are you looking for R.invoker?
Drew
@dtipson
Sep 18 2015 17:49
I think so, but maybe I was just using it incorrectly when I got weird results
oh, I think I see what I had wrong: R.invoker takes the object last
So what I'd want for that specific case is R.flip(R.invoker(1,'then')) I think
Raine Virta
@raine
Sep 18 2015 17:54
dtipson: what's your use case?
David Chambers
@davidchambers
Sep 18 2015 17:57
@dtipson, see https://github.com/plaid/async-problem/blob/36fb9a0d448050ca580de4e2829467acfb86832f/promises-ramda.js#L17-L18 for a nice example of chaining promises via a then function (courtesy of @paldepind).
Drew
@dtipson
Sep 18 2015 17:57
using that function in R.reduce, basically. R.flip(R.reduce(bind))(list_of_functions); creates a variation on pipeP that takes a Promise and returns a Promise, composing a list of functions that either return promises or results
I'm writing an update on an article I wrote about that pattern (very similar to an old Colgan article as well as gulp's reunSequence) but using Ramda to show how much easier it is
@davidchambers yeah, that's exactly the use case I'm looking at, but without even needing something like then() as a helper
Raine Virta
@raine
Sep 18 2015 18:03
basically you want something like pipeP was before it was changed
Drew
@dtipson
Sep 18 2015 18:05
yep, though I totally see the value of pipeP as it is for ease of use.
Martin Algesten
@algesten
Sep 18 2015 18:27
there's also my twist. ppipe which can behave synhcronously or asynchronously depending on any function involved returns a promise. https://gist.github.com/algesten/2a4b6e37a2d764f5672e though i haven't done that one for ramda (yet)
Drew
@dtipson
Sep 18 2015 18:30
chains of Promises handle that directly though, no? .then(fn) works as a composition of functions whether the function returns a value or a new promise
Martin Algesten
@algesten
Sep 18 2015 18:32
@dtipson yes. but once promise always promise. ppipe evaluates directly if no promises are involved.
Drew
@dtipson
Sep 18 2015 18:33
ah
Martin Algesten
@algesten
Sep 18 2015 18:33
I try to write unit tests
that are promise free
and then still be certain it will work well for promised values
Drew
@dtipson
Sep 18 2015 19:01
gotcha. And that pattern doesn't cause frame weirdness (mixing sync vs. async?) or does it do some version of nextTic internally
At least in the pattern I'm working with, it deals with bare values by using unit = resolve = Promise.resolve to start things off
Drew
@dtipson
Sep 18 2015 19:10
speaking of which, was trying to create a repl, thought it was broke because it kept returning {} and realized that maybe it's because "output" is just getting back a Promise, rather than its result. :)
Drew
@dtipson
Sep 18 2015 19:40
Colgan's Promise chaining pattern: imperative, lodash, Ramda: http://bit.ly/1KlqPpj
John-David Dalton
@jdalton
Sep 18 2015 21:20
R.unapply(JSON.stringify)(1,2,3);
_.restParam(JSON.stringify,0)(1,2,3);
R.invoker(1,'then')
_.method('then',1)
Drew
@dtipson
Sep 18 2015 21:47
nice