Live data from Hacker News

Maybe Functions

blog.benwinding.com

51–60 of 103 posts

Re: Maybe Functions

#51
post #34

In C# the closest analogy I can think of is the "Try" pattern. For example, you have int.Parse(string) which returns int, and int.TryParse(string, out int) which returns bool. The fact that the returned value is the validation is a strong incentive to do something with it.

that's a good example!

Re: Maybe Functions

#52
> “Functions should do something, not maybe do something…”

But it did do something, it checked if the user logged was logged in first.

Re: Maybe Functions

#53
I find it very interesting that the higher they are in the stack, the more people tend to talk about algebra (monads, functors, etc). I wonder why is that the case? Doesn't kernel or firmware require this level of abstraction?

Re: Maybe Functions

#54
post #8

Agreed with this essay, and I think it rhymes with two others that I've found pretty influential over the past five years: 1. Parse, don't validate ( https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va... ) 2. Pipeline-oriented programming ( https://fsharpforfunandprofit.com/pipeline/ ) In my experience, the "best" code (defining "best" as some abstract melange of "easy to reason about", "easy to modify", "e…

Isn't parsing itself a maybe function?

Re: Maybe Functions

#55
The author is conflating two separate concepts, and calling them both "the maybe function":

    1) functions which do hidden things outside of their contract and/or whose implementation doesn't properly line up with their types.

    2) functions which (by necessity) cannot always return the desired value and must return something else instead.
> The maybe function is a subtle monster that spreads it’s tentacles across the code-base.

This applies to both points 1 and 2.

> It’s alternating functionality of “does/doesn’t do something” makes code hard to understand, maintain and debug.

This only applies to point 1.

> They seem to be trivial to add, but difficult to remove. But hopefully this illustrates the concern and ways to fix it.

This cannot apply to point 2, because you cannot take a function which might return a user and `fix` it to make it always return a user.

> Solution 2 - Monads

This is not a monad.

He has implemented the Maybe Functor. runSafely most likely corresponds to map in whatever library you're using, not flatMap.

This is visible from its type signature:

    > runSafely(fn: (val: T) => V): Maybe          // map
which should be

    > runSafely(fn: (val: T) => Maybe): Maybe   // flatMap
And it's also visible in the example function:

  function getUser(): User {
    if (!loggedIn) {
      return null
    }
    return fetchUser();
  }
... which still suffers from points 1 and 2. Because it's the same function which was highlighted as bad code at the top.

Re: Maybe Functions

#56
post #54
post #8

Agreed with this essay, and I think it rhymes with two others that I've found pretty influential over the past five years: 1. Parse, don't validate ( https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va... ) 2. Pipeline-oriented programming ( https://fsharpforfunandprofit.com/pipeline/ ) In my experience, the "best" code (defining "best" as some abstract melange of "easy to reason about", "easy to modify", "e…

Isn't parsing itself a maybe function?

The author has conflated two concepts into "maybe function". Parsing is "maybe" in the sense that the parser will either return your object or fail. But it doesn't have to do any hidden, surprising behaviour like the "if (!loggedIn) {" line in the article.

Re: Maybe Functions

#57
post #22

I feel like there's a whole genre of essays (red vs green functions is the worst example) that could be summarised as: * Monads naturally arise out of many problems in programming. * But I don't want my language to support monads. * So here's something you can do to stay in denial about how much you need monads. At least this example only involves writing hard-to-analyse code and doesn't lead to you trying to invent…

The kicker here is that the author implemented a functor and called it a monad. So of course readers are going to think "the monad approach" is confusing and stay away.

Re: Maybe Functions

#58
post #33
post #8

Agreed with this essay, and I think it rhymes with two others that I've found pretty influential over the past five years: 1. Parse, don't validate ( https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va... ) 2. Pipeline-oriented programming ( https://fsharpforfunandprofit.com/pipeline/ ) In my experience, the "best" code (defining "best" as some abstract melange of "easy to reason about", "easy to modify", "e…

What constitues the "best" code depends on the incidental complexity of the problems you're trying to solve. Great code is when you have just enough of all those things, but have too much or too little and the code is worse.

You're right, of course — there are parts of my codebase that flagrantly disregard these rules, and did so for good reasons that I don't regret.

But I've found that while "everything is relative and should be situated in the context of the problem you're trying to solve" is a useful truism, it makes for poor praxis. It's hard to improve existing code or develop newer engineers without _some_ set of compasses and heuristics for what "good code" is, and once you develop that set the patterns and strategies for implementing "good code" naturally follows.

Re: Maybe Functions

#60
post #24

I can't wait for more languages to adopt the "?" operator [1] like the Rust one. It's just syntactic sugar for "if expr null return null" but makes it far easier to write code in a more monadic style. (mostly waiting for this in JS and Go) [1]: https://doc.rust-lang.org/reference/expressions/operator-exp...

I can't wait for more languages to simply not include null at all. It makes trying to spot them in static analysis and runtime checks much easier, because you no longer need either.
Post reply on HN