100までの整数から素数を列挙せよ…を Smalltalk-72 で


悪ノリして、今度は 1974 年からのエントリー。当時の ALTO のフォントとウインドウで。このころの暫定ダイナブック、すなわち“ Smalltalk を OS として動作する ALTO ”のウインドウは、オーバーラップ表示こそ可能でしたが、まだ、簡素な矩形を描いただけのものでした(なので、下のスナップショットも、ただの枠にしか見えませんが、いちおうウインドウです(^_^;))。


http://squab.no-ip.com:8080/collab/uploads/61/primesupto100st72.png
http://www.screenr.com/embed/cdxH


念のため、SqueakSmalltalk-72 エミュへコピペして評価可能なテキストはこちら。

"limit _ 100.
"primes _ stream of vector 1.
primes _ 2.
for i _ 3 to limit by 2
  ("isprime _ true.
   "vec _ primes contents.
   for idx to vec length
      ("prime _ vec[idx].
      (i mod prime) = 0? ("isprime _ false))
   isprime? (primes _ i))
primes

Smalltak-76 といっけんよく似た for 文もどきの式がありますが、制御構造向けの特別な式を用いている Smalltak-76 とは違い、Smalltak-72 では、ちゃんと for という関数オブジェクトへのメッセージ送信として実現されている(for へ、for よりあとの、i ← 3 to limit by 2 (...) や、idx to vec lenght (...) をメッセージとして送っている)ところに感じ入るのが、ツウな楽しみ方です。もちろん、テンポラリ変数への代入もメッセージ送信で、ストリーム(primes)については、代入の記号(←)をセレクタに用いて、多態すらしてます(primes ← 2 は、代入ではなく、ストリームへの要素の追加)。


ほぼ同じ内容を、SqueakSmalltalkSmalltalk-80 以降の Smalltalk)に翻訳すると、こんなかんじ。

| limit primes isPrime |
limit := 100.
primes := #() writeStream.
primes nextPut: 2.
(3 to: limit by: 2) do: [:i |
   | array |
   isPrime := true.
   array := primes contents.
   (1 to: array size) do: [:idx |
      | prime |
      prime := array at: idx.
      (i \\ prime) = 0 ifTrue: [isPrime := false]].
   isPrime ifTrue: [primes nextPut: i]].
^ primes contents

意訳すると、こう。

| limit |
limit := 100.
^ Array streamContents: [:primes |
   primes nextPut: 2.
   (3 to: limit by: 2) do: [:i |
      | isPrime |
      isPrime := primes contents noneSatisfy: [:prime | i isDivisibleBy: prime].
      isPrime ifTrue: [primes nextPut: i]]]


関連: