#MessagePackの文字列型追加において、Extended型を導入する提案
本提案は https://gist.github.com/frsyuki/5022569 https://gist.github.com/frsyuki/5022460 において提案された「バイナリ型」の構造に変更を施すものである。
##解決しようとする問題
- MessagePackへの拡張は今後行われないとしても、独自に拡張する提案が今後頻発しそう
- 拡張フォーマットは、既存のMessagePackに対して後方互換にならない(なりようがない)ため、相互運用性を損なう可能性が高い。これが問題
##提案する手法
今回文字列型とバイナリ型を導入するにあたり、型システムを拡張可能なものとし、拡張された型は、古いバージョンのcodecにおいては、バイナリとして扱われるような設計とすべき。
こうすることで、今後型の拡張が行われたとしても、旧バージョンのツールでラウンドトリップ問題が発生しないことを保証できるし、結局、ツールというものは自分の知ってる型のデータしか扱わないので、それで問題ない。
##フォーマット
https://gist.github.com/frsyuki/5022569 に以下の変更を施すべき。
0xc4-0xc9,0xd4,0xd5 FixExtended (0bytes - 7bytes extended type)
0xd6 Extended 8 (extended type) // new
0xd7 Extended 16 (extended type) // new
0xd8 Extended 32 (extended type) // new
0xd9 string 8 (String type) // new
0xda string 16 (String type) // changed from raw 16
0xdb string 32 (String type) // changed from raw 32
Extended = ExtendedTAG n-OCTETS (nは各FixExtended,Extended8,16,32で規定)
ExtendedTAG = 0x00 - binary 0xf0-0xff - private extension
全てのtypeを使い切るが、今後の拡張はExtendedTagを使って可能だし、その場合確実に後方互換性を保証できる。
###拡張例
たとえばtime_t型をTAG=0x31として追加する場合:
0xc7 0x31 0x51 0x2a 0xd5 0xb0 ; is Feb 25 03:08:32 2013 (0x512ad5b0)
たとえばShift_JIS型をTAG=0x32として追加する場合:
0xd6 0x0a 0x32 0x82 0xb1 0x82 0xf1 0x82 0xc9 0x82 0xbf 0x82 0xcd ; こんにちは
##FAQ
###Q.256個のExtendedTAGを使い切ったらどうなるか?
ExtendedTAGを1バイトとして定義しても可変長の構造として定義しても、後方互換性の観点から言うと優劣は存在しない。
なぜなら、2バイトのExtendedTAGが必要になったら、「データの先頭もExtendedTAGだよーというExtendedTAGを導入すればいい」から。その必要性がある実装は対応するだろうし、対応しない実装では、未知の型をもつバイナリとして扱われるから、後方互換性は維持される。
そこで、現時点でExtendedTAGを可変長フォーマットとして提案することで、提案がリジェクトされる可能性を危惧し、このような提案としている。
仕様のシンプルさという意味ではおっしゃるとおりですね。ですが、実装コストは大してかわらないと思います。
0xc4-0xc7のみを使う方法のもうひとつの問題は、reserved bytes を残すことです。
reserved bytes を残すことにどのような意味があるでしょう?
将来の拡張のため? いえ、その種の拡張は互換性を破壊します。今後全ての拡張を ExtendedType を使って行えるようにすることで互換性を壊さないようにしよう、というのが僕の提案です。reserved bytes を残すことはこの目的に反します。
僕は基本的に、互換性を壊す変更を入れるようなデータフォーマットはクソだと思っています。多くの人は、MessagePackに、相互運用性を求めているというのが僕の理解です。
文字列型を追加することで、MessagePackへのそのような信頼が揺らぐだろうと僕は考えています。彼らは思うと思います(僕なら思います)。「変更は、今回だけよ。って言いながら、どうせまたやるんでしょ。MessagePackは安定なフォーマットじゃないんでしょ」って。特に、声の大きい人が型の追加を求めているような現状において、この懸念は正当なものだと思います。
その懸念を払拭するために、文字列型の導入と同時に、今後非互換な変更が入り得ないような設計にすることが望ましい、というのが僕の意見であり、本提案の背景にある考え方です。