These are chat archives for ramda/ramda

31st
Jul 2015
Martin Algesten
@algesten
Jul 31 2015 05:37
thanks @scott-christopher
it gives me food for thought regarding reduce. which is a function I struggle with.
Martin Algesten
@algesten
Jul 31 2015 07:00
@scott-christopher thanks again! given your input, i revised my approach to this https://gist.github.com/algesten/f8165c3b8c914899c656 it's still not great, especially the fn = _fn which is needed to avoid all arguments are promises. and also. it will use .then twice of the first found promise.
Martin Algesten
@algesten
Jul 31 2015 07:30
the reduce + curry trick is very neat.
Scott Christopher
@scott-christopher
Jul 31 2015 07:58
Yeah, I can't think of much else you could do to avoid the fn = _fn.
Bran van der Meer
@branneman
Jul 31 2015 09:38
ramda/ramda.github.io#24 :)
Tobias Pflug
@gilligan
Jul 31 2015 09:54
just wondering - am I reinventing something here or would you implement a collapse function like this in a similar way ? https://gist.github.com/gilligan/991020497219d5e827a8
Hardy Jones
@joneshf
Jul 31 2015 11:07
I think it'd be a bit more reusable if you didn't case on the length ofthe group.
when you go to consume this result array, you have to then case on each element, rather than being able to reason about it uniformly.
does that make sense?
I think you're also showing that ramda is missing some kind of split/break/span thing that gives you the behavior of takeWhile and dropWhile. Then you wouldn't have to do that length/slice thing.
Scott Sauyet
@CrossEye
Jul 31 2015 11:23
@joneshf: I didn't quite follow. Are you suggesting an output more like [[1, 1, 1], [2], [3, 3], [4]]? If so, I heartily agree, and if so I imagine it should be fairly straightforward to do.
Hardy Jones
@joneshf
Jul 31 2015 11:23
yeah
Tobias Pflug
@gilligan
Jul 31 2015 11:29
@joneshf just came back ...
Scott Sauyet
@CrossEye
Jul 31 2015 11:29
I'm not sure I see the larger abstraction you're pointing to, but a version like this should be easy enough to write with a fold at least for lists. There would probably be a simple enough easy to do it as a steam transformation too.
Tobias Pflug
@gilligan
Jul 31 2015 11:31
@joneshf @CrossEye yeah it would make things easier to always return lists
@joneshf @CrossEye this code snippet is the result of rewriting some code i discovered in a code base at work that looked kind of ugly
Hardy Jones
@joneshf
Jul 31 2015 11:36
@CrossEye I mean something like the following:
var span = R.curry(function(f, xs) {
  return {_1: R.takeWhile(f, xs), _2: R.dropWhile(f, xs)};
});
though ideally more efficient in its implementation
Scott Sauyet
@CrossEye
Jul 31 2015 11:42
Ok, so a single span at a time, that makes sense. It might require flattening a resulting structure in order to be usefu lfor the original problem, but that's doable. Hmm.
Scott Sauyet
@CrossEye
Jul 31 2015 12:47
Hardy Jones
@joneshf
Jul 31 2015 13:21
(R.length(acc) && elt == R.head(R.last(acc))) === R.contains(elt, acc.slice(-1))
Martin Algesten
@algesten
Jul 31 2015 13:34
@scott-christopher i'm thinking about naming. would that last gist technically be a "lift"? i mean since it's optional whether you use promises. it's not a pure lift then, right?
Scott Sauyet
@CrossEye
Jul 31 2015 13:40
@joneshf yes, and there ate probably other improvements to be had. Just a quick proof of concept.
Hardy Jones
@joneshf
Jul 31 2015 13:54
@CrossEye sorry, that was supposed to be a question, but I forgot to put the question mark.
Hardy Jones
@joneshf
Jul 31 2015 14:00

@algesten So you want to combine the behavior of map and chain into plift? There was a HUGE issue about this: promises-aplus/promises-spec#94

You can do that if you want, but you make plift quite a bit harder to reason about. It's easier to use, no doubt, but parametricity goes right out the window.

Of course, if you keep all three, then no harm no foul, or something.
you still get all the goodness of parametricity when you care about that, and you get all the goodness of an api that tries to do its best when you care about that.
Just don't try to reason in the large about what plift is doing.
Martin Algesten
@algesten
Jul 31 2015 14:14
@joneshf i don't know if i want to combine the behaviour of map and chain. the only thing i want is fn = plift (a,b) -> a + b to work for both fn(1,2) as well as fn(Promise(1),Promise(2)). the former resulting in 3 and the latter a Promise(3)
i.e. making any function multi purpose to accept both plain values as well as promise for values.
Hardy Jones
@joneshf
Jul 31 2015 14:19
Oh, I misunderstood what plift was doing with _promapply.
Scott Sauyet
@CrossEye
Jul 31 2015 14:19
@joneshf: I don't have any time to look at it closely. But that looks like it would serve an equivalent row role even if the behavior's not identical.
Thomas Collardeau
@collardeau
Jul 31 2015 16:21
Does anyone know, when given two objects, how to return a new object of the differences? Like an opposite R.merge, if you will.
So, { a: 'a', b: 'b'} and {a: 'a', b:'c'} would return {b:'c'}
Scott Sauyet
@CrossEye
Jul 31 2015 16:30
I've never seen that, but it sounds relatively straightforward to write, using functions such as differenceWith, keys, and fromPairs. Sorry I have no time to try it now.
Thomas Collardeau
@collardeau
Jul 31 2015 16:31
thanks i'll check out these functions now
Nieralyte
@Nieralyte
Jul 31 2015 18:02
what's up! is there a way to export all the R.* functions into a local scope? i don't want to pollute the global object
David Chambers
@davidchambers
Jul 31 2015 18:04
JavaScript doesn’t provide this, unfortunately. In Python, for example, one could write from ramda import *.
Nieralyte
@Nieralyte
Jul 31 2015 18:05
ah, alright, thanks
and another question, how do i convert "regular" functions like obj.fn(arg1, arg2) into curried fn.(arg1, arg2, obj)?
i know there's _.rearg in lodash, but maybe there's built-in way
Nieralyte
@Nieralyte
Jul 31 2015 18:19
not sure what's gonna happen with functions taking arbitrary number of args
Simon Friis Vindum
@paldepind
Jul 31 2015 19:12
@Nieralyte R.invoker?
Nieralyte
@Nieralyte
Jul 31 2015 19:25
@paldepind finally i've figured out how to use it! i've been trying... should've done this: R.invoker(2, 'fn')(arg1,arg2,obj). thanks!
David Chase
@davidchase
Jul 31 2015 19:36
hey question for you guys, is there a nice way to merge an array of objects so object at index 0 with object at index 3, and index 1 with index 4, and so on::
[{"name": "twitter"}, {"name": "pinterest"}, {"name": "instagram"}, {"url": "davidchase03"}, {"url": "davidchase"}, {"url": "david.chase"}]
David Chambers
@davidchambers
Jul 31 2015 19:45
@davidchase, it looks as though you need to split the list in two halves then “zip-with” the resulting lists.
Nieralyte
@Nieralyte
Jul 31 2015 19:48
what would i use to convert fn(val, cb1, cb2) into curried fn(cb1, cb2, val)?
e.g. to convert "regular" map(val, cb) into map(cb)(val)? (i know there's R.map, but it's for an example)
David Chase
@davidchase
Jul 31 2015 19:49
@davidchambers interesting so i can R.zipWith with R.merge
David Chambers
@davidchambers
Jul 31 2015 20:04
Something like that should work.
David Chase
@davidchase
Jul 31 2015 20:08
it did, thanks for the tip :smile:
David Chambers
@davidchambers
Jul 31 2015 20:28

Several times I’ve wanted a “split-at” function. Something like this:

> R.splitAt(3, [1, 2, 3, 4, 5])
[[1, 2, 3], [4, 5]]
> R.splitAt(3, [1, 2, 3, 4, 5, 6])
[[1, 2, 3], [4, 5, 6]]
> R.splitAt(3, [1, 2, 3, 4, 5, 6, 7])
[[1, 2, 3], [4, 5, 6, 7]]

Have others ever wanted to do this?

Scott Sauyet
@CrossEye
Jul 31 2015 20:40
What's the result for splitAt (3, [1, 2, 3, 4, 5, 3, 6, 3, 3, 3, 7])? Does it already return at most a 2-element list? What if there are no 3's?
David Chambers
@davidchambers
Jul 31 2015 20:45

Here’s a clearer example:

> R.splitAt(3, ['a', 'b', 'c', 'd', 'e'])
[['a', 'b', 'c'], ['d', 'e']]
> R.splitAt(3, ['a', 'b', 'c', 'd', 'e', 'f'])
[['a', 'b', 'c'], ['d', 'e', 'f']]
> R.splitAt(3, ['a', 'b', 'c', 'd', 'e', 'f', 'g'])
[['a', 'b', 'c'], ['d', 'e', 'f', 'g']]

The first argument is just an index.

From time to time I’ve found myself wanting to split a list into two halves, and doing this with both R.take and R.drop is error-prone as one needs to be careful to include the middle element exactly once when the list has an odd number of elements.
Nieralyte
@Nieralyte
Jul 31 2015 20:52
btw, are there functions allowing splitting an array into N subarrays? or a function to split an array into groups of N elements (different)?
David Chase
@davidchase
Jul 31 2015 21:08
R.splitAt would be sweet
Shane Keulen
@SeeThruHead
Jul 31 2015 21:08

hello, i was hoping someone could help me better understand functional programming. I had a simple challenge, to find the biggest difference between elements in an array, where the small number must come before the largest.

function biggestGap(values) {

  function diff(curr, before) {
    return curr - Math.min.apply(null, before);
  }

  function diffs(values) {
    return values.map(function(x, i, ar) {
      return diff(x, ar.slice(0, i));
    });
  }

  return Math.max.apply(null, diffs(values));
}

is what I came up with. How would i do something like this with ramda map where the the array and index isn't passed in?

or what alternative function would i use?
Scott Sauyet
@CrossEye
Jul 31 2015 21:26
@davidchambers: this should still be readily built out of take(n) and drop(n), right?
@SeeThruHead: you can always use addIndex of you need.
Scott Sauyet
@CrossEye
Jul 31 2015 21:34
But as you're looking for a single value, map is not appropriate. Probably a reduce.
David Chambers
@davidchambers
Jul 31 2015 21:39
@CrossEye: Absolutely. It’s just that R.splitAt(n) is nice sugar for R.converge(R.pair, R.take(n), R.drop(n)), particularly since n is only referenced once which avoids the need for a variable.
Martin Algesten
@algesten
Jul 31 2015 21:39
This message was deleted
@SeeThruHead
R.reduce(function(p,c) { return [Math.min(p[0],c), Math.max(p[1],c)] }, [R.take(1,values),R.take(1,values)], R.drop(1,values));
Martin Algesten
@algesten
Jul 31 2015 21:47
but i'm sure someone here can improve on that
Shane Keulen
@SeeThruHead
Jul 31 2015 22:13
algesten, not sure but that produces [1, 30] for [29, 30, 1, 10] where the answer should be 9
@CrossEye that doesn't pass in the array, meaning i would have to reference the array outside the map function, making it non pure, if that matters
David Chambers
@davidchambers
Jul 31 2015 22:33
@SeeThruHead, here’s my solution:
// max :: [a] -> a
const max = Function.apply.bind(Math.max, Math);

// biggestGap :: [Number] -> Number
const biggestGap = xs => max(xs.map((x, idx, xs) => max(xs.slice(idx)) - x));
Shane Keulen
@SeeThruHead
Jul 31 2015 22:42
cool that's the same as what i did, so you would use a map with xs rather than ramda's map
Shane Keulen
@SeeThruHead
Jul 31 2015 22:50
(defn biggest-gap [vals]
  (apply max (flatten (map (fn [x num]
                     (map #(- % x) (drop num vals)))
                   vals
                   (rest (range))))))
what about translating this to ramda?
David Chambers
@davidchambers
Jul 31 2015 22:51
That should be possible.
Shane Keulen
@SeeThruHead
Jul 31 2015 22:51
i don't know clojure but that's what my friend sent me
looks like map is taking two lists though
David Chambers
@davidchambers
Jul 31 2015 22:52
Why do you say that?
Shane Keulen
@SeeThruHead
Jul 31 2015 22:52
map #(- % x)
it's taking vals and (drop num vals) right
which makes a lot of sense
David Chambers
@davidchambers
Jul 31 2015 22:53
#(- % x) is an anonymous function. In JavaScript one would write _ => _ - x.
Shane Keulen
@SeeThruHead
Jul 31 2015 22:53
oh