by Matt Brennan

Javascript Keyword Ungolf

writing a module a week or two ago i noticed that export default async function is an awful lot of javascript keywords in a row. so, because of who i am as i person, i set out to string as many together as i could.

the rules

  1. distinct keywords from ecmascript section 11.6.2.1 only
  2. has to be syntactically valid, i.e. not throw a SyntaxError
  3. has to be semantically valid, i.e. not throw any kind of runtime error
  4. keywords themselves must be separated only by whitespace. extra non-whitespace characters at the beginning or end of the statement are fine
  5. wrapping the statement in something to get you more valid keywords is a-ok

baby steps

pretty quickly i got it up to 6, with export default class extends async function () {} {}. since you can extend any expression that evaluates to a function, we’re golden.

at this point i took it to the FT Slack’s #javascript-devs channel, because it’s full of my kind of nerd, and we’re easy to snipe.

Jake is exactly the person i was intending to snipe. thanks for taking the bait 😉

thanks to Jake’s first stab i was up to 7, by adding a void after the export default, and Rhys pointed out that typeof would bring us up to 8.

the doldrums

i thought we were done. a couple of days passed, and the channel reverted to smoosh-related drama. i thought we’d never beat eight.

i was wrong.

the renaissance

a revelation at 4:30pm after a dreary day: classes can be newed. new is a keyword. nine: export default typeof void new class extends async function () {} {}.

very quickly i added the tenth: export default delete typeof void new class extends async function () {} {}

here we hit our first snag. our code is no longer valid in strict mode, since delete is only valid on configurable own properties of objects in strict mode, and our expression is… well, it’s the string 'undefined'. eventually.

but the export default explicitly kicks the file into the module parse goal, which is implicitly in strict mode.

i’ll realise this in a few minutes, but first a small digression into the past

two thousand called, they want their scripting language back

you know what, Jake, i deserved the counter-nerd-snipe. and it all worked out well in the end.

five keywords is a lot, if we’re losing export default, and class, and async. putting together our work so far, and throw, which didn’t get us anywhere before, gave me throw delete typeof void function () {}. and of course you can new that for 6.

but then.

back to the future

with this in, our ES6 version is up to twelve keywords, and it’s even more invalid now, thanks to the top-level this in strict mode code.

my best work entirely stands on the shoulders of giants, so when Jake mentioned generator functions i’m off to the races. of course, in an async generator, you get two more keywords to play with. we lose the export default, but we’re out of strict mode, so the delete and the this are “fine”.

please god don’t write code like this.

denouement

my final version, weighing in at a staggering thirteen keywords:

async function* () {
  return await yield delete typeof void this in new class extends async function () {} {}
}

the slack reactions make a pretty good summary of the shock and disgust in the channel.

it all comes crashing down

in all the excitement, i’d rather forgotten to actually check the damn thing. and for whatever reason this thing was throwing odd syntax errors.

i don’t know why, but if you flip the await and the yield the thing parses just fine. Jake fixed it. ask Jake 🤷‍♀️

the final final version:

const a = async function* () {
  return yield await delete typeof void this in new class extends async function () {} {}
}

still thirteen keywords, still gloriously filthy.

epilogue

instanceof needs two operands, matt. how you gonna make an expression with just keywords, matt.