ktat.gauche RSSPLAIN

Related pages:
5515555543455155555555555555555555511111155555555555555555555555555555555555555555533333555555555350000005551535555555553333533333333333333333333333333333332333233332233333332333333323333333331111111111111111111111111111111111111111111111111111
5

Gauche の練習

5

 

1

ktat が Gaucheの練習をするページ。

5

Perlから採り入れたものもあるらしいし、親近感わいた感じ。

5

 

5

突っ込み歓迎。勝手にcommit歓迎。

5

でも、基本、独り言のように書き散らしてるだけです...。

5

 

4
 をを、ついにGaucheに手を染めましたかー。応援しています!
3
  がんばりまーす!
4

 

5

いつまで続くかは不明。

5

 

1

ktatのGauche知識

5

 

5

処理系はだいぶ前に入れたもの。そのときは、入れただけで、コードは全然書かなかった。

5

Sumibiにかかわり出した頃かな...。でも、Sumibiで手伝ったのは、JavaScript部分だから、

5

そっちのコードはほとんど見なかった。

5

 

5
 % gosh -V
5
 Gauche scheme interpreter, version 0.8.3 [utf-8,pthreads]
5

 

5

只今、

5

 

5

4873113482

5

 

5

で勉強中。下記に、章とか、p.とか出てきたら、それは上の本です。

5

 

5

とりあえず、FSWiki のフォーマットから OldType への変換でも書いてみようかなぁ、などと思ってます。

5

 

5

一応、7章途中まで読みました。が、後は行ったり来たりで読もうかなーみたいなみたいなスタンス。

5

上の本ですが、今のところわかりやすく書かれてて、いい感じに思えます。

5

 

5

Emacs の scheme-mode

5

 

1

とりあえず覚えとけ

1

 

1

C-c s gaucheのshellみたいなのがでてくる

1

C-x C-e 評価してくれる gauche のshellの方に、実行結果とかでてきます

1

 

1

微妙なところ

5

キーバインドが僕の設定と競合してて、微妙な感じ。

5

 

5

C-.

5

C-;

5

 

5

なんだろこれ...?

5

僕の通常の設定では、上はredoで、下は anything。

5

 

5

module の use

5

 

5
 (use srfi-1)
5

 

5

p.38参照。主なものが一覧されてます。1がリスト処理で、13が文字列処理らしい。

5

本にでてくる、fold とかは srfi-1を use しないといけない。

5

 

5

lambda と let

5

 

5

似たようなことして練習してみる。

5

 

5
 ((lambda (x y) (print (+ x y))) 5 5)
5
 
5
 (let ((x 5)
5
       (y 5))
5
   (print (+ x y)))
5
 
5
 (define (test x)
5
   (if (< 5 x)
5
       ((lambda () (print (* x 2))))
5
       (let () (print x) (print x))
5
       )
5
 )
5
5
 (test 10)
5
 (test 2)
5

 

5

 

5

Fileの読み込み(14章)

5

 

5
 (define (readfile f) 
5
   (let ((in (open-input-file f)))
5
     (define (reading)
5
       (let ((line  (read-line in)))
3
       (if (not (eof-object? line))
3
           (let ()
3
             (print line)
3
             (reading)
3
             ))))
5
     (reading)))
5

 

5

なんか素直にかいたら、こんなのかな。

5

 

5

with-input-from-fileを使うと、下記のような感じ

5

 

5
 (with-input-from-file "/home/ktat/tmp/hoge.tmp"
5
   (lambda ()
5
     (port-for-each (lambda (line) (print line))
3
              read-line)))
5

 

0

port-for-eachには引数を1つ取る関数を指定するので、

0

↑の例のように呼びだす関数が決まっているならlambdaで無名関数を作る必要はありませんよ。

0

こんな感じです。

0
     (port-for-each print
0
              read-line)))
0

 

5

port-for-each を自分で実装したら、こんなのかな。

5

 

5
 (define (port-for-each2 func read_line)
1
   (let ((line (read_line)))
5
     (if (not (eof-object? line))
3
       (let () (func line) (port-for-each2 func read_line)))))
5

 

5

あぁ、read-line は暗黙で開いたものを読んでくれるのかな。

5

では、最初のは、下記でもOKですね。

5

 

5
 (define (readfile f) 
5
   (open-input-file f)
5
   (define (reading)
5
     (let ((line  (read-line)))
5
       (if (not (eof-object? line))
3
         (let ()
3
           (print line)
3
           (reading)
3
           ))))
5
   (reading))
3

 

3

FizzBuzz

3

 

3

FizzBuzz問題があったのでやってみた。

3

とりあえず、最初は何にも知らない状態から。考えてみる。

3

 

3
 (define (fizzbuzz cur max)
3
   (if (equal? (modulo cur 15) 0)
3
         (print "FizzBuzz")
3
         (if (equal? (modulo cur 5) 0)
3
             (print "Buzz")
3
             (if (equal? (modulo cur 3) 0)
3
                 (print "Fizz")
3
                 (print cur))))
3
   (if (< cur max)
3
       (fizzbuzz (+ cur 1) max))
3
   )
3

 

3

あぁ、数値の比較は、= だって。後、cond ってのがあるらしい

3

 

3
 (define (fizzbuzz cur max)
3
   (cond ((= (modulo cur 15) 0) (print "FizzBuzz"))
3
         ((= (modulo cur 5)  0) (print "Fuzz"))
3
         ((= (modulo cur 3)  0) (print "Bizz"))
3
         (else (print cur)))
3
   (if (< cur max)
3
       (fizzbuzz (+ cur 1) max))
3
   )
3

 

3

結構きれいになった。数値の連続のリスト出すのに

3

 

2
 (iota max min)
3

 

3

ってのがあるらしい。じゃぁ、map でかけますね。

3

 

2
 (define (fizzbuzz max)
3
   (map (lambda (n)
3
         (cond ((= (modulo n 15) 0) (print "FizzBuzz"))
3
               ((= (modulo n 5)  0) (print "Fuzz"))
3
               ((= (modulo n 3)  0) (print "Bizz"))
2
               (else (print n)))
2
         ) (iota max 1)
3
  ))
3

 

3

print 都度都度いらなくね?

3

 

3

というわけで、schemerは、次のようにするそうだ(p.91)。

3

(思考の順番は違うけど)

3

 

2
 (define (fizzbuzz max)
3
  (for-each print
3
    (map
3
     (lambda (n)
3
       (cond ((= (modulo n 15) 0) 'FizzBuzz)
3
             ((= (modulo n 5 ) 0) 'Buzz)
3
             ((= (modulo n 3 ) 0) 'Fizz)
3
             (else n))
2
       ) (iota max 1))))
3

 

3

Perl で似せてみるとこんな感じか。

3

 

3
 print "$_\n" foreach map {
3
     !($_ % 15) ? "FizzBuzz" :
3
     !($_ % 5 ) ? 'Buzz'     :
3
     !($_ % 3 ) ? 'Fizz'     : $_
3
     } (1 .. 100)
3

 

1

map と for-each の違い

1

 

1

Perlでの使い分けと一緒ですね。

1

map は結果を捨てないけど、for-eachは結果を捨てる。

1

 

1

練習問題

1

 

1
 (define (length list)
1
   (if (null? list)
1
       0
1
       (+ 1 (length (cdr list)))))
1

 

1

下は末尾再帰というらしい。上は戻りを計算する必要があるけど、下はない。

1

 

1
 (define (length list)
1
   (define (lengthin lis n)
1
     (if (null? lis)
1
        n
1
        (lengthin (cdr lis) (+ 1 n))))
1
   (lengthin list 0))
1

 

1

Filter。

1

絶対違う...orz

1

 

1
 (define (filter proc list)
1
   (define (filterin proc list filtered)
1
     (if (null? list)
1
        (reverse filtered)
1
        (if (proc (car list))
1
            (filterin proc (cdr list) (cons (car list) filtered))
1
            (filterin proc (cdr list) filtered))))
1
   (filterin proc list ()))
1

 

1

下記が正解。全然ちがうね!

1

 

1
 (define (filter proc lis)
1
   (cond ((null? lis)     '())
1
         ((proc (car lis)) (cons (car lis) (filter proc (cdr lis))))
1
         (else             (filter proc (cdr lis)))))
1

 

1

先頭要素が該当したら、先頭要素 + filter 残りの要素

1

先頭要素が該当しなければ、先頭要素は捨てて、filter 残りの要素

1

 

1

を返すだけだもんねぇ。ですよねぇ...。

1

 

1

FSWiki2OldType

1

 

1
 (with-input-from-file "/home/ktat/tmp/hoge.tmp"
1
   (lambda ()
1
     (port-for-each fswiki2oldtype read-line)))
1

 

1

な感じかなぁ。