Protocol BuffersとJSONの扱い in OCaml

以前の記事で、ProtocolBuffersでOCaml/TypeScript間の定義を作成して色々やっていたのですが、いくつか問題が出てきたので書いてみます。 <!–more–> ocaml-protoc-pluginに乗り換えた 前回は ocaml-protocを使いましたが、ocaml-protoc-pluginに乗り換えました。理由としては以下となります。 標準のprotocにおけるpluginという形での提供 自前で解析していてもいいとは思いますが、他のproductではprotocのplugin形式が多かったので 型定義にannotationを付けられる yojsonとかに変換するのが簡単です ts-protoc-gen + protoc標準から、pbjs(protobufjs)に乗り換えた 前はprotocに標準添付されているJavaScript実装と、ts-protoc-genを組み合わせていたのですが、以下のような問題があったので乗り換えました。 Jsonからの変換とかが出来ない protocの標準では、 protocolbuffers以外に対するserialize/deserializeがありません JSON-RPCを利用しているので、軽く絶望しながら切り替えました(先に調べろと 発生した問題 今作っているapplicationでは、Electronとbackend server間をWebsocketでつなぎ、RPCとしてJSON-RPCを利用しています。この構成、面倒ではありますが、割と使い勝手がよいのです。しかし、protoファイルから生成した型を使っていると、困る割にいい解決策が無い問題にあたりました。 その問題とは、 OCamlでの型定義とProtocolBufferでの型定義との互換性 です。ナンノコッチャですが、要はocaml-protoc-pluginが生成してくれる型と、protocol_conv_jsonのでのJSON変換が一筋縄では行かない、ということです。 私は大きく2つの問題にあたりましたが、そのうちの一つを例に上げます。 enum Types { Unknown = 0; String = 1; Number = 2; } message Foo { Types value = 0 } こんな感じのprotoファイルからOCamlの定義を作成すると、以下のような感じになります(moduleの定義は省略しています)。 open Ocaml_protoc_plugin.Runtime [@@warning "-33"] module rec Types : sig type t = Unknown | String | Number val to_int: t -> int val from_int: int -> (t, [> Runtime'.Result.error]) result end and Foo : sig val name': unit -> string type t = Types.t val to_proto: t -> Runtime'.Writer.t val from_proto: Runtime'.Reader.t -> (t, [> Runtime'.Result.error]) result end ここでポイントとなるのが、protoファイルにおいてenumと定義した部分と、OCaml版におけるTypes moduleです。OCamlにおいては、Enumを代数的データ型として表すのはごく自然だと思うのですが、問題はProtocol Buffersにおいては、enumは 単なる数値 でしかありません。 to_int とかがそれを物語っています。 ...

January 13, 2020 · derui

格子配列に適したかな入力を模索する

以前の記事で、薙刀配列を利用している、と書きましたが、色々思うところがあり、今は別の可能性を探っています。 <!–more–> 現在色々と提案されているカナ入力方式は、TRON配列を除くと、基本的に 一般的なJISキーボードに合わせて設計されています 。99%の人は、JISキーボードを利用しているであろうから、その課程は至極当然です。 しかし、Ergodoxを始めとする、通称 格子配列 とJISキーボードでは、押しやすいキーや指の可動範囲がかなり異なります。人差し指が担当する TYBN であったり、小指が担当する PQ は使い勝手が変わります。また、JISキーボードのようなRow-struggleなキーボードで押しやすいキー連接は、必ずしも格子配列で押しやすいとは限りません。 格子配列の特徴と個人の身体的特徴 格子配列には、次のような特徴があります。(個人的な感覚ですが) 列をまたいで指を移動するのが厳しい 同じ列内での移動はやりやすい また、これは私の身体的特徴ですが、 人差し指と小指がかなり短い 格子配列でT/Yに指を伸ばすのに若干気合が必要なくらい 手ごと移動すれば、指の不可は大分減りますが、今度は腕を持ち上げるという負荷がかかります P/Qは、手ごと移動しないと押せない という特徴があります。模索している配列では、これらをどう解決していくか?が肝になります。 シフトの設計 現在利用しているキーボードであるCrkbdには、そもそも42キーしかなく、親指以外の指に割り当たっているキーは36キーしか存在しません。このうち6キーはCtrlやShiftなので、事実上は30キーが物理的な限界です。 どのみちひらがなだけで50音あるので、必然的に何らかのシフト機構が必要になります。シフト機構にも色々ありますが、大別して次のようなものがあります。 前置きシフト JISかな、新JIS、親指シフト、月配列 同時シフト 蜂蜜小梅配列、新下駄配列、薙刀配列、飛鳥配列 他にも色々ありますが、要は シフトに順序性があるかどうか が大きな違いです。順序性がある場合、ロールオーバーが可能になりますが、ほぼ同時にキーを押下した場合、意図しない入力になる場合があります。順序性がない場合、ほぼ同時に押下しても問題ありませんが、その代わりに単打時の誤爆が起こりやすくなります。 また、どのキーをシフトとして利用するか?というのも重要です。 小指シフト JISかな 親指シフト NICOLA、蜂蜜小梅配列、薙刀配列、飛鳥配列 人差し指シフト 薙刀配列 中指シフト 月配列、新下駄配列 Crkbdに限って言うと、Layer切り替えがかなりの頻度で発生する上、SandS/Enterを親指に割り当てている都合上、これ以上負荷をかけるのはリスクがあります。実際、親指だけ痛くなったことがあるので。そうなると、弱い小指に負荷を与える小指シフトは論外として、人差し指/中指シフトが有力に思えます。月配列や新下駄配列を利用していても、あまり違和感は無かったので、個人的にも問題はありません。 清濁同置と清濁別置 新下駄配列や飛鳥配列では、清濁別置を選択することで、高効率を実現しています。しかしその分記憶負担が大きく、また運動記憶が確立するまでに時間がかかります。 蜂蜜小梅配列や薙刀配列では、濁音を入力する時に清音+シフトで入力するようにして、記憶負担を抑えて、連想記憶で思い出せるようにしています。新JISでは後置きで濁点を追加する方式です。 最終的には運動記憶に帰着するため、効率だけで言えば清濁別置の方で効率的なのは明らかです。ただ、滅多に利用しない濁音や半濁音も連想無しで覚えなければならないので、滅多に利用しないかなの入力時にはかなりスピードに影響することが想像できます。 行段系かどうか かな50音を、列=子音と行=母音に分解して、2打鍵で入力する方式です。けいならべ、かわせみ配列、Phoenix配列などが該当します。 行段系の利点としては次のような点が挙げられます。 記憶負担がちいさい 子音と母音だけ覚えればいい 左右交互打鍵にしやすい 大抵は子音と母音をそれぞれの手に配置するため、基本的左右交互打鍵になるケースが多いようです 対して、次のような欠点があります。 使用頻度による配置が難しい 規則的になる半面、各指の運動特性に準じた配置とかはかなり難しい つまり、効率をある程度犠牲にして、連想記憶などで思い出せるようにしたものです。基本的に一文字の入力に2打鍵かかるため、何らかの拡張を施さないと、ローマ字入力とさほど効率が変わりません。 実際に利用してみたところ、確かに記憶はすぐ出来ますが、やはり運動記憶にするまでに時間がかかります。また、どうしても2打鍵必要になるケースが多い、というのが結構気になります。 拗音拡張 最近の配列には、大抵拗音拡張が取り入れられています。拗音拡張を取り入れることで、やゆよの小文字を単独で入力する必要がなくなり、一動作で入力出来る文字数が増え、結果として効率が向上します。 ただ、拡張を取り入れることで、記憶負担の増加もまた避けられないため、各配列で覚えやすくするための工夫を取り入れています。 蜂蜜小梅配列 蜂蜜マトリックスという仕組みを起点として構築されている 新下駄配列 専用のシフトを割り当て、拗音拡張だけは規則的にしている かわせみ配列 子音+やゆよの入力で規則的な配置 薙刀配列 拗音の最初の文字+後ろに続く小文字で統一 記憶負担の増加にどう対処するか?というのが肝のようですが、利用できると効率が向上するので、出来れば使えるようにしたいところです。 ...

January 24, 2019 · derui