記事内に広告が含まれています

【ワレコPython】インデント位置で文脈が変わるのは設計ミスだと思う【欠陥言語か⁉】

この記事は約13分で読めます。
スポンサーリンク

このところ、Pythonとやらを使って極秘のプログラム開発を行っている。

このプログラム開発の過程でPythonの長所、短所を発見した。

自称、プログラミング言語評論家のワテであるが、そのPythonが持つ短所(あるいは欠点と言っても良い)に関する感想を述べてみたい。

かつ、そのPython特有の欠点を解決する為の画期的なアイディアを思い付いた。

そのアイディアが世間に普及すればPython業界に革命が起きる事は間違い無い。

当記事ではそれらを紹介したい。

ちなみに、ワテの開発環境は以下の通り。

  • 自作Windows10x64パソコン(詳細)
  • Visual Studio 2017 Community 15.8.1

だ。

 

では、本題に入ろう。

スポンサーリンク
スポンサーリンク

Pythonにはカッコ {・・・} が無いぞ

Pythonにはカッコ {・・・} が登場しないと言うのは、ワテも知っていた。

例えば、C,C++,C#系の言語でループ処理をするならこんな感じか。

for (int i = 0; i < 3; i++) {
	printf("%d\n", i);
}

その実行結果は、

0
1
2

 

Pythonの場合ならこんな感じだ。

for i in range(3):
    print(i)

その実行結果は、

0
1
2

となり、先ほどのC言語の場合と同じ結果になる。

まあ、これくらい単純なコードならカッコ{・・・} が無くても困らないのだが、実際のプログラミングの状況では、カッコの無いPythonの文法には、ワテは戸惑う事が多い。

それを紹介しよう。

C言語やPythonで2重ループの例

では、C言語でforループが入れ子になった二重ループの場合はこんな感じになる。

for (int i = 0; i < 3; i++) {
	printf("i=%d\n", i);
	for (int j = 0; j < 3; j++) {
		printf("\tj=%d\n", j);
	}
}

その実行結果は以下の通り。

i=0
        j=0
        j=1
        j=2
i=1
        j=0
        j=1
        j=2
i=2
        j=0
        j=1
        j=2

 

これをPythonで書くとこんな感じか。

for i in range(3):
    print('i=',i)
   
    for j in range(3):
        print('\tj=',j)

その実行結果は、C言語の場合と同じで以下の通り。

i= 0
        j= 0
        j= 1
        j= 2
i= 1
        j= 0
        j= 1
        j= 2
i= 2
        j= 0
        j= 1
        j= 2

ここまでは問題は無い。

Pythonはインデントの位置が文脈に影響する

ところが、Pythonの場合、インデントの位置が変わるだけで、コードの文脈も変わってしまうのだ。

つまり、以下のコードを実行すると、

for i in range(3):
    print('i=',i)         
for j in range(3):
    print('\tj=',j)

その実行結果は以下の通り。

i= 0
i= 1
i= 2
        j= 0
        j= 1
        j= 2

本来は 変数 i, j の2重ループを実行する予定であったのだが、それが単なるループを2回続けて実行する処理に化けてしまう。

こんな状況は良く起こるだろう。

つまり、プログラミングをしていて、エディタで表示されたコードの一部をカットアンドペーストで切り貼りしていると、インデントの位置が変わるなんて事は良くある。

その結果、自分が知らない間に、勝手にコードのロジックが変わってしまっているのだ。

あかんがなPython。

 

では、コード整形でインデント変化しないようなPython専用のエディタを使えば安心なのか?

そんな事は無い。

例えば数万行のコードをエディタで編集していると、知らないうちにウッカリ手が滑って[Delete]や[BackSpace]などのキーを押す確率も僅かながらある。あるいは、[Space]バーなら幅が広いのでその確率は高い。

この場合カッコを使う言語なら余分なスペースが追加されてもコードのロジックに影響しない場合が多い。一方、Pythonは余分なスペースが一個入るだけでコードのロジックが変化する可能性が高い。

まあそれはPythonの問題では無くてエディタあるいはプログラマーの責任と言う人もいると思うが、何事も安全性が高い事に越した事は無い。

そう言う点でも、Pythonは欠陥言語だとワテは思う。

Visual Studio環境ではPython編集がやり辛い

さらに困った事に、ワテが使っているVisual Studioの環境のエディタは、Pythonとの相性があまり良く無い。

例えば先ほどの2重ループのコードを再び掲載すると以下の通り。

ただし、先頭にコメントがある。

    #コメント
    
for i in range(3):
    print('i=',i)
   
    for j in range(3):
        print('\tj=',j)

かつそのコメント行はインデントの位置がその下に続くコードよりも一つ下のレベルに成っているとする。

実際のVisual Studioエディタの画面キャプチャは以下の通り。

 

この状態で、Visual Studioのエディタでコードを整形して綺麗にフォーマットしてくれる機能を使ってみる。

全選択(CTRL+A)しておいて、

CTRL+K, CTRL+D を連続して押すと整形機能が動く。

つまりコントロールキーを押した状態で、KとDを連続で押せば良い。

その結果、こんな風になってしまうのだ。

その画面キャプチャは以下の通り。

コメント行の下の for i ループのインデント位置が勝手に一つ下がり、上のコメント行と同じ深さになってしまう。

その結果、unexpected indent なんてエラーが出ているし。

この場合はエラーメッセージが出たので気づいたのだが、もしエラーメッセージが出ないようなインデント変化が起こった場合には、コードを整形した瞬間にプログラムのロジックが勝手に変わってしまってバグが入り込む事になる。

あかんがなPython。

いや、あかんがな Visual Studioなのか?

うっかりミスでインデントが狂う場合も有り得る

例えばPythonソースコードをエディタで編集中に、エディタの置換コマンドを実行して何らかの文字列を別の文字列に一括置換するなんて作業は、プログラム開発中には時々やるだろう。

その場合に、正規表現パターンを使って置換する場合も良くある。

そんな時に、うっかりしていて間違った正規表現パターンを書いてしまい、置換対象文字列の前後の空白あるいはインデントを変化させてしまった!なんて事も無きにしも非ずだろう。

それを知らずにファイルを上書き保存してしまった!

そうなるとPythonではプログラムのロジックが支離滅裂になるので取り返しがつかない状態になる。

一方、カッコ{}でくくる言語なら空白やインデントが多少変化したとしても全く影響無い場合もあるし、あるいは、少々手直しすれば元に戻せる確率も高い。

そう言う点でも、やはりPythonは欠陥言語だと思う。

それならワテがPythonを拡張してPython++を提唱

エディタによるインデント位置変化問題の画期的な解決方法を思い付いた。

Pythonの文法を拡張して、必要ならforやifブロックをカッコ{・・・}で囲っても良いようにすればいいだろ。

こんな感じだ。

    #コメント

for i in range(3):{
    print('i=',i)
   
    for j in range(3):{
        print('\tj=',j)
    }

}

ワテ独自拡張のPython、名付けてPython++なんてどうかな?

これならC、C++、C#系の人にも馴染みやすい。

カッコ{}を付けないpython本来の書き方をミックス出来る仕様にしておけば良い。

なので、ワテが経験したようなコードのコピペでインデント深さが勝手に変わってしまい、ロジックの意味も変わってしまうような問題を避けたい人は { } を使ってコードを書く。

エディタは必要に応じてそのカッコ { } の表示・非表示を切り替えられる。

あるいは、カッコを除去したファイル出力も出来る。そんな機能をエディタに追加しておけば実用性は高い。

最終的に納品するPythonコードはカッコ { } を除去した純正Pythonファイルで出力、そう言う運用でいいんじゃないかな。

と言う事で、forブロックやifブロックをカッコ { } で囲っても良い拡張Pythonは、ワテの命名でPython++と呼びたい。

どう、この画期的なアイディア!?

ここにPython++の誕生である。

完璧や!!

Visual Studio 2017のPythonデバッガーが直ぐに制御不能に陥る

ちなみに、Visual Studio でPythonをデバッグしていると、Visual Studioが固まってしまい制御不能に陥り易い。

再現性もほぼ100%ある。

再現するのは簡単で、例えば、ブレークポイントをセットしておいて、ブレークしたらローカルウインドウにある変数の中身などを確認しているだけでほぼ確実にVisual Studioが固まる。

処理に時間が掛かっています
    [キャンセル]

こんなダイアログが出るのだが[キャンセル]をクリックしてもボタンが凹まない。

つまりイベントを受け付けていないのだ。

つまり、Visual Studioが完全に制御不能に陥っている。

対策は、タスクマネージャーからVisual Studioのプロセスを終了するしかない。

益々あかんがな。

まとめ

自称、プログラミング言語評論家のワテの感想であるが、恐らくPythonを設計した人は既存の言語が持つカッコ {・・・} を使った文法に変わる新しい文法を採用したかったのだと思う。

まあその点は理解出来るのだが、カッコを排除してしまった為に、コードの文脈を決める物がインデントの深さになってしまった。

つまり、自分で勝手にインデントの深さを決められないのだ。

forループなら次の行は一つインデントを入れなければならない。

for i in range(3):
     print('i=',i)

それをこんな風にすると文法エラーだ。

for i in range(3):
print('i=',i)

Pythonのそんな言語仕様は、誰がコードを書いても似た様なコードになると言うメリットはあるのは分るし、その特徴はPythonの長所として良く聞く。

でもなあ、プログラムなんて長い物だと何万行、何十万行、いや何百万行にも達する訳なので、多くの人の色んな個性によって作られたコードが混じって当然なのだ。

その個性を出来る限り排除して、誰が書いても似た様なコードにする必要があるのか?

ワテの意見では、そんな必要は全く無いと思う。

なぜなら、「似た様なコードになる」と言う程度では、大規模プログラム開発に於いて大きなメリットが有るとは思えない。

誰が書いても「完全に同じコードになる」と言うのであれば価値はあると思うが。

ワテに言わせれば、Python設計した人は無理やりカッコを使わない文法にしたかっただけだと思う。その結果、インデント問題を解決出来ないままPython言語を作って公開してしまった。

と思うのだが。

インデントが一個ずれただけでロケット打ち上げ失敗!

インデントの位置がコードのロジックに深く関与している副作用として、エディタでコピペした瞬間に自分が気付かないうちにインデント位置が変わってしまい、ロジックが変わってしまう欠陥がある。

それはVisual StudioのPythonエディタが悪いのか、それともPythonの設計が悪いのかと問われれば、それはPythonの設計の問題だろう。

今回記事で紹介したような二重forループの場合には、うっかりインデント位置が変わってしまっても文法的には正しいので実行時にはエラーは出ない。でも、当初予定していた処理結果とは異なってしまう。

つまり誰にも気付かれないバグがPythonソースコードの中に埋め込まれてしまうのだ。

このPythonのインデント位置問題でワテのテストプログラムで問題が出る程度なら世間には影響は無いが、例えばロケットとか人工衛星の制御プログラムにPythonが使われたとして、打ち上げたら爆発して失敗。

原因を調べたら、コピペで貼り付けたPythonソースコードがインデント位置が一個だけずれた事が原因だった!なんて事態も起こり得るだろう。

はっきり言って、プログラムロジックがインデントに強く依存するPhtyonの言語仕様は重大な欠陥がある。

Python特有のインデント問題を解決する為の画期的なアイディア

そして、そのPython特有のインデント問題を解決する為の画期的なアイディアを紹介した。

必要に応じてコードブロックをカッコ { } で括っても良いと言う仕様を追加する案だ。

名付けて『Python++』、商標登録しておこうかなw

そんな事をすればPythonの設計思想を台無しにする!と言う意見も出るかも知れないが、何事も安全策を講じておくべきだ。

カッコが付かないので見た目がスッキリするなんて言う軟弱な意見よりも、カッコで確実に括っているのでインデント問題なんて完全に排除できるという安心感の方が良いに決まっている。

ソースコードに美しさなど求める必要は無い

プログラムなんて見た目がスッキリしようがしまいが、そんな事はどうでも良い。

目的のロジックを正しく実装出来ていれば、ソースコードの見た目なんてどうでもいいんだ。

一つの関数が5千行あろうが、forループが6重入れ子になっていようが、ifやswitchが訳分からんくらい入れ子になっていようが、動けばいいんだ。

ソースコードに美しさなんて求めようとしているのは、プログラミング初心者だ。

プログラムを1000行も書いた事が無い初心者に限って、ソースコードの美しさなんてのを気にし始めるのだ。

強いて言えば、正しく動くプログラムこそ美しいのだ。

カッコが無ければ見た目がスッキリするなんてのは、ソースコードを10万行くらい書けば、そんな事はどうでも良くなる(ワテの場合)。

そうだろ!?

一つの関数が5千行有ったとして、それが複雑で難解だと思うのは程度の問題だ。

人間にとっては難解かもしれないが、人類を遥かに上回る知的生命体や人工知能が存在するなら、5千行だろうが5兆行だろうが一瞬でその関数の意味を理解出来るだろう。

難解な数学の定理の証明が、数百ページの論文なんてのは良く聞くが、人間ならそれを読むのに数カ月掛るかも知れないが、全能の神なら数億ページの論文でも一瞬で理解出来る。

だいたい、億とか兆とか言う単位でさえも、人類が普段扱っている大きな数字の概念だ。

でも、数字は無限大まである訳なので、高度な知的生命体なら例えば101000くらいの数字を普段扱っているかも知れない。今日は、101000円の宇宙船を買い物をしたとか。

そう言う知的生命体から見れば、5千行とか5兆行とかは、誤差の範囲だろう。

今の人類はそんな全能者には到底成れないので、カッコの有無なんて言う些細な事に拘らずに、目的とするプログラムを最短で完成させるのが人類に出来る最善の努力なのだ。

まあ、自称プログラミング言語評論家のワテであるが、Pythonの経験はまだ数日なので、もう少し使い込んでから改めて感想を書いてみたい。

Pythonの本を買う

独学プログラマー Python言語の基本から仕事のやり方まで

本日の時点で、アマゾンランキング7位(コンピュータ・IT分野)と言う超人気の書籍だ。

Python習うならこれを買え!と言う人気の教科書なのか?

コーリー・アルソフ

清水川貴之

お二人とも、知らない人だ。

ちょっと調べてみるかな。

多分、Python業界では有名人なのかもしれない。

もし機会があれあインデント位置が勝手に変わるとコードのロジックが変わってしまうと言うPython弱点はどう思っているのか意見を伺いたいものだ。

スポンサーリンク
コメントを読む

この記事には読者の方からコメントが 12件あります。
興味ある人はこのページ下部にあるコメントを参照下さい。

Python
スポンサーリンク
シェアする
warekoをフォローする
スポンサーリンク

コメント

  1. 匿名 より:

    同意見です。
    コピペの際に、とても気を使わなきゃならなかったり、自動整形ツールは便利な反面、勝手にロジックを変えてないか不安になります。
    Pythonは人気ある事が不思議です。

  2. wareko より:

    匿名様
    この度は、小生のブログにコメントを頂きましてありがとうございます。
    私の場合、Pythonはまだまだ初心者なのですが、当記事はそのPythonを少し使ってみた率直な感想です。
    やはりインデント位置が変わるだけでプログラムのロジックが変化するのは神経を使いますよね。
    そんなPythonのインデント位置問題に関して私と同じ意見を持っている人が世の中にいる事を知って安心しました。
    今後、Pythonが改良されてこのインデント位置問題が改善されると良いのですが。
    私が提唱したPython++が採用されるなんて可能性は無いかな。
    無いな。
    では、また、お気軽に小生のブログにご意見やコメントなどをお寄せ下さい。

  3. 匿名のとくさん より:

    デザインと歴史
    ・Python はなぜ文のグループ化にインデントを使うのですか?
    https://docs.python.org/ja/3/faq/design.html

    4.Visual Studio環境ではPython編集がやり辛いの章でコードがズレた原因
    pep8-ja
    ・ブロックコメント
    https://pep8-ja.readthedocs.io/ja/latest/#id19

    参考にしてみてください!

  4. wareko より:

    匿名のとくさん様

    本日は小生のサイトに訪問頂きまして有難うございました。
    Pythonに関する情報有難うございます。

    さっそく教えて頂きましたURLを拝見させて頂きました。
    Visual Studioの環境でコードがズレた理由はブロックコメントの挙動と言う事で良いでしょうか?
    他のエディタでPythonを編集した経験は無いのですが、今回記事で紹介したようなケースでコードを整形した場合、Python編集に適したエディタならVisual Studioの挙動とは異なる動きをするのでしょうか?

    いずれにしましても、今のところやはりPython特有のインデント問題には、私は馴染めていません。
    Pythonプログラミングをしている世の中の多くの人は、インデントが原因のトラブルに巻き込まれるなんてのは、滅多にないのでしょうか?
    疑問が深まるばかりです。
    では、また何か良い情報がありましたらお教えください。

  5. akira0000k より:

    インデントの予期しないズレがバグに繋がるというのは全く同感です。
    僕はインデントの戻る箇所に #end という閉じタグを必ず入れます。これですとpythonの文法は変えずにすみます。自動インデントする機能が、何らかの「野良閉じタグ」を理解してくれるといいのですが。

    • wareko より:

      akira0000k様

      この度は小生のサイトにコメントありがとうございました。
      私は現状ではPyhtonは本格的には使っていないので、インデント問題には現状では悩まされていません。

      しかしながら、世間で人気の言語の第一位が確かPyhtonだったと思いますが、Pyhtonを学習したり、あるいは業務で使ったりしている世間の皆さんはPyhtonのこのインデント問題に不満など無いのでしょうかね。
      ネットでPyhtonのこのインデント問題に付いての議論など、殆ど見掛けないので、そのあたりが私には不思議なのです。

      まあ私のようなFORTRAN, Basic, C言語あたりからプログラミングの世界に入った古い人間としましては、どうしてもPyhtonには馴染めないですね。
      私が考案した{}を追加出来る新仕様のPyhton++が、いつの日か公開される日を待っていますw
      では、また何か良い情報など有りましたらお気軽にお教えください。

  6. あらら より:

    窓使いもりんご使いも犬使いもみんなThonny使え~。
    https://thonny.org/
    それはそうと、私もPythonが欠陥言語にしか見えません。
    インデントルールを採用しているF#でさえも、インデントのルールを変更できるものを搭載して、インデントの代わりにinやoutを使うアイディアを採用しているんですけどもね。Pythonのインデントルールは、狂っていると思います。とても医療機器や自動運転技術になんか採用できません。

    • wareko より:

      あらら様

      この度は小生の記事コメントをお寄せ頂きましてありがとうございます。
      Thonnyと言うのは初耳でした。そいう便利なIDEがあるんですね。
      >それはそうと、私もPythonが欠陥言語にしか見えません。
      私の意見に賛同して頂ける方が見付かり、心強く感じます。
      >インデントルールを採用しているF#でさえも、インデントのルールを変更できるものを搭載して、インデントの代わりにinやoutを使うアイディアを採用しているんですけどもね。
      そうなんですか。インデントルールを変更するなどの機能があるんですね。それは便利そうですが、PythonにしてもF#にしても、そもそもインデントに強く依存する言語設計自体に問題がありそうですね。
      >とても医療機器や自動運転技術になんか採用できません。
      そうですね。インデントが一箇所ずれただけでバグが入り込むなんて言語は、怖いですよね。
      将来必ずそう言うのが原因で大事件が起こると思います。
      では、また何か良い情報などありましたらお教え頂けると嬉しいです。

  7. しげ より:

    Python++いいですね!

    whileループなど、終わりに何か書いてないと落ち着かないので、コメント入れて、しのいでいるんですが、カッコ { } が使えるといいなと思います。

    i = 0
    while i < 10:
    print(i)
    i+=1
    #end while

    • wareko より:

      しげ様
      この度は小生の記事にコメントありがとうございました。
      世間では相変わらずPythonの人気が高いようですが、カッコ{}が無いPythonで大規模なプログラムを書く事は私には出来そうにありません。
      Python++が実用化されれば良いのですが。
      でもそうなるとC言語、C++、C#などのC言語系と似たような文法になりますから、Pythonの独自性が無くなってしまいますね。なのでPython++が作られる事は無いでしょうねw
      末尾にコメントを入れる作戦は私も参考にさせていただきます。
      では、また何か良い情報がありましたらお気軽にお教えください。

  8. ミルCOOK より:

    昔COBOLでピリオド忘れたせいでエライ目に遭いましたからねぇ。
    Pythonはそれに比べてもひどいかと。
    インデント=タブやスペースの個数で制御が変わると思うとゾッとします。

    • wareko より:

      ミルCOOK様

      この度は小生の記事にコメントありがとうございます。
      ミルCOOK様はCOBOLをお使いになっていたという事は、かなりのプログラミング上級者の方だとお見受けしました。
      私自身はPythonでプログラミングする機会は無いのですが、世の中では相変わらずPyhtonが人気言語のようですね。不思議です。

      話変わりますが、Microsoftが「Python in Excel」と言うのを発表したニュースを先日見ました。
      EXCELのアドインを古臭いVBA言語で書くのに比べれば、Pythonを使うほうが効率よくプログラミングできそうですね。
      私もPython in Excelを少し試してみたいなあと思っています。
      でもその為には最新の「Microsoft 365」が必要なようですので、買うのはちょっと躊躇います。
      では、また何かよい情報などありましたらお教えいただけると嬉しいです。