These are chat archives for ramda/ramda

Sep 2016
Craig Dallimore
Sep 11 2016 07:37
It looks like highlightjs is not parsing the variables and operators as I would expect.
I'm going to investigate more
Perhaps there is a way we can reuse codemirror on the right - that way we'd only use one library and there possibly might not need as much effort to make them consistent.
Craig Dallimore
Sep 11 2016 07:50
Hmm, how about a "copy-to-clipboard" button?
Craig Dallimore
Sep 11 2016 08:32
Yep, CodeMirror is sufficient.
Michael Hurley
Sep 11 2016 11:33
:tada: this looks really good
Antony Agrios
Sep 11 2016 12:31
Hi to everyone! I discovered the concept of functional programming recently, and i like ramda and pointfree style a lot!
Although i have some questions and I dont know how to deal with them.
I write an application in which i fetch a bunch of objects.One of their property is an image url.
At the time i have something like this.
and the Array of objects look something like this

fetchItems return a Future (or Task, whatever) and then i save the items to the db.
I want before that to extract all the urls, download the images, and then save to db, replacing the image prop with my own path.
How is this possible in a pointfree way?
How i can 'split' the execution and keep track of the input?
For example if i had something like that
compose(chain(traverse(Future.of, saveItem)),chain(traverse(Future.of, downloadImages)), fetchItems)(url)

it would work because after the download, i would have only the images.
I hope someone can help me out so i can have a better understanding of the pointfree style!
Thank you very much!

Sep 11 2016 17:01
Your example actually seems relatively complete. The only thing I don't see is replacing the image prop unless either saveItem or downloadImages are supposed to return objects with a new property value. If not, shouldn't you be able to just map a map(assocPath) over the array of objects? I'm just going by the nomenclature of your functions and assuming that both saveItem and downloadImages preserve the initial array of objects and don't return anything like Futures of status codes or something.
i.e. I'm assuming traverse(Future.of, downloadImages) returns a Future [{ image: String, title String, price: Number, attributes: Object }] so they would basically match the input.
Sep 11 2016 17:19
I think one other thing you can do is ditch Futures, use co and then can avoid a lot of this Future packing and unpacking because right now, it looks like the function pipeline goes Future [objects] and then you chain over that with a traverse(Future.of, downloadImages) which takes your original array, turns it into an array of Futures and then into a Future of an array so ultimately you're just doing Future [] - > Future [] - > Future []. Generator-based control flow allows you to eschew all this and you can use more synchronous-looking constructs, just operating on the arrays directly.
Antony Agrios
Sep 11 2016 17:57
The downloadImages function is a finction one. This is what im trying to accomplish.The real code is just traverse(Future.of,saveProduct), which actually maps over the array and save each of them using knex. I know what downloadImages function should be in order to accomplish what i want.. co is a solution, but im trying to use fp and pointfree as much as possible to learn all the concepts and idioms of fp.
Sep 11 2016 18:12
Then you should check out the Haskell HTTP server frameworks that are out there. There's actually really good support out there.
Juan Lulkin
Sep 11 2016 18:21
just throwing another idea out there:
so a friend of mine was annoyed by having to write add, multiply...
so I thought: what if we had something similar to coffeescript, but it would only convert regular ops to Ramda's functions?
Sep 11 2016 20:03


I thought about it some more. co can coexist alongside Ramda quite well, actually, and yes, even support a slight pointfree syntax because you can pretty much just yield wherever (including function invocations). I would say that it defeats the purpose of tacit programming to try and enforce it without letting the problem naturally lend itself to a tacit approach. Instead, I think the chain(traverse(/* ... */)) constructs would work better with something that truly needs that kind of scaffolding. Maybe would be a good example, like they have in the API docs.