君のthen-then-then-世はPromiseでFuture

## そもそもなぜ今前前前世なのか
　※あくまで実在のバンド「RADWIMPS」とは関係がありません！！！

　ある日の[限界開発鯖](https://approvers.dev/)での会話です……
　「then().then().then().then()……」「コールバック地獄よりはまし」
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606626/ab97bfee-f5a6-7da3-8723-e12d4e223248.png)

　ということでノリでリポジトリが生え、気が付いたら150Starという~~馬鹿みたいな数字~~人気のリポジトリになりました。(？？？？)

## ルール

- `then().then().then().世()`のようなメソッドチェーンで "前前前世" と末尾に改行付きで出力すればOKです。
- `Promise`や`Future`等の言語機能があればぜひ活用してください。

※なお、このレポジトリは、実在するバンド「RADWIMPS」とは何ら関係ありません。

## then().then().then().世()を支える技術
- メソッドチェーン

　名前の通り、メソッドを鎖のようにつなげて書く書き方のことです。例:`then().then().then().世()`
　オブジェクト指向をサポートする言語であればオブジェクトを返すメソッドであれば、その返すオブジェクトのメンバのメソッドを呼び出してというふうに鎖をつなげるように書くことができます。

- CPS(Continuing Passing Style)

　関数型言語の書き方です。
　前提としてまず関数型の言語でメソッドチェーンはありません……。しかしこの変換を行えば、ぱっと見メソッドチェーンになります()。
　

## いろんな言語でthen().then().then().世()

　実際に、[RADWIMPS](https://github.com/approvers/RADWIMPS)というリポジトリに様々な言語でのPRが立てられ、2020/07/09時点で50ほどの言語のthen().then().then().世()が書かれています。
　今回はその中の内のいくつかを紹介します。
　~~メソッドチェーン使ってない言語もちらほら……()~~

　まずはメジャーな言語から。

### JavaScript

　メソッドチェーンにお世話になってる人が多い言語かと思います。->[Pull Request](https://github.com/approvers/RADWIMPS/pull/1)
 またこの書き方はプロトタイプ汚染なので気を付けましょう。

```javascript
'use strict';

const os = require('os');
const p = c => process.stdout.write(c);
const f = Promise.prototype.then;

Promise.prototype.then = function () { return f.call(this, () => p('前')); };
Promise.prototype.世 = function () { return f.call(this, () => p('世' + os.EOL)); };

Promise.resolve()
    .then()
    .then()
    .then()
    .世()
;
```

### Python
[Code](https://github.com/approvers/RADWIMPS/blob/master/RADWIMPS.py)
[Pull Requests](https://github.com/approvers/RADWIMPS/pulls?q=is%3Apr+python)

```python
#!/usr/bin/env python3


class RADWIMPS:
    @classmethod
    def then(cls):
        print('前', end='')
        return cls

    @classmethod
    def 世(cls):
        print('世')
        return cls


RADWIMPS.then().then().then().世()
```

### Ruby

 [Code](https://github.com/approvers/RADWIMPS/blob/master/RADWIMPS.rb)
 [Pull Requests](https://github.com/approvers/RADWIMPS/pulls?q=is%3Apr+Ruby)

```ruby
class RADWIMPS
  def self.then
    print ?前
    self
  end

  def self.世
    puts ?世
  end
end

RADWIMPS.then.then.then.世
```

### Golang

[Code](https://github.com/approvers/RADWIMPS/blob/master/RADWIMPS.go)

```go
package main

import "fmt"

type RADWIMPS struct {}

func (r RADWIMPS) then() RADWIMPS {
    fmt.Print("前")
    return r;
}

func (r RADWIMPS) 世() RADWIMPS {
    fmt.Println("世")
    return r;
}

func main() {
    RADWIMPS := RADWIMPS {}
    RADWIMPS.then().then().then().世()
}
```

他にも変わり種がたくさん存在します。

### Haskell

　純粋関数型言語なので、まずオブジェクト指向ベースのメソッドチェーンが***書けません***。しかし、CPS変換を行うことにより、メソッドチェーン(大嘘)になっています。
　[Pull Requests](https://github.com/approvers/RADWIMPS/pulls?q=is%3Apr+Haskell)

```haskell
main :: IO ()
main = radwimps $
  then'().then'().then'().世()

radwimps :: (() -> IO ()) -> IO ()
radwimps = ($ ())

then' :: () -> IO a -> IO a
then' () k = putStr "前" >> k

世 :: () -> () -> IO ()
世 () () = putStrLn "世"
```

### VimScript

Vimに組み込まれているスクリプト言語で、Vimの設定や、Vimのマクロやプラグインを書くときに用いるのですが……。
[Pull Request](https://github.com/approvers/RADWIMPS/pull/33)

```vimscript
function! RADWIMPS() abort
    let radwimps = {}

    function! radwimps.then() closure
        echon "前"
        return radwimps
    endfunction

    function! radwimps.se() closure
        echon "世\n"
        return radwimps
    endfunction

    return radwimps
endfunction

let RADWIMPS = RADWIMPS()

call RADWIMPS.then().then().then().se()

```

### HTML

~~カスタムエレメントを果たしてメソッドチェーンというのでしょうか……。~~
[Pull Request](https://github.com/approvers/RADWIMPS/pull/39)

```html

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>RADWINPS</title>
    </head>
    <body>
        <x-then>
            <x-then>
                <x-then>
                    <x-世>
                    </x-世>
                </x-then>
            </x-then>
        </x-then>

        <template id="then">
            前<slot></slot>
        </template>

        <template id="世">
            世
        </template>

        <script>
            customElements.define(
                'x-then',
                class extends HTMLElement {
                    constructor() {
                        super();
                        const template = document
                            .getElementById('then')
                            .content
                        this
                            .attachShadow({mode: 'open'})
                            .appendChild(template.cloneNode(true))
                    }
                }
            )
            customElements.define(
                'x-世',
                class extends HTMLElement {
                    constructor() {
                        super();
                        const template = document
                            .getElementById('世')
                            .content
                        this
                            .attachShadow({mode: 'open'})
                            .appendChild(template.cloneNode(true))
                    }
                }
            )
        </script>
    </body>
</html>
```

### Scratch

　小学生でも知ってるグラフィカルプログラミング言語です。猫が「前前前世」とつぶやくのはなかなかにシュール。(画像のコードは修正版のものです)
[Pull Request](https://github.com/approvers/RADWIMPS/pull/35)
[修正Pull Request](https://github.com/approvers/RADWIMPS/pull/113)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606626/ac39c4dc-f1ed-2279-e29f-0dc5840ad233.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606626/9ef72fe7-8a74-be2c-4b18-a6b2a5d6128d.png)


### wenyan-lang

　**漢文**で書かれたプログラミング言語です(？？？？？)
　もう何が書かれているのかがわかりません……。
　[公式リポジトリ](https://github.com/wenyan-lang/wenyan)
　[Pull Request](https://github.com/approvers/RADWIMPS/pull/70)

```wenyan-lang

批曰。「「是為文言編程也」」。

吾有一術。名之曰「RADWIMPS」。欲行是術。必先得四言。曰「甲」。曰「已」。曰「丙」。曰「丁」。乃行是術曰。
	加「甲」以「已」。
	加其以「丙」。
	加其以「丁」。
	乃得矣。
是謂「RADWIMPS」之術也。

吾有二言。曰「「前」」曰「「世」」。名之曰「then」曰「世」。

施「RADWIMPS」於「then」於「then」於「then」於「世」。書之。

```

## 終わりに
　書かれている言語の内、ほんの少しだけしか紹介できていませんが、この記事を見ている人は、ちょっと暇つぶしに書かれていない言語で書いてみたり、既存の言語をよりよいthen().then().then().世()に書き換えてみたりしてみて下さい！！
　また、`Promise`や`Future`といった言語機能をふんだんに扱ったコードをお待ちしています！！
　Contribute to [RADWIMPS](https://github.com/approvers/RADWIMPS/) !!