These are chat archives for ramda/ramda

2nd
Mar 2017
Rafi
@Rafi993
Mar 02 2017 04:20
There is something i was really wondering what is the reason behind RamdaJs logo. Just curious.
Gabe Johnson
@gabejohnson
Mar 02 2017 04:27
@Rafi993 ram + lambda = ramda
Keith Alexander
@kwijibo
Mar 02 2017 08:22
Have you guys seen https://soundcloud.com/lambda-cast ? Ramda gets mentioned frequently
Julio Borja Barra
@juboba
Mar 02 2017 09:07
how would you change the name of a property? I've been imagining something like compose(dissoc('myprop'), assoc('mynewpropname', [here goes something to get the value of 'myprop']))
Bravi
@Bravilogy
Mar 02 2017 10:11
hey guys, is there a way I can improve this code?
http://ramdajs.com/repl/?v=0.23.0#?const%20result%20%3D%20%7B%0A%20%20%22address_components%22%20%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22long_name%22%20%3A%20%2248%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22short_name%22%20%3A%20%2248%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22types%22%20%3A%20%5B%20%22street_number%22%20%5D%0A%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22long_name%22%20%3A%20%22Pirrama%20Road%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22short_name%22%20%3A%20%22Pirrama%20Road%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22types%22%20%3A%20%5B%20%22route%22%20%5D%0A%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22long_name%22%20%3A%20%22Pyrmont%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22short_name%22%20%3A%20%22Pyrmont%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22types%22%20%3A%20%5B%20%22locality%22%2C%20%22political%22%20%5D%0A%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22long_name%22%20%3A%20%22NSW%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22short_name%22%20%3A%20%22NSW%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22types%22%20%3A%20%5B%20%22administrative_area_level_1%22%2C%20%22political%22%20%5D%0A%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22long_name%22%20%3A%20%22AU%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22short_name%22%20%3A%20%22AU%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22types%22%20%3A%20%5B%20%22country%22%2C%20%22political%22%20%5D%0A%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22long_name%22%20%3A%20%222009%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22short_name%22%20%3A%20%222009%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22types%22%20%3A%20%5B%20%22postal_code%22%20%5D%0A%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%5D%0A%7D%3B%0A%0Aconst%20findByType%20%3D%20curry%28%28components%2C%20type%29%20%3D%3E%20%7B%0A%20%20return%20find%28where%28%7B%0A%20%20%20%20types%3A%20contains%28type%29%0A%20%20%7D%29%2C%20components%29%3B%0A%7D%29%3B%0A%0Aconst%20getTypes%20%3D%20%28types%2C%20components%29%20%3D%3E%0A%20%20map%28compose%28propOr%28%27%27%2C%20%27long_name%27%29%2C%20findByType%28components%29%29%2C%20types%29%3B%0A%0Aconst%20combineTypes%20%3D%20compose%28join%28%27%20%27%29%2C%20getTypes%29%3B%0A%0Aconst%20buildAddressFrom%20%3D%20curry%28%28paths%2C%20components%29%20%3D%3E%20%7B%0A%20%20return%20reduce%28%28result%2C%20key%29%20%3D%3E%20merge%28result%2C%20%7B%0A%20%20%20%20%5Bkey%5D%3A%20combineTypes%28prop%28key%2C%20paths%29%2C%20components%29%0A%20%20%7D%29%2C%20%7B%7D%2C%20keys%28paths%29%29%3B%0A%7D%29%0A%0Aconst%20buildAddressObject%20%3D%20pipe%28%0A%20%20prop%28%27address_components%27%29%2C%0A%20%20buildAddressFrom%28%7B%0A%20%20%20%20street%3A%20%5B%27street_number%27%2C%20%27route%27%5D%2C%0A%20%20%20%20city%3A%20%5B%27administrative_area_level_1%27%5D%2C%0A%20%20%20%20state%3A%20%5B%27country%27%5D%2C%0A%20%20%20%20zip%3A%20%5B%27postal_code%27%5D%2C%0A%20%20%7D%29%0A%29%3B%0A%0AbuildAddressObject%28result%29
Bravi
@Bravilogy
Mar 02 2017 10:21
Basically I have an array of address components and I need to build a new object, based on certain types of these components.
the end result will look like this:
{"city": "NSW", "state": "AU", "street": "48 Pirrama Road", "zip": "2009"}
and each key, for example city can be made up of a few different types of address components
the code works, but I have a feeling that there's a better way in ramda
Bravi
@Bravilogy
Mar 02 2017 11:21
ok if not that, then maybe this one?
ifElse(head, compose(ref => getUsers(null, ref), prop('reference'), head), always([])))
Julio Borja Barra
@juboba
Mar 02 2017 12:01
if getUsers is curried you can also: ifElse(head, compose(getUsers(__), prop('reference'), head), always([])))
oh
no
my bad
I meant null instead of __
Bravi
@Bravilogy
Mar 02 2017 12:08
@juboba good suggestion, thanks
Julio Borja Barra
@juboba
Mar 02 2017 12:08
yw
@Bravilogy do you know if I can do something like:
compose(dissoc('myprop'), assoc('mynewpropname', [here goes something to get the value of 'myprop']))
to change an object's property name?
I would like to change obj.myprop to obj.mynewpropname
Bravi
@Bravilogy
Mar 02 2017 12:16
maybe use lenses?
can use post your code in repl and drop a link here? I could have a look
Julio Borja Barra
@juboba
Mar 02 2017 12:18
yeah, lenses
heh :)
it's just an idea, but thanks
(not an actual piece of code)
Bravi
@Bravilogy
Mar 02 2017 12:19
:+1:
@juboba any ideas how I can make this point - free? :D
const getLongNames = (types, components) =>
  compose(pluck('long_name'), filter(Boolean), map(findByType(__, components)))(types);
Julio Borja Barra
@juboba
Mar 02 2017 12:26
uhm
not really
you have 2 arrays there
Bravi
@Bravilogy
Mar 02 2017 12:29
yeah
damn :D I keep spending so much time refactoring these things
Julio Borja Barra
@juboba
Mar 02 2017 12:31
hehehehe
me too
but sometimes you just can't make it point free
remember this is not a dogma
haha
not everything can be made declarative
and surely not everything can be made point-free
afaik
Bravi
@Bravilogy
Mar 02 2017 12:34
yeah true
oh well
:D
Julio Borja Barra
@juboba
Mar 02 2017 12:34
but it's really fun, isn't it?
Bravi
@Bravilogy
Mar 02 2017 12:37
it is yeah
James Forbes
@JAForbes
Mar 02 2017 12:51
@Bravilogy its total nonsense but...
pipe(
  // make it a tuple so we can lens it!
  unapply(identity)
  // create a find function for every type in the list
  ,over(lensIndex(0), map(flip(findByType)))
  // wrap our list of components in a list for the next step
  ,over(lensIndex(1), of)
  // apply the list of components to each type function
  ,apply(ap)
  // remove any undefined
  ,filter(Boolean)
  // gets the long names
  ,pluck('long_name')
)(types, components)
Live Example: https://goo.gl/sKEQwv
Julio Borja Barra
@juboba
Mar 02 2017 12:55
wow
nice
James Forbes
@JAForbes
Mar 02 2017 12:56
be kind of interesting to use zipObj, lensProp, pick, so its more opaque
@juboba thanks
e.g.
pipe(
  unapply(zipObj(['types', 'components']))
  ,evolve({
    types: map(flip(findByType))
    ,components: of
  })
  ,pick(['types', 'components'])
  ,values
  ,apply(ap)
  ,filter(Boolean)
  ,pluck('long_name')
)(types, components)
Mick Dekkers
@mickdekkers
Mar 02 2017 12:59
Is there an alternative to R.propOr that works with non-own properties? (that is, where obj.hasOwnProperty(property) === false)
Bravi
@Bravilogy
Mar 02 2017 13:01
@JAForbes that looks very interesting! thank you
James Forbes
@JAForbes
Mar 02 2017 13:01
@Bravilogy couldn't resist, you always have great point free problems!
Bravi
@Bravilogy
Mar 02 2017 13:01
:D
I try to lol
James Forbes
@JAForbes
Mar 02 2017 13:01
its a great distraction from work for me :D
Bravi
@Bravilogy
Mar 02 2017 13:02
haha
Mick Dekkers
@mickdekkers
Mar 02 2017 13:02
Specifically, I'm trying to grab the target property from a MutationRecord ( https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord ), but it's apparently not an own property
Bravi
@Bravilogy
Mar 02 2017 13:02
good to know! :D
I've spread ramda on to colleagues now
James Forbes
@JAForbes
Mar 02 2017 13:05
infected them!
Julio Borja Barra
@juboba
Mar 02 2017 13:05
hahaha
Bravi
@Bravilogy
Mar 02 2017 13:27

the main problem I have here is this part:

types: map(flip(findByType))

as findByType needs that components to be passed to it as well

James Forbes
@JAForbes
Mar 02 2017 13:54
@Bravilogy it gets passed in at apply(ap)
Bravi
@Bravilogy
Mar 02 2017 13:56
@JAForbes ah I see! that's very clever
Julio Borja Barra
@juboba
Mar 02 2017 14:18
wow, I have found a really horrible thing with pyramid of doom that screams to be refactored.
        if (angular.isArray(this.tabla.submodulos)) {
            this.tabla.submodulos.forEach(sm => {
                if (angular.isArray(sm.articulos)) {
                    sm.articulos.forEach(a => {
                        if (angular.isArray(a.articulosPlantilla)) {
                            a.articulosPlantilla.forEach(ap => {
                                ap.precioTotal = ap.precio * ap.cantidad
                            })
                        }
                    })
                }
            })
        }
but don't know where to start
it actually mutates the state
adding that 'precioTotal' property
Rick Medina
@rickmed
Mar 02 2017 14:22
@kwijibo is it good?
Keith Alexander
@kwijibo
Mar 02 2017 14:30
@rickmed I've not listened to them all, but I liked the Why FP one where they discuss what the properties are of a good function
they go into quite a lot of detail, and the podcasts are fairly long and discursive rather than short and snappy
Rick Medina
@rickmed
Mar 02 2017 14:32
@kwijibo got it
James Forbes
@JAForbes
Mar 02 2017 14:34
@juboba I think evolve would work well there
Stefano Vozza
@svozza
Mar 02 2017 14:39
three foreach loops, you'd better hope that list doesn't get too big
Gabe Johnson
@gabejohnson
Mar 02 2017 14:46
@kwijibo I listen to it. They're just starting to get into a little CT and algebras.
Keith Alexander
@kwijibo
Mar 02 2017 14:46
@gabejohnson yeah I'm looking forward to them going deeper into that
Julio Borja Barra
@juboba
Mar 02 2017 14:52
@JAForbes yes, but with nested arrays? checkout the forEaches.
Iain Freestone
@iainfreestone
Mar 02 2017 15:23
I am using tap(console.log()) to help debugging. Is there a way which I can also pass an identifer to the console.log?
Julio Borja Barra
@juboba
Mar 02 2017 15:25
isn't that exactly what the documentation shows as an example? http://ramdajs.com/docs/#tap
ohh, you mean like using console.group?
Iain Freestone
@iainfreestone
Mar 02 2017 16:20
@juboba sorry I overthinking it. I was looking for a way to do something similar to . pipe(peek('this val: ').....other funcs in pipe, peek('end val:)). Where peek would tap console log. Got something in place now
Brad Compton (he/him)
@Bradcomp
Mar 02 2017 16:30
@juboba I don't think you can do a refactor of just that section of the code without making changes to your data structures. Initially I would try to update the code that builds this.tabla and its children to ensure that submodulos, articulos, and articulosPlantilla are always arrays. That would remove at least half of your nesting right off the bat :-D
Julio Borja Barra
@juboba
Mar 02 2017 16:38
yeah, but I can't do that because this is a response from the server
the service in charge could parse the data
that's right
you're totally right
Brad Compton (he/him)
@Bradcomp
Mar 02 2017 16:45
Cool!
Bravi
@Bravilogy
Mar 02 2017 17:19

and I am back :D

const extractAndJoin = useWith((fn, glue, card) => join(glue, fn(card)), [props, identity]);

I want to extract certain props and then glue them by a passed argument. So for example, the code above works like this:

extractAndJoin(['firstName', 'lastName'], ' ', {firstName: 'John', lastName: 'Smith'});
I'm trying my best to make things point-free lol
Keith Alexander
@kwijibo
Mar 02 2017 17:26
can anyone recommend a url routing library that works in the browser?
Robert Mennell
@skatcat31
Mar 02 2017 17:29
@Bravilogy so you're lookign for a Function of footprint Object -> String that can be obtained by composing props and join in a way such as
var fullName = R.pipe(
  R.props(['firstName', 'lastName']),
  R.join(' ')
);
Bravi
@Bravilogy
Mar 02 2017 17:30
yeah
but obviously passing the props array and the glue somehow
to keep it point-free
so that way I'm not limited to just full name and neither I am limited to just ' ' space
Robert Mennell
@skatcat31
Mar 02 2017 17:43
Ah so you wan to try and create a point free version of something like this:
var glueValues =
  R.curry(
    (props, glue, obj) => R.props(props)(obj).join(glue)
  );
console.log(glueValues(['firstName', 'lastName'], ' ', {firstName: 'John', lastName: 'Smith'}))
Bravi
@Bravilogy
Mar 02 2017 17:44
yeah exactly
const extractAndJoin = (properties, glue, obj) =>
  compose(join(glue), props(properties))(obj);
originally I had this one

it works fine but I just don't like that (obj) in the end. I could of course do

const extractAndJoin = (properties, glue) => compose(join(glue), props(properties));

and then have

extractAndJoin(['firstName', 'lastName'], ' ')(userObj);
but then it's not clear that way. some arguments are there, some are not
Keith Alexander
@kwijibo
Mar 02 2017 17:57
@ram-bot useWith(pipe, [props, join])(['x','y'])(' ')({x: "hello", y: "world"})
ram-bot
@ram-bot
Mar 02 2017 17:57
'hello world'
Bravi
@Bravilogy
Mar 02 2017 17:58
hah :D nice!
but that won't accept the object as a third argument, right?
Robert Mennell
@skatcat31
Mar 02 2017 17:59
it literally just did
Bravi
@Bravilogy
Mar 02 2017 18:00
what I mean is comma separated
ok I'll give it a try now
it's a curried function
Bravi
@Bravilogy
Mar 02 2017 18:01
perfect!
thanks guys, that's awesome
useWith is such a cool function. This is the 4th clever use of it
that I saw these days
Keith Alexander
@kwijibo
Mar 02 2017 18:03
I'm not convinced point-free is worth it if it involves useWith or converge
Robert Mennell
@skatcat31
Mar 02 2017 18:03
agreed.
Keith Alexander
@kwijibo
Mar 02 2017 18:04
and I can say that now that I've managed to use useWith at least once successfully ;)
Brad Compton (he/him)
@Bradcomp
Mar 02 2017 18:06
I actually use converge and useWith occasionally. They can be really nice in certain cases, but sometimes an arrow function is easier...
Robert Mennell
@skatcat31
Mar 02 2017 18:06
well the issue is with every call of this function he'll be creating O(arguments) functions that get consumed and then collected. It's also hard to read.
Brad Compton (he/him)
@Bradcomp
Mar 02 2017 18:07
const on = curry((g, f, x, y) => useWith(g, [f, f])(x, y)) is really nice
Keith Alexander
@kwijibo
Mar 02 2017 18:12
is that g(f(x), f(y))?
Robert Mennell
@skatcat31
Mar 02 2017 18:12
// to show that it creates a lot of functions
const extract = (o, p) => o[p]
const glueProps = p => g=> o => p.map(extract.bind(null, o)).join(g)
anyway you write this it's pretty ugly. It's going to create a lot of functions
Brad Compton (he/him)
@Bradcomp
Mar 02 2017 18:13
@kwijibo yes
Keith Alexander
@kwijibo
Mar 02 2017 18:15
@Bradcomp the pointed version is shorter and clearer isn't it? what does the useWith indirection buy in this context?
Brad Compton (he/him)
@Bradcomp
Mar 02 2017 18:16
I suppose you're right.
Keith Alexander
@kwijibo
Mar 02 2017 18:16
i wonder if you could use useWith to compose a node.js callback
Johnny Hauser
@m59peacemaker
Mar 02 2017 22:07
I swear my brain is allergic to this concept. I've done this kind of thing a few times and keep forgetting how.
var x = {
  foo: [1],
  bar: [1, 2]
}
/*
{
  foo: [1, 1, 2]
}
*/
Sean Cannon
@SeanCannon
Mar 02 2017 22:09
R.compose(R.objOf('foo'), R.flatten, R.values)(x)
Johnny Hauser
@m59peacemaker
Mar 02 2017 22:10
hmm, I'll mess with that. I just remembered it's converge that I used before. Brad taught me.
Ah, yes, yours makes sense, but not if there are other properties.
Robert Mennell
@skatcat31
Mar 02 2017 22:13
@ram-bot useWith(pipe, [props, concat])(['x','y'])({x: "hello", y: "world"})
ram-bot
@ram-bot
Mar 02 2017 22:13
Unexpected token [
Robert Mennell
@skatcat31
Mar 02 2017 22:14
@ram-bot useWith(pipe, [props, concat])(['x','y'])({x: "hello", y: "world"})
ram-bot
@ram-bot
Mar 02 2017 22:14
[Function]
Robert Mennell
@skatcat31
Mar 02 2017 22:14
nope that didn't work either XD
Bravi
@Bravilogy
Mar 02 2017 22:18
that's because it needs a third argument now as pipe returns a function
i had that problem as well today
with that solution
Robert Mennell
@skatcat31
Mar 02 2017 22:28
well that answers that... it's because concat requires multiple lists. A single list will retunr a function. By passing it an empty list it will join them
@ram-bot useWith(pipe, [props, concat])(['x','y'])([])({x: "hello", y: "world"})
ram-bot
@ram-bot
Mar 02 2017 22:31
[] does not have a method named "concat"
Robert Mennell
@skatcat31
Mar 02 2017 22:32
... well it works in repl
Johnny Hauser
@m59peacemaker
Mar 02 2017 23:03
I have an array of functions and I need an array of results of those functions called with a supplied value
v => map(fn => fn(v), fns)
Johnny Hauser
@m59peacemaker
Mar 02 2017 23:54
What do you think about this?
var x = {
  foo: [1, 2],
  bar: [3],
  baz: ['a']
}

converge(
  R.set(lensProp('foo')), 
  [
    R.pipe(
      R.pick(['foo', 'bar']),
      R.values,
      R.reduce(R.concat, [])
    ),
    identity
  ]
)(x)
Sean Cannon
@SeanCannon
Mar 02 2017 23:54
Just use R.juxt
const obj = { firstName : 'john', lastName : 'doe', ssn : 1234 };

R.juxt([
  R.prop('firstName'),
  R.prop('ssn')
])(obj);

// ["john", 1234]
Johnny Hauser
@m59peacemaker
Mar 02 2017 23:58
Neat. I'd prefer:
R.juxt(
  R.map(R.prop, ['firstName', 'ssn'])
)
Sean Cannon
@SeanCannon
Mar 02 2017 23:59
I mean if we're playing code golf just do R.props(['firstName', 'ssn'], obj);
Johnny Hauser
@m59peacemaker
Mar 02 2017 23:59
even better =D