maybe
maybe copied to clipboard
Add orJustCall, with tests
Resolves #13. Very willing to discuss this further!
Hi @Leeds-eBooks thanks for your contribution. I've given this some thought and am not clear on a concrete use case for this addition.
I think if you want to have lazy evaluation with closures then it's possible to use the existing api.
Another reason I'm reluctant to accept it as is, is because call seems like a very imperative word and this library is trying to introduce a functional programming concept. eval would be more inline, but then again, I think this should just be handled by using closures explicitly rather than a special case function.
Interestingly however, this is the default behaviour for Scala which turns the value into a closure in the function argument (thus making it lazy). https://github.com/scala/scala/blob/2.13.x/src/library/scala/Option.scala#L133
I'm not sure how to achieve the same result in JS.
Understood. I can give you a couple of use cases I am already using my fork for:
import {Seq} from 'immutable'
const seq = Seq(hugeCollection)
return maybe(seq.size).orJustCall(() => seq.count())
Immutable sequences are not guaranteed to have a static size property, and must sometimes be eagerly evaluated to get a count of items. This evaluation can be expensive for a large collection. The alternative, maybe(seq.size).orJust(seq.count()) obviously executes this evaluation even if seq.size is already defined. But it's really convenient to use maybe in the above way.
maybe(existingKey)
.map(ek => db.child(ek).set(newData))
.orJustCall(() =>
db.push({
...newData,
createdBy: currentUser.uid,
})
)
In this example, I realise that it's perhaps not the "idiomatic" way of using maybe. But again, it's really convenient to use the null-handling abilities of maybe to work with data in a functional way.
Perhaps these are not the kinds of uses you envisaged for maybe, and that's why I totally understand if you don't want to merge this in. But I am finding maybe incredibly convenient in my code and this would make it even more so.
It would be possible to create a lazy version of maybe if you could specify the predicate function as suggested here: https://github.com/alexanderjarvis/maybe/issues/4
Then you could provide a closure the the maybe function (instead of having to map the value to a closure which would allow the orJust to work lazily too but it's more verbose).
You could also try:
const lazyMaybe = value => maybe(value).map(v => () => v)
lazyMaybe(seq.size).orJust(() => seq.count())()
However I think your examples could easily be rewritten as ternary or if/else expressions. It's not clear if the second example returns a value or just causes side effects.
Yeah, I think we've hit the fundamental core of our debate, which is whether it's better to add another method, or ask the user to dance around with userland util functions like your lazyMaybe. I can see the pros/cons of both but it's clear which I prefer.
You're right of course – I could just use if/else. But then why use maybe at all?