DEV Community

Should I use fp-ts Option?

Anthony G on September 15, 2020

tl;dr Option is more powerful than nullable but can be cumbersome to work with if you aren’t using it consistently. New apps should us...
Collapse
 
tamcarre profile image
Tam CARRE
function getModifiedName (name: string): string | undefined {
  return isAuthor (name) ? lowercase (name) : lastName (name)
}

function greet (name?: string): string {
  const modifiedName = name ? getModifiedName (name) : undefined
  return modifiedName ? `Hello ${modifiedName}` : 'Greetings!'
}
Enter fullscreen mode Exit fullscreen mode

Shorter and more straightforward than both your traditional implementation, and your Option implementation.

Collapse
 
anthonyjoeseph profile image
Anthony G • Edited

I really like this! Maybe I should add this as an addendum to the nested ternary implementation - dividing functions can be a great way to increase readability.

Anyway, this inspired me to write a similarly terse fp-ts version - playground

Collapse
 
tamcarre profile image
Tam CARRE

I also really like this new fp-ts version.

Collapse
 
lucasaba profile image
Luca Saba

I'm trying to...understand FP so, my comment may be dumb.

I think the initial example is unfair. This is a more concise way to write it.

const greet = (name: string | undefined): string => {
  if (!name) {
    return 'Greetings!'
  }

  if (isAuthor(name)) {
    return `Hello ${lowercase(name)}`
  }

  const last = lastName(name)
  if (last) {
    return `Hello ${last}`
  }

  return 'Greetings!'
}
Enter fullscreen mode Exit fullscreen mode

I think it's very readable. You don't have side effects. You've only one variable, name, and, in every line, just knowing it, you can understand what will be thew outcome.

In the Option version, when you arrive at the second O.fromNullable(name), you need to read back all the pipe to understand what will the outcome be.

Am I wrong ?

P.S. It certainly breaks the single return law but... multiple return allow you not to "stack in your memory" the state of a variable in every step.

Collapse
 
anthonyjoeseph profile image
Anthony G

No, you're not wrong, and your comment isn't dumb. Probably most developers today would say that what you've written is easier to read. You could even argue that your approach looks closer to pattern matching in a language like Haskell.

You're right about reading back the pipe. I think your comment is a bit similar to alnj's, both of which point out a flaw in my article. I wanted to pick a simple example that would showcase some features Option has beyond a more traditional control flow (alt, chain etc). If I had included Either & related functions, it would have been a more elegant flow (example), but I was worried about scope creep

I'm still asking the same questions you are quite frequently in my own work. There really are a lot of grey areas around readability today. Hopefully, as fp catches on, more and more people become adept at reading this kind of code

I'm not sure I agree about the single return law, though - while I understand your point about keeping a stack in your head as you're reading it, I think it can be equally difficult to keep track of the conditions that have caused the function to exit early, and it can lead to less explicit code in general

Collapse
 
alehatsman profile image
Aleh Atsman

@lucasaba I had a similar reaction when I read the example in the blog post. You're right, the projects I've seen using fp-ts can be challenging to read. While I appreciate the safety and reliability it offers, I prefer cleaner and more concise code, like the one you mentioned. I believe that in the world of IT, every technology and idea comes with its own trade-offs, and in the case of fp-ts, readability seems to be a trade-off.

Collapse
 
euphocat profile image
Nicolas Baptiste

Wow ! Great article !! Clear and human-friendly, which is not often the case when dealing with fp-ts :D

Collapse
 
anthonyjoeseph profile image
Anthony G

Thank you! Yes I'm excited to keep writing about fp-ts because I think its verbosity and proximity to JS can actually make it easier to read and can encourage deeper reasoning about fp than languages with terse, high-level syntax. In case you're having trouble finding great articles about fp-ts (of which there are many imo), here's a great resource: gcanti.github.io/fp-ts/learning-re...

Collapse
 
macsikora profile image
Pragmatic Maciej

Will just leave it here - dev.to/macsikora/maybe-just-nullab...

Collapse
 
anthonyjoeseph profile image
Anthony G • Edited

I really like your article! Especially the in-depth detail of the nuances of JS/Typescript nullable and its usage. It was a major inspiration for me when I was doing research. Hopefully readers will see the link in the article & this comment and take a look!

Collapse
 
macsikora profile image
Pragmatic Maciej

Ah. I didn't see that before. Thank you for mentioning and it's great that it has helped. Good work by the way!

Thread Thread
 
anthonyjoeseph profile image
Anthony G

Thank you!

Collapse
 
sumbatx15 profile image
sumbatx15

How about this?

const greet = (name?: string): string => {
    if (!name) return 'Greetings!'
    return `Hello ${isAuthor(name) ? lowercase(name) : lastName(name)}`
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ryanleecode profile image
Ryan Lee

I think you are mistaken about safe array operations, a PR just got merged into Typescript 4.1.

github.com/microsoft/TypeScript/pu...

Collapse
 
anthonyjoeseph profile image
Anthony G

Oh wow I had no idea, how exciting! I updated the article to reflect this. Thanks for pointing this out!