先月はECMAScript 2015 (ECMAScript 6)が採択され、また、WebAssemblyが発表された。多分これらは現代のWebプログラミング言語の歴史に残る出来事だろう。しかし、ここ10年ぐらいのJavaScript/ECMAScriptの歴史と背景事情みたいのをまとめた文章のようなものをあまり見かけないので、ちょっとだけ書いてみることにする。(というよりは「ちょっとだけ調べてみた」の方が適切。あんまりまとまってないし)
Xy-picとdvisvgm
Macの受信メールから自動でリマインダーを作成する
何日までに○○しなさいというメールが届いた!けどほったらかしておいたら期限を過ぎていた!そういう経験、あるよね?
そこで、そういうメールが届いたら自動でMacの「リマインダー」に登録されるようにしよう!という話。
続きを読む
豊穣圏の教科書
最近、豊穣圏(enriched category)という概念に触れることがあって、それの標準的な教科書って何かなあと思ったら、G.M.Kelly “Basic Concepts of Enriched Category Theory”というのがそれっぽくて、しかも無料でPDFをダウンロードできるらしい。
MacLaneのCWMには豊穣圏の名前といくつかの例は出てくるけどちゃんとした定義は出てこない。まあ、ちゃんとした定義を書こうとするとモノイド圏(monoidal category)の定義をしてうんたらしないといけないようだが。
豊穣圏というのは(今の自分の理解で)大雑把に言うと、圏のhom-setに単なる「集まり」以上の構造が入ったものである。例えば、加群の圏には、それぞれのhom-setにアーベル群の構造が入っているので、アーベル群の圏 Ab でenrichされた圏の例となっている。
別の例を挙げると、各hom-setにゼロ射が入っている圏は、それぞれのhom-setに点つき集合の構造(ゼロ射が基点)が入っているとみなせる。つまり、ゼロ射を持つ圏は、点つき集合の圏 Set* でenrichされた圏と言える。
各hom-setに構造が入っていればいいというものではなくて、Ab-enriched categoryだと射の合成が双線形、Set*-enriched categoryだとゼロ射(hom-setの基点)を合成するとゼロ射、という風に、合成の方にも条件が付いてくる。この辺の条件を表現するのに、モノイド圏の構造が必要になる。
QRコードを生成するHaskellライブラリを試した
Aterm MR03LNを一ヶ月ほど使った感想
Aterm MR03LNを買ってから一ヶ月ほどが経って、実際の使用感も大体分かってきた。
Bluetooth接続
普通のWi-Fi接続とは排他的に使うようになっていて、本体のタッチパネルまたはスマートフォン・タブレットのアプリで切り替えられる。
Bluetooth接続はWi-Fiと比べるとやはり遅い。Googleマップを表示させると遅さを感じる。
面倒な点としては、ルーターの電源投入後、あるいはWi-Fiからの切り替え後、タブレットを操作して手動でつなぎに行かないといけない。
AndroidのNexus 7ではBluetooth機器を個別に切断できるが、iPadだとそういうのはできないので注意。
2016年4月27日追記:いつの間にかiOSでもBluetoothアクセサリの「接続解除」(ペアリング解除ではない)ができるようになった。参考:他社製の Bluetooth アクセサリを設定して使う – Apple サポートの「Bluetooth アクセサリの接続を外す」
Wi-Fi接続
言うことなし。5GHz帯にも対応しているようだが、試してない。
リモート起動
起動するのにルーターに触らなくてもいいのは便利。Wi-Fiで繋ぐようにしていれば、起動後自動でつながってくれる。
電池の持ち
そんなにヘビーな使い方をしなければ、外出している間は持つ。
付属のクレードルに置いても、USBケーブルの挿し方が悪いのか充電されていないことがあった。(充電状態になればクレードルのランプが点灯するので、クレードルに置いた時に充電されているかチェックできる)2016年4月27日追記:この現象は結局、使っていたUSBケーブルの問題だった。クレードルは悪くなかった。
IPv6
IIJmioのSIMなので普通にIPv6で繋がるっぽい。IPv6だからといってこれといったメリットを感じているわけではないが。
IIJmioとかのサイトにアクセスすると「CONNECTED via IPv6」と出る。
TypeScript 1.5でのlet文
ECMAScriptの変数のスコープが不思議な挙動をするのはよく知られた話だ。ECMAScript 5での変数のスコープは以下のいずれかに大別される(はず)。ブロックスコープがない。
- グローバルスコープ
- 関数スコープ
- catchスコープ
普通に使う変数が関数スコープしかないのは不便、ということで、MozillaはJavaScript 1.7(2006年頃)でlet文を導入した。が、しかし、他のブラウザには普及せず、Mozillaの独自拡張に留まることになった。
時は過ぎ、ECMAScript 5が制定され、次はECMAScript 6という流れになってきた。そして、ECMAScript 6にはlet文が導入されることになった(MozillaがJavaScript 1.7で導入したものとは微妙に仕様が違う)。めでたしめでたし。
ECMAScriptに静的型を付けたTypeScriptは、当初はlet文をサポートしていなかった。それが、TypeScript 1.4で、ECMAScript 6へコンパイルする場合のみlet文をサポートするようになった。
が、ECMAScript 6(のlet文)に対応していないブラウザはまだまだたくさんある(今調べてみたら、IE11ではES6のlet文に対応しているけど、Safariでは対応していないようだ)。できれば、TypeScriptのようなaltJS言語でlet文を使いつつ、コンパイル後のJavaScriptでは従来のvarを使ってほしい。
が、let文を従来のJavaScript (ECMAScript 5)に変換するのはそう自明なことではない。特に問題になるのは、ループ内の変数を、ループの外に持ち出される関数で使っている場合だ。[code lang=”js”]
var a = [];
for (var i = 0; i < 5; ++i) {
let x = i * i;
a.push(function() { return x; });
}
[/code]上のコードを下のように単純にvarを使うと挙動が変わってしまう。[code lang=”js”]
var a = [];
for (var i = 0; i < 5; ++i) {
var x = i * i;
a.push(function() { return x; });
}
[/code]このコードを正しくECMAScript 5に翻訳するには、即時実行関数(IIFE)を使って以下のようにしなければならない。[code lang=”js”]
var a = [];
for (var i = 0; i < 5; ++i) {
(function() {
var x = i * i;
a.push(function() { return x; });
}());
}
[/code]こういう非自明、というかパフォーマンスに影響するところがあるので、TypeScript 1.4ではES5へのコンパイル時にlet文がサポートされなかったのだろう。
が、しかし、TypeScript 1.5ではES5へコンパイルする場合でもlet文が部分的にサポートされるようになるようだ。「部分的に」というのは、ループが絡まない、変数のスコープのチェックと名前の変更で済む場合、のようだ。[code lang=”js”]
{
let x = 123;
console.log(x); // OK
}
console.log(x); // エラー
[/code]
ループが絡む、IIFEを使った変換が必要な場合は、
test2.ts(2,1): error TS4091: Loop contains block-scoped variable 'x' referenced by a function in the loop. This is only supported in ECMAScript 6 or higher.
というエラーが出た。
[code lang=”js”]
let a: Array<() => number> = []
for (var i = 0; i < 5; ++i) {
let x = i*i;
a.push(() => x);
}
a.forEach(console.log);
[/code]
GitHubでの該当するIssue/Pull Requestは以下のようだ。
- Suggestion: Support ES6 ‘let’ and ‘const’ keyword · Issue #19 · Microsoft/TypeScript
- let support for ES3/ES5 · Issue #1690 · Microsoft/TypeScript
- Downlevel emit for let\const by vladima · Pull Request #2161 · Microsoft/TypeScript
let文のサポートとしては不完全とはいえ、varの関数スコープのせいで意図しない同名の変数を参照していた〜〜みたいな事故は防げると思われるので、積極的に使っていきたい。
ガンマ関数の計算(Lanczos近似)
ガンマ関数とは、みなさんおなじみの、
- \(\Gamma(z+1)=z\Gamma(z),\)
- \(\Gamma(1)=1,\)
- \(x>0\) に対し \(\log\Gamma(x)\)は凸
を満たす \(\def\Complex{\mathbf{C}}\Complex\) 上の有理型関数である。\(\DeclareMathOperator\Re{Re}\Re z>0\) に対しては、以下の積分表示がある。\[
\Gamma(z)=\int_0^\infty t^{z-1}e^{-t}dt
\]
階乗 \(n!\) との関係は\[
n!=\Gamma(n+1)
\]となる。
重要な公式としては、反転公式\[
\Gamma(1-z)\Gamma(z)=\frac{\pi}{\sin\pi z}
\]がある。特に、\(z=\frac{1}{2}\) とおけば \(\Gamma\left(\frac{1}{2}\right)=\sqrt{\pi}\) が得られる。
さて、コンピューターでガンマ関数の値を数値的に計算するにはどうすればいいのか。指数関数とか三角関数だとかは分かりやすい冪級数表示があったから良かったが、ガンマ関数にはそういうのはないのか。
いろいろググって調べた結果、ガンマ関数の近似方法として、Lanczos近似というのがあるらしい。が、ググっているだけではいまいちその実体が釈然としないし、導出方法もよくわからない。なので、Lanczosの原論文(1964)を読むことにした。大学院生という身分は便利なもので、大学の図書館でその論文にアクセスできた。
Aterm MR03LNを買った
半年前から、外出先でインターネットに接続するためにIIJmioのMVNO回線とPocket WiFiの端末(GL02P)を使っていたが、このGL02Pは2年使った後なので電池が死んでいて、しかも元々イーモバイル用の端末だから、NTTドコモの一部の周波数帯に対応していない。
じゃあ新しいモバイルルーターを買おう!となるのだが、GL02P+モバイルバッテリーでも最低限には使えるし、代わりのモバイルルーター(自分の中で)第一候補のAterm MR03LNの価格が2万3千円ほどするので、なかなか買うタイミングが見つからなかった。
しかし、数日前(24日)にAterm MR03LNの価格を調べたらAmazonでタイムセールをやっていて、1万5千円と安くなっていたので、迷わずポチってしまった。しかもクレードル付き。(OCNモバイルONEのSIMとのセットだが、そっちのSIMは無視するものとする)(この記事を書いている現在は価格は元に戻ってしまったようだ)
Aterm MR03LNの製品情報はAtermMR03LN | 製品一覧 | AtermStationで見られる。自分が重視したポイントは、
- LTE対応。(今じゃ当たり前か)
- FOMAプラスエリアや、LTEの800MHz帯にも対応。
- Bluetoothテザリング(PAN)に対応。(Wi-Fiより低速だが消費電力が低い)(ただ、ネットで評判を見るとそこまで期待してはいけない?)
- IPv6対応。(IIJmioのSIMと組み合わせるとIPv6でインターネットに繋がる)
あたりか。
以下のアプリを使うと、このモバイルルーターの電波状態・バッテリー残量等を確認できる。
それから、休止状態にしたMR03LNをスマートフォンやタブレットのアプリで「リモート起動」できるようだ。しかし、「MR03LNのリモート起動」と「スマートフォン・タブレットからのWi-Fi/Bluetoothでの接続」が連携する訳ではないので、ないよりマシとはいえ、使い勝手はそこまで良くないか。(「リモート起動」した後、スマートフォン・タブレットでMR03LNに接続するまでの間、アプリからは何も操作できない状態になる)
以下、パッケージの写真。
本体、電池パック、裏蓋とクレードルの他に、ACアダプターとUSBケーブルとLANケーブルが付属するが、これらは手持ちのものを使うつもりなので、多分開封しないだろう。
そろそろ、携帯機器に付属するACアダプターとUSBケーブルが、「プリンターに付属するUSBケーブル」のポジションになっている気がするが、付属をやめる動きはないのだろうか。(Nexus 7を買った時のACアダプターとUSBケーブルも封印したままな気がする)
クレードルに装着。クレードルにはLAN端子があって、MR03LNをルーターとして使えるらしい。本体のUSB端子でパソコンにつなぐとパソコンからはネットワークインターフェースに見えるようだが、クレードルのUSB端子ではそういうのはできないようだ。充電用に「ケーブルを差す」よりは「クレードルに置く」方が楽だ。
Pocket Wifi (GL02P)と並べてみた。
MR03LNの方が縦横が大きいが、薄い。重量はそれほど変わらないが、気持ちMR03LNの方が軽い。
GL02Pにはイーモバイル時代を含めて2年半お世話になったが、これでお役御免だ。