Soul of A New API: withoutFirst() and withoutLast()

Panu Viljamaa
Apr 18 · 4 min read
Short but not cryptic is a desirable characteristic for an API

Below are some excerpts from the tests of a new Array-API I was working on today. The fact that it is possible to subclass Array in JavaScript/ES6 makes this possible, and easy.

A few notes:

In JavaScript there is no method for getting the last element of an array, you have to do that with clumsy a[a.length-1] every time. With this new API I can do it with fewer key-strokes by calling a method:

a.end()

wof” is short for “withoutFirst()”. So if you want a version of an array without its first element you can write:

let a2 = a.wof();

If you want a version of an array without its first 2 elements you can write:

let a2 = a.wof(2);

wol” is short for “withoutLast()”. If you want a version of an array without its last element you write:

let a2 = a.wol ();

If you want a version of an array without its last 2 elements you write:

let a2 = a.wol (2);

You could do the above by calling JavaScript built-in function “slice()”. But that requires some zero-based-index-arithmetics to be performed in your head. It is not always so easy to get it right. Beware of index-calculation errors I say.

wof() and wol() are semantically simpler since they require max. one argument. They can be called without argument in which case wof() returns the array without its first element and wol() returns the array without its last element. No index-arithmetics that could go wrong. You just need to be familiar with the concepts of ‘first’ and ‘last’. Which I trust you already do.

Both wof() and wol() are non-destructive operations, they don’t modify the recipient-array, they create and return new arrays. They are pure!

To get the length of an array you can write “a.length”. The problem with that is you may mistype and write “a.lenght” and you would get no error. And because undefined can be used in many cases as a replacement for 0 you might get a bug which is only discovered later in production. Therefore I now prefer to write:

let leng = a.size();

“size()” is a method-call so if you mistype it, or call it upon an object which does not have it you get an error right away, not six months after.

Here’s some tests that shows part of the soul of this new API:

const A  = require("arsub"); // the npm module is named 'arsub'
const ok = A.ok;
let a = A (1,2,3); // this is how you create them
ok (a, [1, 2, 3]);
ok (a.size(), 3 );ok (a.end () , 3 );
ok (a.end (0), 3 );
ok (a.end (1), 2 );
ok (a.end (2), 1 );
ok (a.end (3), undefined);
ok (a.wof (0), [1,2,3]) ;
ok (a.wof ( ), [2,3]) ; // 1 is the default argument
ok (a.wof (1), [2,3]) ;
ok (a.wof (2), [3]) ;
ok (a.wof (3), []) ;
ok (a.wof (4), []) ;
ok (a.wof (-1), [3]) ;
ok (a.wof (-2), [2,3]) ;
ok (a.wof (-3), [1,2,3]) ;
ok (a.wof (-55),[1,2,3]) ;
ok (a.wol (0), [1,2,3]) ;
ok (a.wol ( ), [1,2]) ; // 1 is the default argument
ok (a.wol (1), [1,2]) ;
ok (a.wol (2), [1]) ;
ok (a.wol (3), []) ;
ok (a.wol (4), []) ;
ok (a.wol (-1), [1]) ;
ok (a.wol (-2), [1,2]) ;
ok (a.wol (-3), [1,2,3]) ;
ok (a.wol (-7), [1,2,3]) ;

The above tests run with the help of A.ok() -function shown below, which allows you to test for arrays’ and objects’ fieldwise equality. That is another thing that is missing from JavaScript Arrays, much needed above.

For instance “ok (a, [1, 2, 3])” near the top of the above code-excerpt tells us that ‘a’ is an array with elements 1,2 and 3. If it wasn’t, the first ok()-statement would an error. Knowing that ‘a’ is [1,2,3] the rest of the tests make much more sense. They build upon the first test.

function ok (a, b)
{ if (arguments.length > 1)
{ if (a instanceof Array)
{ ok (a.length === b.length);
a.map ( (e,i) => ok (a[i], b[i]));
return ok;
}
if (a instanceof Object)
{ ok (Object.keys(a).length, Object.keys(b).length);
for (let p in a) { ok (a[p], b[p])};
return ok;
}
return ok(a === b);
}
if (! a)
{ throw new Error ('ok() single-arg falsy');
}
return ok;
}
// Copyright (c) 2019 Panu Viljamaa
// LICENSE: Creative Commons CC BY-ND 4.0
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade