These are chat archives for ramda/ramda

27th
Dec 2015
boxofrox
@boxofrox
Dec 27 2015 17:42

When would you want Maybe.of(null) to return Just(null)? I could understand using Just(null) if I really wanted to store null in a Just, but I don't get why implementations for .of always use Just.

Javascript is certainly in a wierd place since it has null and how it's used can determine whether it's a value or effectively Nothing.

In simple cases where I use R.prop... I think I'm about to answer my own question >.<

R.prop doesn't return a Maybe. I have to wrap it myself, so I can use folktale's Maybe.fromNullable, which has the behavior I'm looking for, in the wrapper:

const maybeProp = (key) => compose(Maybe.fromNullable, prop(key))

In the simple case of accessing one property, map is sufficient.

const numLikes = compose(map(length), maybeProp('likes'));

numLikes({ likes: [1, 2, 3] });  // => Just(3)
numLikes({});     // => Nothing

In the complex case--where most of my confusion lay--accessing two layers of properties requires 'map' and 'chain' as opposed to just two 'map's.

const numReallyLikes = compose(map(length), chain(maybeProp('likes')), maybeProp('really'));

numReallyLikes({ really: { likes: [1, 2, 3] } }); // => Just(3)
numReallyLikes({ really: { dislikes: [1] } });     // => Nothing

This way makes sense now that I consider the propagation of types. However, my first intuition was to do something like below, which lends itself to refactoring...

const numReallyLikes = compose(map(length), map(prop('likes')), Maybe.fromNullable, prop('really'));

const numReallyLikes_2 = compose(map(compose(length, prop('likes')), Maybe.fromNullable, prop('really'));

...but I see now this is just wrong. compose(length, prop('likes')) will still throw a null reference exception. Why couldn't I see this days ago?

Aldwin Vlasblom
@Avaq
Dec 27 2015 17:59
@boxofrox There's also a part of the Fantasy Land spec which states that "no parts of [the argument passed to of] should be checked". So implementing Maybe.of like how Maybe.fromNullable works would be breaking the law, whilst completely leaving out Maybe.of would prevent it from being an Applicative. It's there to abstract over, but I see no reason to use it API-wise when you can just use Just.
boxofrox
@boxofrox
Dec 27 2015 18:00
thanks, @Avaq. I hadn't noticed that bit of the spec.
boxofrox
@boxofrox
Dec 27 2015 18:06
I guess I trailed off at the end of my post. I got hung up on Maybe.of since it was used to define Just.map = (f) => Maybe.of(this.value), so I got it my head if of was more like fromNullable, then I could compose many map(prop())s to drill down into a complex object. Stupid intuition :facepunch:
Niloy Mondal
@niloy
Dec 27 2015 19:31
@boxofrox Why not simply use path to drill down a complex object?
boxofrox
@boxofrox
Dec 27 2015 19:47
path was just a plot device. I was trying to figure out how wrap db transactions in a monad when I got hung up on Maybe.of.
Hardy Jones
@joneshf
Dec 27 2015 19:47
I was watching Hickey's "Simple Made Easy" again. He mentions that foldl and foldr are complex because they describe the act of folding and the direction in which to fold. Does that mean that fold is simple since it doesn't mention any sort of order?
boxofrox
@boxofrox
Dec 27 2015 22:03
maybe his fold works from both ends? I wonder if he abstracted the order of iteration into a separate function.
since the result is a Monoid it doesn't matter which way you fold it.
so the implementation can do it whichever way.
but the how is gone.
Does it become more complex because the result is a Monoid? Or is it still simple because there is no direction?
boxofrox
@boxofrox
Dec 27 2015 22:52

My first thought was to vote for the latter, before I got to 25:01. After watching it again, I think fold was the strawman. Using it implies--if this makes sense--that somewhere in your program, you may be managing an ordered list of something. But the slide only mentioned tuples, and folding tuples doesn't make sense to me. Unless I missed something, I didn't see a direct reference to foldr or foldl.

I would definitely call fold a simpler interface to work with, especially if it could dynamically dispatch to the type's implementation of fold which would use the appropriate left or right iterator.

I don't know if this helps. That was an interesting question though.

03:07 he talks about simple as one thing (fold, braid, role, task, concept...).
10:50 simplicity is an opportunity and design is about pulling things apart.
21:30 he lists fold [in general] under complexity vs simple set functions (where sets have no order).
25:01 why care about order, [arbitrary use] adds complexity.
lol abritrary
Aldwin Vlasblom
@Avaq
Dec 27 2015 23:30
Could I get you guys' feedback on this idea I had and worked on a little? It's a Monad, a lot like Future but with a "roll back" computation building up alongside the primary computation. The idea being that the roll-back is executed (in reverse order) when the primary rejects, hopefully abstracting away a lot of the trouble one has to go through to create reliable multi-party transactions. Here's an implementation: https://github.com/Avaq/fantasy-transactions .. Before I write all the tests, I'd love to know your opinions about the idea. :)
boxofrox
@boxofrox
Dec 27 2015 23:34
hah. I've been trying to decipher how to create a similar monad myself the last couples days. I'm still stumped, so this is good timing. :sa:
Aldwin Vlasblom
@Avaq
Dec 27 2015 23:34
If it turns out somebody already did this, or there is a much easier way to solve the problem it tries to solve, then, no biggie. I made it mainly for the exercise.
Hardy Jones
@joneshf
Dec 27 2015 23:37
@boxofrox yeah, I don't think he made a distinction between left or right folding, probably since most languages don't make the distinction, just the idea that there is a direction.
@Avaq have you looked into STM?
Aldwin Vlasblom
@Avaq
Dec 27 2015 23:41
@joneshf Nope. Never heard of the term. Is it the "Slalom Task Management" one?
Hardy Jones
@joneshf
Dec 27 2015 23:41
sorry, software transactional memory
Aldwin Vlasblom
@Avaq
Dec 27 2015 23:46
Reading it now. Though at first sight it appears to target a different problem. I started creating this because I anticipated a project where I'd be working with three separate databases. If during a "transaction" one fails after the other succeeds, I'd want to roll back changes on the other. The key here being that these databases don't share any kind of knowledge or state among each other. I'll keep reading though!
Maybe my naming is wrong.
Hardy Jones
@joneshf
Dec 27 2015 23:54
that seems like somehing stm could handle.
If each db thing is atomic, then they all must succeed.
otherwwise it rolls back.