本の虫

著者:江添亮
GitHub pages: https://ezoeryou.github.io/blog/
Blogger: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

また初心者にプログラミングを教える機会があった

プログラミングでわからないところがあるので教えてほしいと以下のようなことを聞かれた。

こういうJavaScriptの関数がある。

// valuesは配列
// elementはvaluesの要素型の値
// 配列valuesに値elementと等しい要素があるならばそのインデックスを返す。
// それ以外の場合、-1を返す
function find_index( values, element )
{
    for ( let i = 0 ; i !== values.length ; ++i )
    {
        if ( values[i] === element )
            return i ;
    }
    return -1 ;
}

質問は、「なぜreturn -1にelseはいらないのか」というものであった。

似たような問題に、昔遭遇した気がするが、別人だ。

まずここにelseを書くべき文法はJavaScriptに存在しない。if文で何らかの条件を切り分ける必要もない。なぜならば、return -1が評価されるとき、すでにforループを抜けているわけで、その場合要素が見つからなかったということだ。逆に、要素が見つかったのであれば、すでに上のreturn iが評価されているので、すでに処理は関数の呼び出し元に戻っており、return -1は評価されることがない。

ただ、このような机上の説明を繰り返しても理解ができない様子であったので、さらにデバッガーでステップ実行してみせるなどして説明した。

この問題は、逐次実行という概念と、逐次実行がfor文やif文やreturn文によって変わるということ、そしてプログラミングにおける関数の理解が必要だ。しかし、筆者はこのような概念の理解に苦労した覚えはないし、周りの職業プログラマーに聞いても、やはり苦労した覚えはないという。

しかし不思議だ。質問者は数学の素養があり、数学における関数なら理解しているはずだ。聞けば再帰も理解しているという。それならと以下のように再帰で書いてみた。


function find_index( values, element )
{
    function solve( i )
    {
        if ( i === values.length )
            return -1 ;

        if ( values[i] === element )
            return i ;

        return solve( i + 1 ) ;
    }
    return solve(0) ;
}

これを何の説明もせずに見せたところ、「これはとても良くわかる。なんでみんなこう書いてくれないのか」とのことであった。質問者はJavaScriptの初歩の初歩しか学んでおらず、このようなコードは見たことがないはずだ。しかしわかりやすいと言う。再帰は正しく理解できていることが確認できた。

質問者にはHaskellのような純粋関数型の言語のほうが向いているのかもしれない。