Gauche > Archives > 2013/05/17

2013/05/17 06:35:11 UTCyamasushi
#
(define-syntax define-hoge1
  (syntax-rules ()
    [(_ xx)
      (define-method hoge1 (x)
        (^[o] (xx o x)) )
    ] ) )

(define-syntax define-hoge2
  (syntax-rules ()
    [(_ xx)
      (define-method hoge2 (x)
        (^o (xx o x)) )
    ] ) )

(define-hoge1 list)
(define-hoge2 list)

(print ((hoge1 10) 99) ) ; ---> (99 10)
(print ((hoge2 10) 99) ) ; ---> *** ERROR: unbound variable: o
#
define-syntaxのなかで^xを返すようなmethodを定義するときになぞのエラーが出ます。
2013/05/17 06:43:40 UTCshiro
#
今のマクロシステムのlegacy macroとhygienic macroは相性が悪いんですよね。多分そのせい。マクロシステムを書き直してるのでそのうち直りますが、当面はhoge1のやり方で回避しといてください。
2013/05/17 06:45:16 UTCyamasushi
#
commonmacro.scm のコメント ;; TODO: need to make 'lambda's hygineic!
というのがそれのことなんですね。なんのことかよくわからなかったという・・・・
#
ということは、gauche.recordでもマクロを定義するマクロを使っている部分があるわけですが、そこにも絡んでくるということですか。(<list><uvectot>対応の試みをしているのです。)
#
define-ctor-generatorがマクロを定義するマクロになっていて、それを呼ぶマクロを定義するときに、注意しなければならない、ということですか?
2013/05/17 07:03:03 UTCshiro
#
えーっとhygienic macroとlegacy macroの絡みはもうちょい複雑な話でして、「それのこと」とはちょっと違うんですが、まあrule of thumbとしては「マクロ定義マクロは混ぜると危険」って思っておいていただければと。
#
record.scmの<list>対応はもう私の手元では終わってます。重複作業になるとまずいので念のため。練習で実装するなら構いませんが。
2013/05/17 08:25:19 UTCyamasushi
#
マクロの練習にちょうど良い機会でした。 https://gist.github.com/yamasushi/5597731 gauche.uvectorのコードを拝借して、uvectorのI/Fを実装してみました。list/vectorの実装もマクロでまとめてみました。
2013/05/17 10:55:34 UTCyamasushi
#
(use gauche.record)
#?=(define-record-type (vp (pseudo-rtd <vector>)) #t #t (x) (y) (z) )
#?=((rtd-predicate vp) #(1 2 3))
#|
#?="/home/shuji/gauche/debug/rectest.scm":2:(define-record-type (vp (pseudo-rtd <vector>)) #t #t (x) (y) (z))
#?-    vp-z-set!
#?="/home/shuji/gauche/debug/rectest.scm":3:((rtd-predicate vp) #(1 2 3))
*** ERROR: pseudo record type #<class vp> cannot have a predicate
Stack Trace:
_______________________________________
  0  (rtd-predicate vp)
        At line 3 of "/home/shuji/gauche/debug/rectest.scm"
  1  ((rtd-predicate vp) #(1 2 3))
        At line 3 of "/home/shuji/gauche/debug/rectest.scm"
|#
#
マニュアルには、pseudo record typeにもrtd-predicateが作れるような記述があるのですが・・・・
2013/05/17 22:07:33 UTCyamasushi
#
(with-module gauche.record
  (define-method rtd-predicate ((rtd <vector-pseudo-record-meta>))
    (^o (and
      (is-a? o <vector> )
      (>= (vector-length o) ($ vector-length $ rtd-all-field-names rtd) ) ) ) )
  (define-method rtd-predicate ((rtd <list-pseudo-record-meta>))
    (^o (and
      (is-a? o <list> )
      (>= (length o) ($ vector-length $ rtd-all-field-names rtd) ) ) ) ) )
こんな感じでいいのかなと。