2010/01/19

Twitterにポスト

定期的にTwitterにポストするbot作ってみたかったので、インターバルしようとgauche.threadのthread-start!とかthread-delete!を使ってみようとしたら・・・not impemented!・・・・。winだと未実装ということかな。
(use rfc.http) ; http-post
(use rfc.uri) ; uri-encode-string
(use rfc.base64) ; base64-encode-string
(define *twitter-status* "/statuses/update.xml?status=")
(define *twitter* "twitter.com")
(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)
    (((make-poster *twitter* *twitter-status*)
      (make-authorization (cadr args)(caddr args))) (cadddr args))))

参考


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

メモ ふりかえり?

9LISPでもお世話になってるshunsukさんがやっている毎週のふりかえりって私もやってみたいかも・・・。「まずはやってから、話はそれからだ。」と言われそうですが・・・。(誰に?)

 

やるなら他にこの辺りの項目が良いかなー。

  • 先週何を学んだか?
  • 先週一番の達成は何か?
  • やるかどうか迷っていることはあるか?
  • 今週楽しみなことは?

 

週に一度、日曜日に自問すべき20の質問 - IDEA*IDEA ~ 百式管理人のライフハックブログ

2010/01/12

9LISP - 007

9LISP - 007

 

次回008では007で出てきた以下の内容を検討します。


[要望]

  • My SnippetにRSSがあったら嬉しい・・・
    • 新着、コメントなど

[提案]

全体

  • 9LISPのメンバーはプログラミングがまったくの初心者という人はいないわけなので、言語の基本ばかりやっていてもしょうがないのではないか
  • 言語の勉強は別に集まらなくてもできるわけだから、集まったときはもっと疑問をぶつけたいし、議論もしたい
  • LISPを知り、マクロを知り、としているうちに普段使ってる言語を書いてるときに「これ、LISPならできるのになー」が多くなってきた
    • マクロやろうよ
  • もっとガリガリとコード書きたくね?
  • 括弧にも慣れたし、もっと先に進んで良いのでは?
  • LISP、継続やマクロについての読み物はもっと読んでみたい
  • 学習スピードが遅い
  • もっと(勉強会に)スピード感が欲しい
  • コードリーディングなども良いかも
  • 隔週で集まってるんだからきっともっとやれるよ

 

オンライン参加

  • Web参加について何か良い案はないものか
  • オンライン中継するにしても、ひたすらThe Little Schemerの輪読では・・・
  • オンライン用コンテンツって他にどんなのある?
    • 小粒の問題は今後も出す方向で
      • (やってくる人はあまりいない)
      • Wikiに問題のリストを作る
      • 解答はMy Snippet
  • 次回実験的に公開

 

9LISPで翻訳をやらないか?

 

単語の訳のガイドラインを作らないか?

  • 輪読中に訳がバラバラだったり、回によって違ったりするので
  • 訳を統一したい
  • 参考

 

The Little Schemerについて

  • 訳が目的であれば全部やる必要があるがSchemeを学ぶのが目的であれば話が変わってくる
  • 隔週の奇数回を読書会、偶数回をもっとピンポイントでやる?(マクロ、継続など)
  • 開催スパン等の検討

 

「パワフルなLISP」、「LISPだからできる」をやりたい

  • マクロ
  • ならSchemeよりCLだよね

 

Let Over Lambda

  • On Lisp読みづらい、LOLの方が読みやすい
  • 次回LOLを実際に確認してみる
  • CLのマクロをガッツリやらね?
  • とりあえずScheme -> CL -> Schemeの流れでどうか?
  • せっかくなのでSchemeの特徴はやろうよ
  • CLを学んだあとはもう一度Schemeに戻ってみるのがおもしろいのでは
  • SchemeはLispではない、Schemeは本物のマクロが書けない、Schemeが捨てたもの、などがわかるのかも

 

Schemeはどこまでやる

  • 高階関数(The Little Schemer : 8. Lambda the Ultimate)
  • 末尾再帰
  • 継続
    • 継続呼び出し
    • 継続渡しスタイル
  • マクロ
  • OOとかどうでもよくね?
  • The Little Schemerの要所をテンポよく済ます
    • すべてを厳密にやっていくかどうか
    • 8~10章 付近とか

 

例えばマクロや継続でなにやる?

 

学習が済んだものについてはWikiなどに一覧を作っていかないか?

  • 取り合えずWikiに書いてみる?
    • car, cdr, cons・・・など
  •   訳もしかり

 

その他

  • 熊本って本屋に本がないよね
    • LOL置いてねぇー!
  • ジュンク堂オフでもやる?

 

資料

 

 

How to Design Programs: An Introduction to Programming and ComputingThe Little Schemer, 4th Editionハッカーと画家 コンピュータ時代の創造者たちLET OVER LAMBDA Edition 1.0Let Over LambdaOn Lisp

2010/01/08

Clojure + slime + meadow





2010/01/25にgaucheハッカーと画家の訳者であるshiroさん訳でProgramming Clojureの日本語訳が出るそうなので欲しいところです。
しかし私は今ニートなので購入するか(あるいはできるのか)非常に悩ましいところです。
とりあえず環境を作って少ーし試してみました。
少し試して疲れたので続きはまた今度。

環境はclojure boxが手っ取り早いです。



実はclispとslimeを突っ込んではいたもののほとんど触っておらず、slimeの使い方がまだいまいちよくわかりません。

ところでClojureってCommon LispでもSchemeでもないそうですね。Arcなんかと同様、新しいLispの方言ってとこなんでしょうかね?

今回は以下のページを見ながらぽちぽち書いて、なるほど動くな、と試してみた程度。
clojureはGAEで動くらしいのでやっぱやってみたいですよね。
ついでにGAEのSDKも整備してdemoを動かして「すげー」しました。



(defn dbl [x]
  (* x x))
;; C-c C-c

(dbl 5)
;; C-x C-e
; -> 25

; SLIME 2010-01-06
user> (dbl 5)
25
user>


; factorial
(defn fact [n]
  (if (= n 0)
    1
    (* n (fact (- n 1)))))

user> (fact 10)
3628800

user> (+ 1 2)
3
user> (println "hello, world")


(defn hello [name]
  (println "Hello, " name))

(def vowel? (set "aeiou"))
(defn pig-latin [word]
  (let [first-letter (first word)]
    (if (vowel? first-letter)
      (str word "ay")
      (str (subs word 1) first-letter "ay"))))

(println (pig-latin "red"))
; -> edray

(println (pig-latin "orange"))
; -> orangeay


(require 'clojure.contrib.str-utils)
(doc clojure.contrib.str-utils/str-join)
; ->
;; -------------------------
;; clojure.contrib.str-utils/str-join
;; ([separator sequence])
;;   Returns a string of all elements in 'sequence', separated by
;;   'separator'.  Like Perl's 'join'.


(let [x 1]
  (let [x 3]
       (println (str "x = " x))))
; -> x = 3

(count [1 2 "three" 4 5])
; -> 5

(reverse [5 4 3 2 1])
; -> (1 2 3 4 5)

(map #(+ % 3) [2 4 6])
; -> (5 7 9)

(map + [2 4 7][5 6][1 2 3 4])
; -> (8 12)

(map + [1 2 3][1 2 3][1 2 3])
; -> (3 6 9)

(apply + [1 2 3 4 5 6 7 8 9 10])
; -> 55

(def languages
     ["lisp" "scheme" "clojure" "arc"])

(first languages)
; -> "lisp"
(second languages)
; -> "scheme
(third languages)
; -> errorr?
(last languages)
; -> "arc"
(nth languages 0)
; -> "lisp"
(nth languages 3)
; -> arc

(next languages)
; -> ("scheme" "clojure" "arc")
(butlast languages)
; -> ("lispp" "scheme" "clojure")
(drop-last 2 languages)
; -> ("lisp" "scheme")
(filter #(> (count %) 3) languages)
; -> ("lisp" "scheme" "clojure")



ハッカーと画家 コンピュータ時代の創造者たちProgramming Clojure (Pragmatic Programmers)Practical Clojure (The Definitive Guide)プログラミングClojure



9LISP - 007



明日は9LISPの007回目です。
2010年一発目ですよろしくお願いします。


宿題が出ていました。
書いてみました↓
まだThe Little Schemerの序盤です。
今後も小粒な問題が出る予定です。







The Little Schemer, 4th Edition


KPF第五回勉強会



2010/02/06(土)はKPFの第五回勉強会です。
勉強会というかLT大会です。
先日9LISPの後に検討会を開いて内容を相談しました。
明日も9LISP - 007なのでもう一度内容を叩けると良いなと思っています。

2010/01/02

sicp 図形言語 ソース サンプル

計算機プログラムの構造と解釈

 

sample-001  sample-013 WS0894

sample-015 sample-011

WS0895 WS0896

SICPの図形言語をやってみました。(SICP 2.2.4 : P.73~)

役に立つかはわかりませんが、これからやる人の参考になるものがあれば良いなと思います。

 

出力はPostScriptで良いや。と思ってやりましたが、テストが面倒なのであまりオススメできません。何かGUIでも作りたいなーと思っています。

 

ソースの全容はこちらにアップしました。

segments

segmentのリスト同士を合成するappend-segments手続きを追加してみました。ただlistを連結しているだけですけども。

各セグメントのコード(データ)は割愛。必要であればこちらにあります。

;;; segments

(define make-segment cons)

(define start-segment car)

(define end-segment cdr)

; segmentsの座標をframeに対する相対値に変換
(define segments->painter
  (lambda (segment-list)
    (lambda (frame)
      (for-each
       (lambda (segment)
         (draw-line
          ((frame-coord-map frame) (start-segment segment))
          ((frame-coord-map frame) (end-segment segment))))
       segment-list))))

; segmentsを合体させる
(define append-segments
  (lambda segments
    (apply append segments)))

 

frames

frame-coord-mapが

origin(frame) + x * edge1(frame) + y * edge2(frame)をそのままコードに直してあるだけなのはわかるのですが、どういう意味なのかよく理解できませんでした。図に描いてみたところ座標がどのように変換されるかはわかりましたが・・・、なんかよくわかりません。

フレームはいくつか適当に作ってみました。下方にサンプルがあります。

;;; frames

(define make-frame
  (lambda (origin edge1 edge2)
    (list origin edge1 edge2)))

(define origin-frame car)

(define edge1-frame cadr)

(define edge2-frame caddr)

; origin(frame) + x * edge1(frame) + y * edge2(frame)
(define frame-coord-map
  (lambda (frame)
    (lambda (v)
      (add-vect
       (origin-frame frame)
       (add-vect (scale-vect (xcor-vect v)
                             (edge1-frame frame))
                 (scale-vect (ycor-vect v)
                             (edge2-frame frame)))))))

frameのコードと画像。ペインタはwaveとoutlineを組み合わせてフレームの形がわかるように表示してみました。

(define square-frame
  (make-frame (make-vect 0.0 0.0)
              (make-vect 1.0 0.0)
              (make-vect 0.0 1.0)))

square-frame

 

(define parallelogram-frame
  (make-frame (make-vect 0.0 0.0)
              (make-vect 0.5 0.0)
              (make-vect 0.5 1)))


parallelogram-frame

 

(define left-vert-rect-frame
  (make-frame (make-vect 0.0 0.0)
              (make-vect 0.5 0.0)
              (make-vect 0 1)))


left-vert-rect-frame

 

(define bottom-horiz-rect-frame
  (make-frame (make-vect 0.0 0.0)
              (make-vect 1.0 0.0)
              (make-vect 0.0 0.5)))


bottom-horiz-rect-frame

 

(define half-square-frame
  (make-frame (make-vect 0.25 0.25)
              (make-vect 0.5 0.0)
              (make-vect 0.0 0.5)))


half-square-frame

 

(define parallelogram-narrow-frame
  (make-frame (make-vect 0.0 0.0)
              (make-vect 0.75 0.5)
              (make-vect 0.5 0.75)))


parallelogram-narrow-frame

 

operators

ペインタの変換などを行なう手続き群。

transform-painterも上記のframe-coord-map同様よくわからず、何度か絵を描いてみてなんとかわかりました。

各手続きを適用したサンプル画像は下方あります。

 

(define identity
  (lambda (painter)
    painter))

(define compose
  (lambda (f)
    (lambda (g)
      (lambda (x)
        (f (g x))))))

; 実際はフレームを変形させている
; transform-relative-frameとか
; 与えられた3点を用いてframeに相対的な変換を行なう
(define transform-painter
  (lambda (painter origin corner1 corner2)
    (lambda (frame)
      (let ((m (frame-coord-map frame)))
        (let ((new-origin (m origin)))
          (painter
           (make-frame new-origin
                       (sub-vect (m corner1) new-origin)
                       (sub-vect (m corner2) new-origin))))))))

; add
; 複数のペインタを一つのフレームに描画する
(define superpose
  (lambda painters
    (lambda (frame)
      (for-each (lambda (painter)
                  (painter frame))
                painters))))

; add
; 指定した回数ペインタを連結する
(define coupling
  (lambda (combinator)
    (lambda (painter1 n)
      ((repeated (lambda (painter2)
                   (combinator painter1 painter2)) n)
       painter1))))

; add
(define repeated
  (lambda (effecter n)
    (lambda (painter)
      (if (zero? n)
          painter
          ((repeated effecter (- n 1)) (effecter painter))))))

; add
(define quart
  (lambda (vert horiz)
    (lambda (painter)
      (((compose vert) horiz) painter))))

 

(define rotate90
  (lambda (painter)
    (transform-painter painter
                       (make-vect 1.0 0.0)
                       (make-vect 1.0 1.0)
                       (make-vect 0.0 0.0))))

rotate90

 

;; (define rotate180
;;   (lambda (painter)
;;     (transform-painter painter
;;                        (make-vect 1.0 1.0)
;;                        (make-vect 0.0 1.0)
;;                        (make-vect 1.0 0.0))))
(define rotate180
  (lambda (painter)
    ((repeated rotate90 2) painter)))


rotate180

 

;; (define rotate270
;;   (lambda (painter)
;;     (transform-painter painter
;;                        (make-vect 0.0 1.0)
;;                        (make-vect 0.0 0.0)
;;                        (make-vect 1.0 1.0))))
(define rotate270
  (lambda (painter)
    ((repeated rotate90 3) painter)))


rotate270

 

(define flip-vert
  (lambda (painter)
    (transform-painter painter
                       (make-vect 0.0 1.0)
                       (make-vect 1.0 1.0)
                       (make-vect 0.0 0.0))))

flip-vert

 

(define flip-horiz
  (lambda (painter)
    (transform-painter painter
                       (make-vect 1.0 0.0)
                       (make-vect 0.0 0.0)
                       (make-vect 1.0 1.0))))


flip-horiz

 

(define left-half
  (lambda (painter)
    (transform-painter painter
                       (make-vect 0.0 0.0)
                       (make-vect 0.5 0.0)
                       (make-vect 0.0 1.0))))


left-half

 

(define right-half
  (lambda (painter)
    (transform-painter painter
                       (make-vect 0.5 0.0)
                       (make-vect 1.0 0.0)
                       (make-vect 0.5 1.0))))


right-half

 

(define top-half
  (lambda (painter)
    (transform-painter painter
                       (make-vect 0.0 0.5)
                       (make-vect 1.0 0.5)
                       (make-vect 0.0 1.0))))

top-half

 

(define bottom-half
  (lambda (painter)
    (transform-painter painter
                       (make-vect 0.0 0.0)
                       (make-vect 1.0 0.0)
                       (make-vect 0.0 0.5))))


bottom-half

 

;;   (lambda (painter)
;;     (transform-painter painter
;;                        (make-vect 0.0 0.0)
;;                        (make-vect 0.5 0.0)
;;                        (make-vect 0.0 1.0))))

;; (define beside
;;   (lambda (painter1 painter2)
;;     (let ((split-point (make-vect 0.5 0.0)))
;;       (let ((paint-left
;;              (transform-painter painter1
;;                                 (make-vect 0.0 0.0)
;;                                 split-point
;;                                 (make-vect 0.0 1.0)))
;;             (paint-right
;;              (transform-painter painter2
;;                                 split-point
;;                                 (make-vect 1.0 0.0)
;;                                 (make-vect 0.5 1.0))))
;;         (lambda (frame)
;;           (paint-left frame)
;;           (paint-right frame))))))
(define beside
  (lambda (painter1 painter2)
    (lambda (frame)
      ((superpose (left-half painter1)
                  (right-half painter2)) frame))))


beside

 

;; (define below
;;   (lambda (painter1 painter2)
;;     (let ((split-point (make-vect 0.0 0.5)))
;;       (let ((paint-below
;;              (transform-painter painter1
;;                                 (make-vect 0.0 0.0)
;;                                 (make-vect 1.0 0.0)
;;                                 split-point))
;;             (paint-above
;;              (transform-painter painter2
;;                                 split-point
;;                                 (make-vect 1.0 0.5)
;;                                 (make-vect 0.0 1.0))))
;;         (lambda (frame)
;;           (paint-below frame)
;;           (paint-above frame))))))
(define below
  (lambda (painter1 painter2)
    (lambda (frame)
      ((superpose (bottom-half painter1)
                  (top-half painter2)) frame))))


below

 

(define right-split
  (split beside below))


right-split-2

 

(define up-split
  (split below beside))


up-split-2

 

(define corner-split
  (lambda (painter n)
    (if (zero? n)
        painter
        (let ((up (up-split painter (- n 1)))
              (right (right-split painter (- n 1))))
          (let ((top-left (beside up up))
                (bottom-right (below right right))
                (corner (corner-split painter (- n 1))))
            (beside (below painter top-left)
                    (below bottom-right corner)))))))

corner-split-2

 

(define square-limit
  (lambda (painter n)
    (let ((combine4 (square-of-four flip-horiz identity
                                    rotate180 flip-vert)))
      (combine4 (corner-split painter n)))))


square-limit

 

(define cross-limit
  (lambda (painter n)
    (if (zero? n)
        painter
        (let ((cross (cross-limit painter (- n 1))))
          (let ((top (beside painter cross))
                (bottom (beside cross painter)))
            (below bottom top))))))


cross-limit

 

(define cross-corner-limit
  (coupling (lambda (painter1 painter2)
                  (below painter1 (beside painter1 painter2)))))


cross-corner-limit

 

(define grid-limit
  (lambda (painter n)
    (if (zero? n)
        painter
        (grid-limit ((square-of-four identity identity
                                     identity identity) painter)
                    (- n 1)))))


grid-limit

 

(define triple
  (lambda (painter1 painter2 painter3)
    (below
     (beside painter2 painter3)
     (squash-left painter1))))


triple

 

(define dog-ear
  (lambda (painter)
    ((coupling (lambda (painter1 painter2)
                     (triple painter2 painter1 painter2)))
     painter 3)))


dog-ear

 

(define flipped-pairs
  (lambda (painter)
    (let ((painter2 (beside painter (flip-vert painter))))
      (below painter2 painter2))))


flipped-pairs

 

samples

その他、組み合わせのサンプル。とくに気の利いたものはありません。

; sample-001
((square-limit
  (let ((friend (beside wave-painter (flip-horiz wave-painter))))
    (below friend (flip-vert friend))) 3) square-frame)


sample-001

 

; sample-002
((corner-split hexagon-painter 5) square-frame)


sample-002

 

; sample-003
((square-limit diamond-painter 4) square-frame)


sample-003

 

; sample-004
((square-limit (superpose X-painter diamond-painter) 3) square-frame)


sample-004

 

; sample-005
((square-limit (superpose X-painter cross-painter diamond-painter) 3) square-frame)


sample-005

 

; sample-006
((square-limit (below (flip-vert (corner-split outline-painter 2))
        (right-split outline-painter 2)) 3) square-frame)


sample-006

 

; sample-007
((cross-limit (right-split X-painter 2) 4) square-frame)


sample-007

 

; sample-008
((let ((up (up-split (superpose X-painter cross-painter outline-painter) 2)))
   (cross-limit (below up (flip-vert up))  4)) square-frame)


sample-008

 

; sample-009
((grid-limit wave-painter 4) square-frame)


sample-009

 

; sample-010
(((coupling below) wave-painter 4) square-frame)

sample-010

 

; sample-011
((cross-corner-limit wave-painter 4) square-frame)


sample-011

 

; sample-012
((triple X-painter lambda-painter Z-painter) square-frame)


sample-012

 

; sample-013
((square-limit (dog-ear outline-painter) 2) square-frame)


sample-013

 

; sample-014
((square-limit (dog-ear wave-painter) 2) square-frame)


sample-014

 

; sample-015
(let ((p (let ((p1 ((coupling below) wave-painter 4)))
           (let ((p2 (flip-horiz p1)))
             (beside p1 p2)))))
  ((below p (flip-vert p)) square-frame))


sample-015

 

課題

  • フロントエンドGUIを作る
  • 再帰曲線を描いてみる
  • 空間充填線を描いてみる
  • 黄金四角形とその正方形の中点を結んだ曲線を描いてみる
  • 色を付けられるようにする

 

参考

 

計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 51385
おすすめ度の平均: 3.0
1 訳が酷い
4 紙と鉛筆と計算機と
1 内容最高。翻訳最低。
5 食わず嫌いでした。
5 プログラマにとって必読の本です