Hatena::Groupocaml-nagoya

yoshihiro503の関数的日記

2012-05-24 (Thu)

CentOSでocamlからmysqlを扱う

| 16:59 | CentOSでocamlからmysqlを扱う - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - CentOSでocamlからmysqlを扱う - yoshihiro503の関数的日記

CentOS-6では yummysql-develをインストールしても、libmysqlclient.a が得られないようだ。

libmysqlclient.aがあるかどうかはlocateコマンドで確かめることができる。

 $ locate libmysqlclient
/usr/lib/mysql/libmysqlclient.so
/usr/lib/mysql/libmysqlclient.so.16
/usr/lib/mysql/libmysqlclient.so.16.0.0
/usr/lib/mysql/libmysqlclient_r.so
/usr/lib/mysql/libmysqlclient_r.so.16
/usr/lib/mysql/libmysqlclient_r.so.16.0.0
 $ locate libmysqlclient.a
 $

OCamlからMysqlを使う場合はocaml-mysql(執筆時version 1.1.0)を通常使うが、ocaml-mysqlのビルド時にlibmysqlclient.aがないとリンクがうまくされないという問題がある。これでは、ocaml-mysqlのインストール自体はエラーなく出来るが、それを使ったプログラムのコンパイルが失敗する。

例えば次のようなエラーメッセージが出てしまう。

/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `stmt_finalize':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:805: undefined reference to `mysql_stmt_close'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `res_finalize':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:350: undefined reference to `mysql_free_result'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `caml_mysql_stmt_status':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1080: undefined reference to `mysql_stmt_errno'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `caml_mysql_stmt_close':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:859: undefined reference to `mysql_stmt_close'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `caml_mysql_stmt_insert_id':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1072: undefined reference to `mysql_stmt_insert_id'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `caml_mysql_stmt_affected':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1064: undefined reference to `mysql_stmt_affected_rows'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `caml_mysql_stmt_execute':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:986: undefined reference to `mysql_stmt_param_count'
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1000: undefined reference to `mysql_stmt_bind_param'
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1008: undefined reference to `mysql_stmt_execute'
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1018: undefined reference to `mysql_stmt_field_count'
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1028: undefined reference to `mysql_stmt_bind_result'
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:1015: undefined reference to `mysql_stmt_error'
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:987: undefined reference to `mysql_stmt_param_count'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `db_fields':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:605: undefined reference to `mysql_num_fields'
/usr/local/lib/ocaml/site-lib/mysql/libmysql_stubs.a(mysql_stubs.o): In function `db_proto_info':
/home/itp/archives/ocaml-mysql-1.1.0/mysql_stubs.c:636: undefined reference to `mysql_get_proto_info'
...

これを解決するためにはocaml-mysqlをビルドするときの configure で環境変数のLDFLAGSを設定しておけばよい。

例えば上で調べたように libmysqlclient.so の場所が /usr/lib/mysql/ だった場合、次のように ocaml-mysql をインストールし直せばよい。

 $ cd ocaml-mysql-1.1.0
 $ env LDFLAGS='-L/usr/lib/mysql' ./configure
 $ make clean
 $ make all
 $ make opt
 # make uninstall
 # make install

2012-05-23 (Wed)

omakeをocaml-3.12.1でビルドする

| 16:59 | omakeをocaml-3.12.1でビルドする - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - omakeをocaml-3.12.1でビルドする - yoshihiro503の関数的日記

ocamlを使っている人はomakeをソースからビルドしてインストールすることができる。インストール方法は次の3ステップだ。

 $ make bootstrap
 $ make all
 # make install

しかし、ocaml-3.12.1 を使っている人がomake-0.9.8.6-0.rc1とかをソースからインストールしようとしたら、make all の段階で次のようなエラーが出る。

+ ocamlopt.opt -warn-error A -w Aez -I . -c lm_debug.ml
File "lm_debug.ml", line 176, characters 6-45:
Warning 9: the following labels are not bound in this record pattern:
info_info
Either bind these labels explicitly or add `; _' to the pattern.
File "lm_debug.ml", line 192, characters 13-53:                ] 00830 / 01203
Warning 9: the following labels are not bound in this record pattern:
info_info
Either bind these labels explicitly or add `; _' to the pattern.
File "lm_debug.ml", line 230, characters 16-61:
Warning 9: the following labels are not bound in this record pattern:
info_name
Either bind these labels explicitly or add `; _' to the pattern.
File "lm_debug.ml", line 1, characters 0-1:                                    
Error: Error-enabled warnings (3 occurrences)
*** omake: 834/1203 targets are up to date                                     
*** omake: failed (20.28 sec, 218/218 scans, 165/188 rules, 454/1637 digests)
*** omake: targets were not rebuilt because of errors:                         
   src/libmojave/lm_debug.cmx
   src/libmojave/lm_debug.o

この原因はomakeのビルドにおいてほとんどの警告をコンパイルエラーにしている設定と、OCamlがversion-3.12になったときに微妙にrecordに関する警告をキツくしたことである。

この問題はプロジェクトルートにあるOMakefileを編集してOCAMLFLAGSの設定を変えれば、解決する。

OCAMLFLAGS[] += -w Ae$(if $(OCAML_ACCEPTS_Z_WARNING), z)

↓ この行をつぎのように書き換える

OCAMLFLAGS[] += -w ae$(if $(OCAML_ACCEPTS_Z_WARNING), z)

2011-08-04 (Thu)

ocamltter 1.6.0リリース

| 20:05 | ocamltter 1.6.0リリース - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - ocamltter 1.6.0リリース - yoshihiro503の関数的日記

実験的におしゃべり機能を付けてみました。config.mlのtalkをtrueにすることで有効になります。mpg123などのmp3再生コマンドが必要です。

https://github.com/yoshihiro503/ocamltter/downloads

cmoncmon2011/08/05 19:32ツイッターのユーザー名とパスワードはどこで設定するのでしょうか?

yoshihiro503yoshihiro5032011/10/03 13:55oauthを使っており、ユーザー名、パスワードを直接設定する必要はありません。初回起動時に表示されるURLにしたがってPINを入力してみてください。

DaveighDaveigh2011/12/11 14:59Thanks for wrtiing such an easy-to-understand article on this topic.

2010-03-27 (Sat)

TwitterクライアントOCamltterを作ってみた

| 10:24 | TwitterクライアントOCamltterを作ってみた - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - TwitterクライアントOCamltterを作ってみた - yoshihiro503の関数的日記

[追記: 2010 09/13]

この記事は古いです。最新版は ProofCafe - ocamltter をごらんください。

OCamlの対話環境で動作する Twitter クライアント

f:id:yoshihiro503:20100325235611p:image

リポジトリはこちら:

http://github.com/yoshihiro503/ocamltter

ダウンロードはこちら:

http://github.com/yoshihiro503/ocamltter/downloads

必要なもの

コンパイル

  • compile.shを実行すればO.K.

使い方

  • ./ocamltter で起動、Twitterユーザー名とパスワードを入力
  • まず open Top;; でTopモジュールをオープンする
  • いくつかのコマンド(関数)が使用できる。
  • 終了は#quit;;

コマンド一覧

コマンド名 説明
l() タイムラインを取得する
l ~c:N () 長さN件数だけタイムラインを取得する
u "TEXT" 文字列TEXTをポストする
re ID "TEXT" IDのステータスに対してリプライする
rt ID IDのステータスに対してリツィートする
qt ID "TEXT" IDのステータスに対してコメント付きでQTする
help() コマンドのリストを表示する

カスタマイズ

top.mlを書き換えてカスタマイズが可能。カスタマイズしたらリコンパイル(./compile.sh)しよう。

  • ユーザー名等を記入しておく
  • 独自のコマンド(関数)を定義する

camlspottercamlspotter2010/03/27 21:45toplevel で日本語が表示されている例という意味で貴重だなと思いました。

yoshihiro503yoshihiro5032010/03/28 11:24すみません。標準出力にprint_endlineで出しています。

DeryaDerya2012/04/09 01:27It's a pleasure to find soomene who can think so clearly

2009-05-02 (Sat)OCamlRuby更新

OCamlRubyをさらに更新

| 22:53 | OCamlRubyをさらに更新 - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - OCamlRubyをさらに更新 - yoshihiro503の関数的日記

OCamlRubyを更新した。

現在のコードの行数は512行

http://bitbucket.org/yoshihiro503/ocamlruby/

新しく追加したのはブロック構文とラムダ式、さらに無名クラスなども定義した。

OCamlRubyの特徴は全てのものが式であること。このことによって内部の実装が非常にシンプルになった気がする。

具体的な内部構造は以下。

type expr =
  | Ignore of expr * expr  (* 式 e1を実行して, e2 *)
  | Call of obj * string * expr list    (* 関数呼び出し、またはメソッド呼び出し *)
  | Assign of string * expr    (* 変数へ代入 *)
  | If of expr * expr * expr    (* if 式 *)
  | Literal of literal    (* 数値やブール等の定数値 *)
  | Variable of string    (* 変数 *)
  | FunDef of string * string list * expr    (* 関数定義 *)
  | ClassDef of string * expr    (* クラス定義 *)
  | Const of inst    (* 評価済みのオブジェクト(内部で使用) *)
  | External of (inst -> expr)    (* OCamlの関数(内部で使用) *)
and obj = Obj of expr | Self

パースできるブログラムのBNFはこんな形式

	<program> ::= <expr>
	
	<expr> ::= <lterm>*
	<lterm> ::= <rterm> ( [ "&&" | "||" ] <rterm> )*

	<rterm> ::= <aterm> ( [ "==" | "<=" | .. | ">" ] <aterm> )*

	<aterm> ::= <mterm> ( [ "+" | "-" ] <mterm> )*

	<mterm> ::= <factor> ( ["*" | "/" ] <factor> )*

	<factor> ::= <factor1> <factor_next>

	<factor1> ::= <ident> "=" <lterm>
		    | <ident> "(" <expr> "," .. "," <expr> ")"
	    	    | <ident> <block>
		    | <ident>
		    | "def" <ident> "(" <ident> "," .. "," <ident> ")" <expr> "end"
		    | "def" <ident>  <expr> "end"
		    | "class" <ident>  <expr>  "end"
	    	    | "class"  <expr>  "end"
		    | <block>
		    | "lambda" <block>
		    | "(" <expr> ")"
		    | "if" <expr> "then" <expr> "else" <expr> "end"
		    | <literal>
		 
	<factor_next> ::= "." <ident> "(" <expr> "," .. "," <expr> ")"  <factor_next>
		        | "." <ident>  <block> <factor_next>	
			| "." <ident>  <factor_next>
		        | <e>

	<block> ::= "{"  "|" <ident> "," .. "," <ident> "|" <expr> "}"
		  | "do" "|" <ident> "," .. "," <ident> "|" <expr> "end"

	<literal> ::= <string> | <int> | <bool>

実装した構文
================

	- メソッド定義
	- クラス定義
	- 関数呼び出し
	- フィールド参照
	- 変数代入
	- if式
	- リテラル(文字列、数値、真偽値)
	- インスタンス変数
	- 四則演算
	- 大小比較
	- bool演算
	- 引数が無いメソッドの括弧省略
	- ブロック構文、ラムダ式
	- 無名クラス、無名関数


まだないもの
====================
	
	- 配列
	- 特殊なリテラル(範囲、シンボル、正規表現など)
	- 引数カッコの省略
	- 継承、モジュール

OCamlRuby更新

| 17:54 | OCamlRuby更新 - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - OCamlRuby更新 - yoshihiro503の関数的日記

http://bitbucket.org/yoshihiro503/ocamlruby/


  • ファイル読み込みからパージングを lazy list を使った実装に変えた。文字の lazy list として読み込み、トークンの lazy list にして、 パースするようにした。
  • シンボルテーブルをHashにした。
  • フィールドをたくさんつなげれるようにした。(a.foo().bar().hoge("hallo"))
  • インスタンス変数を実装した。
  • newしたときにinitialize関数が呼ばれるようにした。

実装した構文
================

	- メソッド定義
	- クラス定義
	- 関数呼び出し
	- フィールド参照
	- 変数代入
	- if式
	- リテラル(文字列、数値、真偽値)
	- インスタンス変数
	- 四則演算
	- 大小比較
	- bool演算
	- 引数が無いメソッドの括弧省略


まだないもの
====================
	
	- 配列
	- 特殊なリテラル(範囲、シンボル、正規表現など)
	- ブロック構文
	- 引数カッコの省略
	- 継承、モジュール

2009-04-29 (Wed)RubyのインタープリタをOCamlで実装してみた。

RubyのインタープリタをOCamlで実装してみた。

| 21:48 | RubyのインタープリタをOCamlで実装してみた。 - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - RubyのインタープリタをOCamlで実装してみた。 - yoshihiro503の関数的日記

Ruby言語のことをよく知らないので、CSNagoyaの読書会に参加している。次回までちょっと日があいていたのでインタープリターを実装してみた。Objective Caml 言語を使って実装した。

外部ライブラリは使用せず、OCamlの標準ライブラリのみを使った。

プログラムの行数は今のところ全部で415行

フィボナッチを実行してみる。

def fib (n)
  if n <= 2 then
    1
  else
    fib (n - 1) + fib (n - 2)
  end
end

puts (fib (20))

実行結果

 $ time ./ocamlruby fib.rb 
6765

real    0m0.038s
user    0m0.034s
sys     0m0.004s

さらに構文を拡張して関数内クラスや 式の中で関数定義などができるようにした。

次のようなコードが書ける

def hoge()
  def huga(x)
    class X
      def s ()
        "bunbun "
      end
    end
    (X.new()).s() + x
  end
  puts (huga(x))
end


d =
  class D
    def foo (x)
      x + 5
    end
  end.new()

puts (d.foo(3))

詳しい構文のBNFは以下。すべてを式(expression)と扱うことにしたので、シンプルかつ柔軟性が高くなったと思う。

http://bitbucket.org/yoshihiro503/ocamlruby/src/tip/README

2009-04-26 (Sun)Rubyのパーサーを実装してみた

OCamlでRubyのパーサー

| 00:06 | OCamlでRubyのパーサー - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - OCamlでRubyのパーサー - yoshihiro503の関数的日記

Rubyのサブセットmin_rubyのパーサーをOCamlで実装してみた

http://bitbucket.org/yoshihiro503/min_ruby/ (* 引っ越しました *)

http://bitbucket.org/yoshihiro503/ocamlruby/

プログラムは今のところ全部で232行

実装した構文
================

	- メソッド定義
	- クラス定義
	- 関数呼び出し
	- フィールド参照
	- 変数代入
	- if式
	- リテラル(数値、真偽値)
	- 四則演算
	- 大小比較
	- bool演算


まだないもの
====================
	
	- 文字, 文字列, 配列
	- 正規表現
	- ブロック構文
	- 範囲リテラル
	- シンボル
	- 省略可能な引数
	- 引数カッコの省略
	- インスタンス変数
	- 継承
	- モジュール

例えば次のコードをパースできる。

class C
  def f (x, y)
    if (4 * x == 4 || 3 * (y+2) >= 6+1) then
      true
    else
      false
    end
  end
  
  def g ()
    f (0, 1)
  end
end

class D
  def foo ()
    puts 5
  end
end

def fib (n)
  if n <= 2 then
    0
  else
    (fib (n - 1)) + (fib (n - 2))
  end
end

puts (fib (3))

字句解析はgenlexモジュールを使って、パーサーはHaskellのParsecのようなコンビーネータを作って、それを使った。参考にしたのは以下の文献