2020-07-05

スノーボード用の別荘を検討している

COVID-19によりリモートワークが長引いている。ここまでリモートワークが長引くのであれば、いっそのこと冬はスキー場近くに別荘を用意して滑りながら仕事をするのはどうか。これを真面目に検討してみた。

別荘を手に入れるためには購入するか賃貸しなければならない。購入するのは簡単だ。バブル期に立てたリゾートマンションが腐るほどある。現金が数百万もあればよい。中には取引額が負数の不動産さえある始末。問題は維持費だ。固定資産税がかかるし管理費、修繕積立金もかかる。そして日本では不動産を放棄することができないので、バブル崩壊後のリゾートマンションはババ抜きとなっている。

引退後にその地方に移住するならば購入はありだが、運動強度の高いスノーボードを老後も続けられるかどうかはわからない。

賃貸はどうかというと、これがまたスキー場近くの不動産の購入に価値がないと思わせるほど賃料が安い。月3万も出せばワンルームから2DKぐらいの部屋が借りられてしまう。問題は冬の間4ヶ月だけ借りて最低限住めるだけの環境を整え、シーズンが終わったら撤退する手間は面倒だ。通年で借りれば毎年賃貸契約と解約をする手間は省けるが、特に登山趣味もないので夏の間の価値はほとんどない。

手間もさることながら、場所の問題もある。

越後湯沢駅の徒歩4分のところに、月1.6万円のワンルームと3.2万円の少し広いワンルームがある。駅からバスで各スキー場に行くことができる。東京-越後湯沢が2時間、越後湯沢駅から各スキー場まで20-40分といったところだ。月1.6万円は極めて安く、通年借りたとしてもそれほどの負担ではない。問題は、越後湯沢周辺のスキー場は雪質はそれほどでもないということだ。東京からの交通の便がよいために栄えている場所だ。駅前の土地勘はそれほどないが、車なしで数ヶ月滞在することぐらいはできるだろう。

白馬駅から800mのところに月4.8万円の2DKがある。白馬村は前シーズンに2週間滞在したことがあり土地勘がある。白馬駅からバスや電車で各スキー場に行くことができる。スキー場までは1時間弱といったところだろう。付近には温泉もスーパーもある上、好日山荘に小さなクライミングウォールがある。東京からバスと電車の連絡にもよるが4時間ぐらいだ。

妙高市の新井駅の近くに、月3万ぐらいで1Kから2DKぐらいの賃貸がある。問題は土地勘が一切ない。地図を見る限り駅前は車なしでも数ヶ月滞在できそうな気はする。近所にボルダリングジムがある上、トップロープまでできる場所もあるようだ。問題はスキー場なのだが、新井駅から電車で26分かけて妙高高原駅に行き、そこからバスで赤倉温泉、赤倉観光、池の平、杉ノ原といった各スキー場に移動するか、関山駅に行ってバスでロッテアライリゾートと関山温泉スキー場に行くことができるようだ。新井駅からスキー場まで1時間以上かかるだろう。東京からは4,5時間ぐらいだ。

賃貸を借りるならいい加減に不動産屋に連絡を入れないといけないが、何分遠方の物件なので手間がかかるし踏ん切りがつかない。

2020-06-30

職質裁判、上告不受理で終了

職質裁判は上告不受理で終了した。

calling-110-is-suspicious/20200626_zyoukoku_huzyuri.pdf at master · EzoeRyou/calling-110-is-suspicious

経緯はこうだ。3年前にひどい職務質問を受けた。

警察官に職務質問をされた話

警察官職務執行法に規定されている通り、職務質問をするためには職務質問を受ける人物について犯罪を犯した、あるいはこれから犯罪を侵すと疑うに足る相当な理由が必要だ。それに職務質問で規定されているのは質問であって、開口一番にリュックの中身を見せろと発言するのはもはや質問ではない。そして警察官2人がかりで路上に羽交い締めにされたり、多数の警察官によって私有地の駐車場に監禁され、何の法的根拠もない手荷物検査に応じるまで解放しない。これは説得でありお願いであるので法的根拠は必要ないと2時間拘束されたわけだ。職務質問において私が警察官職務執行法に規定する相当な理由について質問したところ、警察官が答えたのは、「帽子を目深にかぶっていた」、「うつむいて下を向いて歩いていた」ということだけで、特に「うつむいて下を向いて歩いている」者は「薬物中毒者である可能性が高い」と言われた。

これに対して東京都を相手に裁判をしていたのだが、一審では不審事由がなくても声をかけることは違法ではなく、110番通報を要請することは不審事由に当たるのでその後の職務質問は正当であるという判決が出された。裁判では、東京都は本当に謎の主張をしてきだ。私が手を小刻みに震わせているという職質当時は一切指摘されなかった主張をしたり、警察はパトカーから私とすれ違ったが、そのとき私は顔を伏せてパトカーから逃げ去ったという主張だ。私には手を震わせる持病はないし、ましてや東京都の主張する私とパトカーがすれ違いざまに走り去ったという地点から10m先の自動販売機で、私はのんびりと飲み物を購入しているわけだ。私は走っていないし、走り去ったとしたらなぜ10m先の自動販売機でのんびり飲み物を購入しているというのか。そして目の前の警察官があまりにも法律を無視しているので110番通報を要請したところ、目の前の警察官は110番通報を阻止したのだ。そして裁判では110番通報の要請は不審事由に当たるとされた。

二審では110番通報の要請は怪しいという部分は削られた。しかし結論は変わらず、不審事由がないにもかかわらず職務質問は妥当であるという結論は変わらなかった。

判決で参照されている判例は、車を運転中に物損事故を起こした上で呼気検査を拒否したとか、検問での呼気検査に引っかかったが検問が違法なので違法な証拠収集であるという、もともと無理筋の裁判で、この判例を歩道を歩いている何の違法行為も事前に認められない人間を相手に適用すべきかということで上告したが、結果は上告不受理であった。

この結果から何の教訓を引き出せばいいのかわからない。一番の敗因は110番通報を妨害され失敗したことであるように思われる。110番通報の通話記録は確実に残り強い証拠として使えるので、今回東京都が主張してきた様々な嘘が嘘であるという証拠になる。当時私は録音録画する装置を持ち合わせておらず、またプライバシーを優先して携帯電話も持たない主義なのでその場で110番通報できなかったのだ。

これからは自衛のために常日頃からボディカメラを装着して持ち歩くべきだろう。常時録音録画しておき記録に残すのだ。

警察の偽証から自衛せねばならぬとは嫌な世の中になったものだ。

2020-06-21

バックトゥザフューチャーのタイムライン

話題になっていたので映画バックトゥザフューチャーのタイムラインについてまとめてみた。タイムトラベルが行われるたびに新しいタイムラインが生成される。これは映画三部作だけを参考にしており、テレビ放送アニメ、コミック・ブック、小説、ビデオゲームについては考慮していない。

T0: タイムトラベルの発生しないオリジナルのタイムライン。アインシュタインは1分後にタイムトラベルしない。地名は二本松モール。ドクはリビヤ人テロリストによって射殺される。マーティの父親は弱気でビフにゆすられている。

T1: アインシュタインが1分後にタイムトラベルする。オリジナルのT0とほとんど変化はないと思われる。

T2: マーティが1985年から1955年にタイムトラベル。木を一本車で引き倒したために地名が孤独松モールに変わる。ドクは防弾チョッキを着ていたので生存。父ジョージが自信家になりビフは真面目になる。マーティのその後の消息は不明。

T3: マーティが1955年から1985年にタイムトラベル。マーティはジェニファーとドライブデート中に腰抜け(Chiken)と煽られ交通事故を起こし障害者になる。マーティの息子がそそのかされて犯罪を起こし、マクフライ家は崩壊。

Ta: ドクがa回のタイムトラベルをしたことによりn個の世界線が発生する。aの数は不明。デロリアンにMr. Fusionが搭載され、家庭ごみを燃料に駆動するようになる。空も飛べるようになった。

T4: ドク、マーティ、ジェニファーが2015年にタイムトラベル。マーティの息子に将来降りかかる危難をなかったことにする。その後のドクとマーティとジェニファーの消息は不明。

T5: ビフが2015年から1955年にタイムトラベル。2015年に入手したスポーツ年鑑を1955年に使い博打で大儲けした結果、ビフが大金持ちになる。周辺の治安は悪化。マクフライ家は崩壊、父ジョージはビフに殺され、母ロレインはビフと再婚。ドクは精神病院に入院。没案では1985年以降にロレインはビフを射殺。

T6: ドク、マーティ、ジェニファーが2015年から1985年にタイムトラベル。T5の世界線を観測する。

Tb?: ドクがビルの屋上に追い詰められたマーティを助けるタイミングの都合が良すぎるので、ドクは何度かタイムトラベルした可能性がある。

T7: 1955年に戻りビフからスポーツ年鑑を奪う。T3の世界線に戻る。

Tc?: ドクがマーティをトンネルで助けるタイミングの都合が良すぎるので、ドクは何度かタイムトラベルした可能性がある。

T8: ドクの乗るデロリアンが雷に撃たれて1955年から1885年にタイムトラベル。マーティは郵便配達人から100年前の手紙を受け取る。ドクは手紙を書いて程なくしてビフの先祖であるビュフォード・タネンに射殺される。

T9: マーティが1955年から1885年にタイムトラベル。クララが生存。マーティがビュフォード・タネンに射殺される。

T10: マーティが1885年から1955年にタイムトラベル。ショナシュ峡谷がイーストウッド峡谷に変わる。マーティは腰抜け(chiken)と煽られても交通事故を起こさない。

Td: ドクがd回のタイムトラベル。

2020-06-13

キックスクーター

キックスクーターに乗り始めて早2年、いろいろと分かってきたので書き出しておく。

最初に買ったキックスクーターは1万円ほどの安物で、これは悪くはなかったが、もう少しいいものがほしいので人に売り払った。

次に買ったのはMicro MobilityのCity BMW Scooterだ。これはBMWとの公式コラボ製品で、日本で正規の購入代理店がいて手軽に買える中では最も高い製品だ。

- micro-mobility.com

しばらく使った感想としては、ソリッドタイヤでは快適に走れる道がかなり限られるということだ。大通りの道の舗装はかなり荒いアスファルトになっているので快適ではない。大通りからそれた路地がおすすめだ。またどうもこの製品はフットブレーキの作りがあまりよくない。すぐに壊れてしまった。

COVID-19の影響もあって電車に乗りたくないので、エアタイヤのキックスクーターを買ってみることにした。前輪が230mm、後輪が205mmのエアタイヤになっている。

FR230P | Frenzy Scooters

しかし、これがまたかなりひどい欠陥品だった。届いた製品の後輪のタイヤが分厚すぎてフレームに干渉してしまう。販売店に相談して純正品の交換パーツを送ってもらったが、これまた同じ欠陥を抱えている。返品を考えたが、物自体はそれほど悪くはないので、アマゾンで中華製の8インチのエアタイヤを買ってみた。これがなかなか悪くなく細めにできていて70PSIも入る。これでようやく快適になった。これで荒いアスファルトも石畳も怖くない。ただ、ソリッドタイヤに比べてほんのわずかに速度で劣る気がする。ベアリングの質の問題ではないはずなので、運動エネルギーの一部が減衰性のある素材のせいで熱に変わっているせいだろうか。

結論から言うと、おそらく前輪後輪とも205mmのキックスクーターでよかったのではないかと思う。というのも230mmエアタイヤというのは珍しすぎて交換品がない。タイヤチューブはあるのだが、ベアリングホイールとタイヤの交換品がみあたらない。205mmはチューブ、ベアリングホイール、タイヤとも豊富に互換品が存在する。

2020-06-01

パブリックドメインの漫画が出てくるのは2050年代から、アニメは2030年代から

Redditでパブリックドメインな漫画は存在するのかと質問されていたので考えてみた。

Are any manga in the PUBLIC DOMAIN? : japan

2018年に改正された日本の著作権法では、個人の著作権の保護期間は死後70年を原則として、映画、無名、周知されていない著作物は公開から70年となっている。改正時にすでに著作権条保護されていない作品について保護期間が延長されることはないので、1967年に著作者の死亡した作品の著作権の保護期間は満了しているが、1968年に著作者の死亡した作品の著作権は2038年まで存続する。

それを踏まえて日本の漫画の歴史を紐解くと、1930年代には、現代風の漫画が公開されている。このときの漫画家達は1970年から1980年頃まで生きているので、著作権の保護期間が満了してパブリックドメイン漫画が出てくるのは、1950年代以降ということになる。

もちろん例外はある、1967年までに死んだ漫画家の著作物はすでにパブリックドメインになっている。ただし、それほど多くはないだろう。

アニメは法律上映画になるので、アニメの著作権は漫画より早く消失する。日本のアニメは1960年代から発表されているので、2030年代にはパブリックドメインのアニメが出てくることになる。

判例を考えると、映像表現をともなうビデオゲームは映画の著作物になる。任天堂のファミコンは1983年に販売されている。したがって2054年以降から、パブリックドメインのファミコンのゲームが出てくることになる。

2020-05-03

マッスルアップができない

クライミングジムがのきなみ営業自粛してしまってからしばらくたつ。その間に筋力だけでも落とさないようにと公園の鉄棒でトレーニングをしているのだが、クライミングとは違う身体の動きを要求される。

最初はなかなかできなかったうんていだが、最近はラクラクとこなせるようになった。これは筋力が発達したのではなく、効率的な身体の動かし方を学んだのだろう。垂直な鉄の棒を腕だけで登ることもできるようになったし、落差50cmぐらいの棒から棒に飛び移ることもできるようになった。

クライマーからすると、鉄棒はガバすぎて指に対する負荷が足りなすぎるので、ロックリングスを買ってみた。ふしぎなことに単に鉄棒で懸垂するより指3本を第一関節だけかけるロックリングスのほうが懸垂がやりやすい気がする。クライミングはするが鉄棒での懸垂はほとんどしてこなかったことが影響しているのだろう。またローリーバーも買った。クライミングジムでたまに触るのとちがって、自分で所有して本格的に30分ほど取り組むと、だいぶ手首に負担がかかることが分かった。ローリーバーはそれほど長時間するものではない。

現在の目標は鉄棒でマッスルアップができるようになることだ。マッスルアップをするための筋力はすでに十分に備わっているはずなのだが、マッスルアップができない。マッスルアップのうち、プルアップはできるが、そこから身体を持ち上げることができない。なので最近はディップスのトレーニングをしている。クライミングジムが再開したらマントル返しやプッシュに向上につながることを期待している。

ところで、電車に乗ることを避けるためにエアタイヤのキックスクーターを新しく購入した。FrenzyのFR230で、前輪が230mm、後輪が205mm。両方共エアタイヤだ。届いた当初、常にブレーキがかかったような感覚を覚えると思ったら、後輪のタイヤがフレームに干渉していた。初期不良を訴えて交換してもらったのだが、交換してから20日で今度は後輪がパンクした。どうもこの製品、製造上の欠陥がある気がしてならない。タイヤというのは荷重するとわずかにたわんで幅が広がる。Frenzyの後輪のフレーム部分の幅が狭すぎ、たわんだ際に干渉する問題があるのではないかと思っている。

とりあえず古いキックスクーターから205mmのソリッドタイヤを移植したが、一度だけ自転車屋にタイヤをパンク修理で持ち込んで見ようと思う。しかし、新品が20日でパンクした以上、あまり期待はしていないのだが。

2020-04-17

検出不可能なゲームのチートが発表、今後のオンラインゲームのデザインはこのチートを前提に設計しなければならない

PCILeechというソフトウェアスタックがある。

ufrisk/pcileech: Direct Memory Access (DMA) Attack Software

これはPICeデバイスを使ってターゲットコンピューターのメモリをDMAで読み取るためのPCIeデバイスのFPGAの実装とその操作のための一連のソフトウェア群だ。

原理は簡単だ。ターゲットコンピューターのPCIeスロットにつないだPCIeデバイスからDMAをするだけ。これによりターゲットコンピューターのメモリ領域を読み取ることができる上、ターゲットコンピューターからは検出不可能だ。なぜならばDMAはCPUを介さずに行われる上、ターゲットコンピューターにカーネルスペース/ユーザースペースともに追加のコード実行を必要としないからだ。

PCILeechを作って作られたゲームのチートに、CSL:GOのチートがある。これはマップ上のどこにプレイヤーがいるかを表示するチートだ。

pcileech-webradar/readme.md at master · EngineOwningSoftware/pcileech-webradar

原理上、このチートはターゲットコンピューターからは検出不可能だ。したがっていかなるDRMであろうとも役に立たない。難読化をして多少チートの開発を嫌がらせすることはできるかもしれないが、所詮その程度だ。もはやゲームにおいてメモリは常に読まれるものと考えなければならない。

このチートに抗うのは無意味だ。したがってこれからのオンラインゲームはローカル環境でのメモリが読まれることを前提に設計しなければならない。CS:GOのようなオンラインFPSゲームでは、全プレイヤーの位置は公開すべきだろう。すなわちこのようなチートの意味をなくすのだ。オンラインポーカーのようなゲームでは、ローカルに秘密情報を保持しない実装にしなければならない。秘密情報については中央の権威サーバーのみが処理するか、メンタルポーカーのアルゴリズムを使う。オンラインFPSも中央の権威サーバーによる実装もできるが、それはGoogle Stadiaのような入力をサーバーに送信して映像をストリーミング再生するだけのような実装になるだろう。

この仕組みを使ってメモリに書き込む場合は検出可能だろう。というのも連続していない任意箇所のメモリに対してアトミックに書き込むことはできないので、ゲーム状態を重複して複数のメモリ箇所に保持したり常時チェックサム計算などの対策で、メモリ改変を検出できるはずだ。

また、自分のプログラムが全メモリアクセスを専有している場合は、メモリ帯域を常時使い切ることにより、メモリ帯域に変化が生じればそれはDMAアクセスが行われたと考えていいだろう。問題はPCILeech以外の各種デバイスかもしれず、またIntel MEやAMD PSPのような邪悪で不自由なバイナリブロブのファームウェアによるものかもしれないので、切り分けができない。そして全メモリアクセスを専有する状態ではもはやPCゲームは実装できない。

世の中から無意味で邪悪で人道上の罪であるDRMは滅ぼさなければならない。

2020-04-16

Error handling in Erlang

Last time, I wrote about how to write a hello world HTTP server by using Erlang, Cowboy and Rebar3.

Walkthrough of hello world HTTP server with Erlang, Cowboy, and Rebar3

Today, I'm going to write about the error handling in Erlang.

The error handling in Erlang is easy if we can ignore the error. That is, we don't expect the error. In the event of unlikely failure, we immediately abandon any computation we were doing and start over. The OTP and other famous frameworks were written by following Erlang culture of error handling so it will handle it well. If, on the ohter hand, the errors are expected to happen, so we have to explicitly deal with it. Erlang is suddenly reared its ugly head.

How a function notify it's caller the failure? In other languages, like Haskell, there is a Maybe type which may or may not contains the value. Erlang is not staticaly strong typed language so the Erlang version of the Maybe is tagged tuple. We return ok or {ok, State} upon success and we return any other value otherwise. It may be {error, Reason}, empty list [], or simply an atom like error, false, undefined whatever.

The user of such functions must match the returned value with ok tagged tuple,

do_something( State ) ->
    {ok, State_1} = f( State ),
    do_normal_things.

If the function f return anything other than {ok, any()}, match failed and throw an exception of error:{badmatch, V}. So hopefully, the higher framework catch these exceptions and restart the process.

But what if the caller want to deal with the error? We have to use the patter match for the conditional execution. It can be done by case expression or function.

case expression:

do_something( State ) ->
    case f( State ) of
        { ok, State_1 } -> do_normal_things ;
        { error, Reason } -> do_error_handling
    end.

function :

do_something( State ) ->
    do_something_1( f( State ) ) .

do_something_1( { ok, State } ) -> do_normal_things ;
do_something_1( {error, Reason} ) -> do_error_handling .

Whichever you use, it became quite verbose and boilar-plate.

Erlang has exception like many other langauges. But I feel some oddities on Erlang's exception and that is the concept of class.

The Erlang has three class of exception: error, exit, and throw. These are thrown by calling function error/1,2, exit/1, and throw/1 respectively.

If you don't care about exception, you need to do nothing. But if you care, that is, you want to run some code on the condition of exception, things get verbose.

Let's suppose that previous function f/1 return { ok, State } on success, but throw some exceptions otherwise and you want to deal with it because you expect it to happen. You can use try expression or catch expression

try expression is strightforward, if you ignore the awkward Erlang grammer that is.

try Exprs
    catch Class1:Pattern1 -> Body1 ;
    catch Class2:Pattern2 -> Body2
end

The class is either error, exit, or throw, pattern may vary. If you were to catch the exception thrown by error class's badmatch(1 = 2), it looks like this.

try 1 = 2
    catch error:{ badmatch, V } -> its_bad_man
end

Now, how to do_normal_thing and do_error_handling depending on the presense of exception? try expression can have of section and it will be evaluated only on no exception in Exprs.

try f( State ) of
    { ok, State_1 } -> do_normal_thing ;
catch
    throw:something_went_bad -> do_error_handling
end

Now how to deal with the situation where the error will be reported in either by value or exception? Use try expression's of section to pattern match the error value.

try f( State ) of
    { ok, State_1 } -> do_normal_thing ;
    { error, Reason } -> do_error_handling
catch
    throw:something_went_bad -> do_error_handling
end

There is another way to deal with the exception. The catch expression.

catch Exprs

catch expression evaluate Exprs and return its value on no exception. In case of exception, the value will be either

For exceptions of class error, that is, run-time errors, {'EXIT',{Reason,Stack}} is returned.

For exceptions of class exit, that is, the code called exit(Term), {'EXIT',Term} is returned.

For exceptions of class throw, that is the code called throw(Term), Term is returned.

Erlang -- Expressions

If it's by throw({error, Reason}), the code will be clean.

case catch Exprs of
    { ok, Value } -> do_normal_thing ;
    { error, Reason } -> do_error_handling
end

But if it's error class, the code is too ulgy to read.

case catch 1 = 2 of
    { 'EXIT', { {badmatch, _} }, _ } -> do_error_handling
end

Perhaps, error and exit class were not meant to be handled by catch expression, but some library use these even for the predictable situations. like list_to_integer, binary_to_integer. My guess is to keep the backward compatibility.

Putting it all togather, it's very verbose to handle errors in Erlang.

Let's quickly borrow a code from the hello world HTTP server I explained in the previous article. Walkthrough of hello world HTTP server with Erlang, Cowboy, and Rebar3

Instead of returning the hello world, we're going to return the sum of two query parameter a, b.

$ curl "http://localhost:8080/?a=1&b=2"
3
$ curl "http://localhost:8080/?a=1&b=-100"
-99

All we need to do is modify the cowboy_handler. The simplest code that assume no error will be like this.

init( Req, State ) ->
    P = cowboy_req:parse_qs(Req),
    { _, A } = lists:keyfind(<<"a">>, 1, P ),
    { _, B } = lists:keyfind(<<"b">>, 1, P ),
    Sum = integer_to_binary( binary_to_integer(A) + binary_to_integer(B) ),
    Req_1 = cowboy_req:reply( 200,
        #{<<"content-type">> => <<"text/plain">>},
        Sum, Req ),
    {ok, Req_1, State ).

Well, it's not bad. But I want to deal the the error.

Suppose, the users forget the query parameters.


$ curl "http://localhost:8080/"
$ curl "http://localhost:8080/?a=1"
$ curl "http://localhost:8080/?b=1"

If this happend, our code failed the pattern match because lists:keyfind returns false.


{ _, A } = false,

In such cases, I want to reply with the helpful error messages like this.


$ curl "http://localhost:8080/"
Error: missing query parameter a, b.
$ curl "http://localhost:8080/?a=1"
Error: missing query parameter b.
$ curl "http://localhost:8080/?b=1"
Error: missing query parameter a.

We can do condional branching with either case expression or function pattern match.

Another type of error is although the query paramters are present, it has a string that cannot be parsed as an integer.


$ curl "http://localhost:8080/?a=abc&b=123"

I would like to reply with helpful error messages in this case too.

After consdering the various code, I come up with this code. It's too verbose and ugly but I think alternatives are worse.

init( Req, State ) ->
    P = cowboy_req:parse_qs(Req),
    A = lists:keyfind( <<"a">>, 1, P ),
    B = lists:keyfind( <<"b">, 1, P ),
    { Http_status_code, Answer } = process( A, B ),

    Req_1 = cowboy_req:reply( Http_status_code,
        #{&lt;&lt;"content-type"&gt;&gt; =&gt; &lt;&lt;"text/plain"&gt;&gt;},
        Answer, Req ),
    { ok, Req_1, State }.

process/2 is set of function that ultimately returns { integer(), iodata() }. Here is the verbose code.

%% for missing query parameters.
process( false, false )     -> { 400, <<"Error: missing query parameter a, b.\n">> } ;
process( false, _ )         -> { 400, <<"Error: missing query parameter a.\n">> } ;
process( _, false )         -> { 400, <<"Error: missing query parameter b.\n">> } ;
%% for invalid query parameters
process( badarg, bardarg)   -> { 400, <<"Error: invalid query parameter a, b.\n">> } ;
process( badarg, _ )        -> { 400, <<"Error: invalid query parameter a.\n">> } ;
process( _, bardarg)        -> { 400, <<"Error: invalid query parameter b.\n">> } ;
% lists:keyfind succeeded.
process( { _, A }, { _, B } ) ->
    process(
        try binary_to_integer( A ) catch error:badarg -> badarg end,
        try binary_to_integer( B ) catch error:badarg -> badarg end
    ) ;
% no invalid query parameter. return the result.
process( A, B ) ->
    { 200, { integer_to_binary( A + B ), <<"\n">> } } .

The -spec attribute for this process/2 is abomination.

-spec process(
    { bitstring(), bitstring() } | false | badarg | integer(),
    { bitstring(), bitstring() } | false | badarg | integer()
)  -> { integer(), iodata() }.

Well, at least, I understand the error handling of Erlang.

2020-04-13

Erlang, Cowboy, Rebar3によるHello World HTTPサーバーのチュートリアル

本記事では、Erlang, Cowboy, Rebar3によるHello worldを出力するHTTPサーバーの実装方法を解説する。

目的は、このプログラムを実行中に、以下のような挙動になることだ。

$ curl "htttp://localhost:8080/"
hello,world

ErlangもCowboyもRebar3も、情報が極めて少ない。しかも公式ドキュメントすら間違っている。公式ドキュメントすら間違っているのには理由があり、実際の実装とドキュメントに差がでているのだ。Erlangは変化の少ない言語ではあるが、それでもOTP17からmapが追加されたりと言語的に少し変わっているし、mapの追加により、cowboyも以前ならproplistsを使っていた部分でmapを使うようになり、しかも2.0でAPIかなり破壊的な変更が入り、2.5からはモジュールの構成も少し変わってしまった。Rebar3は本当にひどい。名前が示すように、すでに破壊的な変更を2回経ている。そして技術的負債の塊だ。

この記事で解説する程度の知識を得るのに私は公式ドキュメントと何ヶ月も格闘するはめになった。公式ドキュメントですらこうなのだから、非公式なドキュメントは本当に参考にならない。ここに書いてあることは2020年の時点では正しいが、来年はわからない。

準備

Erlang実装とRebar3が必要だ。CowboyについてはRebar3がダウンロードしてくれるので考えなくてよい。

Debian系のディストロでErlangをインストールする。

$ apt install erlang

GNU/Linuxでrebar3をインストールする最も信頼できる方法は、自前でビルドすることだろう。

$ git clone https://github.com/erlang/rebar3.git
$ cd rebar3
$ ./bootstrap

これで"rebar3"というファイルができるので、このファイルをPATHの通ったディレクトリにコピーするかシンボリックリンクをはればよい。

ln -s rebar3 /usr/local/bin

これで準備が完了した。

プロジェクト作成

まずrebar3を使ってプロジェクトを作成する。名前を"hello_server"としよう。

$ rebar3 new release hello_server
$ cd hello_server

このコマンドで"hello_server"というディレクトリが作成される。その中にはテンプレート生成されたファイルがいくつかある。重要なものだけ説明する。

"hello_server/rebar.config"は設定ファイルで、cowboyの依存を追加するために編集する。

"hello_server/apps"ディレクトリにはアプリケーションが配置される。rebar3のreleaseプロジェクトはumbrella projectと呼ばれていて、複数のアプリケーションを持つことができる。

"hello_server/apps/hello_server"はrebar3がテンプレートから生成したアプリケーションだ。このディレクトリ内には"src"ディレクトリがあり、3つのファイルが作成されている。"hello_server_app.erl", "hello_server_sup.erl", "hello_server.app.src"だ。

"hello_server_app.erl"はapplication behaviourを実装するソースファイルだ。

"hello_server_sup.erl"はsupervisor behaviourを実装する。今回は編集しない。

"hello_server.app.src"はapplication resource fileを生成するためのソースファイルだ。Erlang VMをどのように実行するかということを設定するためのファイルだ。rebar3はこのファイルから実際のapplication resource fileを生成する。このファイルも編集する。

Cowboyを依存に追加

Cowboyを依存に追加してrebar3にダウンロードしてもらう。そのために"hello_server/rebar.config"を編集する。

$ vim rebar.config

最初の数行は以下のようになっている。

[erl_opts, [debug_info]}.
{deps, []}.

[relx, [{release, {hello_server, "0.1.0"},
...

今回編集するのは2行目、つまり"{deps,[]}."という部分だ。このlistのなかに依存を記述していく。記述のフォーマットは様々だが、すべて"{ package_name, ...}"という形のtupleになっている。このチュートリアルではパッケージをhex.pmからダウンロードしてくるので、フォーマットは"{ package_name, "version number"}"になる。本チュートリアルを執筆時点で、最新の安定版のcowboyのバージョンは2.7.0だ。


{deps, [
    {cowboy, "2.7.0"}
]}.

rebar3は依存ライブラリが必要になった時に自動的にダウンロードするが、今回は正しく記述できていることを確認するために明示的にダウンロードしてみよう。

$ rebar3 upgrade

次に、アプリケーションリソースファイルを編集して、cowboyを先にスタートさせるようにする。今実装しているアプリケーションはcowboyを使っているので、cowboyを先にスタートさせておかなければならない。その設定方法として、"hello_server.app.src"を編集する。

$ vim apps/hello_server/src/hello_server.app.src

このファイルの中身を抜粋すると以下のようになっている。


{application, hello_server,
  [...
  {applications
    [kernel,
     stdlib
    ]},
  ...
  ]}.

applicationsのtagged tupleの中のlistに"cowboy"を追加する。

{application, hello_server,
  [...
  {applications
    [kernel,
     stdlib,    % カンマを忘れないこと
     cowboy     % この行を追加
    ]},
  ...
  ]}.

これはErlangのlistなのでカンマを忘れないようにすること。

HTTPサーバーの始動

容易が全て整ったので、HTTPサーバーを開始する。まず"apps/hello_server/src/hello_server_app.erl"を編集する。

vim apps/hello_server/src/hello_server_app.erl

このソースコードはrebar3によって生成されたapplication behaviourを実装するためのモジュールだ。start/2を変更して、HTTPサーバーを開始する。

start(_StartType, _StartArgs) ->
    hello_server_sup:start_link().

HTTPサーバーを開始してコネクションをlistenするには、まずcowboy用語でルートと呼ばれているものを設定する。これは特定のリモートホストやパスをcowboy_handlerに関連付けるための設定だ。ルートを設定するにはcowboy_router:compile/1を使う。この関数は引数としてcowoy_router:routes()型を取る。型は"[{Host, Pathlist}]"となっている。PathList型を展開すると、"[{Host, [{Path, Handler, InitialState}]}"となる。

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        { Host, [{Path, Handler, InitialState}]}
    ]),
    hello_server_sup:start_link().

ホストとして'_'を指定すると、任意のホストからのコネクションを受けつける。ホストを制限したい場合、例えばlocalhostからの接続しか受け付けたくない場合は、<<"localhost">>を指定する。

今回の場合、Pathは<<"/">>だ。今回は"http://localhost/aa/bb/cc"のようなPathは受け付けないのでこれでいい。

Handlerにはhello_handlerというatomを指定する。これは後でcowboy_handler behaviourを実装するモジュールとして実装する。

特に状態は持たないので、InitialStateは空のlistを使う。

すべてまとめると、以下のようなコードになる。

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        { <<"localhost">>, [{<<"/">>, hello_handler, [] }]
    ]),
    hello_server_sup:start_link().

ルートが準備できたので、HTTPリスナーを開始する。ここでは素のHTTPを使うので、cowboy:start_cear/3を使う。引数はstart_claer( Name, TransportOpts, ProtocolOpts )だ。

NameはこのHTTPリスナーを識別するための名前で、ErlangのTermであればなんでもよい。通常はatomが使われる。ここでは"hello_listener"を使う。

TransportOptsには様々なオプションがあるが、このチュートリアルではlistenするポートを指定するだけだ。今回はHTTPサーバーのポートはは通常80だが、今回は8080を使うので、"{{port, 8080}}"となる。

ProtocolOptsでは先程設定したrouteを指定する。ProtocolOptsの型はmapで、envというキーがあり、値はdispatch型だ。ここに先程束縛したDispatch変数を指定する。

成功した場合、start_clear/2は{ok, pid}を返す。okのtagged tupleに束縛することで失敗時のことはapplication behaviourにまかせよう。

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        { <<"localhost">>, [{<<"/">>, hello_handler, []}] }
    ]),
    {ok, _} = cowboy:start_clear(
        ello_listener,
        [{port, 8080}],
        #{env => #{dispatch => Dispatch}}
    ),
    hello_server_sup:start_link().

接続の処理

HTTP listenerの用意が出来たので、やってきた接続要求を処理していく。そのためにはさきほどのhello_handlerを実装しなければならない。これはcowboy_handler behaviourとして実装する。まず新しいソースファイルを作成する。

$ vim apps/hello_server/src/hello_handler.erl

まず基本的なところを埋めていこう。

-module(hello_handler).
-behaviour(cowboy_handler).
-export([init/2]).

init( Req, State ) ->
    {ok, Req, State}.

Reqはリクエストとレスポンスを保持している。Stateは好きに使える状態だが今回は使わないので空のlistとする。

やるべきことは、HTTPステータスコードとして200を返し、ヘッダーのcontent-typeとしてはtext/plainを指定し、コンテンツは"hello,world"とするだけだ。これにはcowboy_req:reply/4を使う。引数の型は"reply(Status, Headers, Body, Req)"だ。

StatusはHTTPステータスコードで型はnon_reg_integer()もしくはbinary()だ。今回は200を指定する。

HeaderはHTTP headerをmap()で指定する。今回は"content-type"を"text/plain"にする。

Bodyには<<"hello,world">>を指定する。

Reqは現在のReqオブジェクトだ。

replyは新しいReqオブジェクトを返す。これ以降Reqオブジェクトを使う際には、この新しいReqオブジェクトを使わなければならない。

init/2のコードは以下のようになる。

init( Req, State ) ->
    Req_1 = cowboy_req:reply(
        200,
        #{<<"content-type">> => <<"text/plain">>},
        <<"hello,world">>,
        Req
    ),
    {ok, Req, State}.

プログラムの実行

$ rebar shell

確認しよう。

$ curl "http://localhost:8080/"
hello,world

次はErlangのエラー処理について書こうと思う。Erlangのエラー処理はその場で処理を中断して無視していい場合は簡単だが、エラーに明示的な対処が必要だととたんに面倒になる。

2020-04-07

Walkthrough of hello world HTTP server with Erlang, Cowboy, and Rebar3

This is the quick walkthrough of implementing and executing a HTTP server that just return hello world by using Erlang, Cowboy and rebar3.

The goal is, while executing this problem, the following happens.

$ curl "htttp://localhost:8080/"
hello,world

Erlang and Cowboy is easier compared to the god-forsaken rebar3. Rebar3, as its name indicates, had major backward incompatible breaking changes twice, and it still has many technical debt piled up on it. Even the official documentation is unhelpful at this time. I wasated months just figuring out the basics and I write it down here so you don't have to.

Prerequisites

You need Erlang implementation, rebar3. The cowboy can be fetched by rebar3.

To install erlang on debian-based distro:

$ apt install erlang

To install rebar3 in most GNU/Linux distros, you should built it yourself.

$ git clone https://github.com/erlang/rebar3.git
$ cd rebar3
$ ./bootstrap

This create a file "rebar3". You can copy this file to somewhere in the PATH or symlink it.

ln -s rebar3 /usr/local/bin

Now you're ready to start using the rebar3.

Creating a new project.

First, you must create a new rebar3 project. Let's call it "hello_server".

$ rebar3 new release hello_server
$ cd hello_server

This command create a directory "hello_server" and bunch of template files in that directory. I don't explain everything in details, but just for the important bits.

"hello_server/rebar.config" is a config file we have to modify to add cowboy as an dependency.

"hello_server/apps" directory contains apps. rebar3's release project is called "umbrella project", it can contains multiple "apps".

"hello_server/apps/hello_server" is the default apps the rebar3 generated from the template. Inside that directory, there is a "src" directory which contains three template files. "hello_server_app.erl", "hello_server_sup.erl" and "hello_server.app.src".

"hello_server_app.erl" is a source file we modify.

"hello_server_sup.erl" is for implementing supervisor behaviour. We don't modify this file in this walkthrough.

"hello_server.app.src" is a source file for application resource file. It tell the Erlang VM how to start the application. Rebar3 just copy it to the appropriate place so you don't have to. We modify this file too.

Adding cowboy as an dependency

Next, we need to add cowboy as an dependency so the rebar3 can fetch it. To do so, open the "hello_server/rebar.config".

$ vim rebar.config

The first few lines are like these.

[erl_opts, [debug_info]}.
{deps, []}.

[relx, [{release, {hello_server, "0.1.0"},
...

We need to modify the second line, that is "{deps, []}.". You can add dependencies in the list. There are many formats for that but every thing is tuple of "{ package_name, ... }". In this walkthrough, we fetch the package from hex.pm. So the format shall be "{ package_name, "version number"}". As of this writing, the latest stable version of cowboy is 2.7.0.


{deps, [
    {cowboy, "2.7.0"}
]}.

rebar3 fetch the necessary dependency automatically when it is needed, but let's just fetch it explicitly to make sure we wrote it correctly.

$ rebar3 upgrade

Also, we need to modify the application resource file to start cowboy before our application. Since our application requires cowboy, the cowboy application must be started before our application. To do so, modify the "hello_server.app.src"

$ vim apps/hello_server/src/hello_server.app.src

The part of the content of this file should looks like this.


{application, hello_server,
  [...
  {applications
    [kernel,
     stdlib
    ]},
  ...
  ]}.

We add "cowboy" to the list.

{application, hello_server,
  [...
  {applications
    [kernel,
     stdlib,    % don't forget comma
     cowboy     % add this line
    ]},
  ...
  ]}.

As you see, this is Erlang's list so don't forget the comma before cowboy.

Fire up the HTTP server

Now we're going to start the HTTP server. First, we modify the "apps/hello_server/src/hello_server_app.erl".

vim apps/hello_server/src/hello_server_app.erl

This source code is generated by rebar3 to implement the application behaviour. We are going to modify the start/2 to fire up the HTTP server.

start(_StartType, _StartArgs) ->
    hello_server_sup:start_link().

In order to start the HTTP server listening the incoming connection, we first need to set what cowboy call it "route". It's a mapping of the connection from some remote hosts, path to cowboy_handler. To do that, we use cowboy_router:compile/1 which take a parameter of type cowboy_router:routes(). The type is "[{Host, PathList}]", if you expand the PathList type, it'll be "[Host [{Path, Handler, InitialState}]]".

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        { Host, [{Path, Handler, InitialState}]
    ]),
    hello_server_sup:start_link().

The Host can be '_' which means we allow the connections from any hosts. If you are to allow connection from anywhere, use '_', if on the other hand, you want to restrict the access only from, say, localhost, it would be <<"localhost">>.

The Path in our case is <<"/">>. Since we don't support path like "http://localhost/aa/bb/cc".

For Handler, we specify "hello_hander" atom which we have to implement it as a cowboy_handler behaviour later.

We don't use state so the IinitialState be emply list.

Putting all togather so far, the code looks like this.

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        { <<"localhost">>, [{<<"/">>, hello_handler, [] }]
    ]),
    hello_server_sup:start_link().

Now we prepared the route, we're going to fire up the HTTP listener. We are going to use good old plaintext HTTP by cowboy:start_clear/3. The three parameters are "start_clear(Name, TransportOpts, ProtocolOpts)".

Name can be any Erlang term to refer this listener, but atom used used most of the time. Let's use "hello_listener".

TransportOpts has many options, but for this walkthrough, we only need to set the port to listen to. We going to listen port 8080 so it would be "[{port, 8080}]".

In ProtocolOpts, we use the route we made earler. The type of ProtocolOpts is a map which as a key env whose value is also a map which has a key dispatch. We pass Dispatch for the value of this key.

If succeeded, start_claer/2 return "{ok, pid}". Let's make sure it returns ok and fail otherwise.

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        { <<"localhost">>, [{<<"/">>, hello_handler, []}] }
    ]),
    {ok, _} = cowboy:start_clear(
        ello_listener,
        [{port, 8080}],
        #{env => #{dispatch => Dispatch}}
    ),
    hello_server_sup:start_link().

Handling the incoming connections.

Now the HTTP listners are up and running, we need to implement the hander for the incoming connections. For that, we need to implement the hello_handler we specified earlier by following the cowboy_hander behaviour. Create a new source file .

$ vim apps/hello_server/src/hello_handler.erl

Let's write the basics.

-module(hello_handler).
-behaviour(cowboy_handler).
-export([init/2]).

init( Req, State ) ->
    {ok, Req, State}.

Req represents requests and response. We don't use State really. It's just an empty list.

All we need to do is return a HTTP status code 200, the content-type is text/plain, it's content is "hello,world". We can do that by cowboy_req:reply/4. The parameters are "reply(Status, Headers, Body, Req)".

Status is a HTTP status code in non_neg_integer() or binary(). In this case, it's 200.

Header is a map() to specify HTTP header. we set it's "content-type" to be "text/plain".

For the Body, we return "hello,world".

Req is a current Req object.

reply return a new Req object which we must use it instead of old Req objects after the call.

And now, the init/2 code.

init( Req, State ) ->
    Req_1 = cowboy_req:reply(
        200,
        #{<<"content-type">> => <<"text/plain">>},
        <<"hello,world">>,
        Req
    ),
    {ok, Req, State}.

To run the program

$ rebar shell

Now to confirm it.

$ curl "http://localhost:8080/"
hello,world

If I have in the mood, I'll write the error handling next. The reality is more verbose than textbook.

2020-04-04

2019-2020シーズンに行ったスキー場の感想

2019-2020シーズンは腕も上達したし雪が少なかったこともあって普段は行かない様々なスキー場に行った。ここにその感想を簡潔にまとめておこうと思う。

まずは白馬にあるスキー場からだ。2月上旬というハイシーズンに行ったはずなのに、あいにくとほとんどの日は雪質がわるかった。

栂池高原スキー場は白馬にあるスキー場だ。白馬駅からバスで行ける。特徴はゴンドラでふもとから山頂まで一気に上がって長距離を滑ることができる点だ。とはいってもあいにくの暖冬でふもとは雪質が悪かったので、ゴンドラの中間駅まで滑ってゴンドラを往復していた。

白馬コルチナスキー場は白馬にあるスキー場だ。朝早くの行きは白馬駅から電車とバスで、帰りはバスになる。白馬はパウダーキチガイのオーストラリア人で占拠されているので、開き直ってコース外のほとんどを自己責任で滑走可能なエリアとして解放してしまったスキー場だ。コースのどこからコース外に出てもふもとの同じ場所に帰ってくることができるので、コース外を滑るには適しているスキー場と言えるだろう。白馬コルチナスキー上の横には白馬乗鞍温泉スキー場があり、共通リフト券が買えるのだが白馬コルチナスキー場からは接続が悪かったので買う価値はわからなかった。

白馬五竜とHAKUBA 47は2つのスキー場が併設されているがリフト券も共通なので実質一つのスキー場だ。白馬五竜のほうはなだらかで広いゲレンデがあり雪質の悪さと相まって面白さがわからなかったが、HAKUBA 47はなかなか面白かった。

次に赤倉温泉のスキー場だ。周辺にはもっとスキー場があるのだが、今回は2つしかいかなかった。この暖冬の3月上旬にもかかわらず雪が豊富にあった。もっとも、例年はもっと雪が多いらしいのだが。

赤倉温泉スキー場は赤倉温泉の宿が密集する場所の近くにある。スキー場としては初心者向けでほとんどなだらかなコースしかない。一箇所だけ急なコースがあるのだが、そこに上がるリフトが今にも壊れそうでとても怖い。あまりにも簡単すぎるスキー場だったので、初日の足慣らしや最終日の疲れた足でのんびり滑る分にはいいが、連日でいく価値は見いだせなかった。

赤倉観光リゾートスキー場は赤倉温泉スキー場のとなりにあり、相互に連絡できるが、リフト券は別だ。こちらはとても面白いスキー場で難しいコースもあり、連日行く価値があった。ゴンドラで上がって4km滑ることができるのもよい。

これで今シーズンは滑り納めにしようと思っていたのだが、3月24日に越後湯沢にそれなりの雪が降ったので、25日に急遽日帰りで向かった。今年のかぐらは周りのスキー場が雪不足に悩む中、標高が高くて雪があるということで大勢の客がいる上、ゲレンデまでロープウェイで上がらなければならない。しかも2019年の大型台風19号の影響で下山コースが破壊されており、帰りもロープウェイに乗らなければならない。待ち時間が数時間にもなるおそれがあり、行きたくない。ちょうどコロナウイルスが騒がれていた頃でもあったので、人が密集するロープウェイも避けたい。

そこで、神立スノーリゾートに行った。このスキー場、去年までは神立高原スキー場という名前だったはずなのだが、なぜか名前を変えている。別にリゾートと言うほどの規模のスキー場ではない気がするし、周辺にホテルが密集しているわけでもない。

スキー場自体の作りは小さいながらもよい。リフトに一本乗って2km弱ぐらいのなだらかなコースを滑ることができるし、非圧雪もあるし、きれいに形成されたコブ斜面もあり、万人の需要を満たす作りになっている。

2020-03-29

村上原野(ボレロ村上)の思い出

村上原野(ボレロ村上)の思い出を色褪せないうちに書いておこうと思う。

村上原野の父親であり師匠であった猪風来は縄文土器による芸術家である。縄文土器の制作方法を復元した人物だ。

猪風来プロフィール | 美術館の紹介 | 猪風来美術館

縄文土器は窯を使わずに野焼きで焼き上げる。野焼きで窯ほど燃焼温度が上がらないので、低温でも焼き上がるような粘土を使わなければならない。その製法は再発見され、村上原野が縄文土器作成を学ぶ頃には、一通り完成していた。製法を復元した上で、その製法を使って芸術品を作るというのだ。

聞いた話では、猪風来は極めて形から入る芸術肌の人間で、縄文人の心を理解するために、北海道に竪穴式住居をこしらえて家族で住んでいた。つまり、村上原野の父親と母親と本人は中学生か高校生ぐらいまで北海道の竪穴式住居に住んでいたのだ。

竪穴式住居とは歴史の教科書にも出てくる様式の原始的な家だ。地面を掘り下げ、その上に屋根を設営する家だ。竪穴式住居は全国にあるのだが、北海道のような寒い地方では、寒さ対策のために地面をかなり深く掘り下げる。猪風来がかつて展示会で語っていた話では、竪穴式住居の中で座ると、ちょうど目の高さが地面すれすれになるほどだという。そうして猪風来は縄文人の心を会得した。

その後、村上原野の一家は岡山の廃校に引っ越す。廃校を作品制作の作業場と作品の保管所と美術館として利用している。

村上原野はそのような特殊な家庭環境にもかかわらず、当初は高専を卒業し、確か本人の話では製図技師か何かで数年、民間で働いていたそうだ。ただし本人曰く「やはり土をいじっている方が楽しい」ということで仕事をやめ、家業をつぐことにしたのだという。

村上原野のいでたちは、かなりガッシリとした体格で、よく日焼けしていて、母親の作った作務衣を着ている。どこから見ても偉丈夫であり、刺しても死なないほどの健康な見た目であった。

このブログの読者が知る村上原野は、ボレロ村上、もしくは中3女子という名前で知っている人物で、C++プログラマーだ。

https://github.com/bolero-MURAKAMI/Sprout

Sproutは村上原野によるC++ライブラリであり、C++におけるコンパイル時計算用のフレームワークを提供している。

このSproutを使った村上原野の作品としては、コンパイル時レイトレーシングがある。

constexpr レイトレーシング - ボレロ村上 - ENiyGmaA Code

当時の純粋なテンプレートメタプログラミングのみのレイトレーシングや、あるいはC++11時代のまだ本体はreturn文ひとつしか書けなかった頃のconstexpr関数を使ったレイトレーシングがある。

あるいは、コンパイル時音声生成がある。

constexpr で音階生成&シンセサイザー&音声合成 - ボレロ村上 - ENiyGmaA Code

生前の村上原野に、C++によるこの作品は芸術なのかと聞いてみたことがあるが、彼にとってこれらは芸術ではないらしい。

村上原野 aka ボレロ村上, 中3女子 逝去

ボレロ村上、中3女子ことC++プログラマーで陶芸家の村上原野の訃報が流れている。それによるとどうやら、2月16日未明に、陶芸作品を製作中に倒れ、翌朝に発見されたようだ。

2月15日の21時51分のtweetに体調の変化を示唆する書き込みがある。倒れたのが16日の未明とあるので、そこから6時間後ということになる。

この書き込みから急な脳梗塞ではないかと思われる。体調の変化を感じたら病院に行くべきなのだろう。

大一報はおそらく猪風来美術館のFacebookで、これは20日に公開されたとのことだが、我々プログラマーの界隈に知られるまでに9日間を要したようだ。

岡山にある猪風来美術館は村上原野とその両親が経営している廃校を利用した美術館と製作所のはずで、すぐにでも岡山に行きたい気持ちがあるのだが、あいにくと世間にはコロナウイルスが流行している。行けば至近距離で会話をしたくなるだろうから、東京に住んでいる身としては軽々と訪れることができない。早くコロナウイルスが収束してほしい。

ゲンヤよ!

2020年2月16日未明、おまえは32歳という若さでこの世を去った。最後の作品を制作中、倒れる直前粘土をひと掻きした跡そのままに、手に竹べらをもったまま息絶えた。きらめく魂、やさしい魂、躍動する魂よ、おまえのすべての命が燃え尽きたのだ。 力いっぱい、こんなに精一杯生きて、表現して、苦悩し、愛して、未来へ、新しい地平へ翔けていくはずだったおまえは、今力を尽くして、生命を生き切って、美しい魂の宿る作品を私たちに託して旅立っていった。

おまえの大きな縄文の渦はここから湧きあがり、おまえはその渦に乗りここから翔けあがり、おまえの愛した山や海や大地をめぐり、生まれ育ったアイヌモシリや遥かなアメリカの大地をめぐる。おまえの渦はしなやかに美しく螺旋を描き、無数の夢を乗せて伸びやかに繋がっていく。おまえが見た精霊たちは、今おまえの後を追って螺旋の渦をなし、ひきもきらさず列をなしている。

そして渦に乗ったおまえは何度もなんどもこの地に戻ってくるだろう。まわりの森の木々を震わし、みんなで協力して建てた竪穴住居の茅屋根を撫で、野焼きの野炉の灰を散らし、おまえやほかの人の作った縄文作品を愛で、いつも、どこでも残った私たちにおまえの記憶を喚起させるだろう。おまえの成し遂げた仕事、思索、大きな夢、愛する人たち、すべてがここにあったのだから。

おまえはここで新しいおまえの地平を切り開き生きていくはずだった。縄文のスピリットに惹かれ、現代に生きる己の感性で縄文の新時代の美を求めてひたすらに挑戦を続け、その手でやり遂げていく意欲に溢れていた。私たちは底のない悲しみの中、その夢を引き継ぎ繋いでいかなければと、今祈るような気持ちで歩み始めようと思う。

生前、村上原野を支え、愛し、共に力を携えて活動してくださった方々に感謝の思いでいっぱいです。これから私たちは心を寄せる人たちと共に彼の魂の宿る最後の作品を無事焼き上げます。そして彼の残した作品を新しい縄文芸術として世に提示していきたいと思っています。彼の縄文の渦はまだ終わっていないのですから。どうぞこれからもよろしくお願いいたします。

(猪風来・むらかみよしこ)

猪風来美術館 - ゲンヤよ!... | Facebook

2020-03-08

赤倉温泉スキー場に来ている

2月に白馬に2週間滞在してスノーボードと温泉三昧だった。白馬に2週間も滞在することになったのには長い話があるのだがまたの機会に書くとして、結果として、長期滞在して温泉に浸かりスノーボードをしてリモートワークをする価値に目覚めてしまった。3月も同じことをしたいと思ったので、人を誘って再び一週間の長期滞在をしてきた。

滞在先は赤倉温泉だ。詳しくは知らないが、この暖冬にもかかわらず全国のスキー場の積雪ランキング上位にあるスキー場だ。予約時に300cmの積雪があったので、これならば雪はあるだろうと宿を予約した。赤倉ホテルという宿だ。さぞ予約は取りづらいだろうと思っていたが、あっさりと予約を取ることができた。

宿はなかなかよかった。食事は悪くなく、宿の建物内に温泉が3箇所あり、しかも2箇所は24時間入り放題。そしてもう一つ露天風呂があり、これがやや特殊な完全な外に設置されている露天風呂で、涼しくて湯温も高く最高だった。この露天風呂、変わったことに混浴でかつ周りから丸見えなのだが、そもそもホテルにはほとんど客がいないので気兼ねする必要はなかった。ただし、例年では雪が高くつもり、完全に周囲から隠れてしまうそうで、本来は女性客も入りやすいそうだ。

肝心のスキー場だが、宿の目の前に赤倉温泉スキー場がある。当初、このスキー場にのみ行くだろうと思って、あらかじめリフト券を4日分手配しておいた。しかし、これは間違いだった。赤倉温泉の近くには赤倉温泉スキー場、赤倉観光リゾートスキー場、杉ノ原スキー場、池ノ平スキー場、関温泉スキー場がある。特に赤倉温泉と赤倉観光は隣り合ってつながったスキー場で、赤倉温泉スキー場は広くて簡単でつまらないコースばかりだが、赤倉観光リゾートスキー場の方は難しくて面白いコースが多かった。

まず移動日は滑らず、初日は赤倉温泉スキー場で足慣らし、白馬で2週間、1日滑って2日休むという筋肉を鍛えるのに理想的な頻度で滑っていたので、体には余裕があった。2日目に赤倉観光リゾートスキー場に行ったが、これまた前日の疲れがまったく気にならないほどの余裕があった。3日目は流石に連続しては辛いだろうと赤倉温泉スキー場でのんびりと滑ったが、これまた余裕があった。4日目は再びリゾートに行った。5日目は念の為に休みを入れた。膝は多少痛むが、危険な痛みではない。

これを書いている時点では土曜日だが、明日の日曜日に1日滑り、月曜日は余力があれば午前中に滑って帰ってこようと思っている。こんなにも膝と脚に余裕ができているほど体が鍛えられているとは自分でも驚いている。しかも、スノーボードの腕も上達している。白馬でスイッチができるようになったが、さらに滑走が安定した。

白馬での目的はスイッチだったが、今回の目的はGoProを持っている友人と一緒に言ったので、追い撮りと自撮りの上達を目標にした。そのために自撮り棒を購入した。結果は大成功だった。もっと難しいものだと思っていたのだが、自撮り棒を持っての滑走はほとんど滑走に影響を与えない。簡単であることがわかったので、GoProの来年のモデルが販売されたら購入を検討しようと思う。

今回使ったGoProはHERO 7だが、使う上での注意点がいくつかあった。まずGoProはバッテリーが持たない。リフト営業開始から終了までの丸一日の全滑走を撮影したいというのであれば、4K解像度や120FPS撮影は諦めた上で、予備のバッテリーを2つ以上持っていくのがよいだろう。逆に、事前に危惧していたSDカードの容量は全く問題がないことがわかった。今は512GBや1TBのSSDカードが数万円で売られている。動画のビットレートが90Mbpsであったとして、512GBあれば12時間は撮影できる計算になる。そしてGoProのバッテリーは1時間持たない。

GoProを撮影した後の注意点もある。GoProはSDカードのフォーマットにexFATを使っている。exFATのfuseではないマウントにはLinux kernel 5.4が必要だ。Ubuntu 19.10は5.3、Ubuntu 20.04が5.4になる予定となっている。

GoProが使う動画フォーマットはh.265(HEVC)の10bitプロファイルを使用している。この動画のリアルタイムデコードはとても重い。筆者はここ10年ぐらいCPUのパフォーマンスは十分すぎるぐらい向上したので、いまだにSkyLake世代のIntel CPUを積んだラップトップを今回の旅行に持参した。ところが、H.265 10bitのデコードのハードウェア支援はSkyLakeの次の世代のKirbyLakeが必要だ。KirbyLakeもそうだが、AMDやNvidiaのGPUのハードウェアデコード支援も、h.265 10bitに対応したのは2016年に販売された製品からだ。今回の撮影は2.7k 60fpsで行ったが、筆者のPCではリアルタイムデコードできなかった。前のフレームからの差分で表現するIフレームや、前後のフレームからの差分で表現するBフレームを多用するh.265の再生は、リアルタイムデコードが出来ない場合破綻する。そのために当初は単に映像を確認するためだけにffmpegでh.264にエンコードしていたが、いろいろと試した結果、ブラウザーを実行しない状態でmpvを使うとややフレームレートに違和感はあるものの、再生できることがわかった。

2.7k 60fpsでこの負荷なので、4K 60fpsはもっと負荷が高いのだろう。GoProで撮影した動画を編集するには最新の高スペックなコンピューターを容易すべきだ。最も筆者はffmpegのフィルターでできる以上の編集をするつもりはないのであまり気にしていない。今のところ考えている編集は動画の切り出しと連結、あとは別音声のmuxぐらいだ。今回撮影した自撮りと追い撮りはすぐにでも動画サイトにアップロードしたいのだが、現在滞在している宿のWiFiの帯域は20Mbps程度で2割程度のパケットロスが発生するという基本的人権がないほど貧弱な環境なので、自宅に帰ってからアップロードする予定だ。

追い撮りと自撮りについてだが、まず自撮りについては特に難しいことはなかった。単に自撮り棒をもって滑るだけだ。スノーボードは両手が自由なので様々な持ち方ができる。360度カメラではない自撮り棒に固定したカメラの場合、後ろ手で持って山側から谷側への撮影、前の手で持って谷側から自分を含む山側を撮影、前の手で持って谷側を撮影という方法が考えられる。全て試してみたが、どれも特性の違う動画ができあがる。

追い撮りは難しい。単に追いかけて被写体をフレーム内に納めるだけならそれほど難しくはないのだが、問題は距離だ。GoProは画角が広い。これは被写体をフレーム内に維持するという点ではいいのだが、実際の距離以上に被写体との距離感が出てしまう。被写体を大きく移すには近づく必要があるのだが、これも難しい。被写体は自分ではないので滑走の速度があわない。直滑走すると追い越してしまうし、丁度いい速度を保つのが難しい。撮影中、離されたので直滑走して追いつき、そして抜きそうになったので減速してまた離されることがたびたびあった。これは自分のショートターンの腕前を上げるほか、被写体と無線で連絡を取り、離されすぎた場合減速してもらうなどの連携が必要だろう。

もう一つ難しいのが、実際に見たとおりに撮影できないということだ。雪面は日光の反射で白飛びしてしまい、起伏が目立たなくなってしまう。かなり深いコブ斜面でもまるで圧雪されているかのようになだらかに見えてしまう。そして、傾斜も実際より浅く見える。これはカメラ自体が傾斜にそっているために仕方がないことではある。カメラを水平にすると撮影できるのはほとんど空だけだ。速度感も乏しい。カメラを高い位置で保持すると全く速度感がない。それなりの傾斜のある斜面を直滑走しても、雪面が白飛びすることと画角の広さのせいで、全然速度が出ているように見えない。速度感を出したければカメラを低い位置に置かなければならない。

また、今回は追われ撮りもためしてみた。これはカメラを後方に向けて滑り、被写体に追いかけてもらうことで、被写体を全面から撮影しようという試みだ。これはある程度はうまくいったが、なかなか難しい。減速やターンをするたびにカメラを左右に降ってしまうので、被写体はフレームに入るためにかなり努力して滑らなけれならない。直滑走すると被写体と撮影者の道具と技量と体重差によって速度差が出てしまうので破綻する。今回、私はスノーボードで友人はスキーだったが、私は毎回ホットワックスをしているが友人はスプレーワックスで済ませるズボラな人間であるのと、私が友人より20kg重いために、直滑走すると友人よりかなり相対速度が開いてしまう。それに、被写体一人だけで同じ姿勢を維持して直滑走し続ける動画はそれほど映像映えしないという問題もある。複数人でのレースのような面白さを追加する要素が必要だ。

手ブレ補正も一長一短がある。GoProの手ブレ補正はなかなかに優秀ではあるのだが、手ブレ補正をかけると滑走のダイナミックな動きが消えてしまう短所もある。

友人はスキーヤーなので、スキーでの自撮りや追い撮りを模索していたが、自撮りについては圧倒的にスノーボードのほうが楽だ。追い撮りもスキーでは細かい調整が聞かずに難しい。ヘッドマウントではカメラ位置が固定されてしまい、自撮り棒を動かすというダイナミックな撮影ができない。スキーで自撮り棒をもつと滑走が難しくなる。スノーボードでは手を固定して滑ることもできるが、スキーは手を動かしてバランスを取りたい特性があるようだ。

今回、自分の滑りを追い撮りしてもらう機会にも恵まれたが、やはり滑走中にバランスを取るために上半身をリーンする癖が抜けない。下半身の屈伸だけで十分にバランスをとれるところでは積極的に下半身を意識して使っていきたいところだ。

2020-02-16

C++20標準規格がほぼ固まった

2020年2月10日から15日までプラハで行われた会議により、C++20のDIS(Draft Intarnational Standard)が可決された。これはC++20となる標準規格と同じ文面であり、もうこれ以上変更はない。今後、このドラフト案に対して各NBによって可否の投票が行われる。何事もなければこのまま可決されてC++20が制定されるだろう。

今回残念なのはstd::formatだ。これはpythonにあるようなテキスト整形ライブラリだ。ただしロケールに依存している。std::formatのロケールを引数に取らないコンストラクターはグローバルなlocaleオブジェクトに依存する。今の所ロケールの影響を受けるのはtype specifier nで、数値を桁区切りにして出力する機能だ。

std::formatがlocale汚染されたことにより、std::formatは危なくて使えないライブラリになったし、ローカライゼーションの妨げになるので使ってはならないライブラリとなった。

10年前、char8_tの必要性を標準化委員会に説いたときはchar型は生のバイト列を表現するのに最適な型だなどととんでもない話を持ち出されて一笑に付されたが、その後にchar8_tの必要性は認識され、かつcharが生のバイト列を表現するのに不適切な型であることが認識され、std::byteが入った。

コルーチンも問題が多い。C++20に入ったコルーチンとはその名前で連想するようなユーザーモード実装の軽量スレッドではない。C++20のコルーチンとは3種類のキーワード、co_await/co_yeild/co_returnを使った関数をコルーチン関数と認識し、その関数に対してあらかじめ定められた変形を行い、最終的にユーザー定義のクラスの特定のシグネチャーのメンバー関数を呼び出す単なるシンタックスシュガーだ。変形ルールを考慮した上で自力でライブラリを実装すれば、例えばユーザーモード実装の軽量スレッドやジェネレーターやメソッドチェインやステートマシンや非同期I/Oといった機能を実現できる。ただし、コルーチンをサポートした標準ライブラリは存在しないので自力で実装する必要がある。そして自力で実装するのは極めてだるい。

コルーチンのためだけにコア言語にここまでユーザー定義クラスの特定のシグネチャが存在することを前提とした文法を入れるのは汚い。コルーチンのような機能は、静的リフレクションで実現すべきだ。

今現在、環境の変化でC++に時間を割くことができていないし、C++20本は出せるかどうかわからない。

2020-01-18

Erlangについて思うところ

職場の今までいた部署が潰れてしまったので、新しい部署で仕事のためにErlangを学んでいる。基礎的な文法については学び終わったので、現時点でのErlangについての雑感を書いておこうと思う。

Erlangは多数派のプログラミング言語とはだいぶ違う文法を持っている。終端記号がドットであることもそうだが、比較演算子もだいぶ違っている。多くの言語が!=を使うなか、Erlangは/=を使っている。Less than or equal toが=<であるのも多数派とは異なっている。ただし、Greater than or equal toは>=だ。一貫性がない。

終端文字はドットだが、関数の中には一つの式しか書くことができない。式はカンマで区切ることができるので、以下のようになる。

func() ->
    expr1 , % カンマ
    expr2 , % カンマ
    expr3 . % ドット

このような文法はリファクタリングの時に問題になる。というのも、例えば関数の戻り値をexpr3の評価結果に依存した別のものにしたくなったとき、

func() ->
    expr1 , % カンマ
    expr2 , % カンマ
    expr3 . % エラー
    expr4 .

うっかりドットをカンマに修正するのを忘れるとエラーになる。

そもそも関数の文法も問題だ。関数は同名の関数群をセミコロンで区切って一度に定義する文法になっている。

Name( P1 ) when ... ->
    expr ;
Name( P1 ) when ... ->
    expr ;
Name( P1 ) when ... ->
    expr . 

関数群の最後はドットで終端するが、途中の関数はすべてセミコロンで区切る。これは関数を定義する順番を変えたときに、手でセミコロンとドットを修正しなければならない。

Name( P1 ) when ... ->
    expr ;
Name( P1 ) when ... ->
    expr . % エラー、リファクタリング中の修正漏れ
Name( P1 ) when ... ->
    expr ; 

変数が再束縛できないのもコードを汚くする。というのは、結局現実のコードでは式を評価した結果を元に更に計算を行い、その結果を束縛し、途中の結果については参照しないコードがある。


R1 = expr1 ,
R2 = Do_something(R1) ,
R3 = Do_something2(R2) .

もちろん、途中の評価結果を変数に束縛する必要はないのだが、あまりにも式が長い場合は可読性のために途中でわかりやすい名前をつけたくなる。しかし、変数の再束縛が許されていないために、変数名に意味のある単語を使わない文化圏の怠惰な数学者がよく使うX'や、gitを使えないバカがよく使う2020-01-18プロジェクト企画書(最新)(第二項)(承認待ち).zipのようなひどい変数名を作り散らかす原因になる。

他にもガードにBIFしか使えないとか型がないとか型がないとか特に型がないとかいろいろといいたいことはあるし、ErlangはHaskellの爪の垢を煎じて飲んでほしいのだが、汎用プログラミング言語としてみたErlangは貧弱で、主要なプログラミング言語とは違う文法を採用し、しかも融通がきかない不自然な文法で、まことにつまらない言語だ。まるでGOやJavaのような言語と言える。

ただ、言語としてはそれほど難しい概念もないので、習得は容易だろう。

ただし、あらゆる点で言語としておそまつな点が目につく。最初はクソ言語と思っていたが、途中からこれはBrainfuckと同じエソテリック言語の仲間だと思えてきた。

そして基礎的な文法を一通り学び終えた今では、ついにあるひとつの結論に達した。Erlangは分散コンピューティング用のDSLなのだ。SQLとかシェルスクリプトと同じであって、汎用プログラミング言語として考えるからクソ言語だと思うのであって、特定の分野専門のDSLだと考えれば悪い言語ではない。汎用プログラミング言語として考えたとき、SQLやシェルスクリプトはいかにもクソ言語というしかない。しかし、SQLやシェルスクリプトの価値はそこにあるのではない。Erlangも同様に、たまたま汎用プログラミング言語としての機能を備えてしまっただけで、本来は単なるDSLであり、ツールでしかない。1980年台にネットワーク越しのリモートコンピューター群をあたかも一つのコンピューターを扱っているかのように扱えるようなツールを実現したという点で価値がある。

さて、Erlangの基礎的な文法は一通り理解したのだが、まだこれでErlangの習得が終わったわけではない。これからErlangのプロセスやメッセージパッシングなどを学ばなければならない。まだもう少し時間がかかりそうだ。

膝の痛みがなかなか治らない

スノーボードによる膝の痛みがなかなか治らない。

30を超えてから新しい運動を始めると悩まされるのが靭帯と腱の損傷だ。筋肉痛というのは数日で回復するが、靭帯と腱の回復には数ヶ月かかる。これまでにボルダリング、ダンス、スノーボードと新しい運動に挑戦し続けているが、そのたびに靭帯と腱を損傷している。

残念ながら今の日本語圏のインターネットにはまともな情報がないので、せめて自分の怪我の状況と回復時の自覚症状ぐらいは書き残しておこうと思う。

ボルダリングでは指の腱を損傷した。原因は単純で、足を滑らせて指だけで極端な荷重変化を支えてしまったのが原因だ。指の腱を損傷すると、指の曲げ伸ばしと手首、手首の下辺りに違和感を感じる。回復の自覚症状はかなり急峻だ。病院に行ったところ、抗炎症作用のある塗り薬を処方された。塗るとわずかに痛みが減る。最初の一ヶ月ぐらいはほとんど回復が見られず絶望的になるが、ある日を境に1日単位で違和感が減っていく不思議な自覚症状の変化が現れた。

ダンスでは足首が痛くなった。つま先を上げる方向に足を動かすと、足首が痛くなる。医師の診断によるとアキレス腱を痛めたそうだ。一ヶ月ほどダンスを中断して、痛みがやや収まったものの、依然として残るので病院に行ったところ、処方はロキソニンテープとジクロフェナクNa(鎮痛抗炎症剤)とレバミピド(胃薬)とアセトアミノフェン(解熱鎮痛剤)であった。薬の鎮痛効果により痛み自体は軽減されるのだが、痛みがなくなるわけではなく、回復して痛みが減ったのか、単なる鎮痛効果で痛みがわかりにくくなっているだけなのか判断に困る。そのまま更に1ヶ月ほどは自覚症状は変わらなかったが、ある時を境に急激に1日単位で症状が軽くなっていった。

そして今悩まされているのが膝だ。原因はスノーボードだと思われる。ダンスで膝を痛めなかったのはよくわからない。いかにも膝に負担の掛かりそうな動きもしたのだがダンスでは問題がなく、スノーボードに1日行っただけで極端に膝を痛めてしまった。

当初は右膝の内側に痛みがあったのだが、今は左膝も少し痛み、かつ膝の外側にも痛みがある。膝の内側の痛みしか自覚症状がなかったときに医者にかかったところ、膝関節内側側副靱帯(MCL)を痛めたのだろうということだ。処方は足首と同じだ。

肝心の治療経過だが、一ヶ月経過した今、まだはかばかしくない。未だに痛みが残っている。当初は階段を上がるととても大きな痛みがあったが、今は階段を上がるぐらいでは痛みはでない。当初は膝に負荷をかける動きをすると痛みが出ただけで、安静にしていれば痛みはなかったのだが、今は膝に負荷をかけても痛みはそれほどないが、常に膝に違和感を感じている。この安静時の違和感は安定せず、痛みがないときもあれば、痛むときもある。自覚できる痛みがないからとうっかりと地下鉄の階段を上がってしまった翌日は痛みが出ている気がするので、膝への負荷に遅延して安静時の痛みが生じているのかもしれない。

靭帯と腱の回復には2ヶ月かかるという個人的な経験則からすると、回復にはまだ一ヶ月かかる計算になる。スノーボードのシーズンは短い。特に今年は雪が少なく例年より短くなるだろう。

この記事をここまで書いてから2日立った。たまたま膝の調子が良かったのでボルダリングに行ったところ、回復の兆しを感じた。翌日も痛みがあまり膝に残らない。

改めて考えてみると、今まで靭帯や腱を痛めたときの痛みの自覚症状は、いつも同じような状況だ。まず受傷直後はそれほど痛くない。翌日から数日も痛みはあるもののそれほど痛くはない。ただし、少しでも負荷がかかったならば危険な痛みを感じるので運動はできない。その後一ヶ月以上、運動を完全に控えても痛みが収まらない状態が続く。多少の負荷をかけても当初感じた危険な痛みはないのだが、やはり痛みはあるので運動はできない。このような状態が一ヶ月以上続いて絶望するが、ある時急に回復の兆しを感じる。そうすると少しぐらいは負荷を書けても痛みは感じなくなり、運動も様子を見ながら再開できる。そして、不思議なことに運動をすると回復が早まる。

2月にはスノーボードに復帰できるかもしれない。

2020-01-05

2020年の日本には2020年にふさわしい日本語の掲示板がない

情報の流通において最も効率的なのはテキストだ。テキストを効率よく流通させる方法として、古典的なインターネットにはメール、チャット、掲示板があった。

このうち、メールは古典的なEメールがまだ生き残っている他、現代的なSNSがメールの機能を代替し始めてきた。日本では今の所LINEが最も普及しているようだ。

チャットもそうだ。古典的なIRCはまだ生き残っている。しかし現代的なSNSや、Slackのようなサービスが代替し始めてきている。

では掲示板は? 現代の日本には現代的な掲示板サービスが欠けている。

もちろん、掲示板機能を提供するWebサービスはたくさんある。しかし、日本語圏でWebサービスを提供しているものは、いずれもかなり限定的な目的に特化したものだ。例えばユーザー同士で質問と回答をしあうサービス(Yahoo知恵袋など)とか、ソーシャルニュースアグリゲーション(はてなブックマーク)のようなサービスはある。しかしテキストの流通機能としては貧弱であり掲示板ではない。

2ch/5chのような古典的な掲示板はある。しかし見たところ技術的負債と開発リソースの不足により、ほとんど当時のまま運用されているようだ。2020年に使いやすい作りではない。

私の考える2020年の品質の掲示板とは、RedditやHacker NewsのようなWebサービスだ。どちらもソーシャルニュースアグリゲーションだ。そういう意味でははてなブックマークはとてもいい線を行っている。しかしはてなブックマークは掲示板ではない。単に1行コメントが書けるだけで、他人のコメントを参照してテキストを積み重ねることができない。はてなブックマークはソーシャルニュースアグリゲーションというよりはオンラインブックマークとして設計されているので、結果として掲示板にはならなかった。

結果として、日本には2020年にふさわしい現代的な掲示板がない。ないということはどこかが作れば儲かるのではないかと思う。誰かがやってほしい。

Arch Linuxがパッケージ圧縮フォーマットをxzからzstdに変更

Arch Linux - News: Now using Zstandard instead of xz for package compression

Arch Linuxがパッケージの圧縮に使うフォーマットをxzからzstdに変更した。

Archでは圧縮レベル20を使うことにより、xzにくらべて0.8%サイズが増加するが、デコード速度が1300%向上するという。

CanonicalによるUbuntuは2018年にzstdに移行するテストをしていて、その結果による、圧縮レベル19を使うことにより6%のサイズ増加だったということだ。

zstdとはFacebookのYann Colletが2016年に発表した圧縮フォーマットとそのリファレンス実装のことだ。軽く調べてみたところ、メモリ使用量が多く並列実行に力を入れている設計と実装のようで、現代のコンピューター向けという感じがする。

2020-01-04

未来のタクシーはネットカフェになる

深夜にのんびりとRedditを眺めていたところ、以下のような1年前の記事が話題になっていた。

Mean streets: Self-driving cars will "cruise" to avoid paying to park

内容はこうだ。自動運転が実用化されたならば、車は駐車せずに自動運転で周辺を運転するようになる。なぜならば、燃料費と摩耗費よりも駐車料金のほうが高くつくからだ。

たしかに一理ある。都市部の駐車料金は高い。なぜなら土地が高いからだ。自動運転により人件費がなくなれば、後は「車の燃料費と摩耗費<駐車料金」であるならば車を運転し続けたほうが安い。

この考えを推し進めると、将来、タクシーはネットカフェになる。

ネットカフェは簡易的な個室とインターネット、マンガや映画を提供している。貧乏人はネットカフェを簡易宿として利用している。これらネットカフェの機能は、自動運転による無人タクシーで代替できる。

つまりこうだ。都市部を自動運転による無人タクシーが流している。客はこのタクシーを呼び止め中に乗る。中にはフラットに倒すことのできる椅子とコンピューターと携帯電話網によるインターネットが提供されている。またマンガや映画のストリーミングサービスも提供されている。客がネットカフェ機能を利用している間、この無人タクシーは周辺、あるいは指定した目的地まで運転する。この無人タクシーは簡易宿としても利用できる。客は椅子をフラットに倒して寝ることができる。その間もタクシーは周辺を運転する。

荒唐無稽だとも思えない。現実のネットカフェは、土地と建物を用意するのに大掛かりな費用がかかる。しかも場所は固定で、車のように柔軟ではない。

どの程度現実的なのだろうか。車の摩耗費、メンテナンス費用、通信費用、コンテンツ契約費は償却して無視するとしよう。後に残るのは燃料費だ。現在、日本のガソリン価格はレギュラーが146円/Lだ。最新のハイブリット車は20km/Lを上回る燃費を持っている。

ただ、このネットカフェとしての無人タクシーにおいて、燃費というのは「距離/燃料」ではない。本当の燃費は「時間/燃料」だ。このネットカフェとしてのタクシーは走行をしなくても常時電力が必要なので、停止していても燃料を消費する。運転は燃料消費を最小にするが、走行距離を最大にする必要はない。たとえ信号や渋滞や燃料補給によって都合よく停止している時間が長くても、燃料消費が少なければ問題はない。

もしガソリン1リットルで1時間の燃費(時間/燃料)があるのだとしたら、1時間あたり146円の費用がかかる。

あるいは、蓄電池を搭載した完全電動車とすることもできる。この場合、無人タクシーは充電拠点の周辺を運転することになる。

都心部のネットカフェの料金と比較してみよう。都心部のネットカフェの相場は、30分で300円、3時間で千円、6時間で2千円、12時間で3千円程度だ。自動運転による運転手の人件費のかからない無人タクシーとしてのネットカフェは物理ネットカフェと同じ料金で利益を出せそうだ。

では肝心の駐車場の料金はどうだろう。都心部の駐車場の料金はまちまちだが、無人タクシーは場所の利便性を考えなくてもよい。利便性の悪い場所にある駐車場は、都心部であっても夜中は500円といった安いところもある。長時間利用する客を乗せた無人タクシーは、安い駐車場が空いているのならば駐車場を使い、そうでなければ道路を燃費(時間/燃料)のよい運転で流すのがよいだろう。

高度な自動運転が実用化され、このようなネットカフェとしての無人タクシーが大量に公道を流すようになると、公道が渋滞して社会問題になるはずだ。しかし法改正は技術開発よりも時間がかかるはずで、このような未来はありうるのではないか。

2019-12-18

江添自宅ボドゲ会@12月22日

以下の要領で12月22日に自宅ボドゲを開催します。

https://ezoe.connpass.com/event/159944/

今回はコルトエクスプレスのもう一つの方の拡張がしたい。

かぐらスキー場に行ってきた

12月15日に2019-2020シーズン2回目のかぐらスキー場に行ってきた。すでにオープン2日目の12月1日に行っていたのだが、その時は地面が露出していて、板が傷ついてしまった。

エッジの傷はファイルで研摩した。ベースの傷は白い線がはいっているだけで、それほど深くはなさそうだが、ファイバーテックスでこすったぐらいでは取れないようだ。諦めて上からホットワックスをかけた。

2週間膝を休めて15日に再び滑りに行った。当初の予定では14日からガーラ湯沢、石打丸山、舞子といった里のスキー場がオープンする予定だったが、雪不足のために延期していたので、かぐらが混むかもしれない。しかし年内に3回は行きたいことを考えると、今行かなければならない。

始発の上越新幹線で越後湯沢につくと、バス乗り場にはかなり長い列ができていた。バスには全員乗れたが、満員であった。これではみつまたの狭い更衣室が満員になるのではないかと思ったが、更衣室は意外と空いていた。

チケットの購入もそれほど並んではいなかった。

ゴンドラの待ち時間が30分ほどはあった。

今回のかぐらスキー場の客層は、オープン時とはだいぶ異なっていた。オープン時の客層は遠方から来ていて、ウェアの身なりもよく、言葉遣いも丁寧で、たまたまリフトやゴンドラで一緒になろうものなら自分がいかにスキー、スノーボードを愛しているかを問わず語りする種類の人間であった。

ところが15日のかぐらスキー場の客層はひどい。まず身なりが良くない。道具も手入れされておらずエッジ付近にベースバーンの出た板をそのまま使っている。言葉遣いもひどいもので教養のかけらも感じられない。ましてやリフトやゴンドラから漏れ聞こえてくる話はパチンコとセックスばかり。どうやらローカルが多いらしい。

特にひどいのはタバコだ。所構わずタバコを吸うし、あまつさえ滑りながら吸う大ばかものもいる始末。リフトに乗っている最中にもタバコの匂いがしたことさえあった。まだ日本にそんなバカが残っていたのかと驚きさえ覚える。もはや地方に未来はない。

さて、みつまたエリアからかぐらエリアへのゴンドラに乗ろうと道中を滑っていた所、ゴンドラ直前の傾斜で違和感を感じて転倒した。なぜかプロテクターをつけているはずの膝に擦りむいたような衝撃が走る。みると、ピスラボが露出している。しかしカチカチに凍った雪もある。膝のプロテクターをつけていてよかった。最悪に近い状態の斜面をなんとか滑り降りてゴンドラへ。

かぐらエリアにつき、さっそく一本滑ったが、やはり膝が痛む。痛みはなくなったと思ったがまだ早かったのだろうか。しかしここまで来た以上帰るのももったいない。しかし膝は痛む。とりあえず下に降りようと傾斜の極めて緩いゴンドラコースを滑ったところ、膝は傷まない。速度も出せる。楽しい。なるほど、膝の痛む理由が分かった。自分のレベルにあっていない難易度のコースを滑ったからだ。傾斜が厳しく、圧雪もされていないコースを滑り降りるために、強く減速しながら降りてくるために、膝に負担がかかっていたのだ。減速をしなければ膝への負担は軽い。

その日は7本ほどゴンドラコースを滑り、さらに何本かみつまたで滑った。どうやら傾斜20度程度ならば減速せず半ば直滑降、半ばカービングで楽しく滑ることができるようだ。

肝心のスタンス設定だが、やはりスタンス幅56cmは私の体格には長すぎたようだ。今回48cmにしてみたが、だいぶ滑りやすい。56cmのときは膝を極端に内股にしてようやく安定するが、48cmではそのようなことをする必要がない。ただ、流石に少し狭すぎるような気がしたので、次は50cmを試してみたい。

スタンス角であるが、メインのスタンスで+21/+9と+15/-9の違いは実感できなかった。スイッチではダックスタンスのほうがいくぶんか楽に滑ることができるようだ。千シーズンではスイッチはできなかったが、連続ターンがかろうじてできるところまで練習した。しかしスイッチでカービングができないし、直滑降をする勇気も出ない。

翌日、右足に筋肉痛があったが、前回よりは程度が軽く、2日で治った。筋肉痛が治ると、今度は膝の痛みが出てきた。安静にしていると問題はないのだが、地下鉄の階段を登ると痛む。痛むというよりはかゆい。病院に行ったところ、しばらくは運動を控えるべきだと言われたので、次のスノーボードは来年まで控えることにした。

スノーボードの最適なスタンス設定を求めて

前回、スノーボードで膝の靭帯を痛めたが、どうにも解せない。膝を痛めるような過度の負荷をかけるような滑り方はしていないはずだ。そしてグラトリやパークのようなはるかに膝に負荷がかかりそうな運動をしている人でも、膝を痛めていない人がいる。どうもおかしい。健康な人間の靭帯の強度というのはそれほど変わらないはずだ。ましてや片足スクワットが連続してできるほど鍛えた今年、数百メートルおきに休憩するような滑り方でこんなに膝を痛めるのはおかしい。

そこで私は、バインディングの設定に問題があるのではないかと考えた。

スノーボードのバインディングは様々な調整ができる。バインディング自体の調整と、スタンスの調整だ。

スタンスには、スタンス幅とスタンス角がある。

スタンス幅は2つのバインディングの中心部からの長さのことだ。一般に、長いと安定性が増し、かつ板をたわませたり回す力も少なくて済む、ただし膝に負担がかかる。短いと不安定になるし板をたわませたり回す力もより必要になるが、膝への負担が少ないとされている。

一般にグラトリやパークをする人はスタンス幅を長めに設定し、速度を出してカービングする人はスタンス幅を短めにするとされている。また身長の大きな人ほど体格に合わせて長いスタンス幅にするようだ。

私のボードのスタンス幅のリファレンスは56cmあった。膝への負担を軽減するためにスタンス幅を狭くすることにした。板の最も内側のビス穴を使い、かつベースプレートでも幅を狭めることにより、スタンス幅を最短で48cmまで狭くすることができた。まずこれで滑ってみて、あまりにも狭いようであれば現地で調整することにしよう。

スタンス角は大雑把に分けて3種類の設定がある。フォワード(18-27/0-12)、極端にフォワード(30-45/21-35)、ダック(+/-)だ。

前回は初めてダックスタンスを試してみようと+12/-9をためした。極端に強いダックスタンス(+15/-15以上)は後ろ足の膝に負担がかかるという説もある。前回のダックスタンスはそこまで極端でもないので、ダックスタンスで膝を痛めたとは考えにくい。とりあえず次回はカービングをしたいので前向き(21/6)に設定してみた。

バインディング自体の調整としては、ハイバックの傾きを設定するフォワードリーン(forward lean)、ハイバックの位置を変更するロテーション(rotation)、つま先の足置き場の長さを調整するトゥランプ(Toe ramp)がある。

フォワードリーンをいれるとハイバックと靴の間の遊びがなくなり、エッジを立てるときの反応がよくなるが、遊びがないのでわずかな動きもエッジに伝えてしまい操作性が寛容ではなくなる。ロテーションは極端なスタンス角に設定した時に、ハイバックの位置をずらしてボードに対してより平行に当たるようにする目的がある。トゥランプはブーツのつま先が乗る場所だ。

プロのスノーボーダーのスタンス設定をみても、ばらつきが大きすぎて参考にならない。身長とスタンス幅は比例しているように見える。女性のほうがダックスタンスの角度が狭い傾向にある。デモンストレーターには極端なフォワードスタンスがいるが、ハーフパイプやジャンプ競技をするプロはダックスタンスが多い。

少し検索すると以下のような論文が出てきた。

INFLUENCE OF STANCE WIDTH AND BINDING ANGLES ON TIBIAL ROTATION AND OLLIE JUMP HEIGHT IN SNOWBOARD

スノーボードのスタンス設定には科学的な根拠が一切ない。そこで科学的に計測をすることで、膝への負荷の低さとパフォーマンスの観点から最適なスタンス設定を見つけ出す目的で行われた実験である。

実験内容はこうだ。10人のスノーボード上級者に、スタンス幅がshank length(膝から足首までの長さ)と±5cmの3通りと、スタンス角が+30/+15、+18/-15の2通りの、組み合わせで6通りのスタンス設定でオーリーしてもらい、その状況を全身にモーションキャプチャーのようなトラッキングマーカーをつけて計測する実験だ。ジャンプした高さと脚の可動範囲を測定し、スタンス設定のパフォーマンスと脚への負担の影響を調べようという実験だ。

実験結果から言うと、あまり意味のあるデータは得られていないようだ。ジャンプの高さの差は最大で3.6cmだったが、標準偏差が30%もあり、あまり意味がない。もっとサンプル数を上げればましになるだろうか。ただダックスタンスでスタンス幅の広いほうが若干高さが上がる傾向が見られた。

足の可動範囲についてはスタンス幅の影響はみられず、スタンス角の影響は若干観測できたが、やはり標準偏差が大きすぎる。受傷を防ぎやすいスタンス設定については何もわからなかった。

というわけでいろいろとスタンス設定を変えて滑ってみたので、その結果を次に書く。

2019-12-14

Outer Worldsでコンパニオンが死んでいないのに死亡したと認識されるバグ

https://twitter.com/_taylorswope/status/1205252714680045568

今日、#TheOuterWorldsのパッチ1.2をリリースした。これには「ゲームがコンパニオンを死んだとみなす」バグの修正も含まれている。このバグは俺のキャリアで最も長い時間を費やしたデバッグ作業となった。

このバグの概要は、一部のプレイヤーで、コンパニオンクエストが失敗とクエストログにでる。その理由はコンパニオンが死んだからだ。しかし字祭にはコンパニオンは死んでいないにもかかわらずだ。

これは解せないもので、というのも超新星モードでもなければ、コンパニオンは死なないからだ。

リリース前に1度か2度だけこの問題が発生したが、QAチームは再現できなかったので、その原因を特定することはできなかった。

原因の特定が困難だった理由は、どこで問題が発生しているかわからなかったことだ。問題が発現したすべての例で、10時間以内に問題が起こったのでクエストが壊れたらしい、ぐらいしかわからなかった。

この問題の調査にはすべてのスクリプトとコードで、コンパニオンが死亡すると認識する場所を洗い出す必要があった。

論理的に考えて問題の原因箇所となりうる唯一のスクリプトが実行される状況は、コンパニオンのヘルスがゼロになったときだ。銭湯が終わるまで待ち、復活させる。それ以外の場合に、本当に死んだとマークする。

ゲーム中、コンパニオンが存在するがアクティブなパーティには加入していない常用というのは、船の中だけだ。問題は、コンパニオンが船の中にいるときは、ダメージを受けないはずなのだ。

「ダメージを受けない」というのは「死なない」という意味ではない。攻撃によってダメージを受けないが、他の要素ではダメージを受ける。そのうちの一つは、とても高い距離から落下するというものだ。

問題は、船の中には落下死できる場所はない。そこで、今度はなぜコンパニオンがそんな高い場所に移動するのかということを突き止めなければならなかった。

大量の仮説を考えた。「もしかしたらファストトラベルで他のマップに移動したとき時に位置データが維持されているのではないか」とか「もしかしたら2人のコンパニオンが衝突した時に物理演算によって上方向に加速したのではないか」

個人的にお気に入りの仮説は、「コンパニオンがランダムイベントで牛がスポーンする場所に立っていて宇宙に打ち上げられるのではないか」 だ。仮説が否定されたときはちょっと落ち込んだものだ

そしてゲームがリリースされたが、たまたま発生した本来起こりえない不具合だったという希望は打ち砕かれた。世界中のプレイヤーがコンパニオンクエストが失敗したぞと報告し始めたからだ。

最終的に、ユーザーのレビューの中にあった何気ないコメントに、コンパニオンが虚空を登っているという変なバグを見たというものがあり、このコメントによって問題箇所の特定ができた。

開発上、NPCが周りとインタラクトするシステムは、「家具」とよばれている。これは文字通り椅子に座ると言った家具であることもあるが、端末使用とか壁に寄りかかるといった動作もすべてそうだ。

家具システムの奥深いところに、プレイヤーが会話中は、すべてのNPCに新しい家具インタラクションを無効化するコードがあった。

問題は、ハシゴの使用は2つの異なる家具インタラクションになっていた。一つはハシゴに取り付いて登る動作、もう一つは登るのを辞めてハシゴから降りる動作だ。

そのため、誰かがハシゴを登り始め、停止する前にプレイヤーが会話に入った場合、ハシゴから降りることができず・・・まあ、その・・・

なかなか笑えるバグだ。

2019-12-08

違法な職務質問をされたので東京都を訴えた裁判の控訴審は棄却、理由は突然に

職務質問裁判の控訴は棄却された。判決文は以下から読むことができる。

https://github.com/EzoeRyou/calling-110-is-suspicious

2年前の7月3日、職務質問を受けた。

警察官に職務質問をされた話し

この職務質問は明らかに違法であると感じたので、弁護士に相談の上、東京都に対して国賠訴訟を起こした。警察官というのは各都道府県の下に位置する行政組織なので、警察を訴えるというのは、その警察の所属する都道府県を訴えるということになる。

一審判決は請求棄却。理由としては、「最初の10分間は不審事由がないが、刃物などの危険物を入れることができるリュックを背負っていたから声をかけ10分間その場にとどめて話をするのは違法ではない。このとき110番通報を要請したことは不審事由にあたりその後の1時間20分の職務質問は不審事由が存在するために合法である」というわけのわからない判決が出た。

そんな判決は受け入れがたいので控訴した。その控訴は11月14日に判決があり、公訴棄却となった。

公訴棄却の判決文は一審判決に対する差分という形で書かれている。gitでバージョン管理してほしいところだ。110番通報の要請は不審事由に当たらないという至極当然の変更が行われた。築地の往来を歩く当時の私に不審事由は存在しないが、10分間声を書けるのは違法とまでは言えないという部分は維持された。

今回追加されたのは「突然」という理由だ。突然私がその場から立ち去ろうとした、突然話を打ち切った、警察官の制止を振り切ろうとした、突然警察官のいない方向に走った、などという文が追加され、これは不審事由に当たるとされた。

これもおかしな話だ。最初の10分間だけでも、一歩でも足を動かそうものなら警察官2人がかりで抱きつかれてその場に止められたし、話というのも私から切り出さなければなにもなく、ただ最初から荷物の中身を見せろという要求をひたすら繰り返すだけであったし、私はわざわざ「そこを通してください。あなたは動く必要はありません。私が迂回します」と言って動く意思を事前に表明したし、その上で警察官は拳銃を装着している右腰を私に押し付けて「あ、拳銃に触った」などとわざとらしく声を上げたりした。最後の突然警察官のいない方向に走ったというのは事実なのだが、実は東京都の主張ではそのようなことはなかったことになってる。むしろ私の方から主張したのだ。これはさぞかし不審事由だろうから当然書き付けてくるだろうと思った所ない。弁護士によると、私が自発的に応じたということを強調したいがためにわざと省いたのだろうということであった。これだけを見ても東京都の主張には嘘が多い。走った後はすぐに私有地の駐車場に押し込められて、大勢の警察官に囲まれて私有地の駐車場内に監禁されたような状態になった。

さて、真実がどうであれ、高裁判決で認定された事実は事実となる。高裁判決の事実認定が覆ることは原則的にない。日本の裁判は三審制ということになっているが、最高裁への上告は事実関係について争うことはできない。上告は憲法違反や、従来の判例が適用できないような状況の時に行う。

それでは今回の件はどうかというと、弁護士によれば、あるそうだ。

判決文では、警察法2条1項の「警察は、個人の生命、身体及び財産の保護に任じ、犯罪の予防、鎮圧及び捜査、被疑者の逮捕、交通の取締その他公共の安全と秩序の維持に当ることをもつてその責務とする。」と定めているとし、職務質問の条件を満たさない場合においても警察の諸活動は強制力を伴わない任意手段による限り、一般的に許容されるべきもので・・・有形力の行使であっても必要性、緊急性に応じて・・・具体的状況下の下で相当と認められる限度において許容されるものと解すべきであるとし、具体的な判例を挙げている。

その挙げられている判例であるが、これが今回の件にぴったり当てはまるかというと、実はそうでもない。というのも警察法2条1項に基づく、根拠規定のない警察の諸活動がどこまで許容されるかについてはあまり判例がない。というのもこの辺の解釈を要求する裁判など滅多に行われないからだ。裁判というのはとてもコストのかかる行為であり、わざわざ緊急時の警察官による有形力の行使の許容範囲の線引きを試みるような裁判は滅多に行われない。やるとするならば、他にいい方法がないので一か八か警察官による有形力の行使を違法だと認定させ、それによってその後の対応も全て違法であり無効化を狙ったものになる。

一つの判例は昭和50年(あ)第一四六号のもので、任意捜査に置いて許容される有形力の行使の限度について争ったものだ。

具体的に起こった有形力の行使としては、警察官から左手首を両手で掴まれたというものだ。これが許容されると認定された判例だ。

有形力の行使に至るまでの経緯はこうだ。車で道路脇に置かれたコンクリート製のゴミ箱に衝突する交通事故を起こした被告人は、顔が赤くて酒のにおいが強く、身体がふらつき、言葉も乱暴で、外見上酒によっていることが伺われた。そこで警察官は呼気検査に応じるよう要求したがこれを拒否。被告人は署内でマッチを課してほしいと要求し、警察官はこれを断った。被告人は「マッチを取ってくる」と言いながら立ち上がったが、警察官はこの公道を逃げ去るのではないかと思い「風船をやってからでいいではないか。」と言いながら左手首を両手で掴んだ。その後もみ合いに発展したというものだ。

これについて最高裁は、すでに事故を起こし、呼気検査拒否罪があるので本来ならば現行犯逮捕される状況にありながら警察官の配慮により逮捕をしていなかった状況で、警察官は逃げ去ると思って手首を掴んだのでこれは許容される有形力の行使である。その後被告人は警察官を殴っているが、これは公道の自由を実現するためにしたやむをえないもので正当防衛であるので暴行罪も成立しない。法は逮捕勾留されていないのであれば「何時でも退去できる」と定めているが、これは呼気検査を拒否して時間を稼ぎアルコールを身体から抜こうという被告人の公道が捜査に支障をきたすためであるので、署内のとどめたのも許容できるとしている。

この判例の具体的な状況と今回の状況はあまりにもかけ離れている。私は車を運転しておらず路上を歩いていただけで、路上の器物を損壊するなどの行為もなかったわけで、かつ職務質問をするべき不審事由も当初はなかったわけだ。この状況で声をかけ、抱きつくなどしてその場にとどめるのが許容されるべきではない。

もう一つの判例は昭和53年(あ)一七一七号のもので、交通の安全及び交通秩序の維持などに必要な警察の諸活動と警察法二条及び警察官職務執行法一条との関係について争ったものだ。

この事件のあらましはこうだ。警察はかねてから飲酒運転の多発地点とされている場所で一斉検問をしていた。この場所を通過する車両のすべてに停止を求めて、自動車検問を行った。この日1日の検問では被告人を含む酒気帯び運転5人を検挙した。被告人はそもそもこのような一斉検問は違法であり、違法な検問の違法な呼気検査によって収集された証拠は違法証拠であり、証拠能力がないと主張して裁判になった。

最高裁はこれについて、適法であると判断した。

今回の件は路上に検問を設けて通行人すべてを呼び止めていたものではない。警察の主張によれば、たまたま車で築地の道路を巡回中、私とすれ違った所不審(帽子を目深にかぶりうつむいて下を向いて歩いていた)を認めたのでパトカーを停車し、後を追い、自販機で飲み物を買っていた私に声をかけたということだ。この判例が今回の場合と何の関係があるのだろうか。

弁護士によれば、警察法2条1項が許容する範囲について新たな判例を残すのは、結果がどうあれ意義があることであるとのことだった。そこで上告することにした。

2019-12-07

Googleがブログ記事を検閲

私のBloggerのGMailアカウントに以下のようなメールが来ていた。

Hello,
Google has been notified that content in your blog contains allegedly infringing content that may violate the rights of others and the laws of their country. The infringing content that has been made unavailable can be found at the end of this message. For more information about this removal and how it affects your blog, please visit https://support.google.com/blogger/bin/answer.py?l=en&answer=2402711.


The notice that we received, with any personally identifying information removed, will be posted online by a service called Lumen at https://www.lumendatabase.org. You can search for the notice associated with the removal of your content by going to the Lumen page, and entering in the URL of the blog post that was removed. If you have legal questions about this notification, you should consult your legal advisor.

Terms of Service: https://www.google.com/intl/en/policies/terms/
Content Policy: https://www.blogger.com/content.g

The Google Team

Urls affected:
http://cpplover.blogspot.jp/2012/04/blog-post_9853.html

Countries affected:
Japan

またよくあるフィッシングメールかと思ったが、送信者はGoogleのBloggerのドメインで、実際に該当URLのブログ記事は検閲されている。

http://cpplover.blogspot.jp/2012/04/blog-post_9853.html

このブログ記事の内容は、2012年に千葉県八千代市の市役所の公式Webサイトにある内容を自分のブログである日新流山日聞 ™(現在消去されている)に違法にコピーしたとして著作権侵害の疑いで千葉県警サイバー犯罪対策課が同県八千代市米本の無職、****容疑者を逮捕した。容疑者は行為を認めているが違法ではないと主張していた。という報道を紹介し、容疑者のブログを示した上で、これはどうも本来ならば名誉毀損で民事で訴えるべきところを無理やり刑事にするために著作権侵害をでっちあげて別件逮捕したのではないかという見解を示し、その後著作権法を参照して、市のWebサイトには果たして著作権が認められるのか。仮に認められたとして、市役所のWebサイトの内容を著作権の例外である引用を超える範囲で利用することなどできるのか書いたものである。

この7年前の記事の内容になにか日本国内における権利を侵害する内容があるとは思われない。

しかし困ったことに、問題は検閲している相手はGoogleだということだ。Googleから人間のサポートを引き出すのは極めて困難だ。Googleの個人向け無償サービスから人間のサポートを引き出す方法は2つしかない。Google社員、しかも相当の重役、あるいはその該当のサービスを担当している部署の人間にコネを持つか、あるいはインターネット上で大炎上させて対応を余儀なくさせるかだ。いずれにせよ極めて強い影響力を持っていなければGoogleから人間のサポートを引き出すことはできない。

訴訟も容易ではない。まず費用が100万円ぐらいかかるし、Googleの日本法人は担当していないと主張されて逃げられる可能性がある。

とにかくなにか手を考えなければならないのだが、GoogleのBloggerに至っては、問い合わせ先すら容易に見つけられない。

2019-12-02

かぐらスキー場に行ってきた

11月23日のオープン初日にかぐらスキー場に行こうと計画していたが、あいにくの雪不足でオープン延期となっていた。その後もオープンのアナウンスもないので、11月30日は諦めていた。それに、ちょうど自宅でボドゲ会を開く予定もあった。

ところが、29日になって急に30日はオープンすると告知されていることに気がついた。しかしライブカメラをみるとまだ雪は多くない。それに滑走できると告知されているのはかぐら第1ロマンスリフトの範囲の滑走距離600m、幅20mの部分だけだ。幅だけみると軽井沢よりマシだが、距離は軽井沢の400mよりはマシだが大差がない。それに、みつまたエリアに十分な雪がない場合、とても悲惨なことになる。

悲惨なことというのはこうだ。みつまたからロープウェイで雪のないみつまたに上がり、歩いてみつまた第1高速リフトに乗り、そこから徒歩、ブラシ、あるいは今年から第二2ロマンスリフトで下ることでかぐらゴンドラまで移動し、ゴンドラに10分間乗り、ようやくたどり着いた場所で、たったの600m滑走できるということだ。

ところが天候に恵まれたらしく、30日の結果をみてみると、みつまたに雪があり、かぐらの第1高速リフトも可動しており、1500m滑走できるという。30日に滑った人の意見をネット上で探してみると、いずれも評価が高かった。天気予報を見ると翌日の日曜日は晴れ、月曜日からは雨の予報。これは滑りに行くしかない。明日の朝の早朝の起床に成功したら滑りに行こうと決意して急遽用意をし、早めに就寝した。

翌日の12月1日、予め設定しておいた目覚ましの喧しい鶏の鳴き声で起床。5時半に家を出ることに成功した。自宅からは20分ぐらいで東京駅につく。去年、日帰りの越後湯沢が圧倒的にお手軽だと主張してもあまり周りの賛同を得られなかったのは、皆東京駅から遠いところに住んでいるからだ。東京駅から越後湯沢駅までは70分。しかし、東京駅から自宅まで1時間以上かかるのであれば、交通時間は倍以上になるのでお手軽ではない。しかし、片道90分であれば、これは平均的な都心部労働者の通勤時間だ。十分にお手軽となる。

東京駅で予定通りに06:08分の始発新幹線に乗る。駅のホームではスワローテイルのスノーボードが立てかけたあった。持ち主は弁当でも買いに行っているのか見かけなかったが、上越新幹線に乗るということはおなじくかぐらに行くのだろう。

07:24に越後湯沢に到着。かぐらへのバスは07:50から片道20分。待ち時間も含めて40分ぐらいはかかる。駅直結のガーラ湯沢との差の40分だが、この時間の差によって、越後湯沢駅からかぐらに向かう人間は、ファーストトラックのパウダーを食いそびれる。東京駅で見かけた特徴的なスワローテイルの板の所有者もバス停にいた。

このバス停で、たまたま前に並んでいた人は饒舌な人で、本人の主張によると2歳からスキーをしているそうだ。何故か話題がとりとめなく変わる人で、発達障害か高次脳機能障害があるのではないかと思われた。また本人もしきりに、「あ、僕また変なことをいいましたか」と言う。話題がスキーに関連する以外は突然変わる以外は、その発言をしたときにはさほど変なことは言っていないことを考えると、本人に正確な自己評価ができていないことが伺える。曰く、「去年、「家族」が怪我をしたので今年は一人で滑りに来ている」、スキーヤーには珍しくヘルメットを持っていたが「去年からヘルメットを着用している」、「絶対に怪我をしてはならない」ということであった。まるで脳震盪でも起こして高次脳機能障害にでもなったのではないかという感想を持った。

もちろん怪我を防ぐためにプロテクターは重要だ。筆者はスノーボードなので、ヘルメットをはじめとして、尻、膝、肘、手首にそれぞれプロテクターを着用している。手首のプロテクターは新調した。去年は硬いカーボン板で補強された無骨なプロテクターを使っていたが、カーボン板と布の縫い付けが甘く1ヶ月でほつれてしまった。カーボン板には針が通らないので修理もできない。そこで、今年はBURTONの手首プロテクターを買ってみた。こちらは剛性の高いカーボン板ではなく、硬めのクッションと布を使っている。ミトンの中に装着できるので、プロテクターとグローブの間に雪が詰まることもない。

ミトンも新調した。去年は五指を使う必要があるだろうとグローブを買ったが、バインディングを占める程度では五指は必要なく、トイレやヘルメット着脱、財布から現金を取り出すと言った作業ではグローブを外さなければならなかったので、グローブは意味がなかった。

背中と肩を保護する上半身用の着るプロテクターを買うかどうかは迷ったが、今回は買わなかった。いずれパークに挑戦する時に買うかもしれない。

越後湯沢駅周辺や、バス乗車中の道を眺めていると、ある程度雪が積もっている。これは期待できそうだ。

さて、みつまたについて、10分以上着替えに費やした。何しろプロテクターの数が多いのだ。どうせ東京もそれなりに寒いのだから、今度日帰りするときは自宅からプロテクターとウェアを装備した上で移動してもよさそうだ。

さてみつまたからロープウェイでゲレンデに上がる。なんとみつまたも全面雪で覆われていた。さっそくスノーボードを装着し、リフトまで向かおうとするが、これが難しい。雪が硬すぎる上に、体がうまく動かない。去年スノーボードを始めたばかりなので、滑り方を覚えているかどうか心配だったが、案の定滑り方を忘れている。なんとかみつまた第1高速リフトにたどり着いて乗る。待ち時間はほとんどない。みつまたを滑っている人もいるが、こんなに雪が硬くては滑りづらい。やはりゴンドラにのってかぐらエリアに向かうのがいいだろう。リフトを降りると、雪はある程度柔らかかった。これなら滑ることができる。かぐらに行くには、短いがかなり傾斜のある部分を滑らなければならない。ここが辛かった。うまく連続ターンできない上に、土踏まずがとても痛む。なんとかゴンドラにたどり着く。ゴンドラはとても空いていて、私一人で乗ることになった。ゴンドラの中で靴を脱いで足を休める。するとだいぶ楽になった。久しぶりだから慣れていなくてつらいのだろう。前日に一度靴を履いて足を慣らしておくべきだったと後悔した。

かぐらエリアについたので、ロマンスリフトではなく高速リフトで上に上がる。かぐらエリアのコースは、基本的に非圧雪だ。唯一圧雪されているコースも、左側が3分の1ぐらい圧雪されているだけだ。リフトから滑っている様子を眺めていると、圧雪側をすべるときのエッジの音が極めて激しい。まるで氷の上を削りながら滑っているようだ。すでに滑った同乗者によると、圧雪側は完全に凍っていてとても滑りづらいとのことであった。では非圧雪側はどうかというと、凸凹だらけだ。ただし同乗者によるとふかふかだという。

私は非圧雪側を滑ることにした。去年ある程度滑ることができたはずなのにうまく曲がれない。速度も出せない。非圧雪面なので転んでも全く痛くはないのだが、起き上がる時に手のひらが沈みこんでしまいなかなか起き上がれない。一本目をほうほうの体で滑り終えた。どうしたものか。全く楽しくない。完全に滑り方を忘れている。やはりスノーボードの趣味は失敗だったのか。

その心配は、2本目を滑る時になくなった。どうやら滑り方を思い出してきたらしい。内股にして膝を近づけ、板を湾曲させるようにするととてもよく曲がれる。荷重と抜重の感覚も戻ってきた。これなら滑ることができる。非圧雪は滑りづらいが、去年の最後にかぐらでコブレッスンを受けていたのが役に立った。滑ることができる。楽しい。今回はダックスタンスを試してみようと+12/-9にした。あまりにも角度が広すぎると膝を痛めるとのことでこうしたのだが、まだ余裕があるようなので、次は+15/-12も試してみようと思う。そして、ブーツ、バインディング、板が全体的に柔らかい気がする。もっと上達したら、来年は硬い道具を買い揃えてみたい。

ただし足が疲れる。今年はダンスを練習していたので足も鍛えられていたかと思ったが、どうやら下腿部はかなり鍛えられているが、大腿部は鍛えられていないようだ。数百メートル滑ると休まなければならない。そして呼吸にも違和感がある。標高が高いので空気が薄いのだろうか。

この日は私は数百メートルおきに休みながら滑ることにした。この日のかぐらはかなり空いていた。リフト待ちはほぼなく、とくに午後になってくるとリフトを相乗りすることすらなくなった。人がいないので座っていてもまったく迷惑にならない。何しろ本当に人がいないのだ。リフトを降りたところでも数人しかいない。疲労のために仰向けになると背中が冷たい。背中を保護するプロテクターは防寒用に買うのもありではないか。

1日の終わり頃になってくると、かなり滑りが上達してきた。ただし、ヒールエッジが苦手だ。転ぶときは必ずヒールエッジのようだ。少し速度が出た状態でヒールエッジ側でターンをすると転んでしまう。状態は起こしているはずなので、どうもエッジを立てすぎているのが問題ではないかと思う。しかしエッジを立てすぎないのは難しい。

スイッチは逆で、トゥエッジで曲がることができない。もう少し緩斜面で練習をしたいところだが、残念ながらかぐらエリアに緩斜面はリフト付近にしか存在しない。それも斜面と言うよりはほぼフラットに近い。傾斜がなさすぎる。

やがて15:30になりかぐらエリアのリフトが止まった。かぐらからみつまたに戻るコースは閉鎖されているので、ゴンドラで戻る。今日は疲れたのでもうこのまま帰ろうと下山を目指したが、なんとみつまたは傾斜が強すぎず弱すぎない最適な緩斜面だった。あれほど疲れていた足でも速度を緩めずにカービングターンができる。なるほど、かぐらエリアは傾斜が強すぎる上に非圧雪だから難しかったのだな。

下山コースは台風19号の影響で途中の橋が壊れたらしく閉鎖中だ。ゴンドラで降りて帰路につく。大変に満足した1日だった。来てよかった。雪質も想定以上によかった。ただし、ところどころ草木や地面が露出しているところがあった。

20時に帰宅。そこから2時間道具の手入れ。かぐらは楽しかったし、満足したし、後悔はしていない。ただし板の消耗が激しい。雪は汚れていなかったのでベースに汚れはなかったのだが、硫化アンモニウムを大量に使っているはずで、まず水洗いした。ベースに去年2ヶ月滑って累積したよりもひどい傷がついている。草木や地面をこすったからだろう。p-texで埋めるほどの傷ではないが目に見える傷だ。そしてエッジにも傷が入っている。エッジに傷が入ったのは初めてだ。ヤスリで磨き、硬いホットワックスをかける。トップデッキには傷が入っていないようだ。いっそのこと、板が壊滅的に壊れてくれれば、次の硬い板を買う踏ん切りもできるものだ。今年は板を乗り潰すつもりで練習しよう。

そして翌日、心配していた膝はそれほど問題がないようだ。問題は右足の大腿四頭筋が強烈な筋肉痛になっていることだ。スイッチで滑ることができないのと、大腿部の筋肉が十分に鍛えられていないのが原因だろう。次のオフシーズンでは大腿部の筋トレをするべきだろう。

このまま膝に問題がなく、筋肉痛が治り、雪の状態が良ければ、7日にもう一度滑りに行くつもりだ。

ちなみに東京から日帰りする費用としては、新幹線代が12520円、バス代が980円、早割リフト券が3500円、ロッカー代が500円。スキー場の食事は食べられたものではないので食事はしなかったが、自動販売機で飲み物を合計1000円は購入した。道具をすべて持っているとしても日帰りで1万8千500円ぐらいはかかることになる。本格的にシーズン入りして、事前に計画した場合は旅行会社の割安のツアーを使うことで1万4千円程度には抑えられる。スノーボードにはカネがかかる。

2019-11-29

江添ボドゲ会@11月30日

江添ボドゲ会、今月は11月30日。今回はポータル非協力ケーキ獲得ゲームを買った。夜からはぶりしゃぶ。

https://ezoe.connpass.com/event/156214/

2019-11-28

CADDiのC++勉強会#9

CADDiのC++勉強会が12月3日に開催される。応募は以下から。

C++勉強会 #9 - connpass

今回はコンセプトについて学ぶ。コンセプトはコア言語としては6ページぐらいしかない極めて小さい機能だ。コア言語としては誠に小さい機能なのだが、その威力は絶大だ。コア言語としてのコンセプトを理解するのはそれほど難しくないが、正しくライブラリとして設計するのは難しい。

2019-11-25

ダンスを学んで半年たった

ダンスを学んで半年たった。始めた頃はリズム感もなくルーチンも覚えられず散々だったが、最近はリズム感も向上し、ルーチンも覚えられるようになり、ダンスレッスンをまともに受けられるようになった。

次に突き当たった壁は、手足が独立して同時に動かないという問題だ。これはどうも独立して動くようになるまでひたすら訓練するしかないようだ。今は少しづつ改善されてきている。

今抱えている問題は、体が十分に正確に動かないという問題だ。リズムには合わせているし、その場で振りも覚えられるのだが、速いビートに体がついていかない。これはどうもリズム感ではなく単純に体が動かないようなので、体を鍛えるしかないとは思うのだが、なかなかそうはいかない事情がある。靭帯だ。

筋肉痛は数日で回復する。しかし靭帯の回復には1-2ヶ月を要する。どうもダンスは足首にかなり負荷がかかるらしく、ダンスを初めて2ヶ月目に足首の靭帯を痛めてしまった。完全な回復にはダンスのレッスンを控えて2ヶ月かかった。

今通っているダンススクールは定額でレッスン受け放題なので、時間があればダンスのレッスンを受けたいのだが、足首や膝の靭帯の調子を考慮しながら、適切に休息を入れなければならない。日常生活では違和感がなくても、ダンスのような強い負荷をかけると違和感が出ることもあるので、ダンスレッスンを受ける前には一度強い負荷をかけてみて調子を確認している。

また、ダンスレッスン用の靴を買い替えた。最初に買った靴はジョギング用のソールが薄くて柔らかい靴だったが、今の靴はソールが分厚くて硬い靴にした。

靭帯への負荷を減らすためには靭帯周りの筋肉を鍛えるのもいいが、やはり減量もするべきだ。ダンスはかなりの有酸素運動なので減量効果があるだろうかと期待していたが、今の所ダンスでは痩せていない。

今月はこの調子で行くと20コマぐらいのダンスレッスンを受けられそうだ。ダンススクールの月謝が1万2千円なので、レッスン一回あたり600円ということになる。往復の交通費に340円かかっているので、ダンスレッスンに必要な費用の3分の1は電車賃だと言える。