Gaucheでリスト内包表現にチャレンジ(まずは..)

まだマクロが全然わかってないんだがとりあえずやってみたい気持ちが先行中(笑)
ということで実装してみたのがこれ。

>>(define .. (lambda (x y) (let ((e (- y x -1))) (if (< e 0) () (iota e x)))))
=>..

>>(.. 0 10)
=>(0 1 2 3 4 5 6 7 8 9 10)

>>(.. -1 -10)
=>()

>>(.. -10 -1)
=>(-10 -9 -8 -7 -6 -5 -4 -3 -2 -1)

うーん。ここまではhaskellと同じだが、嫌な予感がした小数はどう動く?

Prelude List> [1.1..1.5]
[1.1]
Prelude List> [1.1,1.2..1.5]
[1.1,1.2,1.2999999999999998,1.3999999999999997,1.4999999999999996]

なんだよ、この動きは無視しちゃおうかな。

次にやらなければならないのは [1..3]みたいな個別括弧なんだろうが…なんか実験してると全ての括弧は()の代用品になる?

>>{car '{1 2 3}}
=>1

>>[car '[1 2 3]]
=>1

ねえ、全部予約なの(笑)
どうしてくれよう。マクロでこんなことができるのか興味が湧いてきた。

いかんその前に増分[1,3..10]=>[1,3,5,7,9]に対応しなきゃ

>>(define .. (lambda (x y . z) (let* ((s (if (null? z) 1 (- y x))) (e (if (null? z) y (car z)))) (if (< e 0) () (iota e x s)))))
=>..

>>(.. 1 2 10)
=>(1 2 3 4 5 6 7 8 9 10)

>>(.. 1 3 10)
=>(1 3 5 7 9 11 13 15 17 19)

こりゃへこむな。10までって意味だもんな。終了条件変えなきゃいけないので自前でつくるか。明日にしよう。

とりあえず、filterで着陸したのが以下(cut大活躍)

>>(define .. (lambda (x y . z) (let* ((s (if (null? z) 1 (- y x))) (e (if (null? z) y (car z)))) (if (< e 0) () (filter (cut <= <> e) (iota e x s))))))
=>..

>>(.. 1 2 10)
=>(1 2 3 4 5 6 7 8 9)

>>(.. 1 3 10)
=>(1 3 5 7 9)

追記:filterやめてみたが美しくない。

>>(define .. (lambda (x y . z) (let* ((s (if (null? z) 1 (- y x))) (e (quotient (- (if (null? z) y (car z)) x -1) s))) (if (< e 0) () (iota e x s)))))