These are chat archives for ramda/ramda

20th
Oct 2015
Tom
@tarossi
Oct 20 2015 02:51
hi guys, is it possible for Ramda to be included as an angular module? if yes, how?
Scott Christopher
@scott-christopher
Oct 20 2015 03:06
I'm not very familiar with the specifics of Angular, but it looks like you should be able to do something like:
var ngRamda = R.reduce(function(_ngRamda, fn) {
  _ngRamda[fn] = R[fn];
  return _ngRamda;
}, ng.module('angular-ramda', []), R.keys(R));
or if your environment supports Object.assign ...
var ngRamda = Object.assign(ng.module('angular-ramda', []), R);
Tom
@tarossi
Oct 20 2015 03:12
thanks! i'll try that later
David Chambers
@davidchambers
Oct 20 2015 05:15
One could take the position that Ramda should not provide a Maybe type while at the same time opposing the addition of *Or functions. One could argue that Ramda is a good entry point to functional JavaScript, but that once a user realizes that many Ramda functions fail to clearly differentiate success and failure cases, we should introduce her to Maybe (as provided by several other libraries) rather than muddy the waters with a bevy of *Or functions.
Martin Algesten
@algesten
Oct 20 2015 05:20
@davidchambers i'm still waiting to realize this. one day perhaps. meanwhile I enjoy simple datatypes without any wrapping containers.
David Chambers
@davidchambers
Oct 20 2015 05:21
@algesten, may R.find never fail you. ;)
Martin Algesten
@algesten
Oct 20 2015 05:27
@davidchambers lol :D
Aldwin Vlasblom
@Avaq
Oct 20 2015 08:08
@davidchambers I agree. Over the last months I've been learning functional programming, and it felt very natural to me to start with replacing _ with R after seeing Underscore you're doing it wrong, with the fuzzy feeling that if I'd want, the only change would be the argument order, and I can just use Ramda like lodash. Over time I started doing more and more currying and then realized through the Mostly Adequate Guide that I can abstract away null-checks and other code branches with algebraic types. Recently I replaced Promises with Tasks/Futures and have an ever growing desire to make my programs "pure". But I think that if Ramda wouldn't have been familiar when I started, I would have needed a lot more convincing before making the leap.
Raine Virta
@raine
Oct 20 2015 08:15
we could provide a straightforward way to derive the *Or versions or put them to cookbook
Niloy Mondal
@niloy
Oct 20 2015 08:18
Its just R.ifElse(R.isNil)?
Raine Virta
@raine
Oct 20 2015 08:20
bit trickier in case of pathOr etc.
Julien Goux
@jgoux
Oct 20 2015 09:00
Hello
Niloy Mondal
@niloy
Oct 20 2015 09:01
Hello
Julien Goux
@jgoux
Oct 20 2015 09:02
I have a hard time figuring out how to use some ramda functionalities recursively
I want to filter an object tree recursively
The shape is like { _t: [...], '0': [...], '1': {...} }
Basically, when the parameter is an object, I want to delete some of its keys based on multiple criterias
but I have to do the same when the key's value is an object too
The function to filter an objet is like this : https://gist.github.com/jgoux/5ec1de0e4ecd45a3e0f7
But it's just filtering, it doesn't apply itself if the value is an object too
At the top level it's good, but I'd like to go deeper
Raine Virta
@raine
Oct 20 2015 09:06
call filterDelta with value if value is object?
Niloy Mondal
@niloy
Oct 20 2015 09:07
This message was deleted
Julien Goux
@jgoux
Oct 20 2015 09:12
Ok it wasn't so hard in the end xD
Raine Virta
@raine
Oct 20 2015 09:13
what does it look like?
Julien Goux
@jgoux
Oct 20 2015 09:13
This message was deleted
oops
I use a lib for diffing two json, and it has a lot of noise by default :D
Raine Virta
@raine
Oct 20 2015 09:15
you're not passing key to filterDelta
Julien Goux
@jgoux
Oct 20 2015 09:15
value is either an object or an array
filterDelta is curried, so I pass the object ?
Raine Virta
@raine
Oct 20 2015 09:16
yeah I just realized my reading error
Scott Christopher
@scott-christopher
Oct 20 2015 09:17
A defaultFnTo function seems like a reasonable middle ground:
// something like:
var defaultFnTo = R.curry((fn, def) =>
  R.curryN(fn.length, R.compose(R.defaultTo(def), fn)));

var findOr42 = defaultFnTo(R.find, {a: 42});
var xs = [{a: 1}, {a: 2}, {a: 3}];
findOr42(R.propEq('a', 2))(xs); //=> {a: 2}
findOr42(R.propEq('a', 4))(xs); //=> {a: 42}

var pathOr42 = defaultFnTo(R.path, 42);
pathOr42(['a', 'b'], {a: {b: 2}}); //=> 2
pathOr42(['a', 'b'], {c: {b: 2}}); //=> 42

var headOrFoo = defaultFnTo(R.head, 'foo');
headOrFoo(['fi', 'fo', 'fum']); //=> 'fi'
headOrFoo([]);                  //=> 'foo'
Raine Virta
@raine
Oct 20 2015 09:18
const filterDeltaRecursive = R.cond([
  [ R.is(Object), (v) => R.mapObjIndexed(filterDeltaRecursive, filterDelta(v)) ],
  [ R.T, R.identity ]
])
Niloy Mondal
@niloy
Oct 20 2015 09:18
defaultTo already exists
Julien Goux
@jgoux
Oct 20 2015 09:19
@raine I was trying with ifElse approach ^^
Raine Virta
@raine
Oct 20 2015 09:19
@niloy but doesn't take a function
Julien Goux
@jgoux
Oct 20 2015 09:19
R.T ?
ok
always returns true
Raine Virta
@raine
Oct 20 2015 09:20
in cond R.T is like "otherwise"
Scott Christopher
@scott-christopher
Oct 20 2015 09:21
One day I'll remember all the functions offered by Ramda :D
Raine Virta
@raine
Oct 20 2015 09:22
not sure if this point free version works
const filterDeltaRecursive = R.cond([
  [ R.is(Object), pipe(filterDelta, R.mapObjIndexed(filterDeltaRecursive, R.__) ]
  [ R.T, R.identity ]
])
I don't think it will work anyway because filterDeltaRecursive does not exist at the time the cond is evaluated
Julien Goux
@jgoux
Oct 20 2015 09:23
yes I think I have to use a function declaration
Raine Virta
@raine
Oct 20 2015 09:24
not necessarily
the one I pasted before should work
because the access to filterDeltaRecur is inside a lambda
Julien Goux
@jgoux
Oct 20 2015 09:24
Right it works :D
If prefer to use ifElse
I find it more expressive
const filterDeltaRecursive = R.ifElse(
        R.is(Object),
        (v) => R.mapObjIndexed(filterDeltaRecursive, filterDelta(v)),
        R.identity
    )
Thanks for the lambda tips !
I didn't know
Raine Virta
@raine
Oct 20 2015 09:27
I like switch expressions
Julien Goux
@jgoux
Oct 20 2015 09:28
ok I have to read it like a switch, no it's more clear too :D
Thanks a lot @raine !
Raine Virta
@raine
Oct 20 2015 09:31
you might want to consider separating the predicate part of filterDelta to its own function
I don't understand your data structure that well, aside from the value being an array, but I think it would be more readable
if the predicate described the data
Julien Goux
@jgoux
Oct 20 2015 09:38
@raine I'm not sure I understand what you mean
mapObjIndexed(...) in its own function ?
this separate from pickBy
Julien Goux
@jgoux
Oct 20 2015 09:40
Ok got it :D
And the format is quite weird
I don't need a delta for the movements in a array, and the "_t" key is useless in my case too
Raine Virta
@raine
Oct 20 2015 09:42
const R = require('ramda')

const obj = {
  foo: 1,
  bar: 2,
  xyz: 3
}

const isTwo = x => x === 2

R.pickBy(isTwo, obj);
this example is stupid but same idea, the predicate doesn't have to know you're filtering an object
Julien Goux
@jgoux
Oct 20 2015 09:48
@raine But how do you do when I have to use either the key or the value ?
arrayMove depends on the value, arrayType on the key
    const arrayMove = (v) => R.equals(R.nth(2, v), 3)
    const arrayType = (k) => R.equals(k, "_t")
    const filterDelta = R.pickBy((v, k) => R.not(R.or(arrayMove(v), arrayType(k))))
?
Raine Virta
@raine
Oct 20 2015 10:13
I wonder if the decision to make both and either not short-circuit was too hasty... @gilligan also shared his concern
Niloy Mondal
@niloy
Oct 20 2015 10:15
Yep, not short-circuiting sux :worried:
Anything that involves control-flow should be short-circuitted IMO
Raine Virta
@raine
Oct 20 2015 10:21
there's some thing about the name of allPass that rubs me wrong
const isSmtp5xxError =
  both(is(NodemailerError),
       (err) => err.responseCode >= 500);
becomes
const isSmtp5xxError = allPass([
  is(NodemailerError),
  (err) => err.responseCode >= 500
]);
Niloy Mondal
@niloy
Oct 20 2015 10:27
I dont mind the syntax, for me, evaluating the second function is unnecessary if first function fails, lazyness is a good thing
Hardy Jones
@joneshf
Oct 20 2015 10:35
Why don't they short circuit anymore?
Tobias Pflug
@gilligan
Oct 20 2015 10:37
@raine I added a bothPass to my project ...
Raine Virta
@raine
Oct 20 2015 10:37
@joneshf ramda/ramda#1408
Hardy Jones
@joneshf
Oct 20 2015 10:38
hmm, is that safe?
I mean, the functor implementation, sure, since you can only have one functor (sort of anyway)
but I don't know if the other ones have single implementations.
also, could a lazy implementation of and be used instead of the default eager version?
Niloy Mondal
@niloy
Oct 20 2015 10:48
and does not accepts functions, how would that work?
David Chambers
@davidchambers
Oct 20 2015 10:51
I talked about Ramda and related matters on the latest episode of Functional Geekery. :ram:
Raine Virta
@raine
Oct 20 2015 10:53
@davidchambers nice
Tobias Pflug
@gilligan
Oct 20 2015 10:54
@davidchambers cool!
Niloy Mondal
@niloy
Oct 20 2015 10:55
@davidchambers 👍
David Chambers
@davidchambers
Oct 20 2015 10:57
You can listen to my Kiwi accent. :)
Raine Virta
@raine
Oct 20 2015 11:06
the podcast starts at 3:50
Julien Goux
@jgoux
Oct 20 2015 11:11
R.is(Object, []) ) = true
Is there a function to separate array than object ?
I have to add an extra clause here with isArrayLike I assume
Raine Virta
@raine
Oct 20 2015 11:12
R.type
Julien Goux
@jgoux
Oct 20 2015 11:17
In your example, the R.is(Object) becomes : (v) => R.equals(R.type(v), "Object")
I don't know if I can remove the lambda here
Raine Virta
@raine
Oct 20 2015 11:18
R.pipe(R.type, R.equals('Object'))
Julien Goux
@jgoux
Oct 20 2015 11:19
much better thanks, I need to use pipe more often :D
Raine Virta
@raine
Oct 20 2015 11:19
const typeEq = R.useWith(R.equals, R.identity, R.type)
typeEq('Object', {}) // true
not quite...
Julien Goux
@jgoux
Oct 20 2015 11:21
the pipe version is good for me :+1:
Scott Sauyet
@CrossEye
Oct 20 2015 11:44
@scott-christopher: I started_ the library and still forget some of the functions in it. I was in a job interview coding away at some problem using Ramda when the interviewer said, "Why don't you just use R.scan, here?" How could I explain that I totally forgot we even _had scan? :smile:
Niloy Mondal
@niloy
Oct 20 2015 12:01
😀
Scott Sauyet
@CrossEye
Oct 20 2015 12:02
@davidchambers: well I know what I'm listening to my way home.
Raine Virta
@raine
Oct 20 2015 12:29
Object.assign(exports, objFromKeys(createError, [
  'TemplateMissingError',
  'TemplateDataValidationError',
]));
cool use for objFromKeys I think
Tobias Pflug
@gilligan
Oct 20 2015 12:37
would there be any strong arguments against having pathSatisfies analogous to propSatisfies ?
Raine Virta
@raine
Oct 20 2015 12:39
hmm, I don't know why I was using Object.assign there, defining module.exports is much better
Raine Virta
@raine
Oct 20 2015 13:25
R.mergeAll([
  genReqId ? { req_id: genReqId(req) } : {},
  includesFn ? includesFn(req, res) : {}
]);
does ramda have some pattern for this?
My first attempt at a contribution ;-)
Julien Goux
@jgoux
Oct 20 2015 14:44
Is there an iterator method to iterate over an object and have both key and value as parameter ?
mapObjIndexed doesn't imply side effects
I don't want to return anything, just iterate, without using Object.keys() + a global object
Raine Virta
@raine
Oct 20 2015 14:53
const forEachPair = R.useWith(R.forEach, [ R.apply, R.toPairs ])
forEachPair((a, b) => console.log(a, b), { a: 1, b: 2 })
Aldwin Vlasblom
@Avaq
Oct 20 2015 14:56
And wrap in R.tap to prevent it from returning the pairs instead of the input object.
Julien Goux
@jgoux
Oct 20 2015 14:56
@raine @Avaq I'll try that one, thanks !
Raine Virta
@raine
Oct 20 2015 17:16
in context of transducers, does it make sense to reduce as a transformer?
hmm, I think it's the reducing function I need to configure
Raine Virta
@raine
Oct 20 2015 17:40
thing is transduce-stream takes my transducer and just pushes values and you can't really reduce em in there
joneshf-work1
@joneshf-work1
Oct 20 2015 17:56
speaking of streams, the stream game in js is kind of abysmal.
eh, that's too harsh of a word.
it's not that bad.
just needs some improvement.
Raine Virta
@raine
Oct 20 2015 17:57
what do you not like about them?
joneshf-work1
@joneshf-work1
Oct 20 2015 17:58
it's mostly little things here andthere and add up to making it less powerful than some other options.
Raine Virta
@raine
Oct 20 2015 17:59
what other options, CSP?
joneshf-work1
@joneshf-work1
Oct 20 2015 18:00
different languages.
Raine Virta
@raine
Oct 20 2015 18:27
after some more thought, i don't think transducers are the solution after all. i would need to add a way in ramda-cli to reduce stream after transduce-stream step
Raine Virta
@raine
Oct 20 2015 19:03
ideas welcome raine/ramda-cli#4
Scott Sauyet
@CrossEye
Oct 20 2015 19:30
@raine: do you really want an analog for reduce or for scan? I don't quite understand what the former would mean.
Jethro Larson
@jethrolarson
Oct 20 2015 19:34
reduce on a stream would return a promise, wouldn't it?
I figure you can't get a single value until the stream ends
Raine Virta
@raine
Oct 20 2015 20:53
@jethrolarson not necessarily, you could reduce a stream to get a new stream that emits a combined value when the reduced stream is finished
Jethro Larson
@jethrolarson
Oct 20 2015 22:44
Yeah. I was thinking that as well. I heard it said that a promise is just a stream with only one event
Scott Christopher
@scott-christopher
Oct 20 2015 23:21
@joneshf-work1 Do you have an example of a streaming abstraction that you like in another language?
Scott Sauyet
@CrossEye
Oct 20 2015 23:22
This message was deleted
Scott Christopher
@scott-christopher
Oct 20 2015 23:25
I'm interested in exploring the area a bit more in JS, but not sure how limited it will be.
Scott Sauyet
@CrossEye
Oct 20 2015 23:25
@davidchambers: loved listening to FunctionalGeekery. Great interview! Like the shout-out to the Kahneman book, too.
Scott Christopher
@scott-christopher
Oct 20 2015 23:25
There's scalaz-stream, which looks like a possible candidate.
Or the Kmett's equivalent machines lib
Scott Sauyet
@CrossEye
Oct 20 2015 23:30

So @raine, is the idea something like

on('end', fn, reduce(stream))

That is, reduce would return a stream that always contains at most a single value, and that only if the original stream completes?

David Chambers
@davidchambers
Oct 20 2015 23:30
Thanks, @CrossEye! I hope I wasn't too tough on Ramda's stance on run-time type checking. :wink2:
Scott Sauyet
@CrossEye
Oct 20 2015 23:31
Not at all. It was well-articulated.
I'm less opposed than you may think, too. Half the problem is that I don't want to do it.
joneshf-work1
@joneshf-work1
Oct 20 2015 23:32
@davidchambers when'd that come out? I just got caught up yesterday, and thought there weren't any new episodes.
Scott Sauyet
@CrossEye
Oct 20 2015 23:32
Turns out I'm really far behind.
David Chambers
@davidchambers
Oct 20 2015 23:32
Actually spend the time implementing it do you mean, Scott?
Scott Sauyet
@CrossEye
Oct 20 2015 23:33
the time, the mental effort. It's a totally uninteresting problem to me. Don't want to debug it, to support it, etc.
joneshf-work1
@joneshf-work1
Oct 20 2015 23:33
@scott-christopher I've only barely played with machines, I was thinking more along the lines of pipes
David Chambers
@davidchambers
Oct 20 2015 23:33
@joneshf-work1, it came out within the past 24 hours. Foiled by CDN caching, perhaps?
Scott Sauyet
@CrossEye
Oct 20 2015 23:33
I wouldn't mind having it, so much.
joneshf-work1
@joneshf-work1
Oct 20 2015 23:33
@scott-christopher they're all bascally the same though, it seems.
@scott-christopher i'm going to start working on something by the end of the week if you'd like to contribute.
Scott Christopher
@scott-christopher
Oct 20 2015 23:34
Sure, that sounds great
Scott Sauyet
@CrossEye
Oct 20 2015 23:34
What really intrigued me, though, was the notion of folding type-checking into the curry implementation.
Scott Christopher
@scott-christopher
Oct 20 2015 23:34
I've started diving into Arrows too, which seems to use streams as one of their example use cases ... though I'm not sure if that depends on lazy lists
David Chambers
@davidchambers
Oct 20 2015 23:35
plaid/sanctuary#75 is definitely on my list. Ramda and Sanctuary could both use it (though I know you're against Ramda having any dependencies). Multiple projects would then benefit from the effort involved in supporting it.
joneshf-work1
@joneshf-work1
Oct 20 2015 23:36
@scott-christopher the latest thinking is that you get more mileage out of profunctors and their derivatives than the arrow stuff, so you might want to look into that as well.
Scott Christopher
@scott-christopher
Oct 20 2015 23:36
good to know :)
joneshf-work1
@joneshf-work1
Oct 20 2015 23:36
@scott-christopher I think they're mostly equivalent, but arrow are more restricted or something. I'm not a big arrow person myself so I can't really comment too much.
This message was deleted
geez, nice gitter.
David Chambers
@davidchambers
Oct 20 2015 23:37

What really intrigued me, though, was the notion of folding type-checking into the curry implementation.

This was @paldepind's idea. It's marvellous. With heavy use of partial application, type errors are often caught when evaluating a function's definition (without even applying the function). Pretty neat!

Scott Christopher
@scott-christopher
Oct 20 2015 23:37
If it were possible to throw an iOS app out the window, gitter would have flown a long time ago
Scott Sauyet
@CrossEye
Oct 20 2015 23:38
Yeah, don't mind it at all on a real keyboard, but on my phone, I get ready to strangle someone.
And it doesn't have to be that way, because I don't feel that way about Slack.
Scott Christopher
@scott-christopher
Oct 20 2015 23:39
Yeah, while Slack still has the odd UX issue on mobile, it is still usable.
joneshf-work1
@joneshf-work1
Oct 20 2015 23:40
it feels like it's getting slightly worse rather than better, which is unfortunate.
Jethro Larson
@jethrolarson
Oct 20 2015 23:40
I wouldn't cry if R.nAry caused the returned function to throw or warn if given more args. In a supposed debug mode anyway
joneshf-work1
@joneshf-work1
Oct 20 2015 23:40
hopefully there's big changes a commin'
Scott Christopher
@scott-christopher
Oct 20 2015 23:41
@joneshf-work1 I stumbled across this pdf on Arrows the other day, which seems to be a nice intro www.cse.chalmers.se/~rjmh/afp-arrows.pdf
Jethro Larson
@jethrolarson
Oct 20 2015 23:42
gitter doesn't know that ~ is a valid url character I guess
Scott Christopher
@scott-christopher
Oct 20 2015 23:42
oh-you-gitter.gif
joneshf-work1
@joneshf-work1
Oct 20 2015 23:42
case in point...
Jethro Larson
@jethrolarson
Oct 20 2015 23:43
"Point-free programming is rightly popular"
lol
academics aren't myopic, are they :P
joneshf-work1
@joneshf-work1
Oct 20 2015 23:56
@scott-christopher I'm kind of thinking though, that I'd probably like to do most of it as a free monad if possible, and leave the interpretation for the user. Provide a few interpreters for the standard stuff: rx, bacon, kefir, flyd. So I don't get hosed if I forget something.
@scott-christopher Also, I'd like to see how much of this could be shoved in there as well: http://hackage.haskell.org/package/mmorph-1.0.4
mostly due to what I just stated.
Scott Christopher
@scott-christopher
Oct 20 2015 23:57
Sure. I recently got a free monad implementation working based on the purescript-free package.
Jethro Larson
@jethrolarson
Oct 20 2015 23:58
Only thing I remember from trying to study free monads was that they're not free as in speech nor beer
joneshf-work1
@joneshf-work1
Oct 20 2015 23:58
nice
in js?
Scott Christopher
@scott-christopher
Oct 20 2015 23:58
Yeah
joneshf-work1
@joneshf-work1
Oct 20 2015 23:58
so, about that
Scott Christopher
@scott-christopher
Oct 20 2015 23:58
I got inspired by the "Reflections without Remorse" changes that landed in purescript-free recently
joneshf-work1
@joneshf-work1
Oct 20 2015 23:59
Are you adverse to using ps as the source language and distributing the js on npm?
Scott Christopher
@scott-christopher
Oct 20 2015 23:59
I'd be more than happy to use ps :)
joneshf-work1
@joneshf-work1
Oct 20 2015 23:59
sweet!
Scott Christopher
@scott-christopher
Oct 20 2015 23:59
I've only really played with it for a recent hack-day project