テキストエディタに回転表示機能があったら便利なのではないか

C言語でこういうコードがあったとする。

int f(Z *z) {
    int result;
    W w;
    X x;
    Y y;
    Z z;
    result = hoge(&w);
    if (result != E_OK)
        return result;
    result = fuga(&w, &x);
    if (result != E_OK)
        return result;
    result = piyo(&w, &x, &y);
    if (result != E_OK) {
        /* piyoのエラーはログを出す */
        log("error in piyo !!!! code: %d, arg: (%s, %s)", result, W2str(&w), X2str(&x));
        return result;
    }
    result = hogera(&y, &z);
    if (result != E_OK)
        return result;
    return E_OK;
}

Erlangで同じコードを書くと、Erlangは途中でreturnすることができないので、こうなる。

-spec f() -> {ok, z()} | {error, term()}.
f() ->
    case hoge() of
        {ok, W} ->
            case fuga(W) of
                {ok, X} ->
                    case piyo(W, X) of
                        {ok, Y} ->
                            case hogera(Y) of
                                {ok, Z} ->
                                    {ok, Z};
                                {error, Reason} ->
                                    {error, Reason}
                            end;
                        {error, Reason} ->
                            %% piyoのエラーはログを出す
                            log("error in piyo !!! code: ~p, arg: (~p, ~p)", [Reason, W, X]),
                            {error, Reason}
                    end;
                {error, Reason} ->
                    {error, Reason}
            end;
        {error, Reason} ->
            {error, Reason}
    end.

ネストが深いし、関数の呼び出しとエラー処理が離れていて読みづらい。 returnのある言語でも、single-entry single-exitルールで書いていたり、JavaScriptのいわゆるコールバック地獄になったりすると、同じようになる。

エラー処理が離れている点については、エラー処理を先に書くという手がある。

-spec f() -> {ok, z()} | {error, term()}.
f() ->
    case hoge() of
        {error, Reason} ->
            {error, Reason};
        {ok, W} ->
            case fuga(W) of
                {error, Reason} ->
                    {error, Reason};
                {ok, X} ->
                    case piyo(W, X) of
                        {error, Reason} ->
                            %% piyoのエラーはログを出す
                            log("error in piyo !!! code: ~p, arg: (~p, ~p)", [Reason, W, X]),
                            {error, Reason};
                        {ok, Y} ->
                            case hogera(Y) of
                                {error, Reason} ->
                                    {error, Reason};
                                {ok, Z} ->
                                    {ok, Z}
                            end
                    end
            end
    end.

見た目も元のC言語のコードに近い。 ただし、ネストの深さは変わらない。 C言語では上から下に読めるが、Erlangでは左上から右下に読むことになる。

エディタがこのように斜めに表示してくれれば、ネストの深さの問題が解決する。

f:id:kusano_k:20180310171629p:plain