These are chat archives for ramda/ramda

10th
Oct 2017
Jason Shin
@JasonShin
Oct 10 2017 09:57
hey guys
is there a method like Lodash/fp 's getOr in ramda?

I want to do something like

R.xx(null, 'a.b.c.d', object)

James Forbes
@JAForbes
Oct 10 2017 09:58
pathOr and propOr
Rolf Strijdhorst
@rolfst
Oct 10 2017 09:59
@barneycarroll I sense a new VIM addict? ;)
null?
James Forbes
@JAForbes
Oct 10 2017 10:02
yeah you can't do a.b.c.d with propOr
propOr targets one property
so propOr(null, 'a')
You'd want pathOr
but pass in an array of properties
pathOr(null, ['a', 'b', 'c', 'd'])
Denis Stoyanov
@xgrommx
Oct 10 2017 10:08
I often use {path,prop}Or
James Forbes
@JAForbes
Oct 10 2017 10:11
great functions
Jason Shin
@JasonShin
Oct 10 2017 10:18
hmm, why not just support getOr

getOr will look like

getOr(null, 'a["z"].c.v', obj)

It seems like getOr is just an alias of propOr if I am not mistaken
Jason Shin
@JasonShin
Oct 10 2017 10:24
maybe there's no benefit of it
haha..
Barney Carroll
@barneycarroll
Oct 10 2017 10:26
Does getOr set in the second condition?
James Forbes
@JAForbes
Oct 10 2017 10:39
@JasonShin lodash opts for convenience not simplicity
Barney Carroll
@barneycarroll
Oct 10 2017 11:19
Sorry we don't say 'second' for binary types, we say 'right', right?
Barney Carroll
@barneycarroll
Oct 10 2017 11:32
Isn't the particular variant of authoritarianism down to structural problems @JAForbes?
The 'champions' are self selecting from a set of employees of patronising organisations who are tasked with adopting a proposal from the wild and marshalling it through TC-39 with the backing of their day job
Barney Carroll
@barneycarroll
Oct 10 2017 11:37
So a new power dynamic is established as soon as something becomes adopted by a champion, and becomes a thing where dialog below and dialog above have competing concerns
Barney Carroll
@barneycarroll
Oct 10 2017 11:42
It's fairly formal, most democracies have the same problem. Our representatives are selected by parties and they present themselves to constituents to champion their interests. They have a nominal need to address, in the broad, the concerns of their constituents, but constituents are a pain when you'd rather do something that works for you vis-a-vis the party. If you can get something through relatively easily that plays to party interests that's a less stressful path to success, especially if the constituents are docile.
So the constituents concerns themselves become a problem in the overall dynamic.
James Forbes
@JAForbes
Oct 10 2017 12:26
Oh yeah but beyond just tc39, just programming communities in general. its endemic.
Aaron Mc Adam
@aaronmcadam
Oct 10 2017 14:45
anybody else having trouble with Ramda 0.25? With importing?
var _ramda = require('ramda');

var _ramda2 = _interopRequireDefault(_ramda);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { 'default': obj };
}

_ramda2['default'] // returns undefined
that's the webpack output
So calling R.flip for example fails
_ramda2 returns the right object with all the functions on it, so
Aaron Mc Adam
@aaronmcadam
Oct 10 2017 14:52
It seems I'll have to use import * as R from 'ramda' instead of import R from 'ramda': ramda/ramda#2322
Fred Daoud
@foxdonut
Oct 10 2017 15:18
Are there any release notes about Ramda 0.25?
Kevin Wallace
@kedashoe
Oct 10 2017 17:01
@foxdonut ramda/ramda#2319
Fred Daoud
@foxdonut
Oct 10 2017 17:09
thanks @kedashoe !
Kevin Wallace
@kedashoe
Oct 10 2017 17:10
:beers:
Thomas Kempel
@thomaskempel
Oct 10 2017 19:04
Hi there, at the moment i am refreshing my fp skills and stumbled upon ramda. The documentation is great and helped me a lot. But with my current problem I stuck and can't find any solution out there.
Is there a way to write this nice (not nested)
const inputData = [[1, 2], [2, 3], [4, 5]];
const result = R.map(R.map(R.inc))(inputData);
I thought this would be a case for compose but it didn't work out
Philipp Wille
@Yord
Oct 10 2017 19:09
@thomaskempel Well you could do:
o(map, map)(inc)(inputData)
(although I admit this is not too straight forward)
Philipp Wille
@Yord
Oct 10 2017 19:16
(straight forward is not the right term I guess, maybe I am looking for "clean" or something?)
Thomas Kempel
@thomaskempel
Oct 10 2017 19:17
Cool, didn't know that function. When I compared the signature I just noticed that I used compose the wrong way and it also works.
like compose(map, map)(inc)(inputData)
Philipp Wille
@Yord
Oct 10 2017 19:18
yup, o is a binary and curried version of compose :)
Thomas Kempel
@thomaskempel
Oct 10 2017 19:18
I had compose(map(inc), map)(inputData)
Philipp Wille
@Yord
Oct 10 2017 19:21
I did not like compose when I started using ramda because of the different way of thinking compared to pipe and I made lots of similar errors like that. Recently I began appreciating and preferring compose however. It starts to make sense after a while, I guess ;)
Thomas Kempel
@thomaskempel
Oct 10 2017 19:24
do you mean the right-to-left composition? But shouldn't this still work? I am a little bit confused why I can't partially apply the function
Philipp Wille
@Yord
Oct 10 2017 19:26
Do you mean why compose cannot be partially applied?
As I understand, since the arity of the first parameter, the function list, is variable, compose cannot be curried
In contrast to o, which is restricted to exactly two functions in its first parameter
Thomas Kempel
@thomaskempel
Oct 10 2017 19:28
in your example you compose the two map functions and then apply the first argument (ok partially). But should it be possible to apply the function directly to the map?
Philipp Wille
@Yord
Oct 10 2017 19:28
so while o(map)(map)(inc)(inputData) is valid, compose cannot be partially applied since it is not curried
ah I understand you now, let me think on that ;)
ok so this is possible in general. However, not in this example
since inputData is applied to the outer map
o(map, map(inc))(inputData) for example would apply it to the inner map
so the only way is to flatten out map(map(inc)) first before applying inputData to it
Thomas Kempel
@thomaskempel
Oct 10 2017 19:34
is o(map, map(inc))(inputData) working for you? wehn i call this i get an function back?
Philipp Wille
@Yord
Oct 10 2017 19:34
Yes, that was my point, sry for being unclear. ;) It does not work for me either
If you wanted to keep map(inc) you could do something like:
useWith(map)([identity, identity])(map(inc), inputData)
(which adds a lot of boilerplate)
but could be abbreviated to:
useWith(map)([])(map(inc), inputData)
(since identity is default)
(I guess? ;))
Thomas Kempel
@thomaskempel
Oct 10 2017 19:39
The first solution looks good to me. Thanks so much for you help! I just wanted to know, why it doesnt work.
what did you mean by "flatten out map(map(inc))"
sorry for the maybe stupid questions :-)
Philipp Wille
@Yord
Oct 10 2017 19:41
No problem, I am a little sloppy with words ;)
I meant, if you wanted to pull out map(inc) from the parameter
Oh and just to close up, of course you may also use apply:
apply(map)([map(inc), inputData])
Thomas Kempel
@thomaskempel
Oct 10 2017 19:47
ok, I got it. Thank you! :+1:
Kurt Milam
@kurtmilam
Oct 10 2017 20:03
@thomaskempel Here are two more options, just for fun :)
pipe( unnest
    , map( inc )
    , splitEvery( 2 )
    )
    ( data )

const isNotNil = complement( isNil )
// recursive, works on multiple levels and on objects, i.e. [[1, 2], [2, 3], {a:4, b:5}]
const incDeep =
  map( ifElse( both( is( Object ) )
                   ( isNotNil )
             )
             ( xs => incDeep( xs ) )
             ( inc )
     )

incDeep( data )
arian‮
@arian-swydo
Oct 10 2017 21:06
hmm curious if 0.25 flip fix also fixes the issue i had with flip as a combinator
Scott Sauyet
@CrossEye
Oct 10 2017 21:11

I think about it this way. If I had to map over a Maybe, I would do this:

map(inc)(Just(5)) //=> Just(6)
map(inc)(Nothing()) //=> Nothing()

That Ramda allows me to do this instead is mostly a distraction, syntactic sugar, a convenience:

map(inc, Just(5)) //=> Just(5)

Essentially, I'm calling the function map(inc) on my value. I could name this function, if I chose:

const incrementIt = map(inc)
incrementIt(Just(7))  //=> Just(8)

Now if I want to call this on a list of Maybe values, I can simply do:

map(incrementIt)([Just(3), Nothing(), Just(5)])  //=> [Just(4), Nothing(), Just(6)]

But that of course is the same as:

map(map(inc))([Just(3), Nothing(), Just(5)]) //=> [Just(4), Nothing(), Just(6)]

And then if we have a list of lists instead of a list of Maybes, it's the same process

const inputData = [[1, 2], [2, 3], [4, 5]];
map(map(inc))(inputData) //=> [[2, 3], [3, 4], [5, 6]]

regardless of how we call it:

map(map(inc), inputData) //=> [[2, 3], [3, 4], [5, 6]]

The point is that from the perspective of the outer map function, the inner map(inc) is a unit; it simply can't be broken into meaningful chunks.

I don't think @Yord's useWith solution offers much, but there is an interesting variant. If you're not familiar with useWith, it's essentially this (in the binary case):

useWith(f, [g, h])(x, y) //=> f(g(x), h(y))

So we would do either of these:

useWith(map, [map, identity])(inc, inputData) //=> [[2, 3], [3, 4], [5, 6]]
useWith(map, [map])(inc, inputData) //=> [[2, 3], [3, 4], [5, 6]]

(The only difference is the reported arigy of useWith(map, [map, identity])) of 2 versus useWith(map, [map]) of 1. Otherwise they work the same.

This leads to a potentially useful abstraction:

const doubleMap = useWith(map, [map, identity])
doubleMap(inc, [Just(3), Nothing(), Just(5)]) //=> [Just(4), Nothing(), Just(6)]
doubleMap(inc, inputData) //=> [[2, 3], [3, 4], [5, 6]]

Then we could use this with another function:

const square = n => n * n
doubleMap(square, [Just(3), Nothing(), Just(5)]) //=> [Just(9), Nothing(), Just(25)]
doubleMap(square, inputData) //=> [[1, 4], [4, 9], [16, 25]]
arian‮
@arian-swydo
Oct 10 2017 21:20
maybe I'm mistaken, but wouldn't lift(map(inc))(inputData) work the same
Scott Sauyet
@CrossEye
Oct 10 2017 21:22
Yes, it would do the same thing.
It doesn't have quite the same flexibility, since you can't do lift(map(inc), inputData), but it's essentially the same.
arian‮
@arian-swydo
Oct 10 2017 21:25
yeah so not much better then
Luca Matteis
@lmatteis
Oct 10 2017 21:28
hi guys. is there an easy way to do multiple path operations on the same object, such as: const one = path(['foo', 'bar'], obj) const two = path(['foo', 'baz'], obj)
instead of holding both variables around
arian‮
@arian-swydo
Oct 10 2017 21:34
i would do something terrible like: o(flip(path)(obj))(concat('foo'))('baz')
(I'm am awful human being)
Luca Matteis
@lmatteis
Oct 10 2017 21:58
wat
don't understand that but ok :)
arian‮
@arian-swydo
Oct 10 2017 22:18
if you do flip(path), you can pass the data object before you pass the path 'flip(path)(obj)(['foo','baz'])'
then you can concat the identical part of the path to the unique part
arian‮
@arian-swydo
Oct 10 2017 22:59
I'm sorry, I had to do this: https://goo.gl/o6n7Eg
Fred Daoud
@foxdonut
Oct 10 2017 23:42
@arian-swydo are you ok? :worried:
arian‮
@arian-swydo
Oct 10 2017 23:45
no, but mostly because eslint won't allow me to pretty fp code ;)