Let's start Scheme

2012-02-29

うるう年

すっかり忘れていた。折角なので何か書いておこうというだけの話。

ここ数日(といっても今日で2日目だが)風邪ひいていて結構体がだるい。というか基本起き上がるとくらくらするのでベッドの中でごろごろしている。
早く治らないかなぁ。まぁ、でも明日は仕事にいくだろうけど。

2012-02-26

親の心子知らず

母親とは子供のことでいろいろ何か出来ないか模索せずにはいられない生き物なのだろうとちょっと実体験した話。

いろいろあって関係が壊滅的になっていた(今はほんの少し持ち直したと思う)のが事の始まり。昨日いきなり話し合いの場を設けられた。何故こうなったのかというのが主なもの。こういう話で原因がはっきりしていることってあるのかは知らないが、もし原因があるなら僕だろう。単にいろいろ覚悟が足りなかったという話だ。あんまり優秀な捕手ではないので、飛んでくる球を全部受けきれずという感じだ。(まぁ、直球すら落球していたという話ではあるのだが)
っで、一夜明けて今日、いきなりアントワープに行こうという提案が飛んできた。あぁ、いろいろ考えた結果「2人で何かをする」というのがそこだったんだろうなぁと瞬時に理解。でも、日曜のアントワープなんてただ歩くだけだし、疲れも溜まっていたのでお断りをした。んで、次がどうやらアムステルダムで買い物だったみたい。
正直どういった経緯でアントワープからアムステルダムになったのかは知らないけど、電話があって僕は行かないということを知った際の反応からこれもその一つだったんだなぁと理解。いろいろ申し訳ないなぁとは思いつつ、でも僕買い物に付き合わされても正直ストレスにしかならないんだよなぁとかも思ったり。
いろいろ好意を無にしてるなぁとは思うし、迷惑かけてるなぁとは思うけどう~ん。

甲斐性無しのダメ男ですいません。
(上記は既に謝ってるので、ネット上で言うなよというのはなしの方向で。ブログに書いてるのは単なるはけ口です。こういうとき日本語が分かる友人がオランダでほしいなぁと思う。)

2012-02-25

プロセスをちょっと本格的に実装

以前からとりあえず動く、というか単に他プロセスが呼べるレベル、のものはあったのだがさすがにこのままではなぁと思いちょっと改良(改悪?)してみた。

もともと設計の方針としてはJavaのProcessクラスみたいな感じで入力、出力、エラー出力のポートをプロセスが持っていてそれらをいじれるようにしようとしていた。っが、とりあえず全部標準入出力にリダイレクトして適当にしていた。
っで、ちょっと思い立ってまじめにそれらを割り当てることにした。まぁ上手くいってる。っが、ここでちょっとした問題が。
元々この機能は仕事でmavenを叩くのにWindowsのバッチでは厳しいなぁと思っていたから作ったのだが、今回の変更で標準出力にリダイレクトされないのでログが見辛い。また、走っているプロセスのパイプに対して出力があったのか知る方法がないので、出力ポートからログを上手く取得できないという問題がでた。
解決方法はいまいちいい案がないのだが、とりあえず出力のリダイレクト先を指定できるようにするとか、char-ready?(ポートはバイナリなのでu8-ready?か)的な何かをまじめに実装するか、プロセスが終了するまでじっと待ってからログ吐く(運用回避?)のどれかだろうか?

Rubyのspawnとかどうしてるんだろう?(使ったこと無いけど、いろいろ出来そうだなぁとドキュメント見て思った)

2012-02-23

Boehm GC "too many heap sections" error


Well, the reason why I am writing this article is it's not because I found the solution for that but I have figured out which version I could avoid this. So this is just a memo.

Boehm GC is one of the coolest library for C developer however it still has a lot of problems to use all platform (I guess). When I got this error, I was using Cygwin to develop my own project Sagittarius and trying to run tests. The GC version was 7.2 alpha 6. I actually used version 7.1 before and the reason why I tried to use the latest version was to solve multi thread problem. Well, as you can see it was a wrong decision. Each time I tried to run the tests it failed. So I decided not to use it and revised to stable (they say) version.

If you google this error message, you can probably see the solution which you need to build it with LARGE_CONFIG ld flag. Unfortunately, I haven't tried it because I also saw a lot of article which said it did not solve any problem.

Sorry if you google this error message to solve your problem, I have just written this article for nothing actually:-p

2012-02-20

宗教と家族

またこれ系のネタだ。まぁ、たぶんこれで最後だろうが。

あなたには彼女(もしくは彼氏)がいます。っでその兄妹がオウム真理教の信者であなたの彼女(彼氏)に「この宗教はすごくいいんだ」と勧めています。そんなときあなたはどうしますか?
  1. 止める
  2. 放置する
  3. 自分も改宗する
2もしくは3を選んだ方は続きを読んでもいらだつだけでしょう。

2012-02-17

常識で考えましょう...

Togetterにあったまとめ
@May_Roma流英語習得法:「常識で考えましょう…」
おおむね賛成なんだけど、微妙だなぁと思ったのが1個。(実は最初の15個くらいしか見てないので他にもあるかもしれないが)
https://twitter.com/#!/May_Roma/status/168427967175860225
 日本語力つけたい外人が、日本語でちゃんと喋ったり書いたりできないDQNに日本語習ってもうまくなるわけないでしょう。英語も同じでまともな先生に高い金を払って習わないとうまくなるわけないです。高い先生は自分の勉強に投資してんですよ。常識で考えましょう…
前半は非常に賛成なのだが、後半は実体験からそうでもないなぁというのがあったりする。

とりあえず「日本国内で勉強する」ということに絞るとすれば、当てはまるのかもしれないが、E○Cとかの英会話学校だと「高いけど先生はまともじゃない」なんてことがままある。実際僕も日本で英会話学校にいっていたのだが、あまりたいした成果はなかったような気がする。もちろん0ではないし、その後カナダに行った際に役に立ってはいたので無駄ではなかったとは思うが。この場合はおそらくここで言う「まともな先生」というのがキーワードなんだろう。それを探すのにスキルがいるということだ。

個人的に上記はとりあえず僕が思ったものでも小さいもので、大きくそれは違うだろうと思ったのは、この文章から見て取れた「金を払わないと英語は習得できない」というもの。(国語の点数は低い方だったのでそんなこと言ってないと言われると以下は破綻します)。
僕がある程度(ビジネスでも使える程度)英語が喋れるようになったのは高い金を払って先生から授業を受けたからではない。どちらかといえばそのような環境にいるからだと思っている。つまり英語で仕事をする環境にいるということ。同じことが日本で働いていた時にも言えて、大学を卒業してから身につけた日本語というものが非常にたくさんある。(御社とか弊社とか学生時代は知らんかった)
「習うより慣れろ」という言葉があるように実際に使われている言葉に触れるというのは何者にも代え難い勉強方法ではないだろうか。ただこれを言うと、

勉強なら他所でやれ
この学生の間違いは、会社に入って給料を貰いながらスキルアップしようと思っていること。小学生から大学まで16年学ぶ時間がありました。就職して仕事を するということは、学んだことを生かしてアウトプットするということ。まだスキルが足りないというのなら、その必要なスキルが学べる専門学校にでも行けば いい。会社に入ってスキルアップなんて図々しいことこの上なく、給料は貰うどころか、授業料を払うべきです。会社でのスキルアップというのは仕事の結果と してそうなるわけであり、それ自体を目的にするのは本末転倒。
上記の意見に当てはまる気がするのでそれはそれで微妙かもしれないが。ただ、現場で使われている言葉という点に焦点を絞るならそこにいなければわからないこともあるだろうということだ。
実際、僕もここで働き始めて英語の勉強をせざるを得なかった。具体的には電話の応対とかね。そうはいってもそれに対して金は払ってない(ネット代は含まない)。

効率という点を除けば手段はいくらでもあるはずだ。
「まともな先生」というのが人間以外も指すなら、高い金を除いて賛成ではあるが。

2012-02-12

BNFを書いてみた

Daring Fireball: MarkdownのDingusにあるチートシートからBNFを起こしてみた。無ければ作るのがナンとやら精神で。
BNF of Markdown,

Doc ::= Element*
Element ::= Paragraph | Header | List | Blockquote | Line
         |  CodeBlock | BlockHtml | Reference
Paragraph ::= Inline* Linefeed{2,}
Inline ::= (Text | Emphasis | Link | Image | CoseSpan )
Header ::= Setext-Style | Atx-Style
Setext-Style ::= Text Linefeed ('=' | '-')+
Atx-Style ::= '#'{1,6} Text '#'*
List ::= (Number '.' SP+ Inline+) (Linefeed List)*
      |  ('*' SP+ Inline+) (Linefeed List)*
Blockquote ::= '>' SP* Paragraph
            |  '>' SP* Linefeed (Blockquote)*
Line ::= ( (SP* '-') | (SP* '*') ){3,} Linefeed
CodeBlock ::= SP{4,} Inline+ Linefeed
BlockHtml ::= '<' (div|p|table|pre) '>' (Text | BlockHtml)+ 
              '<' '/' (div|p|table|pre) '>'
Text ::= ANY
Emphasis ::= '*' Text '*' | '**' Text '**'
          |  '_' Text '_' | '__' Text '__'
Link ::= '[' ID ']' '(' URL ('"' Text '"')? ')'
ID ::= Text
Image ::= '!' '[' ID ']' '(' URL ('"' Text '"')? ')'
Reference ::= SP{0,3} '[' ID ']' ':' URL ('"' Text '"')?
実装にある正規表現を追ったわけではないのでかなり微妙かつ、BNFの書き方をあんまり良く知らないので正しくはないかも。ルールに書いてないもので、SPとANYはそれぞれスペースと文字(二つ以上続く改行を除く)。Linefeedは改行で。

> Markdownに詳しい方
間違っている可能性が大いにあるので突っ込み大歓迎ですm(_ _)m

2012-02-11

Markdownがいるのだが

一つ前の投稿に関連するのではあるが、Markdown形式で書かれたテキストをHTMLに変換するスクリプトがいる。本家を使えばいいといえばそうなのだが、それでは面白くないのと、ちょっとした理由でSagittarius上のライブラリとしてほしいわけだ。
っでとりあえずいろいろな実装をみてみたが、どれもこれも正規表現でテキストからHTML一気に(まぁ多少ごにょごにょしているが)変換している。そんな中peg-markdownはCで書かれているがPEGでパーサーを作成している。とりあえず参考になるかもしれないと思い文法ファイルを見てみたが、信じられないぐらい複雑な文法をしていた。
正直あんな複雑な文法をガリガリPackratで記述するよりは手書きでパーサー書いた方が早い気がする。あとPackratは割りと機能が足りてない感じがするのでどうしても冗長に書いてやらないといけなくて結構大変というのもある。これはCSVのパーサ書いて感じた。あんな簡単な文法なのに結構面倒だった。

一番楽なのはshowdown辺りの実装を移植することかなぁと思っている。っがテキスト→HTMLと一括でやっちゃうのは正直面白くなくて、テキスト→AST→HTMLと一枚噛ませたいなぁと思っている。問題はこれだと正規表現とは非常に相性が悪く、自前パーサーが必要になる。とりあえず動くものなら前者の実装でもいいのだが、う~ん。
誰か簡単なBNF定義してくれないかなぁ・・・(他人任せ)

ChickenのPackrat

Markdownのパーサーがいるのでpackratを使ってパーサを書こうとしたのだが、いまいち使い方が分からなかった。なので、練習がてらCSVのパーサを書いてみることにしてみた。
とりあえずいい加減なパーサがこんな感じ。
(import (rnrs)
 (packrat)
 (srfi :14 char-set))

(define *text-set* 
  (ucs-range->char-set! #x2d #x7e #f
 (ucs-range->char-set! #x23 #x2b #f
       (ucs-range->char-set #x20 #x21))))
(define (any results)
  (let loop ((acc '()) (results results))
    (let ((ch (parse-results-token-value results)))
      ;; it's just testing
      (if (and ch (char-set-contains? *text-set* ch))
   (loop (cons ch acc) (parse-results-next results))
   (make-result (list->string (reverse! acc)) results)))))
(define (textdata results)
  (any results))

(define parser
  (packrat-parser 
   (begin 
     (define (crlf results)
       (let ((ch (parse-results-token-value results)))
  (case ch
    ((#\linefeed) (make-result "" results))
    ((#\return)
     (let ((ch (parse-results-token-value (parse-results-next results))))
       (if (char=? #\linefeed ch)
    (make-result "" results)
    (field-entry results))))
    (else (field-entry results)))))

     file)

   (file    ((h <- header '#\linefeed r <- records) (cons h r))
     ((r <- records) r))
   (header  ((n <- names) (cons :header n)))
   (records ((f <- fields '#\linefeed r <- records) (cons (cons :record f) r))
     ((f <- fields) (list (cons :record f))))
   (fields  ((f <- field-entry '#\, fs <- fields) (cons f fs)) ;; (1)
     ((f <- field-entry) (list f)))
   (names   ((n <- field-entry '#\, ns <- fields) (cons n ns))
     ((n <- field-entry) (list n)))
   (field-entry ((e <- textdata) e))))

(define (generator p)
  (let ((ateof #f)
 (pos (top-parse-position "")))
    (lambda ()
      (if ateof
   (values pos #f)
   (let ((x (read-char p)))
     (if (eof-object? x)
  (begin
    (set! ateof #t)
    (values pos #f))
  (let ((old-pos pos))
    (set! pos (update-parse-position pos x))
    (values old-pos (cons x x)))))))))

(define (parse-csv p)
  (let ((result (parser (base-generator->results (generator p)))))
    (if (parse-result-successful? result)
 (parse-result-semantic-value result)
 (apply assertion-violation
        (let ((e (parse-result-error result)))
   (list 'parse-csv
         (parse-error-messages e)
         (parse-position->string (parse-error-position e))
         (parse-error-expected e)))))))
(call-with-input-file "test.csv"
  (lambda (p)
    (parse-csv p))))
#|
入力ファイル
aaa,bbb
ccc,ddd,eee
fff,ggg,hhh
a,b,c
出力
((:header "aaa" "bbb")
 (:record "ccc" "ddd" "eee")
 (:record "fff" "ggg" "hhh")
 (:record "a" "b" "c"))
|#
generatorはドキュメントにあったものをちょっと改変しただけ。多分これが基本なんだろう。
かなり適当で本来はCRLFなのがLFだけだったり、エスケープされたものを認識しなかったりするがまぁ動く。気になったのは「/」の使い方で、こんな感じには使えないという不便さであった。
(entry (((/ (e <- escaped) (ne <- non-escaped))) (if e e ne)))
展開されたコードをみたらまぁ納得なのだが、これがやれないとなると結構面倒だよなぁ。あとこのライブラリは「*」とか「+」とか「?」がないので、それらを書こうと思ったら、(1)のように条件を2つ作る必要がある。

やっぱり正規表現をつかってやるべきだろうか。

2012-02-09

srfi-22

現状部分的に実装しているのだが、もう少しまじめに実装するべきだろうか。単にmain関数を特別視するかどうかというだけだが。
正直実装自体は非常に簡単なので(2~3行足すだけ)やるなら悩むことも無く終わるのだが、どうしよう。毎回(command-line)を呼び出すよりは(main args)と書いて参照できた方が楽だよなぁ。特に使い捨てのスクリプトならなおさら。

やるか。