shibuya.lisp20091107

58
さあ家に帰ったら Schemeのコード書いてみよう Higepon Shibuya.Lisp Tech Talk#4 November 7, 2009

Upload: higepon-taro-minowa

Post on 29-Jun-2015

1.595 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Shibuya.Lisp20091107

さあ家に帰ったらSchemeのコード書いてみよう

Higepon

Shibuya.Lisp Tech Talk#4November 7, 2009

Page 2: Shibuya.Lisp20091107

自己紹介

Page 4: Shibuya.Lisp20091107

MonaオープソースOS

Mosh高速なSchemeインタプリタ

Outputzhttp://outputz.com/

Page 5: Shibuya.Lisp20091107

さて皆さん身に覚えがありませ

んか?

Page 6: Shibuya.Lisp20091107

Scheme/Lispに興味がある

SICP買ってみた(チラ見した)練習問題も解いてみた

プログラミング Gauche 読んだ

Shibuya.lisp に参加した刺激受けた

おし俺 Lisp がんばる!(←今ココ)

Page 7: Shibuya.Lisp20091107

しかし!週明けには

Page 8: Shibuya.Lisp20091107

気付いたらRuby使ってる!

Page 9: Shibuya.Lisp20091107

どうしてこうなった?

Page 10: Shibuya.Lisp20091107

Lisp を何に使ったら良いか分からない最初の1歩が踏み出せない

Page 11: Shibuya.Lisp20091107

どうしたら良いか?

Page 12: Shibuya.Lisp20091107

自分が使うものをLispで作ろう

Scheme/Lisp の良さを生かそう小さいものからはじめて大きくしよう自分が使うから改良したくなるよ

Page 13: Shibuya.Lisp20091107

結論は出ましたが

Page 14: Shibuya.Lisp20091107

初めの一歩の参考になれば

過去に作ってきた小さなツール紹介十分小さく

実用的

今でも使っているものも

Page 15: Shibuya.Lisp20091107

英単語復習スクリプト

Page 16: Shibuya.Lisp20091107
Page 17: Shibuya.Lisp20091107

問題英単語覚えたい

毎日気軽に復習したい

問題追加が簡単に

Page 18: Shibuya.Lisp20091107

問題英単語覚えたい

毎日気軽に復習したい

問題追加が簡単に

解決方法英単語復習スクリプト

英単語データ

Page 19: Shibuya.Lisp20091107

('p227-252 ((acquaint "を紹介する、を知らせる")(condemn "を非難する")(colonist "入植者")(consent "同意する")

C-d で答え表示

実行例 データ

Page 20: Shibuya.Lisp20091107

(call-with-input-file (second (command-line)) (lambda (p) (let1 word* (second (read p)) (for-each (lambda (word) (format #t "~s \n" (first word)) (read (current-input-port)) (format #t "~s \n\n" (second word))) word*) (newline))))

Page 21: Shibuya.Lisp20091107

(call-with-input-file (second (command-line)) (lambda (p) (let1 word* (second (read p)) (for-each (lambda (word) (format #t "~s \n" (first word)) (read (current-input-port)) (format #t "~s \n\n" (second word))) word*) (newline))))

単語のリストを read

Page 22: Shibuya.Lisp20091107

(call-with-input-file (second (command-line)) (lambda (p) (let1 word* (second (read p)) (for-each (lambda (word) (format #t "~s \n" (first word)) (read (current-input-port)) (format #t "~s \n\n" (second word))) word*) (newline))))

単語のリストを read

全ての単語を

Page 23: Shibuya.Lisp20091107

(call-with-input-file (second (command-line)) (lambda (p) (let1 word* (second (read p)) (for-each (lambda (word) (format #t "~s \n" (first word)) (read (current-input-port)) (format #t "~s \n\n" (second word))) word*) (newline))))

単語のリストを read

全ての単語を

問題

Page 24: Shibuya.Lisp20091107

(call-with-input-file (second (command-line)) (lambda (p) (let1 word* (second (read p)) (for-each (lambda (word) (format #t "~s \n" (first word)) (read (current-input-port)) (format #t "~s \n\n" (second word))) word*) (newline))))

単語のリストを read

全ての単語を

問題

答え

Page 25: Shibuya.Lisp20091107

(call-with-input-file (second (command-line)) (lambda (p) (let1 word* (second (read p)) (for-each (lambda (word) (format #t "~s \n" (first word)) (read (current-input-port)) (format #t "~s \n\n" (second word))) word*) (newline))))

単語のリストを read

全ての単語を

問題

答え

10行

Page 26: Shibuya.Lisp20091107

Lisp が生かされる部分英単語データS式にすれば

パーサー要らない

read→リスト操作→表示する

問題追加も人間が読み書きできるS式

少しずつ改良するなら

ランダム出題。正答率記録。

Page 27: Shibuya.Lisp20091107

検索記録ツール

Page 28: Shibuya.Lisp20091107
Page 29: Shibuya.Lisp20091107

問題英辞郎 on the WEB

http://www.alc.co.jp/

「あれ?この単語以前調べたような?」

調べた単語は記録したい

Page 30: Shibuya.Lisp20091107

問題英辞郎 on the WEB

http://www.alc.co.jp/

「あれ?この単語以前調べたような?」

調べた単語は記録したい

解決方法リダイレクタをはさむ

Page 31: Shibuya.Lisp20091107

リダイレクタ

http://monaos.org/word/apple/

リダイレクトリクエスト

apple

記録

http://eow.alc.co.p/apple/

Page 32: Shibuya.Lisp20091107

(define dictionary "/home/monaos/www/mosh.monaos.org/words.txt")(define words (with-input-from-file dictionary read))

(define (register-word word) (define (write-dict words) (write-to-file dictionary words)) (unless (member word words) (write-dict (cons word words))))

(define (redirect-to-alc word) (cgi:moved-temporarily-header (format "http://eow.alc.co.jp/~a/UTF-8/?ref=sa" word)))

(let-values (([get-value method] (cgi:init))) (aif (get-value "word") (begin (register-word (cgi:decode it)) (redirect-to-alc it))))

Page 33: Shibuya.Lisp20091107

(define dictionary "/home/monaos/www/mosh.monaos.org/words.txt")(define words (with-input-from-file dictionary read))

(define (register-word word) (define (write-dict words) (write-to-file dictionary words)) (unless (member word words) (write-dict (cons word words))))

(define (redirect-to-alc word) (cgi:moved-temporarily-header (format "http://eow.alc.co.jp/~a/UTF-8/?ref=sa" word)))

(let-values (([get-value method] (cgi:init))) (aif (get-value "word") (begin (register-word (cgi:decode it)) (redirect-to-alc it))))

単語のリストを read

Page 34: Shibuya.Lisp20091107

(define dictionary "/home/monaos/www/mosh.monaos.org/words.txt")(define words (with-input-from-file dictionary read))

(define (register-word word) (define (write-dict words) (write-to-file dictionary words)) (unless (member word words) (write-dict (cons word words))))

(define (redirect-to-alc word) (cgi:moved-temporarily-header (format "http://eow.alc.co.jp/~a/UTF-8/?ref=sa" word)))

(let-values (([get-value method] (cgi:init))) (aif (get-value "word") (begin (register-word (cgi:decode it)) (redirect-to-alc it))))

単語のリストを read

単語リストになかったら

Page 35: Shibuya.Lisp20091107

(define dictionary "/home/monaos/www/mosh.monaos.org/words.txt")(define words (with-input-from-file dictionary read))

(define (register-word word) (define (write-dict words) (write-to-file dictionary words)) (unless (member word words) (write-dict (cons word words))))

(define (redirect-to-alc word) (cgi:moved-temporarily-header (format "http://eow.alc.co.jp/~a/UTF-8/?ref=sa" word)))

(let-values (([get-value method] (cgi:init))) (aif (get-value "word") (begin (register-word (cgi:decode it)) (redirect-to-alc it))))

単語のリストを read

単語リストになかったら

単語追加

Page 36: Shibuya.Lisp20091107

(define dictionary "/home/monaos/www/mosh.monaos.org/words.txt")(define words (with-input-from-file dictionary read))

(define (register-word word) (define (write-dict words) (write-to-file dictionary words)) (unless (member word words) (write-dict (cons word words))))

(define (redirect-to-alc word) (cgi:moved-temporarily-header (format "http://eow.alc.co.jp/~a/UTF-8/?ref=sa" word)))

(let-values (([get-value method] (cgi:init))) (aif (get-value "word") (begin (register-word (cgi:decode it)) (redirect-to-alc it))))

単語のリストを read

単語リストになかったら

単語追加

リダイレクト

Page 37: Shibuya.Lisp20091107

(define dictionary "/home/monaos/www/mosh.monaos.org/words.txt")(define words (with-input-from-file dictionary read))

(define (register-word word) (define (write-dict words) (write-to-file dictionary words)) (unless (member word words) (write-dict (cons word words))))

(define (redirect-to-alc word) (cgi:moved-temporarily-header (format "http://eow.alc.co.jp/~a/UTF-8/?ref=sa" word)))

(let-values (([get-value method] (cgi:init))) (aif (get-value "word") (begin (register-word (cgi:decode it)) (redirect-to-alc it))))

単語のリストを read

単語リストになかったら

単語追加

リダイレクト

14行

Page 38: Shibuya.Lisp20091107

Lisp が生かされる部分フォーマットS式にすれば(略)

少しずつ改良するならリストを表示。調べた回数記録。

Page 39: Shibuya.Lisp20091107

CPU!CPU!

Page 40: Shibuya.Lisp20091107
Page 41: Shibuya.Lisp20091107

問題Thinkpad に載っているCPU型番忘れた

Core2 Duo だっけ?

Page 42: Shibuya.Lisp20091107

問題Thinkpad に載っているCPU型番忘れた

Core2 Duo だっけ?

解決アセンブラの CPUID 命令使う

Lisp なら違和感なく Cool に書けるよ

Page 43: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

Page 44: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

アセンブラで手続き書く

Page 45: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

引数受け取って

アセンブラで手続き書く

Page 46: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

引数受け取って

CPUID発行

アセンブラで手続き書く

Page 47: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

引数受け取って

CPUID発行

結果を多値レジスタへ

アセンブラで手続き書く

Page 48: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

引数受け取って

CPUID発行

結果を多値レジスタへ

実行

アセンブラで手続き書く

Page 49: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

引数受け取って

CPUID発行

結果を多値レジスタへ

実行

アセンブラで手続き書く

Page 50: Shibuya.Lisp20091107

(define cpuid (asm*->procedure `((movq rax (& rdx)) ;; arg0 ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) ;; arg1 isFalse (je ,label) (addq rax #x80000000) ;; extended? (label ,label) (cpuid) (movq r10 ,(vm-register 'values)) ;; values VM register (movq ,(vm-register 'num-values) 4) ;; number of values ,@(macro-make-fixnum 'rax) ;; rax is result 1 (movq ,(vm-register 'ac) rax) ,@(macro-make-fixnum 'rbx) ;; rbx is result 2 (movq (& r10) rbx) ,@(macro-make-fixnum 'rcx) ;; rcx is result 3 (movq (& r10 8) rcx) ,@(macro-make-fixnum 'rdx) ;; rdx is result 4 (movq (& r10 16) rdx) (movq rax ,(vm-register 'ac)))))

(do ([i 2 (+ i 1)]) [(= i 5)] (receive (rax rbx rcx rdx) (cpuid i #t) (format #t "~a~a~a~a" (u32->string rax) (u32->string rbx) (u32->string rcx) (u32->string

引数受け取って

CPUID発行

結果を多値レジスタへ

実行

アセンブラで手続き書く

24行

Page 51: Shibuya.Lisp20091107

Lisp が生かされる部分アセンブラがS式で。

アセンブラにマクロ

`((movq rax (& rdx)) ,@(macro-to-fixnum 'rax) (cmpq (& rdx 8) 86) (je ,label) (addq rax #x80000000) (cpuid)

Page 52: Shibuya.Lisp20091107

まとめ

Page 53: Shibuya.Lisp20091107
Page 54: Shibuya.Lisp20091107

Lispで自分のためのツールを作る

Page 55: Shibuya.Lisp20091107

Lispで自分のためのツールを作る

小さいものから始めると良い

Page 56: Shibuya.Lisp20091107

Lispで自分のためのツールを作る

小さいものから始めると良いS式をうまく使うと楽できる

Page 57: Shibuya.Lisp20091107

Lispで自分のためのツールを作る

小さいものから始めると良いS式をうまく使うと楽できる

家に帰ったら書いてみよう!

Page 58: Shibuya.Lisp20091107

ご清聴ありがとうございました