Factor クエックブック


Fator とは
素材
サイト
インストール
起動
初期化ファイル
基本
用語
基本的な word
Hello World!
フィボナッチ数
文字列
文字列を連結する
文字列を数値に変換する
数値
数値を文字列に変換する
ファイル
1行ずつ読み込む
ファイルに書き込む
現在のディレクトリ(current working directory)を取得・設定する
ソケット
TCP
Web
Web ページを取得する
Web サーバを起動する
FFI
開発ツール
実行時間を測定する

Fator とは

FAQ によると Factor は 関数型で、動的型付けで、オブジェクト指向で、スタックベースのプログラミング言語であり、Forth と Lisp を組合せたような言語だそうです。 設計者は Slava Pestov さん。 UI 系や Web 系のライブラリも充実しているようです。

素材

まずは素材からです。

サイト

公式サイト : Factor programming language

planet-factor

インストール

ダウンロードは http://factorcode.org/download.fhtml から。 Windows と Mac OS X は バイナリがあります。 Linux はソースからビルドする必要があります。

ソース Factor-0.91.tar.gz と ブートイメージ boot.x86.64.image をダウンロードします。

tar zxvf Factor-0.91.tar.gz
cd factor
make linux-x86-64
cp ../boot.x86.64.image .
./factor -i=boot.x86.64.image

しばらく待つと factor.image ができあがります。 このあたり Lisp っぽいですね。

起動

./factor でいきなり GUI が起動します。 Windows でも factor-nt.exe をダブルクリックすると同じ GUI が起動します。 ただし、パス名に日本語含まれていると起動できないので注意してください。

初期化ファイル

~/.factor-rc を Factor は起動時に読み込みます。 この中で好きなエディタとボキャブラリのサーチパスを設定しておくと便利です。

エディタは "Factor インストールディレクトリ/extra/editors" から好きなものを選んでください。

! -*- mode: factor ; -*-
USING: io.files vocabs.loader namespaces sequences ;

! Emacs を使う
USE: editors.emacs

! ~/letter/factor/lib を vocab-roots に追加する。
home "letter/factor/lib" path+
vocab-roots get push-new

基本

用語

word
他の言語での関数に相当します。
vocabulary
他の言語でのモジュールに相当します。

基本的な word

.s
スタックの中身を表示します。
.
スタックの一番上のオブジェクトを取り出して表示します。
!
行末までコメントです。
#!
行末までコメントです。シェルスクリプトのためです。
1 2 + .
スタックに 1 をつみます。 スタックに 2 をつみます。 スタックから上から2つオブジェクトを取り出してを足した値をスタックにつみます。 スタックの一番上のオブジェクトを取り出して表示します。
"tetris" run
テトリスが起動します。

Hello World!

: hello "Hello World!" print ;

フィボナッチ数

: fib
  dup 3 <
  [ drop 1 ]
  [ dup 1 - fib swap 2 - fib + ]
  if ;

10 fib .                        ! 55 が返る。
あるいは
: fib 1- 0 1 rot [ dup rot + ] times nip ;

文字列

文字列を連結する

USING: sequences prettyprint ;
{ "abc" "def" "ghi" } concat .    ! "abcdefghi"
{ "abc" "def" "ghi" } ", " join . ! "abc, def, ghi"

文字列を数値に変換する

USING: math.parser prettyprint ;
"123" string>number .

数値

数値を文字列に変換する

USING: math.parser prettyprint ;
123 number>string .

ファイル

1行ずつ読み込む

cleanup を使うか何か他の方法で確実に stream-close できた方がいいのだけど。

USING: kernel io io.files io.streams.lines ;

"/tmp/a.factor" <file-reader> <line-reader>
[ dup stream-readln dup ] [ print ] [ drop stream-close ] while

ファイルに書き込む

<file-write> で上書き、<file-appender> で追記になります。

with-stream ( stream quot — ) はストリームを stdio に束縛して quot を実行するので write でファイルに出力ができます。 さらに、quot を抜けると自動的にストリームをクローズしてくれます。

USING: kernel io io.files ;

! 上書きする
"/tmp/aaa" <file-writer>
[ "こんにちは、Factor。" write ] with-stream

! 追記する
"/tmp/aaa" <file-appender>
[ "\nさようなら。" write ] with-stream

現在のディレクトリ(current working directory)を取得・設定する

USING: io.files prettyprint ;

"/tmp" cd
cwd .
"/home" cd
cwd .

ソケット

TCP

USING: kernel io io.sockets ;

"www.yahoo.co.jp" 80 <inet> <client>
"GET / HTTP/0.9\r\n\r\n" over stream-write
dup stream-flush
[ dup stream-read1 dup ] [ write1 ] [ drop stream-close ] while

Web

Web ページを取得する

USE: http.client "http://www.yahoo.co.jp" http-get write

Web サーバを起動する

"doc-root" 変数でドキュメントルートを指定します。 ポート番号を指定して httpd で Web サーバが起動します。 in-thread でリスナとは別プロセスで起動します。

USING: http.server io.files namespaces threads ;
IN: hello-web

home "letter/factor/try/webapp" path+ "doc-root" set
[ 8883 httpd ] in-thread

FFI

USING: alien.syntax io ;
FUNCTION: char* getenv ( char* name ) ;
"HOME" getenv print

開発ツール

実行時間を測定する

[ 32 fib . ] time
<<36#2EOIWZ250R0HR06ZQ2Z0QG02ICDHOUQFJECQY5IZZYIJKIEUGUF4TD2RFEZQ8NYIP1A:344>>.