前回に引き続きPOP
今回はProtocol-Oriented Programmingが、
PONS=Protocol-Oriented Number Systemの紹介
前回取り上げた実例は、
- 誰かが任意精度の数値ライブラリを用意すれば、
それを使うことも可能
でもそれって本当?
それが、
使い方は簡単。
- ①
git clone
してPONS.
を開いて、xcworkspace Framework-OSX
をビルドしたらOSX Playground
の実例が実際に動くようになります。試しに(1...
と打ってみてください。100).reduce(BigInt(1),combine:*) - ②もちろんREPLでも動きます。
make repl
するとREPLが立ち上がるので、import PONS
してから(1...
とか打ってみてください。100).reduce(BigInt(1),combine:*).description - ③読者ご自身のプロジェクトで使いたい場合も、
Frameworkをコピーしてもよし、 ソースファイルをコピーしてもよしです。
これで、
RubyやPythonやHaskellではおなじみの任意精度整数
( BigInt
)が、 GMPなどの外部ライブラリなしで使えるようになります。
→素数判定メソッドも付いてきます。いや、同じく任意精度整数が組込みのPerl6にも組込みだったので。 有理数型
(Rational) もついてきます。分子と分母の型を引数とする総称型ですので、 もちろん任意精度有理数 =Rational<BigInt>
も使えます。よく使うのでBigRat
ととしてtypealias
してあります。任意精度浮動小数点数
( BigFloat
)もついています。 BigRat
だけでも好きなだけ小さな数も実現されているのですが、より高速かつ省スペースです。
→総称的に定義された初等関数(elementary functions) の実装も付いてきます。たとえば Float128
とか、新たな数値型を実装したときに exp
やlog
やsin
やcos
を書き直す必要はありません。実際BigRat
とBigloat
はそれぞれまったく別の型なのに、これらの関数のソースは共通です。
しかし、
1つで十分ですよ、わかってくださいよ!
古のCの時代、man cos
してみると……、
倍精度double
用にcos()
、float
用にcosf()
、long double
用にcosl
と、cosq()
でも加えるんですか? 昨今GPUで採用されはじめている半精度cosh()
ですか? でも待って、cosh
はもう双曲線コサイン
ぶっちゃけ付き合ってられませんよね?
Swiftは、
された状態でXcodeにてcos
と打つと……、Double
もFloat
もCGFloat
も、cos
で呼び出せることがわかります。
しかし、
こうですか?
だが断る!
だがしかし、
でもT
を足したりTどうしを比較する方法をSwiftは知りませんから、Hoge
があれば、
で行けるはずだ。でもそのHoge
ってどこにあるの? PONSは、Hoge
はPOIntegerが相当します。
で、
ぜひご自身でご確認を。
しかし、
BigInt
でやってみましょう。
になりましたか?
でも、
……失礼しました。SEGVです。XcodeでProtocolを多様したプログラムを書いていると本当によくお目にかかれます:-(。
しかし数値は整数だけではありません。整数だけで満足できるのは小学生とクロネッカー先生
とはいえこれらを漠然と並べただけでは、
向き合った結果が、
だから、
これが、
Protocol-Oriented Programming = 正しいものが報われる世界
PONSが目指したもの、int
やdouble
の制約を回避するのに涙ぐましいほどの努力をしていて時代を感じさせます。正しい世界とは、
たとえばモンゴメリー乗算というアルゴリズムがあります。これを使うと割り算なしで冪剰余を計算できたりするので素数が捗ったりします。PONSにも実装されているのですが、BigInt
があればBigInt
使って」
その一方、BigInt
は自分では文字列化メソッドを持っていません。整数の文字列化には、POInteger
でこう実装されています
元の数を底POInteger
に準拠した数値型は、
そもそもBigInt
があればほかの整数型はいらないという意見もあり得ます。大は小を兼ねるじゃないかという意見もごもっともですが、20! = 2432902008176640000
を計算するのに、BigInt
ではSwift組込みIntのなんと500倍も時間がかかるのです。これはPONSの実装がしょぼいから、Math::BigInt
もネイティブな64bit整数の250倍でした。ちなみにPONSのBigInt
は世界最速の任意精度整数からはほど遠いのですが、Math::BigInt
の5倍の速度が出ています。
コードを使い分けずとも、
PONSでそのことを示せたと自負しています。
予告
実はPONSのようなものは、
I have been working for some time on a rewrite of all the integer types and protocols https://
github. com/ apple/ swift/ blob/ master/ test/ Prototypes/ Integers. swift. gyb. One goal of this effort is to enable operations on mixed integer types, which as you can see is partially completed. In-place arithmetic (anInt32 += aUInt64) is next. Another important goal is to make the integer protocols actually useful for writing generic code, instead of what they are today:implementation artifacts used only for code sharing. As another litmus test of the usefulness of the resulting protocols, the plan is to implement BigInt in terms of the generic operations defined on integers, and make BigInt itself conform to those protocols. 「現在数値型の書き直しに取り組んでいる。その次には
(anInt32 += aUInt64のような) 異なる型通しの演算が控えている。もう1つのゴールは、 整数型プロトコルが総称的なコードを書くのに実際に役立つようにすること。実際にプロトコルに準拠したBigIntを実装するというのは、 そのためのリトマス試験紙となりうる」
Swift 2.
ただし、IntegerType
とかはそのまま使えませんでした。見てのとおり、Comparable
やHashable
といった、BigInt
でも(1...
できるのは、POInteger
がRandomAccessIndexTypeでもあるからです。
次回はそんなsin(1.
と書かなくてもsin(1)
で型エラーを起こさないかが見えてきます。
本誌最新号をチェック!
Software Design 2022年9月号
2022年8月18日発売
B5判/
定価1,342円
- 第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識 - 第2特集
「知りたい」 「使いたい」 「発信したい」 をかなえる
OSSソースコードリーディングのススメ - 特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画] Red Hat Enterprise Linux 9最新ガイド - 短期連載
今さら聞けないSSH
[前編] リモートログインとコマンドの実行 - 短期連載
MySQLで学ぶ文字コード
[最終回] 文字コードのハマりどころTips集 - 短期連載
新生「Ansible」 徹底解説
[4] Playbookの実行環境 (基礎編)