Hatena::ブログ(Diary)

あどけない話

2014-06-25

Emacs 24.3/24.4 on Mac のフォント設定

Emacs で一番難しいのはフォントの設定です。特に Mac では地獄のように難しいです。とうわけで、Emacs 24.3 と来る Emacs 24.4 でうまくフォントを使うための設定を公開しておきます。

なお、Mac では素の Emacs を使ってはいけません。Emacs Mac port を使いましょう。パッチを当てるのは面倒なので、早く github なんかで公開されるといいですね。

ちなみに、素の Emacs を Dock から起動すると PATH を引き継がないので、はまります。Emacs Mac port なら PATH を引き継いでくれます。

フォントの設定

以下をお好みに合わせて変えて .emacs などに入れて下さい。

;; 以下はフレームの設定
(defvar my-frame-parameters
  '((height . 40)
    (width . 80)
    (top . 0)
    (left . 0)
    (foreground-color . "white")
    (background-color . "black")
    (cursor-color . "white")
    (mouse-color . "white")
    (tool-bar-lines . nil)))

(when (memq window-system '(x mac ns))
  (setq frame-title-format '(multiple-frames "%b" ("" invocation-name)))
  (setq default-frame-alist my-frame-parameters))

;; 以下が Mac 用のフォント設定
(when (memq window-system '(mac ns))
  (global-set-key [s-mouse-1] 'browse-url-at-mouse)
  (let* ((size 14)
	 (jpfont "Hiragino Maru Gothic ProN")
	 (asciifont "Monaco")
	 (h (* size 10)))
    (set-face-attribute 'default nil :family asciifont :height h)
    (set-fontset-font t 'katakana-jisx0201 jpfont)
    (set-fontset-font t 'japanese-jisx0208 jpfont)
    (set-fontset-font t 'japanese-jisx0212 jpfont)
    (set-fontset-font t 'japanese-jisx0213-1 jpfont)
    (set-fontset-font t 'japanese-jisx0213-2 jpfont)
    (set-fontset-font t '(#x0080 . #x024F) asciifont))
  (setq face-font-rescale-alist
	'(("^-apple-hiragino.*" . 1.2)
	  (".*-Hiragino Maru Gothic ProN-.*" . 1.2)
	  (".*osaka-bold.*" . 1.2)
	  (".*osaka-medium.*" . 1.2)
	  (".*courier-bold-.*-mac-roman" . 1.0)
	  (".*monaco cy-bold-.*-mac-cyrillic" . 0.9)
	  (".*monaco-bold-.*-mac-roman" . 0.9)
	  ("-cdac$" . 1.3)))
  ;; C-x 5 2 で新しいフレームを作ったときに同じフォントを使う
  (setq frame-inherited-parameters '(font tool-bar-lines)))

;; 以下の設定はお好みで
(setq resize-mini-windows nil)
(setq mouse-drag-copy-region t)

あわせて読みたい

2014-06-16

来る Emacs 24.4 を Mac で安定させる

もうすぐリリースされる Emacs 24.4 を Mac で使うと、ほんとうにイライラします。

なぜなら、

が頻発するからです。NEWS を読んでいて、以下を見つけました。

** New Core Text based font backend for Mac OS X 10.5 and newer.
To use the old font backend, use the following on the command line:
  % defaults write org.gnu.Emacs FontBackend ns
GNUstep and Mac OS X 10.4 use the old font backend.

新しいフォントバックエンドを使うのが問題かもしれないと思い、defaults を変え古いバックエンドで暮らししてみました。すると、嘘のように安定しました。

新しいフォントバックエンド用のコードが落ち着いて、設置を元に戻したくなったら、

 % defaults delete org.gnu.Emacs FontBackend

とすればよいようです。

2014-04-15

複数のGHCを共存させる

GHC 7.8.1 がリリースされ、type family がうまく扱えない問題が発覚したため、すぐに GHC 7.8.2 がリリースされました。このおかげで Yesod が、うまくビルドできるようになりました。しばらくして、GHC 7.8.3 もリリースされる気配があります。また、一ヶ月を目処に Haskell Platform 2014.2 が出るようです。

こうなると、GHC をうまく共存させてくれる Haskell Platform 2014.2 のリリースを待とうかと思うかもしれませんが、そんな必要はありません。GHC 自体に複数のバージョンと共存できる仕組みがあるからです。

GHC 7.8.2 を試したい人は、気軽にインストールしましょう。GHC 7.8.3 や Haskell Platform 2014.2 がリリースされたら、GHC 7.8.2 は消せばいいのです。ここでは、後で消しやすくするためのコツを紹介します。対象は、Unix 系の OS です。Windows のことは、誰かに任せます。

インストール

GHC 7.8.2のダウンロードサイトから、必要なバイナリを取ってきて展開します。以下、Mac の例:

% wget http://www.haskell.org/ghc/dist/7.8.2/ghc-7.8.2-x86_64-apple-darwin-mavericks.tar.xz
% tar zxvf ghc-7.8.2-x86_64-apple-darwin-mavericks.tar.xz
% cd ghc-7.8.2

ここで、単に configure を実行すると、/usr/local の下にインストールする設定になります。これでだと、インストールするファイルが散らばって、後から消しにくくなります。そこで、例えば /usr/local/ghc-7.8 というディレクトリの下にインストールするように決めます。

% ./configure --prefix=/usr/local/ghc-7.8

次に /usr/local/ghc-7.8 というディレクトリを作ります。僕は、このディレクトリを自分の所有にしています。root の所有でもいいですが、make install するときに sudo を使わないといけません。おかしなことは起りませんが、不安な人は自分の権限でインストールするのがいいでしょう。GHC 自体が自分の所有になっていても、GHC を壊した経験は僕にはありません。

% sudo mkdir /usr/local/ghc-7.8
% sudo chown あなたのアカウント /usr/local/ghc-7.8
% sudo make install

PATH に /usr/local/ghc-7.8/bin を追加すれば、GHC 7.8.2 のインストールは完了です。

削除

削除したくなったら、3つのディレクトを消します。

~/.ghc や ~/.cabal 自体は消してはいけません。こうすれば、~/.cabal/bin 以下のコマンドは残ります。コマンドは、静的リンクされているので、引き続き使えます。ただし、alex や happy のように lib に設定ファイルを置いているコマンドはうごかなくなるので、インストールし直す必要があります。

応用

この方法は、何も GHC 本体を消したい場合だけではなく、cabal でインストールしたユーザライブラリがおかしくなったときにも使えます。~/.ghc と ~/.cabal 以下のサブディレクトリを消せば、一から世界を構築できるようになります。

2014-03-01

RSSリーダ BazQux と DNS キャッシュ

BazQux(バズクックス)は、Google Reader代替として密かに注目されている RSS リーダです。実装と運用を一人でやっている Vladimir Shabanov さんによると、BazQux のウリは、

  • 高速である
  • ブログのコメントも表示できる
  • 複数のビューがある
  • モバイルに対応している

などらしいです。

BazQux のフロントエンドは、Ur/Web で記述されたコードから生成された JavaScript、バックエンドは Haskell だそうです。高速なのは、Haskell のおかげであると Vladimir さんは言っています。我々が開発している HTTP エンジンの Warp も使われているそうです。

現在、僕は Haskell 用の HTTP/2 ライブラリの作成に取り組んでおり、必要な技術を調べている過程で、redditでの議論のことを思い出しました。今回、よくよく読んでみると、僕が実装している DNS ライブラリを使っているが、ADNS (のラッパーである hsdns)と比べて安定しているものの、ドメインを検索できないことがあると書かれていました。

僕がDNSライブラリを書いたのは、不安定なADNSを見限ったためなので、安定しているのは当然として、ドメインの検索率が悪い点は気になりました。そこで、Vladimir さんにメールを書いたところ、すぐに返事が返ってきました。彼のコードと実際のドメインリストを見せてもらったところ、

  • DNSライブラリの使い方が間違っている
  • MVarを多用していて性能が悪そう (Vladimir は、そこはボトルネックではないと言っている)
  • HashMapで持っているキャッシュを定期的に枝刈りしてないのでメモリをたくさん使いそう

ということが分かりました。

奮い立ってしまった僕は、使ってもらえるか分かりませんでしたが、おもむろに concurrent-dns-cache というライブラリを作り始めました。設計のポイントは以下の通り。

  • DNSライブラリを正しく使う
  • セマフォを STM で実装する
    • 高並行な状況では MVar よりよいはず
  • キャッシュは Priority Search Queue で持つ
    • 優先度に指定した時刻で枝刈りできる。もちろん、ドメイン名で検索もできる。
  • ドメイン名を ShortByteString として扱う
    • ByteString は pinned オブジェクトなので、メモリが断片化する。このため Vladimir さんは Text を使っていたが、ShortByteString の方がメモり利用効率がよい
  • 高速な検索を実現するためにキーの第一要素としてハッシュ値を持つ

concurrent-dns-cache は、めでたく BazQux に採用され、以前よりもドメインの検索率が高く、少ないメモリで安定して動いているようです。高性能で高並列で安定しているネットワークコードをすばやく実装できるのが Haskell のよい点の一つですね。

今回の経験は HTTP/2 の実装にも役立ちそうでよかったし、現場の人と議論できたのはのは楽しい経験でした。

今少し悩んでいることは2つ。

一つ目:キーの定義は以下のようになっています。

type Hash = Int

data Key = Key !Hash            -- making lookup faster
               !ShortByteString -- avoiding memory fragmentation
               -- Haskell 2010 says: Derived comparisons always
               -- traverse constructors from left to right.
               deriving (Eq,Ord,Show)

実際のキーをハッシュ値と一緒にくるむことで、(MapからHashMapへの変更とは違って)コンテナの構造を変えることなく、検索速度を高速にします。みんな使いたいとは思いますが、ライブラリにするには小さすぎるので、どうしようかなぁという感じです。まだベンチマークを取っていないのですが、本当に有用そうなら小さくてもライブラリにするかもしれません。

二つ目:Priority Search Queue の本家本元のライブラリである PSQueueには、ある優先順位以上の要素を取り出す API はあるのですが、要素を取りさらった木を返す API はありません。そこで、僕は GHCソースコードから PSQ.hs をコピーしました。PSQueue の API はあまりよくないし、PSQ.hs はキーと優先順位の型が固定です。両者の API はまっく違うので、PSQueue を PSQ.hs で置き換えてバージョンアップするということもできません。

そもそも、Priority Queue がヒープの別名であることを知らない人は多く混乱の元なので、search-heap という名の別ライブラリでリリースしようかなぁ、どうしようかなぁ、という感じです。

2014-02-06

Real World Haskell の古いところ

Real World Haskell の内容が古くなってきたので、どこが古いかとか、それに変わる新しいものは何とか、まとめたいと思う。

1章 始めましょう

今でも通用する。

2章 型と関数

今でも通用する。

3章 型を定義し、関数単純化する

今でも通用する。

4章 関数プログラミング

ghc に --make オプションはもう不要。

5章 ライブラリを書く

5.14節では、"runghc Setup build" のように Setup.hs を実行しているが、現在では "cabal" コマンドを使うのが一般的だ。

% cabal configure
% cabal build
% cabal install

なお、以前よく起っていたライブラリの依存地獄は、cabal が sandbox をサポートしたことにより解決している。使い方は、@ma0e さんのブログを参照。

6章 型クラスを使う

6.11節の NoMonomorphismRestriction は、GHC 7.8 からはデフォルトとなっているので、指定しなくてよい。

7章 入出力

今でも通用する。

8章 効率的なファイル処理、正規表現、ファイル名マッチング

今でも通用する。

9章 入出力事例研究

9.9節は読まずに、conduitfilesystem-conduitライブラリを理解する方がよいと思われる。

9.10節のレイアウトスタイルよりも、Johan のレイアウトスタイルのほうがいいだろう。

10章 コード事例研究

今でも通用する。

11章 テストと品質保証

QuickCheck はバージョンが1から2になった。だいたい今でも通用でするが、generate 関数はなくなった。また、Test.Quickcheck.Batch モジュールもなくなった。テストを一括処理したい場合は、Haskellの単体テスト最前線を参照のこと。

12章 バーコード認識

僕試した限りでは、この章のコードはちゃんと動かない。バーコードのコードはスルーして、配列、リスト内包表記、および Data.Map を勉強するのがよい。

13章 データ構造

今でも通用でする。

差分リストを理解したら、ByteString を効率よく連結する blaze-builder も勉強しよう。

14章 モナド

今でも通用でする。

15章 モナドを使ったプログラミング

  • liftM は忘れて <$> を使う
  • ap は忘れて <*> を使う
  • MonadPlus は忘れて Alternative を使う
    • mplus は忘れて <|> を使う
    • mzero は忘れて empty を使う

15.8節では、型クラスが使われているが、最近では Free モナドや Operational モナドの方がいいかもしれない。

16章 Parsec を使う

Text.ParserCombinators.Parsec は使わない。代わりに、

import Text.Parsec

とする。入力の型が、String、ByteString、Text から選べる。たとえば String の場合は、以下も import。

import Text.Parsec.String

Applicative スタイルを導入した後に、liftA2 などを使っているのは、修正ミスだと思われる。(Bryan は RWH 執筆時に Applicative スタイルを教えてもらったと思われる。)

17章 CとのインターフェイスFFI

今でも通用する。

18章 モナド変換子

@objectxplosive さん、@khibinoさんとの議論から:mtl が依存している transformersを勉強しよう。これには MaybeT が定義されている。

19章 エラー処理

この章は読まなくてよい。以下を読もう。

20章 Haskellのシステムプログラミング

時間に関するライブラリについては、以下を参照。

21章 データベースを使う

@khibinoさんより:今でも通用する。

22章 規模の大きい例

http-clientxml-conduit ライブラリを使う方がいいと思われる。

23章 gtk2hsを使ったGUIプログラミング

@ma0eさんのブログの後半を参照。

24章 並行マルチコアプログラミング

素直に Parallel and Concurrent Programming in Haskellを読む方がよい。なお、この本は将来翻訳される予定。

25章 プロファイリング最適化

@ma0eさんのブログの前半を参照。

26章 高度なライブラリ設計

ST モナドだけ読めばよい。

27章 ソケットと syslog

今では、Network.Socket ではなく、Network.Socket.ByteString を使うのが普通。

sClose の代わりに Network.Socket.close を使おう。

28章 ソフトウェアトランザクショナル・メモリ

今でも通用するが、Parallel and Concurrent Programming in Haskell を読む方がよい。