タグ

ブックマーク / reinyannyan.hatenadiary.org (10)

  • 関数生成関数の利用例: ミニバッファ履歴の整理 - (new Hatena).blog()

    id:reinyannyan:20070416:p1 (簡易クロージャの実装) で、変数の値を関数式の中にインライン展開することで擬似クロージャを作成する方法を考えました*1。今回はその応用編です。 savehist-mode を有効にして、ミニバッファの入力履歴を Emacs セッションを通じて記憶しておく、というケースを題材にします。 保存された履歴ファイル (~/.emacs.d/history) を眺めてみると、入力内容に重複があることに気付きます。 まずは単純に重複を削除することを思い付くんですが、それだけだと compose や curry の出る幕はありません。 そこで、ファイル名の履歴に注目してみると、入力内容に特徴的なばらつきがあることが分かります。 例えば、ディレクトリ名がスラッシュで終わっていたりいなかったり、"~/.emacs" を "~/work/../.emac

    関数生成関数の利用例: ミニバッファ履歴の整理 - (new Hatena).blog()
  • JSON Parser with Monadic Parser Combinators - (new Hatena).blog()

    PLT Scheme には既に JSON のパーサーが2つあるんですが: http://www.lshift.net/blog/2005/08/22/json-for-mzscheme-and-a-portable-packrat-parsing-combinator-library http://planet.plt-scheme.org/display.ss?package=json.plt&owner=dherman 気にせず作ってみました。 JSON 自体は文法が簡単なので短時間で作れたんですが、その過程でライブラリの重大な欠点も見つかりました。Scheme の #f の値をパース失敗と見なす方式だったために、JavaScript の "false" の値を #f に変換できない、という問題が判明したんです。 そのような問題修正やブラッシュアップを施したコードはこちらです (まだパ

    JSON Parser with Monadic Parser Combinators - (new Hatena).blog()
  • JavaScript でプロファイリング - (new Hatena).blog()

    追記 [20061103]: ライブラリ非依存なバージョンも書いてみました。id:reinyannyan:20061103:p1 でご覧下さい。 最近自分で書いた JS プログラムが驚くほど重かったので、どこに原因があるか調べたいと思いました。 その方法として、怪しいと思う箇所に (あるいは思わない箇所にも) 手作業でタイマーを仕掛けて、部分部分の実行時間を計測するのも手だと思うんですが、クラスのどのメソッドでどのくらい時間が掛かっているのかが自動的に分かる、というのが理想的かなと思いました。 (以下、prototype.js 的な (OO 的な) コーディングを対象とした話になります) まず思いついたのは、プロファイルしたいクラス (function オブジェクト) を受け取って、メソッドを動的に書き換えるという方法です: for (var m in klass.prototype) {

    JavaScript でプロファイリング - (new Hatena).blog()
  • パーサー・コンビネーターで Web スクレイピング - (new Hatena).blog()

    パーサー・コンビネーター (parser.ss) を使って、テキスト全体の解析だけでなく、部分を抽出することも可能なんじゃないかと思い付き、実験してみました。 例として、はてなダイアリーに貼り付けられているコードを抽出するパーサーを作ります。 このページのソースを見ていただくと良く分かると思いますが、Scheme のコード部分は PRE タグに囲まれています。 構文ハイライト無しの場合はシンプルにタグの間の文字列を読み取れば良いんですが、有りの場合、構文要素ごとに細かく SPAN タグが埋め込まれています。 そのまま抽出しても読みにくいので何とかしたいんですが、とりあえず、タグ無しの文字列を読み取るパーサーを作ることにしましょう。 基的には "<" 以外の文字を読み取るだけで良いと思うんですが、文字実体参照が有った場合には特別な処理が必要となります。 (define entities '

    パーサー・コンビネーターで Web スクレイピング - (new Hatena).blog()
  • Windows 版 MzScheme から Cygwin のプログラムを動かす - (new Hatena).blog()

    タイトルの通りです。既存のライブラリそのままでは出来なかったので関数を作りました。 (require (lib "process.ss")) (define shell (find-executable-path "sh.exe" #f)) (define (concat l) (apply string-append (cons (car l) (map (lambda (s) (format " ~a" s)) (cdr l))))) (define (system/cygwin exe . args) (let ((o (open-output-bytes))) (parameterize ((current-output-port o)) (system* shell "-c" (concat (cons exe args))) (open-input-bytes (get-out

    Windows 版 MzScheme から Cygwin のプログラムを動かす - (new Hatena).blog()
  • Emacs - Scheme 間通信 ~ S 式オブジェクト記法による ~ - (new Hatena).blog()

    最近 MP3 のタグを読むプログラムが必要になり、elisp で書こうとしました。が、バイナリ・データの扱いが無理っぽい気がしたので、Scheme で書くことにしました。 一応それは上手くいったんですが、アプリケーション自体は emacs 上に作りたかったため、Scheme プログラムと elisp を橋渡しする仕組みが新たに必要となりました。 たくさんの MP3 ファイルを扱うことを想定しているため、プログラムをサブプロセスとして常駐させる、とか、Scheme シェルに elisp で関数を打ち込む、といったことも考えたんですが、考慮の末、スレッドを使う方法を選びました。 まず、Scheme プログラム側を TCP サーバーとして実装し直します。そして、Scheme シェル (emacs の inferior-scheme または run-scheme モード) 上でスレッドとして走らせ

    Emacs - Scheme 間通信 ~ S 式オブジェクト記法による ~ - (new Hatena).blog()
  • Generic Monad System in Scheme - (new Hatena).blog()

    id:reinyannyan:20070714:p1 で考案したモナド実装案がほぼ実用的になってきましたので、取りあえず公開します。 monad.tar.gz (PLT Scheme 用) monad.ss という、インターフェースとなるモジュールがあり、それを maybe.ss や list.ss 等の具象モジュールが実装する、という形になっています。 アプリケーション側では必要な具象モナドだけを require すれば OK です。 モナド・トランスフォーマーや、Haskell 的な (データ・コンストラクタによる) パターンマッチ構文も利用できます。 サンプル: 確率モナド

    Generic Monad System in Scheme - (new Hatena).blog()
  • JavaScript でプロファイリング (シンプル版) - (new Hatena).blog()

    Game of Life のアルゴリズムの問題点を探ろうと思い、以前作ったプロファイラにかけて調べることにしました。 が、このプロファイラは prototype.js (を自分用に改変したもの) を対象にした内容だったため、ライブラリを使わずに書いた Game of Life では使えません。 ということで、完全にライブラリ非依存な形に書き直してみました: var Profiler = { times: {}, scope: this, // == window watch: function() { for (var i = 0; i < arguments.length; i++) this.profile(arguments[i]); }, profile: function(klass) { this.times[klass] = {}; var proto = eval(["th

    JavaScript でプロファイリング (シンプル版) - (new Hatena).blog()
  • Scheme で vim バッファにテキスト出力 - (new Hatena).blog()

    Vim に Scheme インターフェースを追加して真っ先に確認したかった事が、バッファにテキストを追加する方法です。 新しい情報を画面の末尾に追加していく、という至極当たり前の作業なんですが、これがなかなか難しかったのでメモしておきたいと思います。 まずヘルプ (:h mzs) をあたって: (insert-buff-line-list {linenr} {string/string-list} [buffer])というプロシージャがあることが分かりました。 ここでちょっと難しいのが、vim 用のプロシージャは、MzScheme のそれとの衝突を避けるため "vim-" という接頭辞を付ける、というのが慣わしになっているようです (自分で、です)。 しかも、その設定はバッファ毎に行わなくてはならないらしく、そのための方法がヘルプに書いてあります (端折ります)。 設定が出来たところで、

    Scheme で vim バッファにテキスト出力 - (new Hatena).blog()
  • livedoor Reader で既読記事を非表示にする - (new Hatena).blog()

    livedoor Reader で特定のサイトや記事の文を非表示にする に関して、はてブコメントにて表題のアイデアを提案していただきました。ちょうど、サイトの既読判定をスクリプトで行う手法が考案されて (g:subtech:id:secondlife:20060812:1155379084 id:brazil:20060812:1155388762)、面白いなぁと思っていたところで、絶妙のタイミングでした。 (以下、既読判定の実装について、直接的にははてなアンテナのコードを参考にさせてもらいました) フィード表示前のフックを使って、既読であればその記事を削除する、という方法を考えてみます。 概要としては: register_hook("before_printfeed", function(feed) { for (var i = 0; i < feed.items.length; i+

    livedoor Reader で既読記事を非表示にする - (new Hatena).blog()
  • 1