Hacker News new | past | comments | ask | show | jobs | submit login

I got to 14 (now 15!) in javascript so far:

    async function* foo() {
        return yield delete void await null in this instanceof typeof new class extends async function () {} {}
(not sure whether the code needs to successfully run? But it at least parses)

What's really fun is seeing how babel transpiled the above function:


EDIT: here's an explanation https://medium.com/@bluepnume/how-many-keywords-can-you-plac...

Well, you are correct that that parses. But how? I'm with it right up to around "new class extends"; `new` I'm okay with, but doesn't `new` require a symbol (the name of the type to allocate) after it? I tried parsing "class extends async function" as an expression that boiled down to a type that we could new, but I get lost at "class extends" — don't we need a class name there? (Also, I didn't think `class` could be used in an expression…)

Here it is with line breaks and as many extra legal parens as I can add without redundancy, showing all the unary and binary operators involved:

  return (
    yield (
      delete (
        void (
          await (
            (null) in (
              (this) instanceof (
                typeof (
                  new (
                    class extends (
                      async function () {}
                    ) {}
`class extends X {}` is an anonymous class extending X. Syntactically, X is an arbitrary expression, which `async function () {}` is. At runtime, X must be a constructor on pain of TypeError, and an async function isn’t; this could be considered grounds for disqualification, as under no circumstances will it execute without exceptions.

`new` does not require an identifier or path to follow it: it can be an expression. So `new (foo)` is fine. It’s just kinda greedy as regards an open paren of a function call: `new foo.bar(baz)(quux)` is equivalent to `(new (foo.bar)(baz))(quux)` rather than any alternative grouping. Remember also that `new foo` is legal, and equivalent to `new foo()`.

TIL class expressions and anonymous classes are a thing that exists in JavaScript.

It’s the same thing as function expressions and anonymous functions, but with classes instead of functions.

Does it mean that you're creating an anonymous new class that inherits from an anonymous async function, since it's really prototype objects all the way down in JS?

In Chrome:

  > (new class {}).__proto__
  {constructor: ƒ}

I think it works out to:

  return yield delete void await(
    (null in this) instanceof typeof(
      new (class /*anon*/ extends (async function () {}) {})
Maybe? Is `await foo in bar` a special case in javascript?

null is technically not a keyword in JS[1]. And fun fact, neither are true, false, undefined, NaN, let, of[2], static[3], as[4], from[4], get[5] and set[5].

[1] https://www.ecma-international.org/ecma-262/9.0/index.html#p...

[2] as in `for (foo of bar) {}`

[3] as in `class { static foo() {} }`

[4] as in `import {foo as bar} from 'baz'`

[5] as in `{get foo() {}, set foo() {}}`

It runs successfully in Chrome returning:

  foo {<suspended>}
That's the craziest statement I've ever seen!

That's because a generator is being returned from `foo` (the yield syntax gives you this).

Try calling next() on the return value of foo.

I get:

  Promise {<rejected>: TypeError: Class extends value async function () {} is not a constructor or null
    at foo

You can slip `void` in after delete an indefinite number of times. You can also do an indefinite number of `new class extends class extends class extends class {} {} {} {} {}`.

Good point! Let me update.

I was going for unique keywords with no repetitions.

Yes, according to the OP (in a comment) it has to be unique keywords.

This looks like something a fuzzer would come up with.

If you are in a module context, you could add "export" in front of the whole thing.

The count is from `return` on; the `async function* foo() {` part is excluded due to the `* foo() {`. Thus `export` isn’t applicable.

That's only 4, can't be broken by parentheses or braces

I assume you are on mobile - keep scrolling right on the code, some reason HN doesn't wrap text on mobile.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact