そもそもなぜ今前前前世なのか
※あくまで実在のバンド「RADWIMPS」とは関係がありません!!!
ある日の限界開発鯖での会話です……
「then().then().then().then()……」「コールバック地獄よりはまし」
ということでノリでリポジトリが生え、気が付いたら150Starという馬鹿みたいな数字人気のリポジトリになりました。(????)
ルール
-
then().then().then().世()
のようなメソッドチェーンで "前前前世" と末尾に改行付きで出力すればOKです。 -
Promise
やFuture
等の言語機能があればぜひ活用してください。
※なお、このレポジトリは、実在するバンド「RADWIMPS」とは何ら関係ありません。
then().then().then().世()を支える技術
- メソッドチェーン
名前の通り、メソッドを鎖のようにつなげて書く書き方のことです。例:then().then().then().世()
オブジェクト指向をサポートする言語であればオブジェクトを返すメソッドであれば、その返すオブジェクトのメンバのメソッドを呼び出してというふうに鎖をつなげるように書くことができます。
- CPS(Continuing Passing Style)
関数型言語の書き方です。
前提としてまず関数型の言語でメソッドチェーンはありません……。しかしこの変換を行えば、ぱっと見メソッドチェーンになります()。
いろんな言語でthen().then().then().世()
実際に、RADWIMPSというリポジトリに様々な言語でのPRが立てられ、2020/07/09時点で50ほどの言語のthen().then().then().世()が書かれています。
今回はその中の内のいくつかを紹介します。
メソッドチェーン使ってない言語もちらほら……()
まずはメジャーな言語から。
JavaScript
メソッドチェーンにお世話になってる人が多い言語かと思います。->Pull Request
またこの書き方はプロトタイプ汚染なので気を付けましょう。
'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
#!/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
class RADWIMPS
def self.then
print ?前
self
end
def self.世
puts ?世
end
end
RADWIMPS.then.then.then.世
Golang
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
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
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
<!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
修正Pull Request
wenyan-lang
漢文で書かれたプログラミング言語です(?????)
もう何が書かれているのかがわかりません……。
公式リポジトリ
Pull Request
批曰。「「是為文言編程也」」。
吾有一術。名之曰「RADWIMPS」。欲行是術。必先得四言。曰「甲」。曰「已」。曰「丙」。曰「丁」。乃行是術曰。
加「甲」以「已」。
加其以「丙」。
加其以「丁」。
乃得矣。
是謂「RADWIMPS」之術也。
吾有二言。曰「「前」」曰「「世」」。名之曰「then」曰「世」。
施「RADWIMPS」於「then」於「then」於「then」於「世」。書之。
終わりに
書かれている言語の内、ほんの少しだけしか紹介できていませんが、この記事を見ている人は、ちょっと暇つぶしに書かれていない言語で書いてみたり、既存の言語をよりよいthen().then().then().世()に書き換えてみたりしてみて下さい!!
また、Promise
やFuture
といった言語機能をふんだんに扱ったコードをお待ちしています!!
Contribute to RADWIMPS !!