These are chat archives for ramda/ramda

5th
Oct 2017
Victor Viale
@Koroeskohr
Oct 05 2017 08:58
hey people, I just wanted to know if i was becoming crazy or not. or returns true if any of its arguments return true for a given value right ?
then why does this return false ? or(isNil, isEmpty)('')
Adam Szaraniec
@mimol91
Oct 05 2017 09:06
@Koroeskohr you should use either
it returns true becuase isNil is an function , its equivalent to isNill || isEmpty

To be honest I think

or(isNil, isEmpty)

Should return false (It return 1st truth argument -> its JS specific)

Victor Viale
@Koroeskohr
Oct 05 2017 09:08
I'm stupid :D thanks Adam, sorry for bothering
Adam Szaraniec
@mimol91
Oct 05 2017 09:11
There is cool feature, which I didnt notice in documentation, unless someone told me -> You can click on EXPAND parameters, near function documentations
Aaron Mc Adam
@aaronmcadam
Oct 05 2017 10:40
I didn't want to transform the array values when sorting @Bradcomp. I was trying to use ascend but that didn't work the way I thought
so I'll have to use identity
Aaron Mc Adam
@aaronmcadam
Oct 05 2017 10:50
Jason Shin
@JasonShin
Oct 05 2017 10:56
Hey guys can I ask you a question?
If you have an array of Futures, how do you resolve them all but in order of the array content?
[Future, Future2, Future3], I want to resolve them 1 by 1 and pass down result to next Future

Somehow when I

R.compose.apply(null, listOfFutures).fork() it does not work

Rolf Strijdhorst
@rolfst
Oct 05 2017 11:00
By future you mean promise?
Jason Shin
@JasonShin
Oct 05 2017 11:00
I mean fluture.Future
I am currently doing R.traverse(Future.of, futureFunction, [listOfArgs]) but I cannot pass down result of previous future into next future
Rolf Strijdhorst
@rolfst
Oct 05 2017 11:01
Sorry I have no experience with Futures
Jason Shin
@JasonShin
Oct 05 2017 11:02
ok, thanks anyways
Kurt Milam
@kurtmilam
Oct 05 2017 11:05
@JasonShin there is a gitter channel for Fluture here
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 15:18
@JasonShin I would think you could use...
R.pipeK
Robert Mennell
@skatcat31
Oct 05 2017 16:05
@JAForbes Well if compose becomes native code and reserved as a language construct reserved word, then there we go inlining is fine as long as nothing overwrites compose in which case it's just remembering to refactor any calls to compose with a rename in the build tool, ala take from point of overwriting in code with variable reference, go to end of scope, replace compose with next var name in unclaimed randoms. We've noticed this behavoiur when we overwrite any built in type function(often Promise with Bluebird) where it will pull in Bluebird into the build. It would depend on the build tool at that point to be intelligent enough to notice those sorts of things... man I hope they are
Rupesh Tiwari
@roopkt
Oct 05 2017 16:55
const s =  [ "paint", "shirt"  ] 
const d =  [ 3, 2  ] 

const x = assoc("new",4, zipObj(s,d));
console.log(x) //=>{"new": 4, "paint": 3, "shirt": 2}
How to get back 2 arrays again ?
output //=> [ "new", "paint", "shirt" ] and [4,3,2]
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 17:00
@ram-bot
compose(transpose, toPairs)({"new": 4, "paint": 3, "shirt": 2})
ram-bot
@ram-bot
Oct 05 2017 17:00
[ [ 'new', 'paint', 'shirt' ], [ 4, 3, 2 ] ]
Rupesh Tiwari
@roopkt
Oct 05 2017 17:13
@Bradcomp Excellent ! I learned new thing called transpose
It worked
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 17:14
:bowtie:
Brian Gates
@brian-gates
Oct 05 2017 18:15
Hey all. I have an object which contains a value at one of several possible known locations. What's the best way to get that value?
I'm thinking an array of R.path definitions
then iterating through the list and returning the first non-null value
I'd like to quit early if an answer is found, however.
I kinda want R.or but with > 2 options
var possibleValueLocations = [
  R.path(['foo']),
  R.path(['foobar']),
  R.path(['foobaz']),
  ...
];
Brian Gates
@brian-gates
Oct 05 2017 18:21
to which you could pass any of the following and get 'bar':
{ foo: 'bar' }
{ foobar: 'bar' }
{ foobaz: 'bar' }
Michael Rosata
@mrosata
Oct 05 2017 18:24
@brian-gates you could do const possibleValueLocations = either(prop('foo'), either(prop('foobar'), prop('foobaz')))
Brian Gates
@brian-gates
Oct 05 2017 18:25
true, but that gets a bit unwieldy pretty quickly
))))))))))
hehe
I could reduce a list of transform functions, I suppose
var result = fn(current); return result || current;
return fn(current) || current
Brian Gates
@brian-gates
Oct 05 2017 18:30
that'd unnecessarily execute each transform though
🤔
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:31
R.reduced
Urban
@UrKr
Oct 05 2017 18:31
Could the notion of transients (like clojurescript) apply to ramda? Some way to do some of the operations with mutations. R.assoc inside R.reduce for instance is quite expensive. Would be much cheaper to shallow copy the initial value once, and just mutate after. Just throwing it out there, not sure how it applies :)
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:31
R.reduceWhile
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:32
But really, could you use R.find
R.find
Brian Gates
@brian-gates
Oct 05 2017 18:32
ooh
Brian Gates
@brian-gates
Oct 05 2017 18:32
those are useful
I suppose find could work, if the list were the transform functions and the predicate were the result of those transforms
it's the inverse of what find is typically used for, but it still makes sense
let me give that a try.
actually I don't think find will work, exactly
well, not ideally, anyway
it'd find the transform function (by executing it), then you'd have to execute it again to get the value
R.reduced seems slightly more efficient
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:36
https://goo.gl/pC131a

it'd find the transform function (by executing it), then you'd have to execute it again to get the value

Yup

Brian Gates
@brian-gates
Oct 05 2017 18:37
a short circuited reduce seems ideal
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:37
That seems like a small point in this case, path isn't terribly computationally expensive
Brian Gates
@brian-gates
Oct 05 2017 18:37
very true
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:39
But if the check was computationally expensive, I would consider using reduced to ... reduce the overhead ;)
Brian Gates
@brian-gates
Oct 05 2017 18:44
var possiblePaths = [
  R.path(['foo']),
  R.path(['foobar']),
  R.path(['foobaz']),
];

var findBar = R.reduce((obj, fn) => {
  var val = fn(obj);
  if (val !== undefined) {
    return R.reduced(val);
  }
  return obj;
}, R.__, possiblePaths);

R.map(findBar, [
  { foo: 'bar' },
  { foobar: 'bar' },
  { foobaz: 'bar' },
]);
I see what you did there ;)
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 18:52
That looks good. One thing to consider in either case is what you get if none of the paths match
Brian Gates
@brian-gates
Oct 05 2017 18:52
good point
ideally it would be undefined
in this case it'd be the object
Brian Gates
@brian-gates
Oct 05 2017 18:58
hm, can't think of a good way to do that.
I could pipe the result to a final check to see if it's the original value
/shrug
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 19:00
Gimme a minute
Brian Gates
@brian-gates
Oct 05 2017 19:02
var getters = [
  R.path(['foo']),
  R.path(['foobar']),
  R.path(['foobaz']),
];

var reducer = R.reduce((obj, fn) => {
  var val = fn(obj);
  if (val !== undefined) {
    return R.reduced(val);
  }
  return obj;
}, R.__, getters);

var findBar = R.pipe(obj => {
  var reduced = reducer(obj);
  return reduced === obj ? undefined : reduced;
});

R.map(findBar, [
  { foo: 'bar' },
  { foobar: 'bar' },
  { foobaz: 'bar' },
  {},
]);
kindof a hack
but it does work
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 19:02
You can do this with Either. Use Right(obj) to represent the original object. map over it, returning a Left if you find it. Then at the end you have either a Right(obj) or a Left(matching prop)
Because map only maps over the Right of an Either you don't need to worry about modifying the value once you find it
Brian Gates
@brian-gates
Oct 05 2017 19:04
true, I don't have those methods at my disposal though
but that does sound generally more elegant
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 19:06
Gotcha.I'll generally use data.either from Folktale (the old one) when I want to reach for that structure
Michael Rosata
@mrosata
Oct 05 2017 19:06
This is ugly, but I think it works
const getFirstAvailableProp = props => obj => o(
  flip(prop)(obj),
  find(has(R.__, obj))
)(props)

getFirstAvailableProp(['foo','foobar', 'foobaz'])({ foobar: 300 }) // 300
getFirstAvailableProp(['foo','foobar', 'foobaz'])({ foobiz: 300 }) // undefined
Brian Gates
@brian-gates
Oct 05 2017 19:08
what's o?
compose?
Michael Rosata
@mrosata
Oct 05 2017 19:08
binary curried compose
const getFirstAvailableProp = props => obj => pipe(
  find(has(R.__, obj)),
  flip(prop)(obj)
)(props)
that maybe prettier (relatively speaking)
Brian Gates
@brian-gates
Oct 05 2017 19:10
yeah, gee golly, I'll do find. the elegance is worth the double execution.
readability gains > performance gains in this case
Kurt Milam
@kurtmilam
Oct 05 2017 19:14
@skatcat31 I thought your original position was that compose should remain a userland construct.
@brian-gates I'd appreciate it if you'd moderate your language in this forum.
Brian Gates
@brian-gates
Oct 05 2017 19:15
sure, my apologies.
Robert Mennell
@skatcat31
Oct 05 2017 19:15
@kurtmilam it totally is, but if things are gonna happen regardless of my voice might as well get ready for it and/or try to improve it
Kurt Milam
@kurtmilam
Oct 05 2017 19:15
@brian-gates :+1: Thanks!
Robert Mennell
@skatcat31
Oct 05 2017 19:15
after all there is no problem with respectful discord or intelligent discussion
Kurt Milam
@kurtmilam
Oct 05 2017 19:20
I'm of the opinion that compose is useful enough to be added as a native construct, partly because that will make inlining easier. I'd prefer to see it work like Ramda's o or Haskell's ., which means it's a perfect candidate for an infix operator. I find the first example far superior to the second, here:
const missyElliot = reverseBits +> negate +> add(-1)

const missyElliot = compose(compose(reverseBits, negate), add(-1))
Nice touch on the missyElliot example btw ;)
Brian Gates
@brian-gates
Oct 05 2017 19:30
is there a babel plugin for this, maybe?
Fernando Montoya
@montogeek
Oct 05 2017 22:36
How could I use Ramda to given an array of elements filter up to 3 elements that matches certain criteria?
I already did it using JS, but want a better approach:
const videos = posts.filter(post => post.format === 'video').slice(0, MAX_VIDEOS)
const photos = posts.filter(post => post.format === 'photo')
posts = photos.concat(videos)
Michael Rosata
@mrosata
Oct 05 2017 22:42
@montogeek maybe something like this?
// I just edited to add in some example data
const posts = [
  { format: 'video', id: 1 },
  { format: 'text', id: 2 },
  { format: 'photo', id: 3 },
  { format: 'video', id: 4 },
  { format: 'photo', id: 5 },
  { format: 'video', id: 6 },
  { format: 'text', id: 8 },
  { format: 'photo', id: 11 },
]
const takeThree = pipe(
  filter(either(propEq('format', 'video'), propEq('format', 'photo'))),
  take(3)
)
takeThree(posts) // [{"format": "video", "id": 1}, {"format": "photo", "id": 3}, {"format": "video", "id": 4}]
Fernando Montoya
@montogeek
Oct 05 2017 22:55
@mrosata Thank you so much and sorry, I didnt explain myself clearly, I want to take all the photos and only 3 videos
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:03
Fernando Montoya
@montogeek
Oct 05 2017 23:05
@Bradcomp Thank you, know I have to study every function
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:05
Haha
It would be totally valid to use converge instead of lift
R.converge
Fernando Montoya
@montogeek
Oct 05 2017 23:08
I have never used Ramda, I knew about its existence, feels like this was a good use of it
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:09
:+1:
It's a good use for it, but I think your solution is good too
Fernando Montoya
@montogeek
Oct 05 2017 23:09
What I dont like about my solution is that all3 videos would be at the end of the array
I thought in a classical for that counts up to the limit and break if all videos were added
But want a functional approach haha
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:16
Aaah, so you want to keep the first three videos, all the photos, but inline instead of partitioned
Fernando Montoya
@montogeek
Oct 05 2017 23:17
correct
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:21
It's not totally pure, but we keep the impurity wrapped up in a separate function at least.
Fernando Montoya
@montogeek
Oct 05 2017 23:21
@Bradcomp We can say that this works but it is a poor way to use Ramda https://goo.gl/6rgQsG ?
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:22
I don't think that's a poor use at all
I like naming things. It helps with readability
Fernando Montoya
@montogeek
Oct 05 2017 23:23
Compared to your solution, it is very poor haha
I tried to implement it the same way I see it on my brain
R.lift
Fernando Montoya
@montogeek
Oct 05 2017 23:25
I dont understand lift function at all
I get the idea now...
Brad Compton (he/him)
@Bradcomp
Oct 05 2017 23:28
It works differently depending on what gets passed to it. But it takes a function and lifts it up so it can operate on higher level structures
so concat works on values, but we lift it to work on functions that return those values
lift(concat)(f, g)(val) === concat(f(val), g(val))
Fernando Montoya
@montogeek
Oct 05 2017 23:33
@Bradcomp Great explanation, it is more clear with that notation
I recall something like that from college...
Robert Mennell
@skatcat31
Oct 05 2017 23:46
@kurtmilam XKCD thought so too XD. The thought of it working like o is an interesting idea which makes +> much more papable to me for some reason...
Hadn't actually thought of it like that since got it in my head it should behave like Ramdas compose and compose all arguments