Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
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
    machad0 commented #2771
  • Jan 31 2019 02:26
    JeffreyChan commented #2777
  • Jan 30 2019 14:30
    CrossEye closed #2777
  • Jan 30 2019 12:13
    vanyadymousky updated the wiki
  • Jan 30 2019 01:42
    JeffreyChan commented #2777
  • Jan 29 2019 21:06
    vanyadymousky updated the wiki
  • Jan 29 2019 16:28
    CrossEye commented #2777
  • Jan 29 2019 15:50
    mbostock commented #2772
  • Jan 29 2019 15:48
    CrossEye commented #2772
Aldwin Vlasblom
@Avaq
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
@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
@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
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
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
Yeah, convergeSpread was the most logical name based on that, and it really is very long. :smile:
Aldwin Vlasblom
@Avaq
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
Good point.
Scott Sauyet
@CrossEye
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
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
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
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
@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
@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
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
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
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
yes. that's it.
I can pretend I don't use promises :)
Danielle McLean
@00dani
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
it's an idea. I have road tested it a bit and its sort of neat.
John-David Dalton
@jdalton
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
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
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

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
@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
@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
I found a neat example for useWith (aka modArgs) in ld land
var assign = _.partial(_.modArgs(_.assign, Object), null);
super neat!
Scott Sauyet
@CrossEye
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

@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
I think I've settled on modArgs and modArgsSet
Scott Sauyet
@CrossEye
@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
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
anyone found this useful? http://www.contractsjs.org/
Danielle McLean
@00dani
@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
@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
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
Danielle McLean
@00dani
I figure it's basically just injecting a dependency, which is Good Design™ as much as it is specifically accommodating testing.
hemanth.hm
@hemanth
If you were to pick and imperative code and convert it to functional using ramda to explain the features of FP, which code would that be?
Simon Friis Vindum
@paldepind

@hemanth Depends on the size of the example

const max = R.reduce(R.max, 0, [3, 4, 1, 9 ,3]);

Imperative code would be something like this:

let max = 0;
for (let i of [3, 4, 1, 9 ,3]) { max = R.max(max, i); }
hemanth.hm
@hemanth
@paldepind looking for some example that would involve the basics, so it would be nice to explain it to a huge group who are new to FP, thanks!
Explaining the hows are easy, whys are though...
Simon Friis Vindum
@paldepind
The important difference in the example above is that in the FP code I can let max be const. In the other I have to make it a let. IMO this highlights the key difference between imperative and functional code. The first is a definition of what max is. The second is a sequence of steps that ends of with max having the correct value.