DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป is a community of 963,673 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for ๐Ÿ—œ๏ธ Optimal Tuple vs Record
๐Ÿฅ‘ Andrew Luca
๐Ÿฅ‘ Andrew Luca

Posted on

๐Ÿ—œ๏ธ Optimal Tuple vs Record

Let's say we have this createStore function:

Ignore the implementation, we focus only on return value.

function createStore() {
  const state = 0;
  const dispatch = () => { /* ... */ };
  return /* ... */;
}
Enter fullscreen mode Exit fullscreen mode

What is a Store ? See Flux In-Depth Overview
React uses Redux, Vue uses Vuex, Angular uses NgRx

And we have two ways to return state and dispatch:

Record:

What is a Record? Wikipedia

function createStore() {
  // ...
  return { state, dispatch };
}

const { state, dispatch } = createStore();
console.log(state);
dispatch();
Enter fullscreen mode Exit fullscreen mode

Tuple:

What is a Tuple? Wikipedia

function createStore() {
  // ...
  return [state, dispatch];
}

const [state, dispatch] = createStore();
console.log(state);
dispatch();
Enter fullscreen mode Exit fullscreen mode

We used Destructuring assignment when called our createStore

Now let me show you something amazing โœจ โœจ โœจ We will build both examples using webpack

throwing sparkles

Record:

(()=>{const{state:t,dispatch:s}={state:0,dispatch:()=>{}};console.log(t),s()})();
Enter fullscreen mode Exit fullscreen mode

Tuple:

(()=>{const[o,c]=[0,()=>{}];console.log(o),c()})();
Enter fullscreen mode Exit fullscreen mode

amazed chris pratt

To the moon? ๐Ÿš€ Compiled code that uses tuples is far smaller than one using record. And I suppose this scales when your code base is far bigger.

But why this happens ๐Ÿค” Well, we can assume that everything that is returned from anywhere is a public API to the consumer. And when using a Record return, webpack will consider all fields as a public API, and cannot obfuscate them.

On the other hand when returning a Tuple, webpack does not see any actual fields names, they are just items into an array, and it will obfuscate all the code.

Record also has an advantage that you can reorder the names of the API, while with Tuple you need to use the exact same order as it was defined.

What about the consumer that uses this public API? ๐Ÿง‘โ€๐Ÿ’ป

Actually here is one more advantage when returning Tuple. Let's say that consumer wants the API under different name. Instead of state and dispatch to be value and execute

Record:

const { state: value, dispatch: execute } = createStore();
Enter fullscreen mode Exit fullscreen mode

Tuple:

const [value, execute] = createStore();
Enter fullscreen mode Exit fullscreen mode

As you can see consumer code becomes too verbose with Record example, and when he will compile his code, webpack again wil not have the ability to obfuscate his code ๐Ÿ’ฏ

Example: StackBlitz

Some dangerous tips:

Tuple can be destructured as Record, and you can change order:

function createStore() {
  // ...
  return [state, dispatch];
}

const { 1: dispatch, 0: state } = createStore();
Enter fullscreen mode Exit fullscreen mode

Or you can return and Tuple and Record, and consumer can use API how it wants:

function createStore() {
  // ...
  const store = [state, dispatch];
  store.state = state;
  store.dispatch = dispatch;
  return store;
}

const [state, dispatch] = createStore();
const { 0: state, 1: dispatch } = createStore();
const { state, dispatch } = createStore();
Enter fullscreen mode Exit fullscreen mode

Conclusion

In the end I think that using tuples is a better approach.
I think React team when released hooks took this into consideration for hooks that return multiple values like useState.

Thanks for reaching the end of this blog post ๐Ÿ™


Cover Photo by Pietro Mattia on Unsplash

Top comments (3)

Collapse
 
alexander89 profile image
Alexander Halemba

To be honest with you, I use both of them where it makes sense.

If you return the tuple [number, number, number, number] in your API, it is easyer to mix them up than 4 fields with a meaningful name.

I won't say that you should not use tuples. const [x, y, z] = vec3() is a good example where everyone will understand this without any docs, but use everything at the right place ๐Ÿ˜‰

Collapse
 
fjones profile image
FJones • Edited on

(Technically, [number, number, number, number] is a quadruple, not a tuple. Tuple specifically refers to two-element lists)

That said, yes, the rule of thumb is to only do this for actual tuples, where the two elements are implicitly clear: one for state, one to modify, and in that order. Otherwise, as much as it bloats the resulting runtime, prefer keys to allow omitting an element declaratively, i.e. by specifying the other two elements you wish to retrieve.

(exceptions exist, such as cases where all elements are mandatory to the consumer in every case)

Collapse
 
iamandrewluca profile image
๐Ÿฅ‘ Andrew Luca Author

Totally agree ๐Ÿ˜€ [number, number, number, number] is a no no ))

In defense of the modern web

I expect I'll annoy everyone with this post: the anti-JavaScript crusaders, justly aghast at how much of the stuff we slather onto modern websites; the people arguing the web is a broken platform for interactive applications anyway and we should start over;

React users; the old guard with their artisanal JS and hand authored HTML; and Tom MacWright, someone I've admired from afar since I first became aware of his work on Mapbox many years ago. But I guess that's the price of having opinions.