schemeのパラメータオブジェクトの使い方を調べた。

r7rsでは標準。

パラメータオブジェクトは、値を束縛して動的存続期間中にその値を変更できるオブジェクト。
make-parameterで、パラメータオブジェクトを作れる。

(define foo (make-parameter 123))
(foo);123



パラメータオブジェクトに値を渡した時の挙動は処理系依存とされているが、 CHICKEN,picrinなど、値を変更するケースが多い。

(foo);123
(foo 100)
(foo);100



parameterizeを使うと、その中でのパラメータオブジェクトが返す値を変更できる。

(foo);123
(parameterize ((foo 10)) (foo));10
(foo);123



make-parameterに2つ引数(init converter)を渡すと、初期化や値の変更時に converterを通した値がセットされる。

(define boo (make-parameter 123 (lambda (x) (* x x ))))
(boo);15129
(boo 3);9

python-mechanizeでログインするぞ。

mechanizeは、スクレイピングとか用のweb操作ライブラリ。
標準ではないのでpip等でinstall。

で、ためしにログイン画面をつくってmechanizeでアクセスする。
ログイン画面はこんなかんじ。

index.html

<html>
    <head>
    </head>
    <body>
        <form name="LOGIN" action="/cgi-bin/form_test.py">
            USERNAME <input type="text" name="USERNAME"></input><br>
            PASSWORD <input type="text" name="PASSWORD"></input><br>
            <input type="submit"></input>
        </form>
        <div id="foo"></div>

    </body>
</html>

cgi-bin/form_test.py

#!/usr/bin/env python
import cgi

print "Content-Type: text/html\n\n"

print "<html><body>"

form = cgi.FieldStorage()

name = form["USERNAME"].value
password = form["PASSWORD"].value
if name == "user" and password == "pass":
    print "OK"
else:
    print "ERROR"


print "</body></html>"

ユーザ名がuserで、パスワードがpassだとOK、それ以外だとERRORと出力するようにした。
クライアントは以下

#coding:utf-8
import mechanize
URL = "http://127.0.0.1:8000"

#ブラウザオブジェクトを生成
br = mechanize.Browser()
#robot.txtを無視
br.set_handle_robots(False)

#アクセス
br.open(URL)

#form情報を作る
br.select_form(name="LOGIN")
br["USERNAME"] = "user"
br["PASSWORD"] = "pass"

#submit
ret = br.submit()

#帰ってきたhtmlを見る
print ret.read()


以上。

openboxにターミナル起動キーバインドを追加しました。

ctrl+alt+tでターミナルエミュレータを起動するようにする。
~/.config/openbox/rc.xmlキーバインド関係の設定がある。

<keybord>内に以下のような感じで書き加える。
こちらの環境では、lilytermを使っている。

    <keybind key="C-A-t">
        <action name="Execute">
            <command>lilyterm</command>
        </action>
    </keybind>

修飾キーの略語は、
C:Control
A:Alt
S:Shift
W:windows key
のような感じ。

gentooにtint2をいれました。

openboxのお供にする。

インストール

ランチャー機能がある0.12以上を入れる。

emerge --ask xdotool   
emerge --ask "=x11-misc/tint2-0.12.3"   

コンフィグを修正

~/.config/tint2/tint2rcを編集する。
初期状態では、そんざいしないアプリケーションへのリンクとかがあるので、
#Launcharの#launcher_item_app から始まるものをすべてコメントアウトする。

アプリケーションをメニュに加える

.desktopファイルを追加するだけでよい。
例えば、forefox-binだと、
.desktopファイルをapplications下において、

cp /usr/portage/www-client/firefox-bin/files/firefox-bin.desktop /usr/share/applications/

コンフィグファイルに追加する。

launcher_item_app = /usr/share/applications/firefox-bin.desktop


おしまい。
f:id:niyarin-man:20160921171606j:plain

schemeのcaseについて

キーと各データをどう比較しているのか気になったので調べた。
r5rsによるとeqv?で比較しているそうだ。(4.2.1)
というわけで、
・symbol、char、symbol、空リストは見た目が同じならよい。
・数値は、正確数同士か不正確同士で数値的に等しければよい。
・文字列、リスト、ベクタはアドレスが同じならばよい。
ということですな。

3impの3章を読みました。

3impの3章は、schemeのheap型VMとそのコンパイラの実装について書かれている。
コードを見てだいたい分かったので文のほうはさらっとしか読んでないけど。

vm用コードもs式
レジスタは、a,x,e,r,sの5つで、それぞれ(アキュムレータ(返り値とか次のコードで使うための一時保存領域?)、次に実行するコード、引数の一時置き場、コールスタック)
・aとrを統合してもいいのではないか?
・構文は、if、lambda、set!,quoteをサポートしている(いくつか機能は省かれている)
・call/ccもある。
・ただしVM上に継続の補足と呼び出しを実装しているので、手続きではない。
レジスタと次に実行するコードをまとめてオブジェクトにするという形で実現している。

ちょっと拡張

pythonで実装して、lambdaのbodyが2つ以上の式でも動くように拡張した。
コンパイラに手を加える。
FRAME命令をつなげてできそう。

・FRAMEについて

(FRAME A B)

・B実行後Aを実行する。
・aレジスタはB実行時のものを、それ以外はFRAME実行時のを
・BからAにつなげるためBにはRETURNが含まれている必要あり。

以上をふまえて

            c = ["RETURN"]
            for b in  bodies:
                bi = compiler(b,["RETURN"])
                if (c[0] == "RETURN"):
                    c = bi
                else:
                    c = ["FRAME",bi,c]
            compiled_body = c