Python 3.0に盛り込まれた後方互換性を崩す変更のうち一番目を引くのはprint文がprint関数になり,文から式に変更されたことだろう。当初は大きな反発が寄せられることが予想されたが,意外にもこの変更は比較的スムーズに受け入れられた。
この反応を受けて,PythonのBDFL(慈悲深き独裁者) GuidoはPython 3.1から,if文やfor文,def文などを関数にし,Pythonのすべての文を式に変更する計画を明らかにした。Pythonの文は改行を要求するため,言語の文法に大きな制限を課していた。この変更が実現すれば,より自由な形式でプログラムを表記できるようになる。ワンライナーの愛好家には歓迎される変更となることが予想される。
新しいfor(),if()などの仕様は旧来の仕様を踏襲している。2.xでのコードと比較をしながら使い方を見てみよう。
まずはifから。
2.xまで
if x > 100:
print "Grater than 100"
3.1から
if(x > 100, print("Grater than 100"))
次はfor。
2.xまで
for i in range(10):
print i
3.1から
for(i, range(10), print(i))
この例を見れば分かると思うが,コードブロックは一つの複合式として記述することになる。ワンライナー好きな開発者の腕の見せ所といえる。
次は所謂FizzBuzz問題を解くコードを比較してみよう。Python 3.1ではelse節で実行する式を第3引数に指定する。それに伴ってelif相当の文法が廃止されていることがわかる。
Python 2.x
for i in range(1,101):
if i%15 == 0:
print "FizzBuzz"
elif i%5 == 0:
print "Buzz"
elif i%3 == 0:
print "Fizz"
else:
print i
Python 3.1
for(i, range(1, 101), if(i%15 == 0, print("FizzBuzz"), if(i%5 == 0, print("Buzz"), if(i%3 == 0, print("Fizz"), print(i))))
Pythonのコードらしく,インデントを使って整形するとこうだ。
if(i%15 == 0, print("FizzBuzz"),
if(i%5 == 0, print("Buzz"),
if(i%3 == 0, print("Fizz"),
print(i)
)
)
)
)
def()関数は実行可能オブジェクトを返す関数となる。関数ブロックで実行するコードは,if()やfor()と同様,複合式として記述する(具体例は横に長くなりすぎるので書かない)。class()関数は,クラスオブジェクトを返す関数となる(同じく横に長くなりすぎるので省略)。その他,import()関数,代入式の変わりに使い,変数を定義し代入を行うlet()関数の導入などが提案されている。
この発表は一部では大きな反響を呼んでいる。「PythonこそLispの正当な継承者であることが証明された」「Pythonistaはあと10年は戦える」という肯定的な意見もある一方で,「インデントの意味が無くなっている,こんなのPythonじゃない」「let()なんてBASICみたいで嫌だ」「3.0から3.1の間では後方互換性を崩す変更がされないと言っていたじゃないか,大人は嘘つきだ」というような反発も散見される。
この発表に前後して,GuidoがBDFLからBDEVIL(Benevolent Dictator Emeritus Vacationing Indefinitely from the Language,言語を離れて無期限の休暇に出る慈悲深き名誉独裁者)になった事がアナウンスされている。長年の夢だったエベレスト制覇が理由だと公式にはうたわれているが,今回の決定にはこの暴挙を食い止めるねらいもあったようである。Guidoの後継で「Barryおじさん」として親しまれているBarry Warsawは,Python 3.0.2からprintを文に戻すとしているが,この決定は,Guidoの暴挙の反動なのではないかとさる筋は見ている。