2010/01/27

Gauche apropos

こんなのがあったんですか。

(apropos 'call-with)
;; call-with-current-continuation (scheme)
;; call-with-input-file           (scheme)
;; call-with-input-string         (gauche)
;; call-with-output-file          (scheme)
;; call-with-output-string        (gauche)
;; call-with-string-io            (gauche)
;; call-with-values               (scheme)

 

(apropos 'map)
;; %make-tree-map                 (gauche)
;; %tree-map-bound                (gauche)
;; %tree-map-check-consistency    (gauche)
;; %tree-map-dump                 (gauche)
;; %tree-map-iter                 (gauche)
;; <tree-map-meta>                (gauche)
;; <tree-map>                     (gauche)
;; alist->tree-map                (gauche)
;; hash-table-map                 (gauche)
;; library-map                    (gauche)
;; make-tree-map                  (gauche)
;; map                            (scheme)
;; map$                           (gauche)
;; port-map                       (gauche)
;; tree-map->alist                (gauche)
;; tree-map-ceiling               (gauche)
;; tree-map-ceiling-key           (gauche)
;; tree-map-ceiling-value         (gauche)
;; tree-map-clear!                (gauche)
;; tree-map-copy                  (gauche)
;; tree-map-delete!               (gauche)
;; tree-map-empty?                (gauche)
;; tree-map-exists?               (gauche)
;; tree-map-floor                 (gauche)
;; tree-map-floor-key             (gauche)
;; tree-map-floor-value           (gauche)
;; tree-map-fold                  (gauche)
;; tree-map-fold-right            (gauche)
;; tree-map-get                   (gauche)
;; tree-map-keys                  (gauche)
;; tree-map-max                   (gauche)
;; tree-map-min                   (gauche)
;; tree-map-num-entries           (gauche)
;; tree-map-pop!                  (gauche)
;; tree-map-pop-max!              (gauche)
;; tree-map-pop-min!              (gauche)
;; tree-map-predecessor           (gauche)
;; tree-map-predecessor-key       (gauche)
;; tree-map-predecessor-value     (gauche)
;; tree-map-push!                 (gauche)
;; tree-map-put!                  (gauche)
;; tree-map-successor             (gauche)
;; tree-map-successor-key         (gauche)
;; tree-map-successor-value       (gauche)
;; tree-map-update!               (gauche)
;; tree-map-values                (gauche)
;; tree-map?                      (gauche)

 

(apropos 'string)
;; %hash-string                   (gauche)
;; %maybe-substring               (gauche)
;; %string-pointer-dump           (gauche)
;; %string-replace-body!          (gauche)
;; %string-split-by-char          (gauche)
;; <string-meta>                  (gauche)
;; <string-pointer-meta>          (gauche)
;; <string-pointer>               (gauche)
;; <string>                       (gauche)
;; byte-substring                 (gauche)
;; call-with-input-string         (gauche)
;; call-with-output-string        (gauche)
;; call-with-string-io            (gauche)
;; get-output-byte-string         (gauche)
;; get-output-string              (gauche)
;; get-remaining-input-string     (gauche)
;; keyword->string                (gauche)
;; list->string                   (scheme)
;; make-byte-string               (gauche)
;; make-string                    (scheme)
;; make-string-pointer            (gauche)
;; number->string                 (scheme)
;; open-input-string              (gauche)
;; open-output-string             (gauche)
;; port->byte-string              (gauche)
;; port->string                   (gauche)
;; port->string-list              (gauche)
;; read-from-string               (gauche)
;; regexp->string                 (gauche)
;; rxmatch->string                (gauche)
;; rxmatch-substring              (gauche)
;; string                         (scheme)
;; string->list                   (scheme)
;; string->number                 (scheme)
;; string->regexp                 (gauche)
;; string->symbol                 (scheme)
;; string->uninterned-symbol      (gauche)
;; string-append                  (scheme)
;; string-byte-ref                (gauche)
;; string-byte-set!               (gauche)
;; string-ci<=?                   (scheme)
;; string-ci<?                    (scheme)
;; string-ci=?                    (scheme)
;; string-ci>=?                   (scheme)
;; string-ci>?                    (scheme)
;; string-complete->incomplete    (gauche)
;; string-copy                    (scheme)
;; string-fill!                   (gauche)
;; string-immutable?              (gauche)
;; string-incomplete->complete    (gauche)
;; string-incomplete->complete!   (gauche)
;; string-incomplete?             (gauche)
;; string-interpolate             (gauche)
;; string-join                    (gauche)
;; string-length                  (scheme)
;; string-pointer-byte-index      (gauche)
;; string-pointer-copy            (gauche)
;; string-pointer-index           (gauche)
;; string-pointer-next!           (gauche)
;; string-pointer-prev!           (gauche)
;; string-pointer-ref             (gauche)
;; string-pointer-set!            (gauche)
;; string-pointer-substring       (gauche)
;; string-pointer?                (gauche)
;; string-ref                     (scheme)
;; string-scan                    (gauche)
;; string-set!                    (scheme)
;; string-size                    (gauche)
;; string-split                   (gauche)
;; string<=?                      (scheme)
;; string<?                       (scheme)
;; string=?                       (scheme)
;; string>=?                      (scheme)
;; string>?                       (scheme)
;; string?                        (scheme)
;; substring                      (scheme)
;; symbol->string                 (scheme)
;; with-input-from-string         (gauche)
;; with-output-to-string          (gauche)
;; with-string-io                 (gauche)
;; write-to-string                (gauche)
;; x->string                      (gauche)

 

プログラミングGauche

ダイナミックスコープ

ってこういうものだったんですか。

 

SBCL

(defvar temp-special)

(setq temp-special 1)

(defun temp-special-returner ()
  temp-special)

(temp-special-returner)
; ->  1

(let ((temp-special 2))
  (temp-special-returner))
; -> 2

(temp-special-returner)
; -> 1

 

schemeだとこうはならんですね。常にレキシカルスコープ(こういう言い方していいのか知りませんが)ということですかね。

(define temp-special 0)

(set! temp-special 1)

(define temp-special-returner
  (lambda ()
    temp-special))

(temp-special-returner)
; -> 1

(let ((temp-special 2))
  (temp-special-returner))
; -> 1

 

dynamic-windを使うと同じようなことができるそうな。

 

funcall とか function とか #' とか・・・、今のところとても面倒でややこしい印象。まともに Common Lisp さわるの初めてです。

 

LET OVER LAMBDA Edition 1.0

vimはSchemeで拡張できるの?



え、そうなんだ!? RT @omasanori: Schemeで拡張できるViクローンって、それVimじゃね?


from twicli
だから9LISPKPFもvi派が圧倒的に多いのか。違うか。ちょっと使ってみたくなった。

はじめてのvi&Vim (エッセンシャルソフトウェアガイドブック)入門vi 第6版



2010/01/26

Webで読めるLisp関連書籍

書籍じゃないのもありますけども。
他にあったら教えて欲しいです。よろしくお願いします。

エッセイ

ハッカーと画家 コンピュータ時代の創造者たち

Emacs Lisp

Common Lisp

 Common Lisp: A Gentle Introduction to Symbolic Computation
Practical Common Lisp (Books for Professionals by Professionals) 実践Common Lisp
Let Over Lambda LET OVER LAMBDA Edition 1.0
Common Lisp: An Interactive Approach (Principles of Computer Science Series)
On Lisp
Partial Evaluation and Automatic Program Generation (Prentice-Hall International Series in Computer Science)

Scheme

Structure and Interpretation of Computer Programs, 2nd Edition (MIT Electrical Engineering and Computer Science) 計算機プログラムの構造と解釈
The Scheme Programming Language, 3rd Edition
The Scheme Programming Language, 4th Edition
How to Design Programs: An Introduction to Programming and Computing
入門Scheme―Scheme入門からXツールを使ったアプリケーションプログラミングまで
プログラミングGauche

参考



その他

読み物

PostScript

Erlang 他


Webで読めないけど

Lisp 関連書籍
Land of LispANSI Common Lisp (スタンダードテキスト)入門Common Lisp―関数型4つの特徴とλ(ラムダ)計算リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)考える道具としてのLisp入門これがLISPだ! (Information & computing (30))Common Lisp 入門 (岩波コンピュータサイエンス)プログラミング言語Lisp入門からマルチメディアまで (ASCII SOFTWARE SCIENCE Language)

2010/01/25

TLSで書くコード

9LISPでも使ってますが、全部はやらないので参考までにThe Little Schemerで書くコードをMy SnippetにUPしました。

読んでる人、これから読む人で書くのが面倒な人は使ってください。名前付け等が微妙に違うところとかありますけども・・・。

追記

exercises.psなんてもんがあったので今度やってみる。35ページくらいある。

もうひとつ追記

githubに上げました。

The Little Schemer, 4th Edition

さっきの5の階乗

lambda, cond, zero?, +, -, 0, 1 だけで、というルールで階乗してね、ということで。

; 5の階乗
(((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n)
      (cond ((zero? n) 1)
            (else (((lambda (f)
                      (f f))
                    (lambda (f)
                      (lambda (n m)
                        (cond ((zero? m) 0)
                              (else ((
(lambda (f)
                                        (f f))
                                      (lambda (f)
                                        (lambda (n m)
                                          (cond ((zero? m) n)
                                                (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))

                                     n ((f f) n ((lambda (n)(- n 1)) m))))))))
                   n ((f f) ((lambda (n)(- n 1)) n)))))))) 5)

 

一応どうなっているかというと・・・。

こんなの書けてもお得なことは何もありません(と思います)。暇つぶしとか頭の体操(罰ゲーム?)としてどうぞ・・・。

 

インクリメントとデクリメントで加算を行なう無名関数を作る(無名関数での再帰ということで再帰はYコンビネータ的な)

;加算

((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n m)
      (cond ((zero? m) n)
            (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))

 

;実行してみる

(((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n m)
      (cond ((zero? m) n)
            (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))
3 4)

; -> 7

 

↑の加算で乗算を作る。再帰はY(ry

;乗算

((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n m)
      (cond ((zero? m) 0)
            (else (
((lambda (f)
                      (f f))
                    (lambda (f)
                      (lambda (n m)
                        (cond ((zero? m) n)
                              (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))
                   n ((f f) n ((lambda (n)(- n 1)) m))))))))

;実行してみる

(((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n m)
      (cond ((zero? m) 0)
            (else (
((lambda (f)
                      (f f))
                    (lambda (f)
                      (lambda (n m)
                        (cond ((zero? m) n)
                              (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))
                   n ((f f) n ((lambda (n)(- n 1)) m)))))))) 4 5)

; -> 20

 

で最終的に階乗の手続きを作って5を渡してみる・・・

(((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n)
      (cond ((zero? n) 1)
            (else (((lambda (f)
                      (f f))
                    (lambda (f)
                      (lambda (n m)
                        (cond ((zero? m) 0)
                              (else ((
(lambda (f)
                                        (f f))
                                      (lambda (f)
                                        (lambda (n m)
                                          (cond ((zero? m) n)
                                                (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))

                                     n ((f f) n ((lambda (n)(- n 1)) m))))))))
                   n ((f f) ((lambda (n)(- n 1)) n)))))))) 5)

; -> 120

 

参考

The Little Schemer, 4th Edition 計算論 計算可能性とラムダ計算 (コンピュータサイエンス大学講座)

 

 

5の階乗

 

; 5の階乗
(((lambda (f)
    (f f))
  (lambda (f)
    (lambda (n)
      (cond ((zero? n) 1)
            (else (((lambda (f)
                      (f f))
                    (lambda (f)
                      (lambda (n m)
                        (cond ((zero? m) 0)
                              (else ((
(lambda (f)
                                        (f f))
                                      (lambda (f)
                                        (lambda (n m)
                                          (cond ((zero? m) n)
                                                (else ((lambda (n)(+ n 1)) ((f f) n ((lambda (n)(- n 1)) m))))))))

                                     n ((f f) n ((lambda (n)(- n 1)) m))))))))
                   n ((f f) ((lambda (n)(- n 1)) n)))))))) 5)

 

追記

-と+を間違えてたので修正


計算論 計算可能性とラムダ計算 (コンピュータサイエンス大学講座)The Little Schemer, 4th Edition

9LISP - 007, 008 , 次回009

まとめではないまとめのようなもの。

次回からオンライン中継が始まりますので暇な方はのぞいてくださいね。

9LISPは勉強会自体より、その後のランチと雑談がクソ盛り上がります(笑)プログラマが集るとすごく素敵な空間を作り出します。変態技術的な意味で。

 

007

参加者:6人

初参加:1人

 

008

参加者:7人

初参加:0人

  • 決定した今後の予定
    • Schemeでやること
      • 末尾再帰
      • 高階関数
      • クロージャ
      • 継続
      • マクロ
    • その後の大まかな予定

 

 

大雑把にまとめると・・・

  • もっとコードをバリバリ書きたい
  • 一人でもできることではなく、集まったからこそできることをやりたい

勉強会の目的

  • keyword を仕入れる機会としての勉強会
  • 難しい概念を勉強する
    • すでに理解している人が何か喋る
    • 難しいので一緒に頑張る

高階関数とかクロージャとか継続とか

  • 例えば参照渡し、値渡しって概念自体より教え方が難しいよね
  • 高階関数やクロージャや継続はそれと似てるよね

オンラインでのやりとりをもっとどうにかしたいよね・・・

  • 興味あることが書けるとこ
  • わかんないこと
  • 疑問 & 質問
  • 気軽にアップできるとこ
  • 「それやりたいならまずこれ知らないといけないよ」
  • My Snippet

 

009

同日の午後にKPFもあるのでよろしくお願いします。

 

The Little Schemer, 4th Edition LET OVER LAMBDA Edition 1.0 On Lisp

2010/01/21

Gauche amazon web service

うまく取得できなかったんで、結局途中で諦めました。取り合えずメモがてら。

 

(use srfi-19)
(use srfi-27)
(use rfc.http)
(use rfc.uri)
(use rfc.hmac)
(use rfc.sha)
(use rfc.base64)
(use sxml.ssax)
(use sxml.sxpath)

 

(define *subscrive-key* "hoge")
(define *secret-key* "hogehoge")
(define *associate-tag* "valvallow-22")

 

(define pad0
  (lambda (n x)
    (format #f "~v,,,'0,@a" n x)))

 

(define date->gmt
  (lambda (date)
    (let ((g (lambda (ls dl)
               (string-join
                (map (lambda (f)
                       (pad0 2 (f date))) ls) dl))))
      (string-append (g (list date-year date-month date-day) "-")
                     (format #f "T~aZ"
                             (g (list date-hour date-minute date-second) ":"))))))

 

(define param-list
  (lambda ()
    (list (cons "AWSAccessKeyId" *subscrive-key*)
          (cons "keyword" "complete")
          (cons "SearchIndex" "Books")
          (cons "AssociateTag" "valvallow-22")
          (cons "Operation" "ItemSearch")
          (cons "ItemPage" "1")
          (cons "ResponseGroup" "ItemAttributes")
          (cons "Service" "AWSECommerceService")
          (cons "Timestamp" (date->gmt (current-date)))
          (cons "Version" "2009-07-01"))))

 

(define params-join
  (lambda (pl)
    (string-join
     (sort (map (lambda (pair)
                  (string-append (car pair)
                                 "="
                                 (uri-encode-string (cdr pair))))
                pl)) "&")))

 

(define auth-req-str
  (lambda ()
    (string-join (list "GET" "ecs.amazonaws.jp" "/onca/xml"
                       (params-join (param-list))) "\n")))

 

(define digest-sha256
  (lambda (str key)
    (hmac-digest-string str :key key :hasher <sha256>)))

 

(http-get "ecs.amazonaws.jp"
          (string-append
           "/onca/xml"  "?"
           (params-join (param-list))
           "&Signature="
           (uri-encode-string (base64-encode-string
                               (digest-sha256 (auth-req-str) *secret-key*)))))

 

gosh> "403"
(("date" "Thu, 21 Jan 2010 08:23:29 GMT") ("server" "Server") ("vary" "Accept-Encoding,User-Agent") ("cneonction" "close") ("transfer-encoding" "chunked") ("content-type" "text/plain"))
"<?xml version=\"1.0\"?>\n<ItemSearchErrorResponse xmlns=\"http://ecs.amazonaws.com/doc/2009-07-01/\"><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message></Error><RequestID>49890d99-620b-40b4-9580-6c52d44d2e5d</RequestID></ItemSearchErrorResponse>"

どっか間違ってるんだろうけど、またそのうち。

 

参考

 

プログラミングGauche Programming Amazon Web Services: S3, EC2, SQS, FPS, and SimpleDB RESTful Webサービス

quoteされたリストとlist手続きで作ったリスト

あれ?

っと思った自分がにくい・・・。
(map (lambda (f)
       (f 5 5))
     '(+ - * /))

; *** ERROR: invalid application: (+ 5 5)
(map (lambda (f)
       (f 5 5))
     (list + - * /))


; gosh> (10 0 25 1)
気づけばGaucheをやり始めて1年が経ちました。なのに未だに全然書けないのは、そもそも書いてないからだろうなーと思います。何か作るようにしようと思います。  

ところで

上記の点にハマったのは、日付を「2010-01-21T01:25:23Z」の形式にしたいと思ったときにこういうコードを思い浮かべました。
(define date->gmt
  (lambda (now)
    (let ((pad0 (lambda (n)
                  (format #f "~2,,,'0,@a" n))))
      (let ((yyyy (date-year now))
            (MM (date-month now))
            (dd (date-day now))
            (hh (date-hour now))
            (mm (date-minute now))
            (ss (date-second now)))
        (string-append
         (string-join (list (number->string yyyy)(pad0 MM)(pad0 dd)) "-")
         (format #f "T~aZ"(string-join (list (pad0 hh)(pad0 mm)(pad0 ss)) ":")))))))
↑の箇所が「なんだかな・・・」だったので↓のように書いてみたわけです。特に良くなったとは思いませんけども。
(define pad0
  (lambda (n x)
    (format #f "~v,,,'0,@a" n x)))

(define date->gmt
  (lambda (date)
    (let ((g (lambda (ls dl)
               (string-join
                (map (lambda (f)
                       (pad0 2 (f date))) ls) dl))))
      (string-append (g (list date-year date-month date-day) "-")
                     (format #f "T~aZ"
                             (g (list date-hour date-minute date-second) ":"))))))
 
  プログラミングGauche

Gauche 文字列のフォーマット

フォーマット指示子、覚えれません・・・。
(format #t "hello, ~a !" "valvallow")
;; gosh> hello, valvallow !#<undef>


(format #t "~2,,,'0,@a" 1)
;; gosh> 01#<undef>


(format #f "~2,,,'0,@a" 1)
;; gosh> "01"


(format #f "~v,,,v,v@a" 5 #\0 5 1)
;; gosh> "00001"

25日のプログラミングClojure(訳本)が楽しみですね。
欲しいけどニートなので当分買えないかもしれませんけども・・・。

プログラミングGauche Programming Clojure (Pragmatic Programmers)

2010/01/19

Twitter bot 「良いこと言ったー?」

WS0898
なんの変哲もないつぶやきbotです。
つぶやく内容は真に受けないでください。
1日に1~3回くらいつぶやきます。
せっかくなのでbotにしました。ちなみに私自身はこちら↓。

追記

遅ればせながら oauth に対応しました。(2010/12)つぶやく間隔も1時間に3回に変更しました。


プログラミングGaucheThe Little Schemer, 4th Edition 計算論 計算可能性とラムダ計算 (コンピュータサイエンス大学講座)

Google SpreadSheets のデータをTwitterにランダムにポストする

なんか手軽に使えるデータストアないかなー・・・、ということでgoogle spreadsheetsをデータソースにできるっぽいという話。
インターバルについては・・・。
(use srfi-27)
(use rfc.http)
(use rfc.uri)
(use rfc.base64)
(use sxml.ssax)
(use sxml.sxpath)

(define *ss-server* "spreadsheets.google.com")
(define *ss-uri-prefix* "/feeds/list/")
(define *ss-uri-sufix* "/od6/public/basic?alt=rss")
(define *twitter-post-path* "/statuses/update.xml?status=")
(define *twitter-base-host* "twitter.com")

(define get
  (lambda (server request-uri)
    (http-get server request-uri)))

(define rss->sxml
  (lambda (srv req-uri)
    (call-with-values (lambda ()
                        (get srv req-uri))
      (lambda (ret ls xml)
        (ssax:xml->sxml (open-input-string xml) '())))))

(define make-src-list
  (lambda (sxml)
    (let ((ls '()))
      (map (lambda (item)
             (append ls (cadar ((sxpath '(// title)) item))))
           ((sxpath '(// item)) sxml)))))

;(make-src-list (rss->sxml *ss-server* (string-append *ss-uri-prefix* *ss-id* *ss-uri-sufix*)))

(define make-authorization
  (lambda (username password)
     (string-append "Basic "
                    (base64-encode-string
                     (string-append username ":" password)))))

(define make-poster
  (lambda (base-host post-path)
    (lambda (auth)
      (lambda (message)
        (http-post base-host
                   (string-append post-path
                                  (uri-encode-string message))
                   ""
                   :authorization auth)))))


(define main
  (lambda (args)
    (let ((tw-usr-name (cadr args))
          (tw-psw (caddr args))
          (post-uri (string-append *ss-uri-prefix* (cadddr args) *ss-uri-sufix*)))
      (letrec ((poster ((make-poster *twitter-base-host* *twitter-post-path*)
                        (make-authorization tw-usr-name tw-psw))))
        (let ((src (make-src-list (rss->sxml *ss-server* post-uri))))
          (random-source-randomize! default-random-source)
          (poster (list-ref src (random-integer (length src)))))))))



参考


プログラミングGaucheプログラミングClojureいつでもワープロ、どこでも表計算! Google Docs&Spreadsheetsの使い方