These are chat archives for ramda/ramda

30th
Jun 2015
Jack Jennings
@jackjennings
Jun 30 2015 15:32
Is there an elegant way to compose two functions of different arity? I have a pattern like addClass(toClass(name), el) where toClass has arity 1 and addClass has arity 2.
R.compose I assume curries based on the arity of the last function…
Raine Virta
@raine
Jun 30 2015 15:34
sounds like a job for R.useWith
Jack Jennings
@jackjennings
Jun 30 2015 15:37
I saw that, but I wasn't able to wrap my head around how exactly it transforms the arguments. Can you show me how it would be used in this case, please?
Raine Virta
@raine
Jun 30 2015 15:38
something like
myFn = R.useWith(addClass, toClass, R.identity);
Jack Jennings
@jackjennings
Jun 30 2015 15:40
Hmm, ok. That seems straightforward. I'll mess around with it so that I can figure out the examples in the docs.
Thanks!
Raine Virta
@raine
Jun 30 2015 15:40
> var without = R.useWith(R.reject, R.identical, R.identity);
> without(1, [1,2,3])
[ 2, 3 ]
so basically you read it like R.reject but so that the functions after that are applied to the arguments in that order, and after that do R.reject
I guess you can unroll it like this
R.reject(R.identical(1), R.identity([1, 2, 3])
Jack Jennings
@jackjennings
Jun 30 2015 15:44
Ahh, that's really helpful
Raine Virta
@raine
Jun 30 2015 15:44
and I believe R.identity is optional
but it might be good to add for clarity
Jack Jennings
@jackjennings
Jun 30 2015 15:45
The docs indicate that it's used to report the correct arity of the new function, which seems like it's probably a good practice regardless.
Raine Virta
@raine
Jun 30 2015 15:46
hmm, right
Stefano Vozza
@svozza
Jun 30 2015 21:59
i have an array of heterogenous objects and i'd like to apply different functions to certain keys. if i were dealing with objects that were the same it'd be a perfect time for R.evolve; however, if i did that whenever evolve encounters a key that's not in a particular object it will add the key and that key will have undefined as its value. short of passing the objects through evolve and afterwards going through the array again and removing any keys from each object that are undefined is there an elegant way of doing this?
Stefano Vozza
@svozza
Jun 30 2015 22:10
var arr = [{a: 1, b:2,  c:3}, {a:4, c:5, d:6}];
R.map(R.evolve({a: R.inc, b: R.add(2), d: R.add(3)}), arr);

// => [ { a: 2, b: 4, c: 3, d: NaN }, 
//          { a: 5, c: 5, d: 9, b: NaN } ]
Aldwin Vlasblom
@Avaq
Jun 30 2015 22:17
When I paste your code into Try Ramda I get [{"a": 2, "b": 4, "c": 3}, {"a": 5, "c": 5, "d": 9}] as an output.
Stefano Vozza
@svozza
Jun 30 2015 22:27
that's really weird, i copy and pasted from the REPL
i did it in firefox but i get the same result in node, which is what i'm interested in
Aldwin Vlasblom
@Avaq
Jun 30 2015 22:31
Perhaps some kind of version inconsistency. :worried:
David Chambers
@davidchambers
Jun 30 2015 22:33
@svozza, I made a tweak to R.lensProp locally on my composable-lenses branch so that R.over only applies the transformation if the property exists:
var bLens = R.lensProp('b');

R.over(bLens, R.inc, {a: 1, b: 2});
//=> {a: 1, b: 3}
R.over(bLens, R.inc, {a: 1});
//=> {a: 1}
This seems nice to me. What do you think?
Stefano Vozza
@svozza
Jun 30 2015 22:38
yeah, i was considering lenses but i'm not going to use them until the new api is available in ramda 0.16. unfortunately i need to have this done by tomorrow so i can't afford to wait. also, i have about 7/8 keys in these objects that i want to update (some nested three levels down) so evolve is a bit more concise
David Chambers
@davidchambers
Jun 30 2015 22:40
For now you may like to define evolve in your project, using R.evolve as a starting point, to get the behaviour you want.
Stefano Vozza
@svozza
Jun 30 2015 22:42
yeah, i've just done that. all i did was add a check to see if the key was undefined and if it is just skip over it
i would have thought that was nicer behaviour anyway than filling an object with undefineds or NaNs
David Chambers
@davidchambers
Jun 30 2015 22:47
I agree.
The thing is that there are many functions I’d like to deprecate if and when we have the new lenses API, and R.evolve may be in this category.
I’d certainly be happy to see a pull request for your change, though.
Raine Virta
@raine
Jun 30 2015 22:48
what would replace evolve?
David Chambers
@davidchambers
Jun 30 2015 22:49
Composition of lenses, potentially.
Something like:
R.pipe(R.over(aLens, R.inc), R.over(bLens, R.dec), R.over(cLens, R.negate))
The nice thing is we’re composing individually useful pieces into something equivalent to what we can do with R.evolve.
Stefano Vozza
@svozza
Jun 30 2015 22:52
Yeah, i'll do up a PR, it's literally a one line change. might not get to it tonight cos i really have to finish this. ;)
definitely tomorrow
i look forward to breaking the build...
David Chambers
@davidchambers
Jun 30 2015 22:52
No rush. Good luck getting the project finished!
Raine Virta
@raine
Jun 30 2015 22:53
evolve is one of my most used functions in ramda, I wouldn't be too excited about any change that makes it less accessible :smile:
Stefano Vozza
@svozza
Jun 30 2015 22:53
how do you use lenses with nested keys, is it basically a lens on a lens?
David Chambers
@davidchambers
Jun 30 2015 22:54
@svozza, that’s exactly right.
Stefano Vozza
@svozza
Jun 30 2015 22:54
nice
David Chambers
@davidchambers
Jun 30 2015 22:54
@raine, I’d love to see some examples. I think I’m yet to use R.evolve in a project.
Raine Virta
@raine
Jun 30 2015 23:05
well, I guess one good example I've seen lately is the use with union-type's case matching to update a data model, like https://github.com/paldepind/noname-functional-frontend-framework/blob/f2cf584e6ff69fcb269b9d0e2b021ede6b82f5e1/examples/who-to-follow/main.js#L32-L36
another example, livescript though, http://git.io/vt9rQ used in https://www.habbo.com/mosaic/
not to mention that it's been insanely useful with ramda-cli
David Chambers
@davidchambers
Jun 30 2015 23:12
Do these two examples provide just one transformer?
In the first example it appears only the suggested property is transformed; in the second it appears only the background-color property is transformed.
I may be misreading the code, though.
Raine Virta
@raine
Jun 30 2015 23:16
I don't think you are
is there a better option?
David Chambers
@davidchambers
Jun 30 2015 23:20
Not currently. What I’m trying to ascertain is whether switching to lenses will be less convenient in common cases. R.evolve({a: R.inc, b: R.dec, c: R.negate}) is definitely more convenient than the equivalent lens-based composition, but if it turns out that multiple-property “evolutions” are uncommon I’ll be more inclined to suggest deprecating R.evolve.
Stefano Vozza
@svozza
Jun 30 2015 23:33
var alternateEvolver = evolve({
    alternates: R.find(R.propEq('cropName', 's458'))
});

var imageEvolver = evolve({
    image: {
        alternates: alternateEvolver
    },
    images: R.map(evolve({
        src: R.replace(/\/ALTERNATES\/s\d{3}/, '/ALTERNATIVES/s458')
    }))
});

evolve(R.compose(evolve({
    galleries: R.map(imageEvolver),
    contentTypes: R.map(R.compose(alternateEvolver, imageEvolver))
}), imageEvolver), test);