PythonとRubyが変数の値の宣言と割り当てを区別しないのはなぜですか?


8

最も一般的な動的型付けスクリプト言語の2つであるPythonとRubyは、変数の宣言と変数への値の割り当ての間で構文を区別しません。

それは両方の言語であり、変数nを宣言してそれに値を割り当てることは次のようになります:

n = 10

そして、後で変数に新しい値を割り当てても、まったく同じように見えます。

これにより、2つの大きな問題が発生します。

  1. 値を変更するときに変数の名前にタイプミスがあると、新しい変数が作成されてバグが発生します。

  2. コードの意図が不明確になります。変数が最初に宣言されて使用される場所がわからないため、コードがさらに混乱する可能性があります。

私が理解していないのは、これらの言語にvar、宣言と割り当てを区別するために、宣言で使用するキーワードがない理由です。これによって言語の動的型付けが減ることはなく、欠点もありません。

変数を明示的に定義する必要がないことの利点は何ですか?



@Akashこれは質問とはまったく関係がないようですs/variable/name/g。実行しても同じように有効です。

回答:


4

Pythonの(デザイナーではなく)ユーザーとして、この決定に満足している3つの理由があります。

主に、それはよりよく読みます。もちろん、私はを書くときに意識的に新しい変数を導入することを決めなければなりませんが、コードは書かれているよりもはるかに頻繁に読み取られます。制御フローとネストが変数の意味と存在に影響を与えないという意味で、多くのコードは単純です。私が読んだとき

it = Snark()
message = "A letter, not signed"
if random.random() > 0.5:
    hunt(it)
    message += " (by the Knave)"
return [it, message]

それから、私は通常、名前のどの(もしあれば)言及が最初にそれを導入するかを本当に気にしません、それがそこにあることとそれがどうなるかを気にします。

擬似コードの重要な本体は同じ規則(宣言なし、代入による暗黙の導入)を使用していることに注意してください。Pythonは、冗談でありながら、実行可能な擬似コードとして記述されることがよくあります。すべてのローカル変数の4つの追加文字は、Pythonのコンテキストでは、特に値を追加するように感じられない場合(以下を参照)は、乱雑な目にはかなり混乱しているように感じます。これは:=、Goの場合と同様に、オペレーターによって軽減されます。

第二に、私はまだ(この特定の機能のために)タイプミスのバグに遭遇していませんが、別の明確な方法でそれ自体を表示しませんでした。たぶん、この種のバグに遭遇した数年後には気が変わってしまうかもしれませんが、これまでのところ、バグの原因となるもののリストからはかなり下がっています。かなりの数の質問UnboundLocalErrorがあり、初心者に説明するのは少しトリッキーですが、それらの質問の頻度と人気は、他の問題(可変デフォルトパラメーター、参照セマンティクス、クラス変数とインスタンス変数)と比較して、それがまれな問題であることを示しています。

最後に、意図したこと...申し訳ありませんが、これは本当に理解できません。Pythonを読み書きするとき、それは常に完全に明確です:割り当てられたものは、大声で明示的に宣言されていない限り、ローカルとして意図されています。それについての質問はありません。さらに、(少なくともPythonでは)変数は関数全体に対してローカルであるか、まったくそうでないため、あるブランチでローカル変数を使用し、別のブランチでグローバル変数を使用するトリッキーなコードを作成することはできません。名前が割り当てられているのがわかりますか?あなたはそれが最初から常にローカルであったことを即座に知っています。まあ、コードが非常に特別な方法で破壊されない限り(そしてUnboundLocalError、それらのケースに入るときに実行時に恐怖を投げます)。


ここでは実用的なケースから、宣言を欠くによって引き起こさPHPのバグの例である: $a = [1, 2, 3]; foreach ($a as $k => &$v) $v++; foreach ($a as $k => $v) echo "$k => $v\n";
アレクサンダーGelbukh

@AlexanderGelbukh原因を特定するのに十分なほどPHPを知りませんが、説明してもらえますか?

私の答えをください。ご覧のように、私を含めてかなりの数の人にとっては予想外でしたので、たくさんの実験をしなければなりませんでした。このようなバグのために、正しくないプログラムがいくつあるか想像してみてください。
Alexander Gelbukh 14

1
@AlexanderGelbukhあなたが説明するバグはいくつかのPHP機能(主に参照)の相互作用によるものであり、宣言のない他の言語ではIIUCはそのようには起こり得ないことに注意してください。書き込み/デバッグについて:ほとんどのデバッグ戦略(ローテクの「明確になるまでそれをじっと見つめる」から、空想の時間移動デバッガまで)には、デバッグ中のコードの読み取りのかなりの部分が含まれていることに注意してください。

1
完全に同意します。読みやすさが非常に重要です。バグを防ぐことが重要であることに同意します。あなたはその宣言に同意せず、バグの防止に役立ちます。私は宣言が読みやすさを損なうことに同意しません。おそらく私たちは同意しないことに同意できます:-)
Alexander Gelbukh 14

-3

変数を定義することは、変数に割り当てることと同じではありません-変数がまったく定義されていないということです。これはDynamic Typingと呼ばれます。

変数を定義できる動的型付け言語を使用することはできません。これは、動的型付けがそうであるからです

これを行うという決定は、パーサーの性質を完全に変更し、完全に異なる種類の言語をもたらします。エンドユーザーとの主な違いは、通常、関数を定義するときに、パラメーターがすべての型( "ダックタイピング")になるということです。呪い。コードが失敗する可能性がある多くの新しい方法を可能にします。

私はコンパイラの専門家ではありませんが、動的タイピングが言語で得られるOOPのフレーバーに大きな影響を与えることも事実だと思います。


3
エラーです。ストリクトモードのJavaScriptでは、変数を使用する前に変数を使用する必要があります。ただし、動的に型付けされます。一方は他方とは何の関係もありません。動的型付けとは、変数が任意の型の値を保持できることを意味します。定義する必要があるかどうかには関係ありません。同様に、型推論のある静的型付け言語では、変数を定義する必要なしに変数を使用できます。これら2つは直交しています。
back2dos 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.