@seiyab/do-expr
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

package of do expressions

This package is inspired by proposal-do-expressions

Motivation

  • expression-oriented programming one of the great advances of FP
  • expressions plug together like legos, making more malleable programming experience in-the-small

Installation

npm install @seiyab/do-expr

Examples

Write in an expression-oriented style, scoping variables as locally as possible:

import { do_ } from "@seiyab/do-expr";

let x = do_(() => {
  let tmp = f();
  return tmp * tmp + 1
});

Use conditional statements as expressions, instead of awkward nested ternaries:

let x = do_(() => {
  if (foo()) { return f() }
  else if (bar()) { return g() }
  else { return h() }
});

Especially nice for templating languages like JSX:

return (
  <nav>
    <Home />
    {do_(() => {
      if (loggedIn) return <LogoutButton />;
      return <LoginButton />;
    })}
  </nav>
)

Edge cases

var declarations

var declarations are allowed, with the hoisting to the parameter function's scope. This behavior differs from proposal-do-expressions.

Empty do

do_(() => {}) is almost equivalent to undefined.

Some lint tool might blame it.

await

Works fine. To use await, you need an await before do_ and an async before ().

const result = await do_(async () => {
  const x = await fetchSomeData();
  if (x.isSuccess) return "ok";
  return "oops";
});

throw

Works fine. Does what you expect.

break/continue/yield

These won't work like proposal-do-expressions.

The major reason is technical one. And it's also for readability. Allowing these might induce confusion. These don't fit the motivation "expression-oriented programming".

return

It has a different functionality from proposal-do-expressions.

return is used for declaring result of do_, rather than returning from outer function.

Conflict with do-while

No problem at all.

Comparison

vs. IIFE

Yes, do-expr is just IIFE as you noticed. do-expr still has some advantages.

The main advantage is readability. We need to read last part of the expressions to know whether expressions are IIFEs or not.

// plain IIFE
const x = (() => {
//         ^^^^^ is x a function?
  if (f()) return g();
  return h();
})()
//^^ Finally I got it. this is an IIFE.

// do_
const x = do_(() => {
//        ^^^ OK, this behaves like a do expression.
  if (f()) return g();
  return h();
})

As another idea, you can declare _do argument to indicate it behaves like do expression.

const x = ((_do) => {
//          ^^^ OK, this behave like a do expression.
  if (f()) return g();
  return h();
})()

In this case, you need to write coding guideline documents and notify colleagues. Because this is not idiomatic yet. If readers don't know this idiom, they are confused by a mysterious _do argument and might consider that it is a function declaration until they reach the last ().

On the other hand, do_ already has README.md that you read now. If readers don't know do_, they are likely to google @seiyab/do-expr and find this README.

vs. proposal-do-expressions

Functionality

Some features like break / continue / yield doesn't work with @seiyab/do-expr.

The reasons are not only technical ones. It is an intended interface design. The main motivation of @seiyab/do-expr is expression-oriented programming. Though the features are perhaps helpful, they don't fit the original motivation. They will induce unnecessary complexity.

The following issue reports proposal-do-expressions vs IIFEs: https://github.com/tc39/proposal-do-expressions/issues/34

Availability

proposal-do-expressions is still stage 1 of the TC39 process. But a babel plugin @babel/plugin-proposal-do-expression is available.

@seiyab/do-expr already has stable release.

Readme

Keywords

none

Package Sidebar

Install

npm i @seiyab/do-expr

Weekly Downloads

3

Version

1.0.1

License

MIT

Unpacked Size

6.44 kB

Total Files

5

Last publish

Collaborators

  • seiyab