racket

『キルリスト』(角川書店)なんて本を読んだ。フレデディク・フォーサイスの最新刊。

アメリカには暗殺対象者のリストが有るらしい。CIAとかFBIが対象者を推薦して、それを 大統領が承認すると晴れてリスト入り。後はその対象者を追跡して始末する特殊必殺仕事人が 請け負う。恐い世界ですなあ。推薦される人は、麻薬王やテロリストの親玉。

キルリストに載った、イスラムの扇動者を追跡者が追う。但しその扇動者は、ネットの闇に 隠れて、無垢な教徒を、聖戦の元にテロリストへと変身させる。

尻尾が掴めない。動画の発信元も特定不能。転送に転送を重ね、ネットのブラックホールから やって来るんだ。さあ、どうする? torとか使ってるんですかね。リバース・プロキシが うんたらカンタラとか言ってたぞ。

ふとしたきっかけで追跡者は、オタクと知り合う。そのオタクはいわゆる社会適合不能者。 ネット上に生きるのみ。そんな彼の協力をどうやって取り付けるか?

追跡者は言う。今一番欲しい物は何? オタクは、6コアで32Mのメモリーを積んだ、 レッドハットのエンタープライズ版Linuxマシンが欲しいと。(おいらも欲しいぞ。でも 電気を喰いそうなので、女房に取り上げられちゃうかな)

そんなシチエーションで、テンポよく話は進んで行く。所々、ビン・ラディンは盗聴を 恐れて、パソコンや携帯は絶対に使わなかったとか、プレディクターと言う無人機は 、ロボット型の殺人飛行機だ、なんて話を添えながら。。。

さすが、良く調べていますな。こういうのは、世界情勢に通じていないと書けないからね。 著者の昔の作品も読み直してみるかな。『ジャッカルの日』とか『戦争の犬達』とかが、 有ったはずだから。

読書メーター 9冊 / 2736頁 / 14229円

racketのインストール

前回arcやろうとしてmzschemeが必要になり、それは現在racketと名前を変えて売り出して いる事を知った。何でまた、ラケットなんだ。球打ちのラケットとぶつかってしまって、 検索が酷い事になってる。ツイター創業物語なんてのを最近読んだけど、命名にはみんな 苦労してるぞ。ラケットと付けた奴、出てこい。小一時間問い詰めてやる。

で、苦労して、Racketのページを見つけておいたから、もう大丈夫。

恐いもの見たさで、入れてみるか。(近頃、Gauche 0.9.4が出たのにか)debian様とうぶ用が用意されてた。けど、臍曲がりの おいらは、万次郎Linuxのパッケージになっていなか確認してみた。そしたら、ちゃんと 用意されてたんで、入れましたとさ。Scheme界では確固たる地位を築いているから、普通に 用意されてるんだ。

でも日本だと余り流行っていないみたいだな。日本語本も出てないし。。。海の向こうだと Land of Lispに対抗して、 Realm of Racketなんてのが有るみたい。 お試しの版が公開されてたので、*漫画* だけ読んでみたぞ。日本語版のLoLすら持って いない輩が言うかね。まあ、許してタモレ。

で、入れたは良いけど、どんなコマンドで起動するの?

[sakae@manjaro ~]$ pacman -Ql racket
racket /usr/bin/drracket
racket /usr/bin/gracket
racket /usr/bin/gracket-text
racket /usr/bin/mred
racket /usr/bin/mred-text
racket /usr/bin/mzc
racket /usr/bin/mzpp
racket /usr/bin/mzscheme
racket /usr/bin/mztext
racket /usr/bin/pdf-slatex
racket /usr/bin/plt-games
racket /usr/bin/plt-help
racket /usr/bin/plt-r5rs
racket /usr/bin/plt-r6rs
racket /usr/bin/plt-web-server
racket /usr/bin/racket
racket /usr/bin/raco
racket /usr/bin/scribble
racket /usr/bin/setup-plt
racket /usr/bin/slatex
racket /usr/bin/slideshow
racket /usr/bin/swindle
 :

binの下だけでも、これだけ有る。全部で400Mを超える程の容量だから、色々な分担が有るのかな? 一番偉そうな名前の、ドクターラケットを起動すると

[sakae@manjaro ~]$ drracket
Gtk initialization failed for display ":0"

どうもXの上で動くっぽい。しょうがないんでXを立ち上げてから起動してみた。昔見たような アプリが上がってきたぞ。このSchemeの出目は、学校の先生達が教材のために作った らしいんで、生徒に不用な負担をかけないように、マウスでぐりぐり出来るように工夫 されてるんだな。

おいらみたいにCUIな人間向けは無いのか? 上記のWebを見てたら、案内に書いてあったぞ。

[sakae@manjaro ~]$ racket
Welcome to Racket v6.0.1.
> (require xrepl)
->
   ,install!
; writing new contents, with an added "(require xrepl)"
; (if you want to load it conditionally, edit the file and
;  use "(dynamic-require 'xrepl #f)" instead, which is a plain expression)
; OK to continue? yes
; new contents written to /home/sakae/.racketrc
-> ,exit

これがCUI人間御用達の環境っぽい。replを拡張して、いろいろ便利に使えるカンマコマンドが 用意されてる。詳しくは、,help で。尚、.racketrcはどうなってるかと言うと

[sakae@manjaro ~]$ cat .racketrc
;; The following line loads `xrepl' support
(require xrepl)

この他にも、.racketって隠しdirが出来ていて、こちらはGUI上での設定とか、コマンド履歴 等を格納してたぞ。

xreplはちょっとした実験に都合がいいんだけど、腰を据えて何かやろうとすると、勝手知ったるemacs上からの方が、 何かと都合が良い。果たしてそんなI/Fが用意されてるのか? ガイドの一番最後に、案内が載ってた。

24.2.1 Major Modesによると、 QuackとGeiserとRacket modeの3大潮流があるんだな。今回はそのうちの Geiserってのを使ってみる。 だって、Lisp machinesのスピリッツを 持ってるなんて、括弧いいじゃん。(単なるミーハーP)

Geiserは簡単に入って、簡単に使えた。チートシートを 見ながらだけど。ああ、emacs上からマニュアルも引けるんだけど、その為のブラウザーに どうもw3mを指定出来ないみたい。drracketで指定したGUI環境のブラウザーが使われちゃう。 (xterm -e sh -c 'w3m ; read line' とかやるのは本末転倒ってもんです。)

Linuxする時X上げるなんて面倒。だったら最初からX相当が上がっているWindows7ででも やればいいんでないかい。

Windowsでもracketするぞ

と言う事で、入れてみた。クリック猿みたいに何も考えないと、あの悪名高き"Program Files" に入ってしまうんでdir名にスペースを含まない所を指定した。 これが生活の知恵ってもんです。

インストールにえらく時間がかかったけど何故? 細かいファイルが ごちゃごちゃと入って、Disk上のサイズが420Mも有ったぞ。かなり大掛かり。まあ、 Firefoxあたりから綺麗に見られるドキュメントも含んでの事ですから、文句を言うまい。

Geiserを入れるには、emacsを新しくしておく必要が有る。重い腰を上げて24.3にした。 こういう機会でも無いと、やらないですからね。ついでに、Windows7側で、使っても いないアプリを多数削除しておいたよ。

Geiserの設定では、racketが何処に有るか指定する必要がある。それにはWindowsの作法に 則り、PATHを通す必要が有るんだけど、そんなの面倒。絶対PATHで在り処を指定した。

;; racket scheme  M-x run-geiser or M-x run-racket
(setq geiser-racket-binary "c:\\app\\racket\\racket")
(setq geiser-active-implementations '(racket))

これで、ラケットマシンというか、ミーハーなLispマシンぽくなったな。

racket scheme のお勉強

さりげなく、ぐぐるの為のSEO対策しときます。(笑)

schemeを教えてくれるサイトは数有れど、racket(mzscheme)に特化したものと言ったら、 独習 Scheme 三週間 を外せない。

そして、お勧めなのがMore: Systems Programming with Racketだ。 スレッドや継続まで繰り出して、サーバーを作ってみせてくれている。

スレッドの事を良く知らないおいらは、スレッドの予習をしましょ。 ガイドに載ってるスレッド で、概要を掴んでから レファレンスにあるスレッド を見るのが、正しい予習方法かな。

どんどん先へ行きます。前に見つけたグラフは書けるのか? 論よりrun。

(require plot)
(plot-new-window? #t)

(parameterize ([plot-width    150]
                 [plot-height   150]
                 [plot-x-label  #f]
                 [plot-y-label  #f])
    (define xs (build-list 20 (了 _ (random))))
    (define ys (build-list 20 (了 _ (random))))
    (list (plot (points (map vector xs ys)))
          (plot (points (map vector xs ys)
                        #:x-min 0 #:x-max 1
                        #:y-min 0 #:y-max 1))))

(plot (lines
         (reverse
          (for/fold ([lst (list (vector 0 0))]) ([i  (in-range 1 200)])
            (match-define (vector x y) (first lst))
            (cons (vector i (+ y (* 1/100 (- (random) 1/2)))) lst)))
         #:color 6 #:label "Random walk"))

これで、散布図2個と、株価チャートもどきの折れ線グラフが出てきた。emacs上から 実行すると、emacsにグラフが張り付く予定だったんだけど、無視されたので、plot-new-window?で、 画面を強制的に作ったよ。なお、了っていう変な文字が混じってるけど、これλ文字が 文字化けしたものです。

Windowsにemacsなんて言う異界のものを入れるから、こういう顛末になるんだな。 もう少し、emacsをWindowsに馴染むように、不毛の戦いをしてみるか。なお、このemacsは、 http://www.t.ring.gr.jp/archives/GNU/emacs/windows/ から取ってきたものです。

(require plot)
(require plot/no-gui)
(require plot/typed/no-gui)

(plot (function sin (- pi) pi #:label "y = sin(x)")
       #:out-file "sin.png"
       #:out-kind 'png)

こちらは、サイン波をpngファイルに落とす例。最初、require plotは必要無いと思って いたんだけど、エラーになったので入れた。って事は、GUI上で動かす事を強要されてて、 何か損した気分。人様に見えない所でグラフを書くんだから、そりゃないよね。

ああ、plotじゃなくて、plot-fileを使えばいいのか。こりゃ、とんだ失態だわな。 でも、おかげで、ちょいとキーワードを追加するだけで、グラフが書ける事が分かり ました。こういうのを、怪我の功名と言うんだな。 (plot-fileを使う時は、キーワード不用。相変わらず、GUI環境じゃないと駄目だけど。)

折角なんで、plot-fileのソースを覗いてみる。コンパイルしてあっても、そのソースが 残っているんで、emacsで言う、hoge.elとhoge.elcみたいなものだな。

/usr/share/racket/pkgs/plot-lib/plot/private/no-gui/plot2d.rktって深い所に有る。

;; ===================================================================================================
;; Plot to a file

(defproc (plot-file [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
                    [output (or/c path-string? output-port?)]
                    [kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
                    [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/crational? #f) #f]
                    [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/crational? #f) #f]
                    [#:width width exact-positive-integer? (plot-width)]
                    [#:height height exact-positive-integer? (plot-height)]
                    [#:title title (or/c string? #f) (plot-title)]
                    [#:x-label x-label (or/c string? #f) (plot-x-label)]
                    [#:y-label y-label (or/c string? #f) (plot-y-label)]
                    [#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
  (define real-kind (if (eq? kind 'auto) (detect-image-file-type output) kind))
  (case real-kind
    [(png jpeg xbm xpm bmp)
     (define bm
       (plot-bitmap
        renderer-tree
  :

どうも、横幅の制限に頓着無いみたいで、80桁の端末で読むのは苦労しそう。きっと マカーな新人類が開発に携わっているに違いない。引数の定義も何となく分かるけど、斬新だしね。

次行ってみよー。CSVファイルって読めるのかな? マニュアルで調べてみると、 read-csv-file ってのと、read-csv-file/rows ってのが出てきた。マニュアルから 思い付いたword(この場合ならcsvとか)で検索出来るのは便利でいいんだけど、javascriptが 使われていて、w3mさんお断りだったよ。時代は変わったねと、年寄りが嘆いていますよ。

[sakae@manjaro racket]$ pwd
/usr/share/doc/racket
[sakae@manjaro racket]$ w3m index.html
  :
Racket Documentation
Search Manuals

License
Acknowledgements
Release Notes

Report a Bug
6.0.1
[...search manuals...]
  top  ← prev uup next →

Search Manuals

Sorry, you must have JavaScript to use this page.
(require 2htdp/batch-io)

(define myfile "smpl.csv")

(read-csv-file myfile)

(read-csv-file/rows myfile
                    (lambda (r) (cons (car r) (cadr r))))

こんなのを作って、順番に評価してみる。(C-x C-eだと、結果がminibufferに出ちゃって、 綺麗にならないため)

それにしても、listのエレメントを取り出すのに、carとかcadrとか、全く旧人類だな。 今風だと、firstとかsecondとか、、、tenthまで用意してるぞ。haskellには完全に勝ってるな。 旧人類でも、cadddrまでは使えるようになってるんで、勝ってるぞ。

racket@> (load "csv.rkt")
'(("130101.03" "118" "80" "60")
  ("130101.21" "107" "67" "72")
  ("130102.05" "121" "76" "57"))
racket@> (load "csv.rkt")
'(("130101.03" . "118") ("130101.21" . "107") ("130102.05" . "121"))

これ、あくまでも結果はstringなので、もう少し上の階層で、数値にするとかが必要。

もう少し上の階層って、そりゃ統計関数を集めた所だな。果たしてそんなのは有るのか?

(require math/statistics) なんてのが有った。気分はPythonっぽいね。おいらの欲しい 物は大体揃っていそう。

ここまで、racketの入力端子と出力端子をチョイ調べてみた。昔々、初めてコンピュータを 習ったのは、TVでやってたFortran講座だったかな。高校生だった頃だから昭和40年台。

そこでコンピュータの5大要素なんてのを大々的に説明してたな。入力、演算、出力、制御、 記憶だったかな。入出力を押さえたので、後は演算、制御、記憶が残るんか。それらは、 おいおいやって行けば良い。焦る事無しにね。

schemeとかは、オイラーの問題を解くのによく使われているけど、果たしてこの5大要素を 万遍なく使っているものかどうか、疑問に思うのね。SICPしかり。ああ、あれは、意識的に 入出力部分を端折っているんだったわい。

Webの作りはMVC、これもちゃんとコンピュータの要素を押さえた仕組みになってるな。

drracketとは

またしてもSEO対策! drracket 使い方 の方が良かったかしら?

drracketを起動してる時、ps awx すると、こんなのが出てくる。

/usr/lib/racket/gracket -N /usr/bin/drracket -J DrRacket -l- drracket/drracket.rkt

gracketって何? そりゃ manセー。

       Run

          gracket --help
MORE INFORMATION
       For further information, run

          raco docs

       to open installed documentation in your web browser.

CUIの人にはお情けで--helpを用意しといたよ。ちゃんとしたのを見たかったら、GUIで やれとな。これにめげずにCUIでやってみる。

  -l <path>, --lib <path> : Like -e '(require (lib "<path>"))' [*]
  -J <name>, ---wm-class <name> : Set WM_CLASS class to <name> (Unix)
  -N <file>, --name <file> : Sets `(find-system-path 'run-file)' to <file>

詳細は、drracket/drracket.rktで、ってコマーシャルだな。

/usr/share/racket/pkgs/drracket/drracket/drracket.rktの尻尾の方に面白いものが 見つかったぞ。プロファイルも出来るのね。

(when profiling?
  (flprintf "PLTDRPROFILE: installing profiler\n")
  ;; NOTE that this might not always work.
  ;; it creates a new custodian and installs it, but the
  ;; original eventspace was created on the original custodian
  ;; and this code does not create a new eventspace.
  (let ([orig-cust (current-custodian)]
        [orig-eventspace (current-eventspace)]
        [new-cust (make-custodian)])
    (current-custodian new-cust)
    ((dynamic-require 'drracket/private/profile-drs 'start-profile) orig-cust)))

(dynamic-require 'drracket/private/drracket-normal #f)

(when repl
  (printf "Welcome to DrRacket, v~a\n" (version))
  (namespace-require 'racket)
  (namespace-require 'drracket/tool-lib)
  (unless (equal? repl "-q")
    (define init-file (find-system-path 'init-file))
    (when (file-exists? init-file)
      (load init-file)))
  (void (thread read-eval-print-loop)))

raco pkg install

racoなんてのが紹介されてたので、helpを簡単に引いておくと

[sakae@manjaro ~]$ raco help pkg
Usage: raco pkg <subcommand> [option ...] <arg ...>
  where any unambiguous prefix can be used for a subcommand

This tool is used for managing installed packages.

For help on a particular subcommand, use 'raco pkg <subcommand> --help'
  raco pkg install         Install packages
  raco pkg update          Update packages
  raco pkg remove          Remove packages
  raco pkg show            Show information about installed packages
  raco pkg migrate         Install packages installed for other version/name
  raco pkg create          Bundle package from a directory or installed package
  raco pkg config          View and modify the package manager's configuration
  raco pkg catalog-show    Show package information as reported by a catalog
  raco pkg catalog-copy    Copy/merge package name catalogs

こういう、gemもどきが見つかりましたよ。見つかったのなら試してみなければ。 pkgのカタログは、racketのホームページに提示されてるんで、適当に選んでくる。

[sakae@manjaro ~]$ raco pkg install gcstats
Resolving "gcstats" via http://download.racket-lang.org/releases/6.0.1/catalog/
Resolving "gcstats" via http://pkgs.racket-lang.org
Downloading https://github.com/samth/gcstats/tarball/b378d1dbcac2813383b536a39b97c6e974cd76a4
   :
raco setup: making: <pkgs>/gcstats/gcstats
raco setup:  in <pkgs>/gcstats/gcstats
raco setup: --- creating launchers ---
raco setup: --- installing man pages ---
raco setup: --- building documentation ---
raco setup: --- installing collections ---
raco setup: --- post-installing collections ---

インストールは、~/.racketの中に納まるのね。成果確認

[sakae@manjaro scm]$ racket -l gcstats -t "tak.rkt"
default-load-handler: expected a `module' declaration
  found: something else
  in: #<path:/home/sakae/src/scm/tak.rkt>


      2,326,704 bytes allocated in the heap
      1,841,328 bytes collected by GC
      2,098,636 bytes max heap size
      5,932,920 bytes max slop
      6,381,568 bytes peak total memory use

Generation 0:       2 collections,       20ms,    16.90ms elapsed
Generation 1:       0 collections,        0ms,        0ms elapsed

INIT  time        76 ms
MUT   time        80 ms (     94.73 ms elapsed)
GC    time        20 ms (     16.90 ms elapsed)
TOTAL time       176 ms (    187.62 ms elapsed)

Max pause time:       9.17 ms
%GC time             20.00 %   ( 15.14 % elapsed)

Alloc rate     29,083,800 bytes per MUT second

結果の見方は、gcstatsに出てた。

racketで実行ファイル作成

racoのメニューにexeなんてのが有って、調べてみたら単独の実行ファイルが作れるみたい。 これはもうやってみる鹿。

[sakae@manjaro scm]$ cat tak.rkt
#lang racket

(define (1- n) (- n 1))

(define (tak x y z)
  (if (not (< y x))
      z
      (tak (tak (1- x) y z)
           (tak (1- y) z x)
           (tak (1- z) x y))))

(display (tak 18 9 0))

毎度代わり映えしないやつ。味噌は1行目の、どんな種類かの指定。

[sakae@manjaro scm]$ raco exe -o zz tak.rkt
[sakae@manjaro scm]$ file zz
zz: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=97cf44043709d39bab1cd53777c02f98501a0d32, stripped
[sakae@manjaro scm]$ ldd ./zz
        linux-gate.so.1 (0xb775d000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0xb76fc000)
        libc.so.6 => /usr/lib/libc.so.6 (0xb753a000)
        /lib/ld-linux.so.2 (0xb773c000)

出来上がったファイルのサイズは5.1M有ったよ。みんな込みって方針だな。