こんにちは。やすといいます。 Schemeを勉強中ですが、まだメリットが良く分かりません。このままだと、再帰のお勉強はするけど、実際には使わないということになりかねません。(^^; まずは、使ってみます!
2002/06/05
(2003/06/02 21:54:33 PDT)下の方法でオブジェクトが作成できません。make <~> は分離ができないのでしょうか?
(define def '(<Dog> :name "pochi" :age 3))
(apply make def)
=>*** ERROR: no applicable method for #<generic make (1)>
with arguments (<Dog> :name "pochi" :age 3)
(define def '(:name "pochi" :age 3)) (apply make <Dog> def) =>OK
P.S. Gauche0.7リリースおめでとうございます
(define var <Dog>) ;; クラスそのものをvarに束縛 (make var :name "pochi" :age 3) ;; 動作するはず (define def (list <Dog> :name "pochi" :age 3)) (apply make def) ;; これも動作するはず
[dog.txt] (<Dog> :name "pochi" :age 3)
gosh> (define l (with-input-from-file "dog.txt"
(lambda ()
(car (port->sexp-list (current-input-port))))))
gosh> (define (make-dog l)
(let ((c (eval (car l) (interaction-environment)))
(p (cdr l)))
(apply make c p)))
gosh> (make-dog l)
[メモ] CGI(escm)プログラミングにおいて、sys-getenvは使えなかった。cgi-parse-parametersを使うこと。
(ただし、(sys-getenv "HTTP_ACCEPT_LANGUAGE")は使えた)
NG (display (sys-getenv "HTTP_COOKIE"))
OK (display (cgi-parse-parameters :query-string "" :merge-cookies #t) )
(2002/12/21 19:14:36 PST)
Shiro (2002/12/23 06:01:35 PST): あれれ。 cgi-parse-parametersも中では結局sys-getenvを呼んでいるんですが、 なんででしょ。どんな不都合が出ましたか。
[メモ] CGIプログラミングにおいて、random-integerを使うと同一値が発生する。当然、インタラクティブセッションでは乱数が発生する。CGIにおいてはmt-random-integerを使うこと。
NG (random-integer 10000)
OK (define m (make <mersenne-twister> :seed (sys-time))) (mt-random-integer m 100000)
Shiro: あれ、(random-source-randomize! default-random-source)すれば いいはず…と思って確かめてみたら、それでも同一シーケンスになりますね。 mt-random-set-seed!にバグがある模様。→Gauche:Bugs (2002/12/21 16:45:01 PST)
早くも2002年を振り返ってみます。今年、やっとSchemeでCGIプログラミングができるようになりました。いろいろなアドバイスをしていただき、感謝です。
そこで、いっぱし気取りで語ります。小さなプログラムなので、速度に不満はないです。でもCGIプログラミングをやっていると、リクエスト毎にSlibのデータベースを読みにいくようなコーディングは気持ち悪いです。やっぱり、Tomcatみたく、マルチスレッドで動いて、コネクションプールも用意したいです。 来年は、Schemeのマルチスレッドと関数プログラミングの深い部分にタッチしたいです。来年もよろしく、お願いします。_o_
2002/12/12 05:36:35 PST
=> *** ERROR: Read error at "(stdin)":line 8: extra close parenthesis Stack Trace:
(html:form :method "POST" :name "form1" action "foo.cgi" (html:input :type "hidden" :name "command" :value "doThat") (html:a :href "#" :onClick "document.form1.submit();return false" "実行"))
[同じ事をhtmlで書くと]
<FORM method=post name="form1" action="foo.cgi">
<INPUT type=hidden name="command" value="doThat">
<A HREF='#' onClick="document.form1.submit();return false">実行</A>
</FORM>
CGIを使っていると、$ENV{'HTTP_ACCEPT_LANGUAGE'}というような環境変数を使いたくなります。Gaucheではどのような方法があるでしょうか?
犬飼さんの「入門Scheme(公開版)」を参考にして、データベースを使ってみました。
(Slib編)
(use slib)
(require 'database-utilities)
(define zrdb (create-database "zosho.db" 'alist-table))
;; デスクリプタを定義
((((zrdb 'create-table) '*nengo-table-desc* '*columns*) 'row:insert*)
'((1 #t 年号 symbol? symbol)
(2 #t 始め #f uint) ;変更前 (2 #t 始め #f uint)
(3 #t 終り #f uint))) ;変更前 (3 #f 終り #f uint)))
;; テーブルの定義
(((zrdb 'create-table) '年号テーブル '*nengo-table-desc*))
;; テーブルのクローズ
((zrdb 'close-database))
;; テーブルのオープン
(define zrdb (open-database! "zosho.db"))
;; 追加
((((zrdb 'open-table) '年号テーブル #t) 'row:insert*)
'((元治 1864 1865)
(慶応 1865 1868)
(明治 1868 1912)
(大正 1912 1926)))
((zrdb 'write-database) "zosho.db")
;; 追加
((((zrdb 'open-table) '年号テーブル '年号デスク) 'row:update)
'(文久 1861 1864))
;; ブラウズ
(require 'database-browse)
(browse zrdb)
((((zrdb 'open-table) '年号テーブル #f) 'for-each-row)
(lambda (row)(write row)(newline)))
;; => 表示される
;;ここをコメントアウトしました ((zrdb 'close-database))
;; 検索
(define z-open ((zrdb 'open-table) '年号テーブル #f))
((z-open 'get* '年号))
;; => (文久 大正 明治 慶応 元治)
((z-open 'row:retrieve*) '明治)
;;=> ((明治 1868 1912))
;; 「1912」年に「始め」のrowを見つける ((z-open 'row:retrieve*) #f '1912) ;; => *** ERROR: too many keys: (#f 1912)
これって、Slibの仕様変更かな?
Shiro: あれれれ。私のところ(Gauche 0.6.2+slib 2d4)だと上の「検索」 のところでエラーになってしまいました。 slibのコードは高階関数を使いまくりで抽象化しているので、何をやっているのか 追うのがしんどいですな。ぼちぼち見てみます。(2002/09/20 02:10:16 PDT)
((((zrdb 'create-table) '*nengo-table-desc* '*columns*) 'row:insert*)
'((1 #t 年号 symbol? symbol)
(2 #t 始め #f uint)
(3 #t 終り #f uint)))
((z-open 'row:retrieve*) #f #f 1912) ;; => ((明治 1868 1912))
(define-class point ()
((x :init-value 1 :init-keyword :xx :accessor xxx)
(y :init-value 2 :init-keyword :yy :accessor yyy))
)
(define-method move ((p point) dx dy) (inc! (slot-ref p 'x) dx) (inc! (slot-ref p 'y) dy))
(define-method write-object ((p point) port)
(format port "[point ~a ~a]"
(slot-ref p 'x)
(slot-ref p 'y)))
(define i (make point)) ;; Point i = new Point() <java> (define j (make point :xx 10 :yy 20)) ;; Point j = new Point(10,20) <java>
(xxx j) => 10 ;; j.xxx() (yyy j) => 20 ;; j.yyy()
(slot-ref i 'x) => 1 (slot-ref i 'y) => 2
(move i 100 200) => *** ERROR: no setter defined for procedure #<subr slot-ref>
(inc! (slot-ref i 'x) 1) => *** ERROR: no setter defined for procedure #<subr slot-ref>
#! /usr/local/bin/escm -c
#? /usr/bin/gosh
Content-type: text/html
<head></head>
<?
(use www.cgi)
(define param-list ())
(define (main args)
(cgi-main
(lambda (params)
`(,
(set! param-list params)))))
(main '())
!>
<head></head>
<body>
<?
上の手続きにより、param-listを使えました。
!>
</body></html>
Webフレームワークには以下のようなメリットを列記してみます。
Schemeの表現は、メソッドが列記されているだけで、人間に優しい形になっていないように見えます。オブジェクト指向のように、人間のイマジネーションを刺激するような形にはなるのでしょうか? それとも関数型プログラミングでは、人間のイマジネーションを刺激しなくてもよく、ただ数学的であるだけで全部解決できてしまうのでしょうか?
(define animal-human-run (略))
(define animal-human-eat (略))