These are chat archives for ramda/ramda

22nd
Feb 2016
GÁBOR Áron Zsolt
@ashnur
Feb 22 2016 02:22
@joneshf my rename is shorter...
anyway, the conditional is annoying me, how would i do that if I want to use renameKey from the cookbook?
since your filter doesn't really do anything
GÁBOR Áron Zsolt
@ashnur
Feb 22 2016 02:36
what do you mean?
Hardy Jones
@joneshf
Feb 22 2016 02:36
the function you use in map will ignore anything that doesn't match the regex.
GÁBOR Áron Zsolt
@ashnur
Feb 22 2016 02:36
it does filter a list
@joneshf the point of the filter is to filter out certain keys, not just to have the keys I want to modify
Hardy Jones
@joneshf
Feb 22 2016 02:38
oh right
maybe it's bed time?
GÁBOR Áron Zsolt
@ashnur
Feb 22 2016 02:38
:))
well, it was not obvious that i want that
but yeah, it's almost 4
Scott Sauyet
@CrossEye
Feb 22 2016 02:39
Bedtime sounds really good to me... I'm usually not in bed for three or four more hours, but I think it's time now~
GÁBOR Áron Zsolt
@ashnur
Feb 22 2016 02:41
....
well, still better than in #nginx on freenode
Richard Seldon
@arcseldon
Feb 22 2016 08:14
@joneshf - found this on loop school - http://school.looprecur.com/?video=122707678 which goes over natural transformations, and some common patterns. Looks like Sanctuary has some of them covered.
maybeToList :: Maybe a -> [a]
maybeToList (Just x) = [x]
maybeToList Nothing = []
listToMaybe :: [a] -> Maybe a
listToMaybe (x:xs) = Just x
listToMaybe [] = Nothing
tupleToEither :: (a, b) -> Either a b
eitherToReader :: Eitehr a b -> Reader a b
These look reasonably straightforward - should we consider implementation conveniences in Ramda-Fantasy ?
Richard Seldon
@arcseldon
Feb 22 2016 08:23
@davidchambers - hi, is there a Sanctuary API documentation page? Like ramdajs.com.. I am struggling to find what Natural Transformations you provide using the README on github home page.
Raine Virta
@raine
Feb 22 2016 08:23
no, just the README
Scott Christopher
@scott-christopher
Feb 22 2016 08:25
How are tupleToEither and eitherToReader implemented?
(Sorry if it's explained in that link, I'm currently on my phone and will have to wait until I'm home to check it out)
Richard Seldon
@arcseldon
Feb 22 2016 08:26
@scott-christopher - compared to you folks I am just a tourist. will try to find out and get back to you.
Scott Christopher
@scott-christopher
Feb 22 2016 08:27
:) no rush
Richard Seldon
@arcseldon
Feb 22 2016 08:27
examples in the link tend to be focusing on Haskell...
Scott Christopher
@scott-christopher
Feb 22 2016 08:28
That's fine, I'll take a look when I get home.
Hardy Jones
@joneshf
Feb 22 2016 08:28
tupleToEither should be pretty easy to implement, choose the side based on whatever laws you need i tto pass
I'm not so sure about eitherToReader.
const tupleToEither = R.compose(S.Right, snd)
Or something
Hardy Jones
@joneshf
Feb 22 2016 08:36
Or, I guess it doesn't really matter which you do.
both should be law abiding
Scott Christopher
@scott-christopher
Feb 22 2016 09:07
That makes sense.
And because type Natural = forall a. f a -> g a, am I right in thinking it would have to be Tuple b a -> Either c a?
at least in Haskell/PureScript where parametricity is a concern
Scott Christopher
@scott-christopher
Feb 22 2016 09:15
I can see how a Right a can be turned into a Reader r a via Reader.of, but don't know what could be done if a Left b was received.
Unless the natural is restricted to Either a a -> Reader r a
¯_(ツ)_/¯
Richard Seldon
@arcseldon
Feb 22 2016 10:58
Was taking a (quick) first look at Trine: https://github.com/jussi-kalliokoski/trine
This comment was of interest:

ES6 introduces the concept of iterators to JS. Iterators are a protocol that most collection types in ES6 (Map, Set, Array, etc.) implement, by exposing a function under the Symbol.iterator symbol. This means you can also extend your custom collection types to support the same protocol, and generator functions support it too. Iterators are a very flexible abstraction over collections, and unlike memory-bound collections, can also represent infinite sets, such as the Fibonacci series or prime numbers. In a memory-bound collection an infinite number of items would require infinite memory.

Iterators, on the other hand, allow us to process only as much as we need

Nothing new there...
But I had thought before, what has the advent of ES6/2015 brought to the table for Ramda?
is there any interest in going down the generator / iterator road etc. Apologies, am quite ignorant of much of the existing code base - should likely devote more time on it soon.
Raine Virta
@raine
Feb 22 2016 11:03
check the issue tracker, has been discussed before IIRC
Richard Seldon
@arcseldon
Feb 22 2016 11:04
ok.. will see if i can find it. cheers.
i am slightly unclear what the overlap would be to say transducer work..
Nisha Sowdri
@sowdri
Feb 22 2016 11:21
Hi All, I've a tsv file in json as array of arrays. [['name', 'age'],['john', 23], ['maggie', 45], [row3], [row4]]. This has to be converted to array of maps. [{name: 'john', age: 23}, {name: 'maggie', age: 45}, ... ]
In the original format, the first row is header
kindly suggest the best way to convert it using ramda
Richard Seldon
@arcseldon
Feb 22 2016 11:38
@sowdri - i am a learner too, but here are a couple of possibly naive suggestions:

it('should work', () => {
const xs = [['name', 'age'],['john', 23], ['maggie', 45]];
const toObj = (x) => {
return {name: x[0], age: x[1]};
};
const convert = R.compose(R.map(toObj), R.tail);
convert(xs);
});

it('should also work', () => {
const xs = [['name', 'age'],['john', 23], ['maggie', 45]];
const yin = R.head(xs);
const yang = R.tail(xs);
const convert = R.map((x) => {
return R.zipObj(yin, x);
});
convert(yang);
});

@raine - thanks for your suggestion. took a look through the issues list
this one interested me: ramda/ramda#992
but didnt finally go anywhere for the reasons given.
This one too: ramda/ramda#1482
Raine Virta
@raine
Feb 22 2016 11:49
@sowdri I would imagine the tsv parser you're using could read the data into that format
@arcseldon you can use markdown code blocks to make syntax highlight code
Richard Seldon
@arcseldon
Feb 22 2016 11:52
ah ok..
 it('should work', () => {
    const xs = [['name', 'age'],['john', 23], ['maggie', 45]];
    const toObj = (x) => {
      return {name: x[0], age: x[1]};
    };
    const convert = R.compose(R.map(toObj), R.tail);
    convert(xs);
  });

  it('should also work', () => {
    const xs = [['name', 'age'],['john', 23], ['maggie', 45]];
    const yin = R.head(xs);
    const yang = R.tail(xs);
    const convert = R.map((x) => {
      return R.zipObj(yin, x);
    });
    convert(yang);
  });
use the former if you definitely know the titles of your TSV file, whilst the latter is more general, and can work that out itself.
you could collapse down the yin / yang nonsense by inlining those variables. just for readability
Richard Seldon
@arcseldon
Feb 22 2016 12:04
if you really wish to boil it down further:
it('should also work too', () => {
    const xs = [['name', 'age'],['john', 23], ['maggie', 45]];
    const convert = R.map(R.zipObj(R.head(xs)));
    convert(R.tail(xs));
  });
@sowdri - is that what you were hoping for?
Aldwin Vlasblom
@Avaq
Feb 22 2016 12:05
Starting to become curious as to what your next test description will be. :P
Raine Virta
@raine
Feb 22 2016 12:05
what's the point if you're not asserting anything
Richard Seldon
@arcseldon
Feb 22 2016 12:05
lol.. i know.
Stefano Vozza
@svozza
Feb 22 2016 12:07
Assertions are Evil Side Effects so I presumed you were just keeping everything nice and pure. ;)
Richard Seldon
@arcseldon
Feb 22 2016 12:08
  it('should also work too with expectations added!', () => {
    const xs = [['name', 'age'], ['john', 23], ['maggie', 45]];
    const convert = R.map(R.zipObj(R.head(xs)));
    expect(convert(R.tail(xs))).to.eql([{name: 'john', age: 23}, {name: 'maggie', age: 45}]);
  });
Raine Virta
@raine
Feb 22 2016 12:10
@ram-bot
const dataToObjs =
  pipe(splitAt(1), 
       apply(useWith(map, [ pipe(head, zipObj), identity ])))

dataToObjs([ ['name', 'age'], ['john', 23], ['maggie', 45] ])
ram-bot
@ram-bot
Feb 22 2016 12:10
[ { name: 'john', age: 23 }, { name: 'maggie', age: 45 } ]
Raine Virta
@raine
Feb 22 2016 12:11
no points. a solution which i don't necessarily endorse
Raine Virta
@raine
Feb 22 2016 12:37
httpGet(URL)
  .then(pipe(prop('body'), trim, mdCode('')))
  .catch(always('Something went wrong'))
  .then(res.reply)
the catch resembles fromMaybe
Richard Seldon
@arcseldon
Feb 22 2016 14:58
Hi. have been trying to read up on how to do lazy infinite lists with Ramda. It appears from here: ramda/ramda#1482
that transducers will achieve this. Do we have some easy to understand "hello world" style examples to grok this with?
I got into it a couple of weeks ago, watched the Rich Hickey videos, studied the code base, got a sense that it was all happening in reduce, then forget everything!
Just a lightweight example or two would help - i appreciate we are cleverly dispatching so we don't reinvent the wheel everytime map, reduce, filter comes along.
i'd like to be able to create functions that behave like generators when interacting with ramda functions.
Richard Seldon
@arcseldon
Feb 22 2016 15:07
(i realise i get this for free when combining a third party lib, say RxJs with ramda)
But how do i write my own transducer compatible functions in a way that they run lazily... hope this isn't a stupid question... perhaps i have overlooked something fundamental.
Drew
@dtipson
Feb 22 2016 15:09
there's a transducer protocol which I believe ramda follows
or, maybe I said that wrong: a transformer protocol for creating specific transducers? https://github.com/cognitect-labs/transducers-js#transformer-protocol
Richard Seldon
@arcseldon
Feb 22 2016 15:11
thanks. I am wondering whether I simply define an object with a say a map interface, that internally uses generator syntax (yield etc)
and then ramda dispatches to that map implementation and because it is a generator it runs as an iterator...
Drew
@dtipson
Feb 22 2016 15:12
you can see the guts of it built into the internal implementation of reduce: https://github.com/ramda/ramda/blob/master/src/internal/_reduce.js
Richard Seldon
@arcseldon
Feb 22 2016 15:12
Right, i checked that last time. Thanks for the reminder. will take a look and play around. appreciate the input @dtipson
ok.. bad memories of this.. lol. all that @ step / @ this / @ that ... right, lets work this out again.
Hardy Jones
@joneshf
Feb 22 2016 16:08
@scott-christopher yeah, those types look good, though it would be type Natural f g = forall a. f a -> g a and Natural (Tuple b) (Either c) in your first example :) But you can't actually enforce that second type (the Either/Reader one). It would be Natural (Either a) (Reader r), so there's no mention of the as being the same.
Drew
@dtipson
Feb 22 2016 16:22
After reading through this http://raganwald.com/2015/02/17/lazy-iteratables-in-javascript.html, it seems like composing chainable iterables and composing transducers for a reduce operation both avoid creating temporary arrays/overhead and allow short-circuiting unnecessary computations, but in pretty different way. This is really interesting stuff
Hardy Jones
@joneshf
Feb 22 2016 16:22
@ram-bot
const tsv = [['name', 'age'],['john', 23], ['maggie', 45]];
const [header, rows] = R.splitAt(1, tsv);
R.lift(R.zipObj)(header, rows);
ram-bot
@ram-bot
Feb 22 2016 16:22
SyntaxError: Unexpected token [
Hardy Jones
@joneshf
Feb 22 2016 16:22
k, maybe not
Drew
@dtipson
Feb 22 2016 16:22
or maybe there's a deep connection I've yet to see, which is even more exciting
Hardy Jones
@joneshf
Feb 22 2016 16:23
@ram-bot
const tsv = [['name', 'age'],['john', 23], ['maggie', 45]];
const split = R.splitAt(1, tsv);
const header = split[0];
const rows = split[1];
R.lift(R.zipObj)(header, rows);
ram-bot
@ram-bot
Feb 22 2016 16:23
TypeError: Cannot read property 'map' of undefined
Hardy Jones
@joneshf
Feb 22 2016 16:24
@sowdri ^
But as @raine says, your tsv parser should be able to handle something like that.
David Chambers
@davidchambers
Feb 22 2016 16:47

@davidchambers - hi, is there a Sanctuary API documentation page? Like ramdajs.com.. I am struggling to find what Natural Transformations you provide using the README on github home page.

No, @arcseldon, but I'm working on it. I have a half-built site which is more useful than the readme. Killer feature: All the code examples are editable!

I'll have a chance to work on the site again on Friday. :)

For right now, though, running grep '//# .* :: ' index.js will give you an overview of the public API.
Scott Sauyet
@CrossEye
Feb 22 2016 17:11
Added compose(apply(lift(zipObj)), splitAt(1)) to the Cookbook. It does look useful.
Richard Seldon
@arcseldon
Feb 22 2016 17:22
@davidchambers - thanks for clarifying. look forward to the new documentation when available. appreciate it.
2:30 ish here, packing up for the day.
David Chambers
@davidchambers
Feb 22 2016 17:26
Bye, @arcseldon.
Scott Sauyet
@CrossEye
Feb 22 2016 17:30
Good night @arcseldon !
Richard Seldon
@arcseldon
Feb 22 2016 22:59
Good morning.
Answered my first question on SOF for Ramda today - http://stackoverflow.com/a/35559392/1882064
Be grateful if anyone interested could review / edit / vote up / critique etc
Jakub Korzeniowski
@kujon
Feb 22 2016 23:19
@arcseldon I'd personally use sortBy or sort http://goo.gl/6AJQe8. Btw, does any of you know a nice way of parameterising sortBy to do ascending/descending order? I was fighting with it for quite a while today with no luck
@arcseldon I screwed up the signature, sorry: http://goo.gl/566pD8
Scott Sauyet
@CrossEye
Feb 22 2016 23:33
@arcseldon: I had chosen not to answer that one as the vanilla answers seemed good enough. But I had already discovered something like kujon's solution:
sortBy(pipe(prop('id'), indexOf(__, a)))(b)
@kujon: I don't know of any good way to parameterize ˋsortByˋ, but of course it's easy enough to ˋcomplementˋ a ˋcomparatorˋ
Jakub Korzeniowski
@kujon
Feb 22 2016 23:40
comparator is the function I was missing, cheers!
Scott Sauyet
@CrossEye
Feb 22 2016 23:46
@arcseldon: I might also be a little less effusive about the library in an answer like that. The question was tagged with Ramda. The user did want to consider Ramda-solutions, and probably does not need a sales job. :smile: