Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change toMaybe API to work more like encase #465

Closed
Avaq opened this issue Dec 8, 2017 · 5 comments · Fixed by #632
Closed

Change toMaybe API to work more like encase #465

Avaq opened this issue Dec 8, 2017 · 5 comments · Fixed by #632

Comments

@Avaq
Copy link
Member

Avaq commented Dec 8, 2017

From our Gitter conversations:

Maybe we could make this change:

-toMaybe :: a? -> Maybe a
+toMaybe :: (a -> Nullable b) -> a -> Maybe b

And [we'll] add toMaybe2 and toMaybe3, naturally

Converts a partial function* to a total function by wrapping its output in a Maybe.
If the output was Nil, Nothing is returned. Otherwise a Just of the output.

* Note that if the function is within your control, it's better to patch the function itself.

I hope that will move users from asking the question: "how do I deal with this null?" to: "how do I deal with this partial function?".
The goal is that when the question "how do I deal with this partial function" is raised, the answer: "make the function total" is more natural than: "wrap the function to become total". Whereas a question "how do I deal with this null" has a natural answer of "convert it to a Maybe" - the concept of the function was not even mentioned.

@davidchambers
Copy link
Member

I'm not sure that S.toMaybe(f) is preferable to S.compose(S.toMaybe, f).

You mention the possibility of providing S.toMaybe2 and S.toMaybe3. I imagine you're thinking that…

S.toMaybe3(f)

is less noisy than…

(x, y, z) => S.toMaybe(f(x, y, z))

As of #418, though, Sanctuary no longer includes any functions which take uncurried functions, so one would first need to curry f

S.toMaybe3(S.curry3(f))

One of the things I dislike about Ramda is that it provides so many functions for interoperating with unprincipled JavaScript functions. I'd prefer to provide a minimal set of tools and let users wrap unprincipled functions manually. In my experience manual wrapping is helpful as I often find myself wanting to curry a function and reorder its parameters in addition to changing its return type.

@Avaq
Copy link
Member Author

Avaq commented Dec 12, 2017

This idea came in response to my observation that new Sanctuary users often simply replace code like this:

function getX(){ Math.random() > .2 ? 'x' : null }
var x = getX() || 'default value';

With code like this:

function getX(){ Math.random() > .2 ? 'x' : null }
var x = S.fromMaybe('default value', S.toMaybe(getX()));

The latter clearly having no advantages; Failing to (realize that they should) address the source of the null, these users end up doing these convoluted null-checks using Sanctuary-based type casting..

Changing the toMaybe signature from one that lifts a value, to one that lifts a function might push users into the right direction.

Though you have compelling counter-arguments. I just posted this not to lose the idea. Feel free to close it if you prefer keeping things the way they are. :)

@davidchambers
Copy link
Member

Your concern is significant. I do wonder whether it would be better addressed by mentioning the fromMaybe . toMaybe anti-pattern in the documentation of S.toMaybe. We could note that this function should rarely be used, and provide an example of wrapping a “broken” function.

@gabejohnson
Copy link
Member

I'd vote for eliminating toMaybe altogether. If users really want it they can roll their own easily enough.

@davidchambers
Copy link
Member

That's a good option, Gabe. I could get behind that. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants