## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### 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
• Jan 31 2019 02:26
JeffreyChan commented #2777
• Jan 30 2019 14:30
CrossEye closed #2777
• Jan 30 2019 12:13
• Jan 30 2019 01:42
JeffreyChan commented #2777
• Jan 29 2019 21:06
• 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
But it works. :P
"Extracting the parameter from the middle" like you said is done with R.useWith or R.converge (if I understand you correctly).

Basically:
converge(f, a, b)(x, y) === f(a(x, y), b(x, y))
useWith(f, a, b)(x, y) === f(a(x), b(y))

So the passed in variable makes its way "deeper" into "the middle".

Jason Heard
@101100
@Avaq Thanks for the solution and explanation!
Jason Heard
@101100
I managed to remove the (null) hack: R.useWith(R.filter, R.pipe(R.unary(R.flip(R.contains)), R.partial(R.pipe, R.prop('id'))), R.identity), but I'm not sure if it is "better".
Aldwin Vlasblom
@Avaq
Certainly interesting, using partial to prepare a pipeline for its final function, I would never have thought of that. It's still a little convoluted, but I would say it's an improvement as there's no more artificial noop in there (always(x)(null) to get x :P ).
Scott Sauyet
@CrossEye
@101100: If you're doing this as a learning experience, it's an interesting exercise. But I would not make a fetish out of points-free. I think the following version is much more readable. (Of course the es6 syntax helps.):
((a, b) => R.chain(id => R.filter(R.propEq('id', id), b), a))
hemanth.hm
@hemanth
under what license is web ramda-repl ?
Aldwin Vlasblom
@Avaq

@CrossEye Agreed, I do believe this was meant to be an exercise though. :)

And coming back to it, @101100, I've found another way around the (null)-hack, much closer to my original plan. My first try was R.converge(R.compose, R.flip(R.contains), R.always(R.prop('id'))), but that returned a 2-ary function and I didn't understand why (it should only take in a). So I looked at the converge source today and noticed it chooses its arity based on the highest arity from the input functions, which was 2 for R.flip(R.contains). So the fix was to flag it as unary, so the complete thing becomes:

R.useWith(R.filter, R.converge(R.compose, R.unary(R.flip(R.contains)), R.always(R.prop('id'))), R.identity);

I'm not saying it's a better solution by any means (there's still a secret noop), but I did learn something new about converge I wanted to share. :)

Raine Virta
@raine
how do you map over a return value of a function that returns a thenable in pipe? is there a ramda function that checks for .then?
it used to be possible to use pipeP so that not all functions returned a Promise
Raine Virta
@raine
ramda/ramda#1314
Raine Virta
@raine
const then = curry((fn, thenable) => thenable.then(fn));
const getStuff = pipe(formatPath, readFile, then(toUpper));
there's probably a better way than coming up with a map (the then) specific to promises
Danielle McLean
@00dani
Well, typewise R.chain should be the right function for "mapping" promises. Of course, the standard promise API is incompatible with fantasy-land's monad definitions so it doesn't quite work out.
Martin Algesten
@algesten

I was trying to parse xml data using cheerio/jQuery the other day and it struck me how awkward those libraries are for functional programming.

So I decided to learn top down operator precedence-parsers and applied it to parsing CSS-expressions. End result is an attempt to make a lightweight tool for reading XML/HTML in a functional style. https://github.com/algesten/zu

Now I want it to work really well with Ramda, but I'm a bit stuck on currying. I want to have zu.parents(nodes, 'div > span') be curried as zu.parents('div > span')(nodes) but maybe also zu.parents(nodes)('div > span') but then that last form is not possible since i may also want zu.parents(nodes)as a one-arg version (just parents without an expression).

Does any of you fine minds have any thoughts on that currying conundrum?

jeffcato
@jeffcato
does ramda have an abstraction for switch or if/else that would make sense to use here?:
switch(req.method) {
case 'GET':
getCacheKey(cache, url).fork(
function(err) {
getDocuments(getCollection(db, collectionName)).fork(
send404(res),
sendPage(res, cache, collectionName, url)
);
},
function(value) {
console.log('sent cached value');
res.end(value);
}
);
break;
case 'POST':
// handle post req's
break;
default:
send404(res, null);
break;
}
Scott Sauyet
@CrossEye
@algesten: raganwald does this by offering a second version of many functions, suffixed with 'With'. So parents(selector)(nodes) and parentsWith(nodes)(selector) or vice versa.
jeffcato
@jeffcato
or possibly a monad in ramda-fantasy could handle it better?
i'm pretty new to functional programming in general so forgive me if this is obvious
Scott Sauyet
@CrossEye
@jeffcato: Ramda does have both ifElse and cond. One of those might help.
Martin Algesten
@algesten
@CrossEye thanks! i check raganwald out
Scott Sauyet
@CrossEye
@algesten, the first edition of his book JavaScript Allongé was a huge inspiration for me.
Almost finished with the second.
jeffcato
@jeffcato
@CrossEye ok thanks - i'll give one of those a shot
Martin Algesten
@algesten
@CrossEye googling. thanks :D
i just realised i had a bunch of essays to go through on his site.
good times!
Raine Virta
@raine
@typedef annotation in the lens functions throws off jsdoc parser, making it think those functions' kind is typedef (while it should be function), the name property is wrong as well
that's why they are not picked up by ramda-json-docs
Scott Sauyet
@CrossEye
I hacked together something to avoid that on the last release. I was hoping someone who understood lenses better could update the docs before the next one. ping @davidchambers.
David Chambers
@davidchambers
@algesten, I look forward to trying zu! I’d been thinking of writing a similar library myself. Hopefully that’s no longer necessary.
Scott Sauyet
@CrossEye
Glad you said something @davidchambers! I meant to look at this tonight, but it had already fallen off my radar. Too many things to do! Now I can add one more that I'm really interested in. Where to find the time?...
Scott Sauyet
@CrossEye
@algesten: just looked at the zu API. Very nice!
Jethro Larson
@jethrolarson
Zu is interesting. Personally I'd try swapping order of nodes and expr on the api
Martin Algesten
@algesten
@davidchambers @CrossEye @jethrolarson thanks!!! i'm about to put it into production code at work today. so i'll have it a bit more road tested.
@jethrolarson i have considered that. the order is to do with fnuc. but i want to play nice with the community. so i have a thought that require('zu/inverse') would give me same API but reverse order. i would consider making the default order expr/nodes since i acknowledge i may be the odd one out with fnuc.
Jethro Larson
@jethrolarson
Not heard of fnuc. I'll check it out
Jethro Larson
@jethrolarson
Is it a weird irony that it's "func" but jumbled :smile: neat stiff though
Raine Virta
@raine
@CrossEye I wonder if the @typedef annotation is used correctly. http://usejsdoc.org/tags-typedef.html
Scott Sauyet
@CrossEye
@raine: it's pretty clearly not used in the way JSDoc would like.
Martin Algesten
@algesten
@jethrolarson fnuc was me throwing toys out of the pram with ramda argument order. since then however, ramda has gone deep into fantasyland territory and i’m lost. i still use my own lib, but i know i must raise my game and understand why i would want functors, monads, etc.
Alex Schenkman
@alesch

Hi ramda folks,
I’m new to rambda and I would like to transform this JSON:

{
‘2’ : { ‘name': ‘two’},
‘1’ : {’name’ : ‘one’}
}

into some sorted iterable (list?) like this:

 [
{ id: ‘1’, name: ‘one'},
{ id: ‘2’, name: ’two'}
]

In other words I need to:

1. Iterate throgh the object entries, and set the id property to its key.
2. Iterate on that and sort by id.

How can I do this in an elegant way? All my attempts become quite imperative.
Thanks!

Danielle McLean
@00dani
@alesch Here's one way.
R.pipe(
R.mapObjIndexed( R.flip( R.assoc('id') )),
R.values,
R.sortBy(R.prop('id'))
)
Alex Schenkman
@alesch
@00Davo Thank you, I’ll read up on those functions.
Scott Sauyet
@CrossEye
Another: R.converge(R.zipWith(R.assoc('id')), R.keys, R.values). Note that if your ids are actually integers you won't need an additional sort.
Danielle McLean
@00dani
Oh. Whoops, my version compares the IDs as strings and so won't work if there're multiple digits. :blush: This fixes it, but @CrossEye's version is also correct and shorter so. Yeah.
R.pipe(
R.mapObjIndexed( R.useWith(R.flip(R.assoc('id')), R.identity, Number)),
R.values,
R.sortBy(R.prop('id'))
)
Martin Algesten
@algesten
every time i reach for R.pipe i feel a bit disappointed with myself...
Alex Schenkman
@alesch
Thank you @CrossEye. I’ll have to digest that one, :-P
Scott Sauyet
@CrossEye
@algesten: what's wrong with pipe?