見出し画像

Retro-gaming and so on

Lisp経験者はビビらない

まず、親友が何人いるかをユーザーに尋ね、それらの友達の名前をそれぞれ入力させます。
(例えば、ユーザーが4人の親友がいると答えた場合、4人の親友の名前をそれぞれ尋ね、入力させます。)
その後、親友の中でどの人が一番長い名前を持っているかを確認します。

ごめん。
昼飯時でパスタ茹でてた最中だったんで、とっちらかったコード書いちゃったや。
動くは動くけど、あんま美しくなかった。

本来、最適化されたコードは次みたいなカンジで充分だった。

print("{0}".format(max([(len(name), name) for name in [input("{0}: ".format(i + 1)) for i in range(int(input("How many friends do you have? > ")))]])[1]))

うん。ワンライナーで充分だった。
別に奇をてらってワンライナーにしてるわけじゃなくって、LispやHaskellのような関数型言語だとこういう考え方はフツーなのです。
そして、この辺がC言語経験者と袂を分かつ部分なんだよなぁ。

元々、関数型言語では関数型プログラミングと言うパラダイムで物事を考える。
例えばプログラムが次のように表現されるとする。

(処理 データ)

これを走らせた時、返り値は「処理済みデータ」で、どっちにせよこれもデータとなる。
そして、延々とデータを別の処理に渡して行って、「欲しいデータに整形する」のを関数型プログラミングと言います。
つまり、関数型プログラミングだと、次のように関数の連鎖でプログラミングしていくのが結構フツーなんだよね。

(処理N ...(処理2 (処理1 データ))...)

まあ、実際この形式だと困った事があるこたぁある。何か間違った時、テキストエディタ上で修正しづらい、とかさ(笑)。
ただ、元データを変更しないので、非常に綺麗なプログラムにはなります。参照透過性、とかカッコつけて呼んだりするけど。
別に参照透過性があるから、と言ってバグらない、たぁ限らない。ただ、変数を「破壊的変更」しないので、バグの原因を特定するのがラクにはなる。データに問題が無いとしたら関数の使い方を間違ったんだろ、みたいにね。二者択一だったのが原因を一つと特定出来る。これは大きい。

Pythonは関数型言語じゃあないんだけど、関数型言語から機能を借りてきている。元々、Haskellの機能だったリスト内包表記と言うのがそれだ。
これは慣れるまでちょっと大変なんだけど、Pythonでは既に超重要な機能になっていて、繰り返しを記述する際、最適化を施されてるんで、forやwhileループなんかより速い。つまり、Python開発者はリスト内包表記を使いまくって欲しい、って考えてるって事だな。
この質問のように、

例えば、ユーザーが4人の親友がいると答えた場合、4人の親友の名前をそれぞれ尋ね、入力させます。

なんつってる場合、どの道、配列に近いデータ構造が「保存」の為に必要になる。つまり、Pythonだとリストの出番だし、リストが出てくる以上、リスト内包表記は「使うべき候補」として真っ先に思い浮かべないとならない。
スパゲッティ茹でてて忙しかったんで忘れてたよ(笑)。まだまだだな(笑)。修行が足りん。

まぁ、さすがにワンライナーは極端だろ、って言う場合、内側のリスト内包表記を別に変数にまとめても良い。

names = [input("{0}: ".format(i + 1)) for i in range(int(input("How many friends do you have? > ")))]
print("{0}".format(max([(len(name), name) for name in names])[1]))


こっちの方が見た目まだ分かりやすいだろ?
もう一声!ってな場合は、数値入力等を別にまとめても良い。

num = int(input("How many friends do you have? > "))
names =  [input("{0}: ".format(i + 1)) for i in range(num)]
ans = max([(len(name), name) for name in names])[1]
print("{0}".format(ans))

これならC言語経験者でも納得行くと思う。
まぁ、それでもC言語経験者が言う「美しさ」とLispやHaskell経験者の言う「美しさ」の間には壁があるけれどもね。

いずれにしても、取り敢えず、Lisp経験者はデータに関数を連鎖させていってもビビらない、ってこった。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事