by

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
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.
hemanth.hm
@hemanth
@paldepind Why not Math.max.apply(null,[3,4,1,9,3]) ?
Simon Friis Vindum
@paldepind
@hemanth Well. Let's say we don't have that function and that we want to define it.
hemanth.hm
@hemanth
hmm
Simon Friis Vindum
@paldepind
Of course that example in itself does not really show how FP is better.
hemanth.hm
@hemanth
Agree, will have set of examples
BTW, is this functional enough?
let map = function(f, args) {
  let [x, ...xs] = args;
  if (x === void 0) {
    return [];
  } else {
    return [f(x)].concat([].slice.call(map(f, xs)));
  }
};
if let [x,...xs] = args is avoided it would be nice...
Simon Friis Vindum
@paldepind
@hemanth Well. I don't like it. You get the head and the tail of the list before you check if it is empty. I'd much rather do the destructuring after you've checked if the list is empty.
hemanth.hm
@hemanth
@paldepind Makes sense, trying to implement reduce in a similar manner
Simon Friis Vindum
@paldepind
Something like this:
const map = (f, list) =>
  list.length > 0 ? [f(list[0])].concat(map(f, list.slice(1)) : []
hemanth.hm
@hemanth
^ I'm getting an error on that. Like to use the spread operator rather thanslice
Simon Friis Vindum
@paldepind
I didn't test it :S I think spread would only complicate things in this case.
I'm missing a parentheses after slice.
hemanth.hm
@hemanth
@paldepind Nice, I would rather have list first and fn next in the param order
Jack Firth
@jackfirth
@raine @CrossEye Re contracts and Eiffel - that implementation is significantly different from Eiffel's in that it allows contracts for higher order functions - you can specify "this function accepts a function of two arguments that returns a boolean" in the contract. Makes it a huge win for FP, and drastically improves error messages. Eiffel contracts are more "before calling this, state is X, after calling, state is Y"
hemanth.hm
@hemanth
@paldepind slice doesn't mutate the array, nice.
Dave Keen
@ccapndave
Hey everyone - is there a way to write R.pipe(R.prop('rows'), R.pluck('doc')) with a single function?
Scott Sauyet
@CrossEye
@jackfirth: I only glanced at the docs, and didn't dig very deep. While I've never bought the notion that the only good FP is strongly typed FP, I certainly have some sympathy for attempts to add stronger typing to JS. After all Ramda's avoidance of overloading and of optional parameters certainly works along those lines. But I'm usually not that intetested in attempts to add real strong typing to JS. I'll have to take another look at this one though.
Hardy Jones
@joneshf

@raine another options is to add another function, one that performs the algorithm, like @00Davo said:

baseAlgorithm = (read, payload) =>
  read(payload.type, payload.site)
    .then(buildEmailOptions(payload))
    .then(transporter.sendMailAsync.bind(transporter));

ioAlgorithm = (payload) =>
  baseAlgorithm(readTemplates, payload);

module.exports = {baseAlgorithm, ioAlgorithm};

Then you can test the algorithm with a unit test, and the io version with an integration test.

But you still have the shortcut function that you care about
If yu don't want to expand the public api, then shove the base algorithm in some internal file somewhere, or move it to an entirely separate module and depend on it.
Tamas
@bling5630
hey guys, do you have any ideas how can I solve this much more elegant? thanks,Tamas

input is

['apple', 'the', 'one', 'two', 'three', 'elephant', 'whatever']

var filterByLength = R.filter(function(str) {

    return str.length > 3 && str.length < 6;
});

desired output is

['apple', 'three']
Hardy Jones
@joneshf
@bling5630 what do you view is inelegant about it?
Tamas
@bling5630
I just like a shorter one, what do you think about it?
Matthew Steedman
@knubie
@bling5630 if you're looking for a point-free solve something like this would work:
var filterByLength = R.filter(
  R.converge(
    R.and,
    R.compose(
      R.lt(3),
      R.prop('length')
    ),
    R.compose(
      R.gt(6),
      R.prop('length')
    )
  )
);
that's obviously longer, though
Aldwin Vlasblom
@Avaq
Something like R.filter(R.where({length: R.allPass([R.gt(6), R.lt(3)])})) is shorter.
Danielle McLean
@00dani
Pity Ramda doesn't make functions into applicatives. filter $ ((> 3) <&&> (< 6)) . length
Matthew Steedman
@knubie
This would work too R.filter( R.compose( R.contains(R.__, R.range(4,6)), R.prop('length')))
Scott Sauyet
@CrossEye
I'd still choose R.lt(R.__, 3) or R.flip(R.lt)(3) for readability.
Aldwin Vlasblom
@Avaq
@CrossEye I was just going to ask; What's up with the argument order of gt and lt? It had me confused for a moment. I expect var lt6 = R.lt(6) to make a predicate function that returns true when the argument is Less Than 6.
Danielle McLean
@00dani
It's because R.lt(x, y) means x < y and curried arguments apply left to right. https://github.com/algesten/fnuc exists mainly because that's Kind of Weird.
Scott Sauyet
@CrossEye
@00Davo: the language doesn't really offer us the opportunity. We did try something once, but it wreaked havoc with one's sense of what currying would do.
Danielle McLean
@00dani
Yeah, fnuc's approach to currying is also pretty confusing.
Scott Sauyet
@CrossEye
@Avaq: but what would you expect R.lt(7, 12) to return?
Danielle McLean
@00dani
Could "reverse" currying like fnuc be added, but only applied in Ramda itself to lt and similar functions? Or would that be too inconsistent?
Since those functions are all binary it shouldn't be too difficult to figure out how the reverse-curry should behave, I figure.
Scott Sauyet
@CrossEye
that's what we did try. The resulting confusion is what got is to add the placeholder.
Danielle McLean
@00dani
Dang.
Oh hey, speaking of: Why's the placeholder an object with a specially-named field on it? Just making it an empty object and then comparing against that in the functions would work too, no?
Aldwin Vlasblom
@Avaq
@CrossEye Well, I would have to think about it for a brief moment, taking into consideration that Ramda tends to "swap" arguments, and conclude that it would probably return false because 12 is not less than 7.