These are chat archives for ramda/ramda

5th
Sep 2015
Jethro Larson
@jethrolarson
Sep 05 2015 00:43
About half the time I use useWith I actually want the W combinator
W (foo)(x) == foo (x)(x)
Jethro Larson
@jethrolarson
Sep 05 2015 00:54
Well, that's only true if everything is manually curried, including compose
Matthew Steedman
@knubie
Sep 05 2015 02:11
@jdalton I actually think converge makes a lot of sense as a name
Dominik Dumaine
@Bondifrench
Sep 05 2015 02:50
Hi all, is there a function in Ramda that loops over the values of an array, and transforms them to keys of an object ie ['FY', 'Q3', 'Q2'] => {'FY': [ some filtered stuff here], 'Q3': [ 'some other stuff' ], 'Q2': [ ]} Use case is when getting some stuff from SQL and transforming into more json like structure
John-David Dalton
@jdalton
Sep 05 2015 03:22
@knubie you can be wrong it's ok ; )
Jethro Larson
@jethrolarson
Sep 05 2015 05:30
Converge made sense to me. UseWith not so much
Stefano Vozza
@svozza
Sep 05 2015 06:59
@Bondifrench do you mean something like fromPairs?
Dominik Dumaine
@Bondifrench
Sep 05 2015 07:25
@svozza will have a look, thx
Aldwin Vlasblom
@Avaq
Sep 05 2015 07:48
@jdalton I also like converge as a name. I do think useWith would have to be renamed as it can mean anything. How about converge ("To come together from different directions") and disperse ("To strew or distribute widely")? The two words are related because they're kind of opposite, but they also both say something about what happens to the arguments. Besides, I think the subtle differences between the two are too great to name them after the same thing. I'm specifically talking about how the arity for the returned functions is chosen. For converge it will be the biggest arity of all given transformers, and for useWith it will be equal to the amount of given transformers.
Tamas
@bling5630
Sep 05 2015 07:57
Hi folks, I would like to use Ramda, but didn't find the right solution, do you have any ideas how can I do this? Thanks
// input

var input = {
    apple: 3,
    cucumber: 1
};

// desired output

[{
    name: 'apple',
    quantity: 3
}, {
    name: 'cucumber',
    quantity: 1
}];

function transformData(content) {

    return reduce(function(output, key) {
        output.push({
            name: key,
            quantity: content[key]
        });
        return output;
    }, [], Object.keys(content));

}
Aldwin Vlasblom
@Avaq
Sep 05 2015 08:04
@bling5630 var transformData = R.pipe(R.toPairs, R.map(R.zipObj(["name", "quantity"]))) - http://bit.ly/1QfI7WH
Tamas
@bling5630
Sep 05 2015 08:30
@Avaq thanks, I really appreciate your help!
Aldwin Vlasblom
@Avaq
Sep 05 2015 08:43
You're very welcome. :)
@jdalton The more I think about my naming of disperse, the more I like it! Converge "converges" the arguments with every given transformer, and disperse "disperses" the arguments across all given transformers! :D .. Maybe I'm falling in love, and I should kill my darlings and such.. It's a good name right? :worried:
Danielle McLean
@00dani
Sep 05 2015 08:56
@Avaq Well, both converge and useWith necessarily disperse first, converge dispersing the entirety of arguments to all transformers and useWith dispersing individual arguments to individual transformers. So it's a little unclear from that perspective, I think. It's still better than useWith to describe the behaviour at least.
Aldwin Vlasblom
@Avaq
Sep 05 2015 09:07
@00Davo Ah, I think of the word "disperse" as kind of "being driven apart". Like a herd of sheep is "dispersed" when a dog runs into the center of the herd. From that point of view I can't think of "dispersing the entirety of arguments to all transformers", because it would involve cloning the sheep ;). But maybe my concept of the word is wrong, I'm no native speaker.
Danielle McLean
@00dani
Sep 05 2015 09:09
Ah, true, you're right. "disperse" is literally a synonym for "distribute" in this context, but it does seem to connote "driven apart" where "distribute" wouldn't necessarily.
Perhaps working the word "spread" into useWith's new name would be helpful, considering "spread" is used with similar meaning by Q (and other promise libraries?).
Aldwin Vlasblom
@Avaq
Sep 05 2015 09:24
That's an interesting idea too. It lacks the intrinsic connection to the word "converge" (via opposites) that "disperse" does though :). Also, to me just R.spread sounds like an alias to R.apply (which is really what it means in Q and such too), so you would have to come up with a function name containing "spread", which might get long.
Danielle McLean
@00dani
Sep 05 2015 09:25
Yeah, convergeSpread was the most logical name based on that, and it really is very long. :smile:
Aldwin Vlasblom
@Avaq
Sep 05 2015 09:28
Yeah, plus convergeSpread makes it seem like it sub-categorizes converge behavior-wise, which it doesn't because the arity of the resulting function is decided in a completely different manner.
Danielle McLean
@00dani
Sep 05 2015 09:29
Good point.
Scott Sauyet
@CrossEye
Sep 05 2015 12:07
I have never minded the name converge. It seemed an improvement on the original fork. But useWith has always been a placeholder in my mind, filling the space until we could arrive at a good name.
diverge is not bad, as long as we don't make to much of its connection with converge. The two words describe well different parts of the operation, and in actuality the way the word 'converge' fits would equally fit useWith.
Raine Virta
@raine
Sep 05 2015 14:01
any ideas how to unit test a function pipeline that has IO in the middle? specifically, a function that returns a promise
Danielle McLean
@00dani
Sep 05 2015 14:05
Mock out the IO function with an equivalent that returns a promise for a constant, unless there's some significant reason that won't work.
Martin Algesten
@algesten
Sep 05 2015 14:18
this is sort of the purpose of my https://github.com/algesten/fnuc/blob/master/api.md#ppipe function. you can test the pipe using non-promises and then both accept promises in and return promises in production code.
Danielle McLean
@00dani
Sep 05 2015 14:26
@algesten Why not just use promises in your tests, though? You don't have to actually do IO to create or manipulate promises, so you might as well still use them in the test too.
Martin Algesten
@algesten
Sep 05 2015 14:47
@00Davo I have this idea that I want promises but I don't want to see them. if I resort to long .then-chains I failed. I rather have a ppipe chain of simple functions that I can test with straight function application.
granted it doesn't work well if the IO is in the middle.
Danielle McLean
@00dani
Sep 05 2015 14:49
Right, and I agree to a point - I've got a ppipe-esque function in my current project too. But shouldn't you still be passing promises to the pipeline to test it?
Martin Algesten
@algesten
Sep 05 2015 14:50
I like the idea that whether I test with a promise or not is irrelevant. promise in - promise out. or normal value in - normal value out.
Danielle McLean
@00dani
Sep 05 2015 14:52
Oh, wait, your pliftreturns a value synchronously when you only pass regular values to the function in the first place. So the whole pipeline stays synchronous if you never use a promise, gotcha.
Martin Algesten
@algesten
Sep 05 2015 14:52
yes. that's it.
I can pretend I don't use promises :)
Danielle McLean
@00dani
Sep 05 2015 14:53
I generally like to be "safer" and always return a promise from anything that might be async, even if it isn't for some arguments, but if you're consistently using plift and such I suppose it doesn't actually matter.
Martin Algesten
@algesten
Sep 05 2015 14:55
it's an idea. I have road tested it a bit and its sort of neat.
John-David Dalton
@jdalton
Sep 05 2015 15:04
Ya converge and useWith are essentially the same. It comes down to one passes the transforms a single argument of the index of the transform and the other passes it all arguments. So I'm trying to come up with a common name that describes that (tough). I'll keep kicking it around.
Raine Virta
@raine
Sep 05 2015 15:11
00Davo: what if the function that returns the promise is private to the module, do you use rewire or something to replace it with mock implementation?
and by module i mean the file that exports something else that uses the private function in a pipeline
Danielle McLean
@00dani
Sep 05 2015 15:13
Something like that, yeah. But if you're writing a mostly-pure pipeline that happens to do one impure action in the middle, it'd probably be a good idea to parameterise it on the impure function anyway? Maybe make the usual source of the promise a default argument, and pass a replacement for it in unit tests.
Scott Sauyet
@CrossEye
Sep 05 2015 15:42

Although I recognize that there's an abstraction where useWith and converge are quite similar, my mental models of them are so different that it's hard to think of them as even related, except in that they both offer extensions to the notion of compose.

To me, useWith is all about running transformations on each of the parameters before supplying them to the main function; the focus is clearly on the main function. But converge is about running a number of functions against the same data, and then at the end, almost incidentally, combining their results; the focus is on the individual transformations.

Of course this is only a matter of perspective, and it's certainly no more or less valid than the notion that @jdalton is proposing based on potentially similar implementations. But it's interesting to realize how different such perspectives can be.

John-David Dalton
@jdalton
Sep 05 2015 15:48
@CrossEye I think of them as modifiers on a function (kinda like arity, arg order, partially applied args, curried state) I think I could store them in metadata if needed
Scott Sauyet
@CrossEye
Sep 05 2015 16:00
@jdalton: Understood, but my mental model doesn't really allow that for converge. The focus there is on the individual functions, and not on the one that combines the results. As I said, it's just a matter of focus... and of course, a matter of opinion.
John-David Dalton
@jdalton
Sep 05 2015 16:11
I found a neat example for useWith (aka modArgs) in ld land
var assign = _.partial(_.modArgs(_.assign, Object), null);
super neat!
Scott Sauyet
@CrossEye
Sep 05 2015 17:28
I'll try to wrap my head around that when I'm in front of a computer. Too hard to try to understand the types and signatures on my phone.
Raine Virta
@raine
Sep 05 2015 18:52

@00Davo

Maybe make the usual source of the promise a default argument, and pass a replacement for it in unit tests.

It currently looks like this,

module.exports = (payload) =>
  readTemplates(payload.type, payload.site)
    .then(buildEmailOptions(payload))
    .then(transporter.sendMailAsync.bind(transporter));

readTemplates is the impure one. did you mean that in this case, readTemplates would be passed as an argument to the exported function?

John-David Dalton
@jdalton
Sep 05 2015 18:53
I think I've settled on modArgs and modArgsSet
Scott Sauyet
@CrossEye
Sep 05 2015 18:59
@jdalton: I'm glad you've found something you like. It's too bad it's not something I think would fly for Ramda as well, but that's not a very big deal. I will have to see what others think of disperse. It seems that converge is already pretty well accepted.
John-David Dalton
@jdalton
Sep 05 2015 19:18
Ya i dig it, looking at the API you already get a hint of what it will be doing modArgs modifying args, modArgsSet modifying a set of args. It also shows their close relationship so woot. I don't dig the sS bit of modArgsSet or using Set but it's short and gets the point across.
Raine Virta
@raine
Sep 05 2015 21:12
anyone found this useful? http://www.contractsjs.org/
Danielle McLean
@00dani
Sep 05 2015 23:14
@raine That's my thinking, yeah. Make it (payload, templateSource) => or something like that, and if the second argument's not passed you can use readTemplates as the source?
Scott Sauyet
@CrossEye
Sep 05 2015 23:48
@raine: never tried it. Never really impressed by Eiffel, and this doesn't hold a great deal of appeal, although I am a bit curious.
Raine Virta
@raine
Sep 05 2015 23:55
00Davo: interesting approach. i've always kind of thought that changing code to accommodate testing is bad but i'm going to try this approach. the alternative would be to couple tests to private parts of the code, in order for the tests to know which function does the impure stuff