見出し画像

Retro-gaming and so on

RE: プログラミング学習日記 2024/02/23〜

龍虎氏の記事(2024/02/25)に対するコメント。


 言われてみれば変更不可なんだからAppendとかは無いはずだ、たしかに!そしてスライスは新しく作るのでOK、と。むちゃ解りやすいな!

なお、Racketの(Schemeの、ではない)リストは実はこの定義で言うとPythonのタプルに近い。Racketのリストも変更不可、だからだ。
Racketのリストは、Schemeの仕様に反し、set-car!set-cdr!を適用出来ない(と言うか、そもそもそれらが存在しない)。
結果、実の事を言うと、PythonのリストはRacketではMutable Pairs and Listsって事になる。

そして、PythonではRacketのconsは例えば

>>> (1,) + (2, 3)
(1, 2, 3)

と表現出来る・・・が、このコンマ(,)が一体何なんだ、って話が出てくるんだよな(笑)。
この辺がPythonの「アレ?」って思うトコで、実は単項のデータ、ってのと「タプル表記」の境界線が曖昧なんだ。
つまり、上のコードをこう書こうとするとバグる。

>>> (1) + (2, 3)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
(1) + (2, 3)
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

丸カッコだけ、を使って単項のタプルを表現しようとすると、上の例では(1)は単なる1として解釈されてしまう。
これはPythonで良くハマるトコだ。「丸カッコ付き」と「丸カッコ無し」の境界線が実は曖昧なんだ。
これが次の議題へと繋がる。


 これイイっすねぇ!

これはPython上では次と同義なんだ。

>>> v = ('a', 2, True)
>>> x, y, z = v
>>> x
'a'
>>> y
2
>>> z
True

つまり、変数名をコンマで区切って横に並べると、それは「タプル」として解釈されるんだ。丸カッコがあろうがなかろうが関係ない。
そしてここで「プログラミング書法」が顔を出す。要は「記述する際にどっちの方が明解なんだ?」って事だよね。
もちろん、これに関しては龍虎氏が決める事だ。

なお、上のコードがRacketやSchemeで何を意味してるか、ってぇと実はこういう事なんだ。

> (define v '("a" 2 #t))
> (define-values (x y z) (apply values v))
> x
"a"
> y
2
> z
#t

Pythonには多値がない。代わりに多値をタプルで表現してる。
んで、Pythonは明示的な多値が無い(デメリット)お陰で、構造化代入を簡単に行える(こっちはメリット)、と言う特徴がある。
ある意味、トレードオフだよな。

いずれにせよ、結果、Racketで

(define (foo)
 (values 'bar 'baz))

と書くのをPythonでは

def foo():
 return 'bar', 'baz'

と書く。returnは一つの値しか返せない、けど、コンマで並べられた値は「タプルだと解釈される」。
結果、Pythonでは多値を返すようなプログラムを書く際には、タプルを自然と利用するようになってるんだ。

 セットって何に使えるの?と思ったのでWrtn君(中身はGPT4-Turbo)に聞いてみる。ほーん・・まあ実際何かを作るときに思い出せるようにしておこう。

いやまぁ、単純にセットって数学で言う「集合」以上の意味はないです。
特徴としては

  1. 含まれる要素に重複はない
  2. 含まれる要素に順序はない

ってな辺りで。
まぁ、Lispだと歴史的には「集合はリストで表す」って事やってきたんだけど、順序は無視出来ても、「要素の重複を許す」ってぇんでその辺正確にプログラムせなアカンかった際にちとメンドイ事は起きてたよね、ってな話だ。
その「重複要素を自然と取り除く」機能が場合によっては割と重要、っつーか(※1)。

なお、「集合」の実例は、いつぞや見せたババ抜きで使われている。カードの数字の「重複を取り除く」と言うのは、前提としてカードの数値が「集合に属してる」と言う観点が必要になる。

また、実はRacketにも集合(set)は存在する。重複した要素を持ったリストを集合に変換した途端、重複要素が消える。

> (list->set '(1 2 3 1 2 3 1 2 3 1 2 3))
(set 1 2 3)

データ変換しただけ、で重複要素が消える、と言うのは場合によってはプログラミングでは非常に便利だ。

> (set->list (list->set '(1 2 3 1 2 3 1 2 3 1 2 3)))
'(3 2 1)

ただし、上に書いた通り「集合の要素は順序を持たない」ので、変換後、データの順序に関しては「元通り」とは限らない(これを「不安定」と表現したりする)。
そこだけは気をつけよう。

 で、現在テキストデータのところ読んでます。Unicodeに至る道、先人の大変な苦労があったんですね。

そうそう、大変だったんだよ(笑)。
そう言えば、2000年代とか?外国の?Webサイトによっては開いてみれば文字化けばっか、とかさ(笑)。そんなんばっかだったじゃん。
逆に言うと、日本のWebサイトを外国のPCから除くと、やっぱ文字化けで。EUC-JPとか当時のUNIX系で標準的に使われてるエンコーディングとか、ある種迷惑でさ(笑)、「WebサイトはShift-JISにすべきかEUC-JPにすべきか」とか、当時はそういうバカな議論とかもあったよな(笑)。で、大体マカーの奴らがWindows系のShift-JISに難癖付けるんだよ(笑)。「これは機種依存文字だーーー!」とか言って(笑)。
そもそも、一体世の中の存在率5%以下の奴らの為に何を気にするんか、っての(笑)。
これが世の中での「マイノリティに対してのコンプライアンス問題」の最初の例じゃなかろうか(笑)。
でも今は昔、だ。2010年前後辺りからUTF-8が事実上標準になって、そういう「ブラウザ上の文字化け」が滅多に起こらなくて非常に快適な世の中になった(笑)。今でも文字化けするサイトって1990年代〜2000年代に作られたような古いサイトばっかだしな。

なお、いっつも文句ばっか言ってるけど、多分文字列に対する文字セットで、旧来の方式じゃなくって、UNICODEとかUTF-8をスタンダードにすべきだ、って提言したプログラミング言語ってJavaが最初じゃないのかね?僕、あんまJava褒めないんだけど、「スタンダードはこうあるべきだ」ってユニコードないしUTF-8での文字列のエンコーディング/デコーディングを提唱した、って意味ではJavaの功績ってすんごく大きい、って思ってるのね。
そのお陰で、それまで「文字列どうすんねん」となってた各プログラミング言語のUTF-8化が一気に進んだんだ。そしてUTF-8が扱えない処理系は一気に廃れた。Javaの影響力、っつーか当時のSUN Microsystemsの影響力が「世界を正常にした」んだ。これには感謝しても感謝しきれないと思う。

Javaは言われた。
「UTF-8あれ。」
こうして、UTF-8があった。 JavaはUTF-8を見て、良しとされた。
---創世記より(違

時系列的にはJavaがあって、各プログラミング言語の「文字列の扱い」及びその実装に影響を与えて、そして最後にWebサイトが・・・って順番だったんじゃねぇのかな、うろ覚えだけど。

※1: 例えば次のような連想リストを考える。

 (define *data* '((a . 1) (b . 2) (c . 3)))

SRFI1を使う前提で、例えばキーcに対して6と言う値を割り当てたいとする。

> (alist-cons 'c 6 *data*)
'((c . 6) (a . 1) (b . 2) (c . 3))

もちろんこれは「関数型プログラミング」なんで大本のデータである*data*は破壊的変更をされていない。再束縛されない限り、*data*は最初に設定された*data*のままだ。
一方、返り値は見る人によっては「何だこれは」って事になるだろう。幸い、検索関数のassq/assv/assocの類は「一番最初に見つかったキーと値のペアを返す」仕様になってるため、'cで探すと直近の'(c . 6)を返す。逆に言うと'(c . 3)は永久に見つからないわけだ。
「見つからないモノを永久に抱え続けてる」と言うのはある意味無駄だ。もちろん、データ操作を「逐一記録する」、つまり、ログとして考えるとこの形式は悪くはないんだけど、実の事を言えば殆どの人が「想像する」望ましい形式か、と言うと「そうでもねぇよな」とは言えるとは思う。
この原因は、そう、「リストは要素の重複を許す」と言う性質の為だ。言い換えると、実は何らかの検索テーブルに於いて、一般的に望まれるのは「キーは集合である」と言う事なんだ。よって「同一キーは削除されるべき」と言うのが自然と実装されている、ってのは大方の望むシステムだろう。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「RE: プログラミング学習日記」カテゴリーもっと見る

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