5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

毎年256日目は #プログラマの日 を JavaScript (ES2018) で実装する

Last updated at Posted at 2019-10-11

毎年256日は #プログラマーの日 という以下のコードを Twitter で見かけました。
もとの開発言語は不明ですが、車載端末でも動くような JavaScript に移植してみます。
async/await と非同期イテレータを使ってみます。

    while (everyYear) {
    if (today().dayNumber == 256) {
        celebrate("Programmers' Day");
        }
    }

https://twitter.com/TRIAD_Japan/status/1172412070769258496 より。

もとのコードの処理を頭の中でシミュレーションすると、
256日目に「Programmers' Day」のお祝いがずっと続いてしまう気がしますので、
どこかでウエイトが入っているはずです。

さらに、256日目以外のことも考慮すれば、while (everyYear) の部分でウエイトが入り、
1日1回だけ while 文の中が実行されると解釈するのが妥当です。
毎日の処理ぽいのに everyYear という変数名?を利用していたもとの命名規則は、
謎ですが、なにか意図があるかと思いますので、そのまま移植することにします。

1. async/await で実装した場合

JavaScript 移植では、最初の while (everyYear) のところがクセモノです。
everyYear を変数でなくて、関数呼び出しに変更してよければ、async/await で実装できます。
もとの while (everyYear)while (await everyYear()) になります。

const sleep = s => new Promise(r => setTimeout(r, s));
const celebrate = m => console.log(m);
const today = () => ({dayNumber: 256}); // TODO
const everyYear = async () => await sleep(1000) || true;
(async () => {

    // ここから
    while (await everyYear()) {
        if (today().dayNumber == 256) {
            celebrate("Programmers' Day");
        }
    }

})();

1年を待つのは辛いので、ここではデモのため、1秒ごとに「Programmers' Day」をお祝いします。
Top-level await が実装されると、(async () => {})(); を省けるようになるはずです。

実行結果:(node v10 と Chrome 77 で動作確認済)

Programmers' Day
Programmers' Day
Programmers' Day

ただし、while (await everyYear()) { の部分については、
動詞 await の目的語が everyYear に読めてしまうので、英語として読み取りにくいです。
読みにくいコードは、安全の敵なので、イマイチです。

2. 非同期イテレータで実装した場合

あるいは、非同期ジェネレータ async function* という呪文と for-await-of 構文を使えば
everyYear を非同期イテレータの変数にできるので、関数呼び出しのカッコ () をはずせます。
もとの while (everyYear)for await (safety of everyYear) のようになります。

const sleep = s => new Promise(r => setTimeout(r, s));
const celebrate = m => console.log(m);
const today = () => ({dayNumber: 256}); // TODO
const everyYear = (async function* () {
    while (true) yield await sleep(1000) || true;
})();
let safety;
(async () => {

    // ここから
    for await (safety of everyYear) {
        if (today().dayNumber == 256) {
            celebrate("Programmers' Day");
        }
    }

})();

for-of 構文では、受ける変数が必要そうなので、safety としてみました。
while (true) yield await sleep(1000) || true; の1行は気持ち良いですが、
非同期ジェネレータ async function* はまだ arrow function で書けなないらしく、そこは残念。

仮に for await safety of everyDay であれば、日々の安全を求めて活動しながら、
256日目だけは Programmers' Day をお祝いするようなエモいニュアンスが込められそうです。


上記の JavaScript 移植版のライセンスは、もとのソースコードのライセンスに従います。

TRI_AD.jpg account.jpg


[余談]
そういえば、https://hack4.jp/relatedinfo/t-shirt/1st/ にある
Hack for Japan の T シャツに記載するコードを検討したときは、みんなでコードレビューして、
いくつかの言語でそのまま動きそうな感じに考慮した記憶があります。

    while (Japan.recovering) {
        we.hack();
    }

事故を防ぐためには、ソースコードはレビューをしてもらうのが大事ですね。

5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?