2008-01-01から1年間の記事一覧

ML っぽいカリー化関数を定義するマクロ

ML とか Haskell のコードを読む時に私がどうしても憧れてしまうのが、自動的にカリー化定義される関数です。Scheme にもカリー化関数を定義する構文自体は存在します (処理系にもよるでしょうが)。例えば、このようなラムダ式のネストで定義された関数を (d…

パーサーコンビネータの性能向上について

自前の XML パーサーやウェブ・スクレイピングなどにパーサーコンビネータ・ライブラリを使っているんですが、どうも実行速度が遅いのが気になってきたので、原因を考えてみました。で、気付いたんですが、例えばこのようなパーサーを定義した時に、 (doP (c…

パーサーコンビネータで作るインタープリタ

ふと、パーサーコンビネータでパーサーを作ると、それをそのままインタープリタとして走らせられるんじゃないか、ということを思い付きました。普通はファイルやネットワークの入力ポートを (parse p input-port)のようにして渡すことで (p はパーサー関数)…

なぜ JavaScripter が Schemer になったか

以前は JavaScript のことばかり書いていたのが信じられないくらい、Scheme のことばかり書いていることについての説明文です。 ホップ 当ダイアリーのタイトルからもお分かりかもしれませんが、私は元々 JavaScript について書きたくなって、ブログというも…

恒等関数としての values

再び多値関連の小ネタです。PLT Scheme のあるライブラリを見ていて、こんな values の使い方を発見しました。 (filter values (list ...))一瞬 values が再定義されているのかな?と思って辺りを探したんですが何も無く、試しにやってみると > (filter valu…

多値と関数合成

PLT Scheme のレファレンス・マニュアルを読んでいてちょっと驚いたことがあるので書きます。compose 関数で合成する関数の中に、多値を返す関数を入れられるんですよ: (map (compose list split-path path->complete-path) (directory-list)) ; => ((#<path:C:\home\desktop\> #<path:onlisp.pdf> #f</path:onlisp.pdf></path:c:\home\desktop\>…

livedoor 番組表から Google Calendar へ

plagger 界隈等で話題としてはおなじみだと思うんですが、Scheme でやってみました。livedoor 番組表の RSS フィードで番組検索をし、ATOM ドキュメントに変換して Google Calendar のフィード API にポストする、というものです。 livedoor tv とりあえず、…

パーサー・コンビネーターで Web スクレイピング

パーサー・コンビネーター (parser.ss) を使って、テキスト全体の解析だけでなく、部分を抽出することも可能なんじゃないかと思い付き、実験してみました。例として、はてなダイアリーに貼り付けられているコードを抽出するパーサーを作ります。 このページ…

GMailにアクセス

IMAP で GMail にアクセスし、メール一覧を表示するプログラムを PLT Scheme で作ってみました。SSL 接続の他、メールのタイトル等のデコードの方法、syntax-case でのマクロの作り方といったポイントにも触れていきたいと思います。 SSL ライブラリ PLT に…

JSON Parser with Monadic Parser Combinators

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 気にせず…

Monadic Parser Combinators - Haskell 風パーサー・コンビネーターの実装

Abstract for English readers:This article describes an implementation of a purely functional, monadic parser combinator library in PLT Scheme.With this library, one can easily build non-ambiguous, recursive-descent style parsers for string…

部分継続による Python 風ジェネレータ

ここ数日 HTML パーサーの開発に取り組んでいたんですが、その過程で次のような問題にぶつかりました。HTML を構文解析して木構造を作る際に、トークン (字句) を一つずつ返してくれるジェネレータが欲しい、と思ったんです。一般に、言語の解析は字句解析と…

部分継続を用いたエンコーディング変換

最近 XPath の Scheme 版 (SXPath) を自前で開発しているんですが、その関連で HTML パーサーも作ってみようと思い立ちました。が、パーサー以前の問題でいきなり躓いてしまいました。文字コードの判定の仕方が分からなかったんです。PLT Scheme では、入出…

Zipper - 関数的 (非破壊的) なデータ構造の更新

PLT Scheme の新しいバージョンからリストが immutable になる (set-car! とか append! とかが使えなくなる) ことは随分前にアナウンスされていて知ってはいたんですが、何の対策もしないままリリースを迎えてしまいました (バージョン 4 のアナウンスメント…

虹色の括弧、灰色の括弧

私は Vim では S 式は書かないんですが、たまたまヘルプを見ていてちょっと面白い機能を発見しました。括弧の色付けをカラフルにする機能です:多分お遊び的なものだと思いますが、括弧が何重にネストされていても色で対応関係が分かって便利そうですよね。基…

リスト内包表記の活用 - 数独ソルバー

Peter Norvig 氏の Solving Every Sudoku Puzzle というエッセイで、数独の解き方が Python を使って示されています。ちょうど SRFI-42 (eager comprehension) というライブラリを使ってみたいなと思っていたところに見つけたので、ジェネレータ式というもの…

カリー化関数 (curried function) について

SML という言語のテキストを読んでいて、これまで自分がカリー化という言葉をよく理解せずに使っていたことに気付きました。どうやら部分適用の概念と混同していたようです。一般に、ML や Haskell のような関数型言語においては、カリー化とは n 要素タプル…

マルチスレッドと副作用

(排他制御の件での初歩的なミスに頭を悩ませている最中ではありますが、また別な話題です) 並列処理プログラミングにおける副作用というのは様々な厄介な問題の温床ですが、MzScheme の channel を使うと問題を解決できる場合があります。スレッド下の処理を…

マルチスレッドと排他制御

threaded-map という関数を用いて、高階なマルチスレッド・プログラミングをしています。 (threaded-map f l) f は1引数関数で、リスト l の各要素に適用されるんですが、要素ごとに独立したスレッド下で処理される点が普通の map と異なります。しかも、各…

クロージャの活用 - 設定ファイル関数、動的オブジェクト・ローダー

クロージャ (内部状態を保持する関数。SICP 2 章では残念な誤用とされております) を用いて、データに対する手続きを抽象化する例をいくつかお見せします。 オブジェクトの動的ローダー 重いオブジェクトを、必要に応じて読み込んだり開放したりするための関…

データベース検索エンジン

youtube データベース検索の話の続きです。当初は (and (and "wa" "bi") (not "wasabi")) のように、タイトルもしくはコメントを対象として検索式を組む仕様だったんですが、より自在な検索ができるよう、DB レコードのフィールド名を明示的に指定して検索す…

再帰的な Migemo 検索

最近 youtube のデータベースを Scheme で作っています。ただ、データベースはかなり大きくなってきたものの、検索エンジンの実装は、経験が無かったためずっと後回しにしていました。Migemo (C/Migemo ライブラリ) が使えそうなことは Winamp 等の実験で分…

経路探索: 京都の鉄道乗り換え案内

気付いたんですが、MzScheme って日本語を変数名にできるんですね。 > (define 梅田 'erika) > (cond ((memq 梅田 '(erika aka ageko)) => caddr) (else 'sageko)) ageko なぜ気付いたかと言いますと、探索アルゴリズムの勉強のために、鉄道のルート探索のプ…

Unit - Winamp と CD プレイヤーの共存

MzScheme の FFI 機能を利用して、REPL 上で動く CD プレイヤーを作ることにしました。Meadow の例 でコマンドの作り方は分かっていたので簡単です。ただ、前回作った Winamp プレイヤーと play や stop などのコマンド名が被りそうなのが少々問題でした。も…

FFI: 外部ライブラリ関数の呼び出し

MzScheme では (MzScheme に限りませんが)、外部ライブラリの API 関数を呼び出す FFI (Foreign Function Interface) という仕組みが提供されています。今回は、zip ファイルを解凍するプログラムと、Winamp を REPL で制御する例をご紹介します。 UNZIP dll…

Progress Char

よくプログラムの作業中、ユーザーを待たせる間に、回転するカーソルが表示されることがありますよね?それを作ってみました。 (define (progress) (define chars '(#\| #\/ #\- #\\)) (define (loop l) (if (null? l) (loop chars) (begin (ticker (car l))…

Scheme でつくるプロキシ・サーバー

私は Winamp という mp3 プレイヤーを愛用しています。特に、ウェブ上の mp3 ファイルをストリーミングのようにイン・メモリーで再生できるのが便利で (キャッシュファイルを作りません)、ポッドキャストなどはダウンロードせず直接 URL を入力して聴くこと…

Windows 版 MzScheme から Cygwin のプログラムを動かす

タイトルの通りです。既存のライブラリそのままでは出来なかったので関数を作りました。 (require (lib "process.ss")) (define shell (find-executable-path "sh.exe" #f)) (define (concat l) (apply string-append (cons (car l) (map (lambda (s) (forma…

部分継続とストリームで作るジェネレータ関数

最近、とある目的で Jpeg 画像を読むプログラムを書きました。(はてなのロゴを Jpeg で保存し、青い部分をキャラクタで表示したところです)難しい部分は Common Lisp のコードなどを参考にしたんですが、いくつか Scheme ならではと思えるテクニックの発見も…

クールな文字列連結のテクニック

HTML や RSS など、テキストをプログラムで生成する時に、最終的にどうしても文字列の連結ということをしますよね。でも Lisp の場合、文字列として組み立てる前に、S 式で (ツリー構造として) ドキュメントを作成するのが普通です。そのようなツリー構造で…