Make programming easier

Introduction
Little known technique for self-describing code

Little known technique for self-describing code

It is very common to describe your code with comments but they have one big issue. Quickly getting out of date.

One developer creates a code, adds few comments.
Second developer changes the code a little bit and forgets about comments.
Third developer changes the code and forgets about comments.
So on so forth and then... You can no longer trust if the comments are actually valid/accurate.

Here I'd like to explain you one more method that I found useful, reduces amount of necessary comments and it's type-safe.

Monads!

My personal choice for implementation of monads is monet.js as it does not force you to go into full-blown FP programming like fp-ts does.

Returning single entity but sometimes it cannot be found

If a method tries to find something but it might not be found then instead of returning Smth or undefined use Maybe instead. That clearly describes the operation might return an empty result.

In other words we can say:
> find article by id and optionally return result

class ArticleRepository {
    findById(id: string): Promise<Maybe<Article>> {
    }
}

Especially useful for environments where strictNullCheck is not enabled for some reason.

Creating an entity but fails once it is a duplicate

If a method creates an entity but that entity violates some constraints then instead of throwing an error return Maybe.

In other words we can say:
> create entity and optionally return created entity if that succeeds, if none then there is a duplicate

class ArticleRepository {
    create(input: ArticleCreateInput): Promise<Maybe<Article>> {
        try {
            // make insert to database
            // if succeeds
            return Maybe.Some(newlyCreatedArticle);
        } catch (e) {
            if (e.code === 'UNIQUE_VIOLATION') {
                return Maybe.None();
            }
            // throw other errors
            throw e;
        }
    }
}

You can also use Validation if you prefer.

Parse something but parsing is likely to fail

This one is my favorite.

Parsing some input is very likely to fail since simply input might not be valid. How are you going to catch an error for it? Creating new error type? How do you know you've handled all type of errors possible to be thrown by parser?

For all that problems here it comes - Validation.

function parseDomain(
    domain: string
): Validation<'INVALID_SYNTAX' | 'UNKNOWN_TLD' | 'TOO_LONG', Domain> {
    
}

In other words we can say:
"parse domain and return fail which might one of following strings, if succeeds return Domain object"

  • No extra error types
  • No unnecessary try/catch when you don't need it
  • You know upfront what kind of errors to expect
  • If something unexpected happens (regular TypeErrors or smth) then error gets thrown

Other use cases for Validation

  • regular data validation - Validation<Violations, SanitizedData>
  • RPC operations - Validation<RPCError, TResult>
  • Run a task but it might fail - Validation<TaskError, TResult>

That's not all

There are other monads that might be helpful for your case so do not hesitate to experiment and share the results.

Author

wookieb

Fullstack developer with 10 years of experience. Passionated about programming, computers and how things work.

View Comments
Previous Post

Is `instanceof` broken?