These are chat archives for ramda/ramda

6th
May 2016
saurshaz
@saurshaz
May 06 2016 05:06
anyone who has written a fairly decent sized api/mvc app(which is shared) using ramda and fp style of coding ?
Constantin Dumitrescu
@dumconstantin
May 06 2016 09:37
@saurshaz I'm doing at the moment and it's been a great experience
saurshaz
@saurshaz
May 06 2016 10:15
@dumconstantin is it shared on github ?
i am getting to get more functional. looking for more learning material :-)
Constantin Dumitrescu
@dumconstantin
May 06 2016 10:58
@saurshaz its for the company I work currently so its private, but I wrote ramda-loader just to use Ramda everywhere instead of writing vanilla javascript, these days I'm only constructing programs using Ramda + Kefir so almost no custom code
saurshaz
@saurshaz
May 06 2016 10:59
@dumconstantin thanks that info also helps. had a look at ramda-loader . it also seems it would be useful to me , in future.
Constantin Dumitrescu
@dumconstantin
May 06 2016 10:59
I refactored some older modules with Ramda + Kefir and had 90% less lines of code which is amazing
saurshaz
@saurshaz
May 06 2016 11:00
what would be the tips you would give me. i wanna go more functional way in node.js and JS code using Ramda
Constantin Dumitrescu
@dumconstantin
May 06 2016 11:00
let me know if ramda-loader works for you, I'll be glad to help you with setting it up or tweaking it to match your use case
yup, highly recommend you do that, makes programming so much more fun
Constantin Dumitrescu
@dumconstantin
May 06 2016 11:07
@saurshaz I recommend this course https://frontendmasters.com/courses/functional-javascript/, made a lot of things clear for me about functional programming in general
saurshaz
@saurshaz
May 06 2016 11:13
@dypsilon Thanks. that's what i am on. right now. that's what was the starting :-)
@dumconstantin thanks for that also.will do.
@dumconstantin i actually bumped into ramda-loader while working on one of my riot projects. i like the problem it serves. and it could make namespacing go away completely. i think that's a super cool project.
Constantin Dumitrescu
@dumconstantin
May 06 2016 11:35
@saurshaz thanks a lot, I also use Riot, its been a great match so far
saurshaz
@saurshaz
May 06 2016 11:40
:+1:
Brad Compton (he/him)
@Bradcomp
May 06 2016 14:12
@saurshaz We were talking about projects using Ramda just the other day :point_up: https://gitter.im/ramda/ramda?at=572a0d5e12cceadb7b1a9148
saurshaz
@saurshaz
May 06 2016 14:13
Thanks @Bradcomp
Constantin Dumitrescu
@dumconstantin
May 06 2016 14:21

hi @davidchambers, regarding the Ramda curry wrapper question, it seems that relying on the length prop doesn't always guarantee that the returned function is non-ramda:

let fn = curryN
fn.length // 2
let args = [3, () => {}]
let result = fn.apply(null, args)
fn.length <= args.length // true, BUT the result is now another curried function:
result // function (a0, a1, a2) { return fn.apply(this, arguments); }

This only happens for curryN, so I might make a validation to see if the fn is curryN before applying the args to it but do other Ramda functions return a curry wrapper function just like curryN does?

Chet Harrison
@ChetHarrison
May 06 2016 16:11
@saurshaz @dypsilon here is a short app I have been working on for a talk I have coming up. I plan to add Sanctuary and a few monads to it but at the moment it has an imperative and functional versions of the same code. http://jsbin.com/hifanu/edit?js,output
saurshaz
@saurshaz
May 06 2016 16:41
Thanks @ChetHarrison
Chet Harrison
@ChetHarrison
May 06 2016 16:41
:+1:
Carlos Gottberg
@clinoge
May 06 2016 17:22

Hey, got a very simple question. I'm a bit confused about the mostly adequate guide (https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch10.html) specially on applicative functors. He defines a method ap like this:

Container.prototype.ap = function(other_container) {
  return other_container.map(this.__value);
}

For the IO functor, map is defined like this:

IO.prototype.map = function(f) {
  return new IO(_.compose(f, this.__value));
};

However, then, I think this should fail, while he claims it does indeed work:

IO.of(signIn).ap(getVal('#email')).ap(getVal('#password')).ap(IO.of(false));

^ would be reduced to IO( ((( f . g ) . g' ) . g'') ) according to my education on the subject. Which, IMO, would be equal to f . g . g' . g''. When released through __unsafePerformIO(), this function, by the definition of compose would only have 1 argument. Would it not?

Unless every invokation of ap would evaluate the value of IO, which kinda defeats the point of holding side effects until evaluation is really needed, IMO, main logic.
Carlos Gottberg
@clinoge
May 06 2016 17:28

When writing a bit of this code

// Roughly equivalent to IO.of(add).ap(IO.of(3)).ap(IO.of(4)).unsafePerformIO();
var add = R.curry( (x, y) => x + y );
var f = R.compose(add, (x) => 3);
var g = R.compose(f, (x) => 4);
g();

I get a function, not the expected result (according to mostly adequate guide) of 7. And this, I think, is the correct result. If I execute, however,

g()(5);

result would be 8 (as expected by me).

Brad Compton (he/him)
@Bradcomp
May 06 2016 17:31
@ram-bot Maybe.of(add).ap(Maybe.of(4)).ap(Maybe.of(3))
ram-bot
@ram-bot
May 06 2016 17:31
_Just { value: 7 }
Brad Compton (he/him)
@Bradcomp
May 06 2016 17:32
Just checking to see if Ram bot can handle Maybe
Carlos Gottberg
@clinoge
May 06 2016 17:33
@ram-bot IO.of(add).ap(IO.of(4)).ap(IO.of(5))->__unsafePerformIO()
ram-bot
@ram-bot
May 06 2016 17:33
IO { fn: [Function] }
Brad Compton (he/him)
@Bradcomp
May 06 2016 17:34
@clinoge It doesn't listen to edits
@ram-bot IO.of(add).ap(IO.of(4)).ap(IO.of(5)).__unsafePerformIO()
ram-bot
@ram-bot
May 06 2016 17:34
IO.of(...).ap(...).ap(...).__unsafePerformIO is not a function
Brad Compton (he/him)
@Bradcomp
May 06 2016 17:35
@ram-bot IO.of(add).ap(IO.of(4)).ap(IO.of(5)).fn()
ram-bot
@ram-bot
May 06 2016 17:35
9
Carlos Gottberg
@clinoge
May 06 2016 17:36
My, I will check Ramda's code to see how's that implemented :)
Brad Compton (he/him)
@Bradcomp
May 06 2016 17:39
I haven't fully grokked the implementation details, but I know that ap allows for partially applying functions in containers to values in containers.
Carlos Gottberg
@clinoge
May 06 2016 17:41
That's what it looks life from the Ramda Try It console :). I'm kinda writing a functional library for PHP (works makes me use it so much ^^) so I'm really interested in implementation details : D
Brad Compton (he/him)
@Bradcomp
May 06 2016 17:41

So

IO.of(signIn).ap(getVal('#email')).ap(getVal('#password')).ap(IO.of(false))

Represents applying the signIn function to the three values returned by getVal and of. The function gets built up, but it takes __unsafePerformIO() (or fn in the ram-bot case) to actually execute the code.

Carlos Gottberg
@clinoge
May 06 2016 17:42
Yup, and withouth the fn() it would just be an IO(f) with f ready to be evaluated
Carlos Gottberg
@clinoge
May 06 2016 17:52
IO.prototype.ap = function(thatIo) {
  return this.chain(function(f) {
    return thatIo.map(f);
  });
};
from ramda-fantasy. Works flawlessly.
Carlos Gottberg
@clinoge
May 06 2016 17:58
Thank you very much @Bradcomp :-)
Paul
@pauloliver
May 06 2016 18:44

I'm having some trouble transforming an object like

{
    foo: 123,
    bar: {
      baz: 456
    }
}

into

{
    foo: 123,
    baz: 456
}

I guess something like flatten or unnest, but for objects?

Brad Compton (he/him)
@Bradcomp
May 06 2016 18:50
@ram-bot
const obj = {
    foo: 123,
    bar: {
      baz: 456
    }
}
converge(merge, [omit(['bar']), prop('bar')])(obj)
ram-bot
@ram-bot
May 06 2016 18:50
{ foo: 123, baz: 456 }
Brad Compton (he/him)
@Bradcomp
May 06 2016 18:53
@ram-bot
const unnestProp = prp => converge(merge, [omit([prp]), prop(prp)])

const obj = {
    foo: 123,
    bar: {
      baz: 456
    }
}

unnestProp('bar')(obj)
ram-bot
@ram-bot
May 06 2016 18:53
{ foo: 123, baz: 456 }
Vladimir Starkov
@iamstarkov
May 06 2016 18:58
@Bradcomp that's cool
Brad Compton (he/him)
@Bradcomp
May 06 2016 18:59
:+1:
Paul
@pauloliver
May 06 2016 19:02
Thanks @Bradcomp !
BasH
@bas080
May 06 2016 19:34
I would have used assoc. http://goo.gl/7Df6Lg

@ram-bot
var obj = {
foo: 1,
bar: {
baz: 1
}
}

assoc('bar', path(['bar', 'baz'], obj), obj)

How does rambot work?
Carlos Gottberg
@clinoge
May 06 2016 19:36
at ram-bot plus single backtick code plus single backtick
@ram-bot var a = 2
ram-bot
@ram-bot
May 06 2016 19:36
undefined
BasH
@bas080
May 06 2016 19:37

@ram-bot ` var obj = {
foo: 1,
bar: {
baz: 1
}
}

assoc('bar', path(['bar', 'baz'], obj), obj)`

Carlos Gottberg
@clinoge
May 06 2016 19:37
At least, that's how I use it, dunno if it will work with a code block (three back ticks)

@ram-bot ``` var obj = {
foo: 1,
bar: {
baz: 1
}
}

assoc('bar', path(['bar', 'baz'], obj), obj)```

ram-bot
@ram-bot
May 06 2016 19:37
{ foo: 1, bar: 1 }
BasH
@bas080
May 06 2016 19:37

@ram-bot + `var obj = {
foo: 1,
bar: {
baz: 1
}
}

assoc('bar', path(['bar', 'baz'], obj), obj) +

Brad Compton (he/him)
@Bradcomp
May 06 2016 19:37
@clinoge @bas080 it will work with three backtick blocks too
BasH
@bas080
May 06 2016 19:38

@ram-bot ```
var obj = {
foo: 1,
bar: {
baz: 1
}
}

assoc('bar', path(['bar', 'baz'], obj), obj)
```

I'm so sorry bu it doesn't wok
Brad Compton (he/him)
@Bradcomp
May 06 2016 19:39
@ram-bot
var obj = {
  foo: 1,
  bar: {
    baz: 1
  }
}
assoc('bar', path(['bar', 'baz'], obj), obj)
ram-bot
@ram-bot
May 06 2016 19:39
{ foo: 1, bar: 1 }
BasH
@bas080
May 06 2016 19:39
@ram-bot
var obj = { foo: 1, bar: { baz: 1 } } assoc('bar', path(['bar', 'baz'], obj), obj)
I tried :worried:
BasH
@bas080
May 06 2016 19:41
@ramda-bot
var obj = {
  foo: 1,
  bar: {
    baz: 1
  }
}
assoc('bar', path(['bar', 'baz'], obj), obj)
So the backticks have to be on their own line
Carlos Gottberg
@clinoge
May 06 2016 19:42
Maybe, not really sure ^^
BasH
@bas080
May 06 2016 19:42
Btw, nice meeting you people. Love the Ramda. My go to toolbelt when possible.
Brad Compton (he/him)
@Bradcomp
May 06 2016 19:59
Welcome @bas080 !
Carlos Gottberg
@clinoge
May 06 2016 21:12

Let's say that I once had a IO that read from standard input, and after reading one char, some functions were lifted and composed to process this data. At some point, the computation was to branch and these two saplings continued their elders tradition of lifting and composing.

At some point, however, both of them needed to consult their ancestors, cause they had forgotten what they needed to evaluate. So, they each ask for the read to be made.

var mysteryAncestor = new IO ( function() {
   // Will return {a: '2', b: '3'} the first time it's called, but undefined the second time
    return mysteryRead();
};

var firstOperation = function (x) { ... };
var lifted = lift(firstOperation, mysteryAncestor);

// and so on, and so on

var lastOfItsName = lift(fn, father);

var redBranch = lift(compose(lots of functions), lastOfItsName);
var blueBranch = lift(compose(lots of functions), lastOfItsName);

However, blueBranch needed the initial b: 3.

And it is getting undefined
This is expected behaviour, yes or no?
(I strongly think it is, because each chain of functions, when evaluated, makes mysteryRead be invoked once again)
Now, had I wanted redBranch and blueBranch to share a common mysteryRead, I should have made lastOfItsName to evaluate and then branch.
Correct me if wrong :-)
Scott Sauyet
@CrossEye
May 06 2016 21:20
Correct me if wrong
You could be, but it's the ends of a long work week, and I'll be dammed if can tell. :smile:
Carlos Gottberg
@clinoge
May 06 2016 21:22
Funny, thought it was phrased like that x). Same here, that's why I'm asking ^^
Scott Sauyet
@CrossEye
May 06 2016 21:23
And I can't type either. ...
BasH
@bas080
May 06 2016 21:26
@ram-bot
weekLength = Infinity;
weekLength === Infinity;
ram-bot
@ram-bot
May 06 2016 21:26
true
Scott Sauyet
@CrossEye
May 06 2016 21:32
:smile:
BasH
@bas080
May 06 2016 21:32
@ram-bot
function wasMyWeekLongRamBot(weekLength, user){
if (weekLength == Infinity)
return "Ram-bot agrees that "+ user+ "'s his week was long";
else
return 'meh';
}

var weekLength = Infinity;
wasMyWeekLongRamBot(weekLength,'@CrossEye');
ram-bot
@ram-bot
May 06 2016 21:32
Infiity is not defined
Scott Sauyet
@CrossEye
May 06 2016 21:33
Botty doesn't recognize edits.
"Rambo"? Or is that too obvious?
BasH
@bas080
May 06 2016 21:35
hehe
Brad Compton (he/him)
@Bradcomp
May 06 2016 21:44
Is there a Task / Future based library for making HTTP requests?
R.assoc
BasH
@bas080
May 06 2016 21:48
@Bradcomp, this might help. https://github.com/ramda/ramda-fantasy
Brad Compton (he/him)
@Bradcomp
May 06 2016 21:50
@bas080 Thanks! I am looking for something like axios, but with Futures...
I've been using folktale's Tasks as my futures in my application code, looking for a request library that plays nicely with it.
BasH
@bas080
May 06 2016 21:54
@Bradcomp , Maybe write a Monad that takes an axios promise and does the magic you want it to do.
Brad Compton (he/him)
@Bradcomp
May 06 2016 21:56
@bas080 That might be what I do... Just write a wrapper to help it play nice
BasH
@bas080
May 06 2016 22:13
@Bradcomp I made something of a sketch a while back. I'm not an expert. https://gist.github.com/bas080/169c2fe7ad2d1b69a1ac#file-applicative-js-L215
Brad Compton (he/him)
@Bradcomp
May 06 2016 22:26
@bas080 Thanks!
Kevin Wallace
@kedashoe
May 06 2016 22:27
@Bradcomp maybe try https://github.com/futurize/futurize with axios?
Brad Compton (he/him)
@Bradcomp
May 06 2016 22:27
I need to spend some time making my own Monads. I am becoming more comfortable with using them, but designing them is more tricky
@kedashoe Thanks!