ベンチャーの起業家に私たちが推薦しているのはデール・カーネギーの「人を動かす」。仕事をする人は必ず読むべき本だ。1960年代より前の版を入手してほしい。 カーネギーの死後、本は委員会に「改訂」され続け、その結果かえって悪くなってしまった。有名な本ですね。読んでいません。個人的に「うさんくせぇー本だな・・・。」と思う本の一つだったので。。
ポール・グレアムがオススメしているとなると読みたくなる不思議。
しかし、一体どうやってそんな古書を・・・。。
ベンチャーの起業家に私たちが推薦しているのはデール・カーネギーの「人を動かす」。仕事をする人は必ず読むべき本だ。1960年代より前の版を入手してほしい。 カーネギーの死後、本は委員会に「改訂」され続け、その結果かえって悪くなってしまった。有名な本ですね。読んでいません。個人的に「うさんくせぇー本だな・・・。」と思う本の一つだったので。。
;; PAIP chapter.6 tree-search | |
(use srfi-1) | |
(use gauche.sequence) | |
(use liv.debugs) | |
(debug :search) | |
;; (undebug :search) | |
(define fail '()) | |
(define (tree-search states goal? successors combiner) | |
;; (debug-indent :search 10 ";; Search: ~a" states) | |
(dbg :search ";; Search: ~a" states) | |
(cond ((null? states) fail) | |
((goal? (car states))(car states)) | |
(else (tree-search (combiner (successors (car states)) | |
(cdr states)) | |
goal? successors combiner)))) | |
(define (tree-search states goal? successors combiner) | |
(if (null? states) | |
fail | |
(let1 a (car states) | |
(if (goal? a) | |
a | |
(tree-search (combiner (successors a) | |
(cdr states)) | |
goal? successors combiner))))) | |
(define (tree-search states goal? successors combiner) | |
(if (null? states) | |
fail | |
(let rec ((states states)) | |
(dbg :search ";; Search: ~a" states) | |
(let1 a (car states) | |
(if (goal? a) | |
a | |
(rec (combiner (successors a) | |
(cdr states)))))))) | |
;; successors | |
(define (binary-tree x) | |
(let1 x (* 2 x) | |
(list x (+ 1 x)))) | |
(define (finite-binary-tree n) | |
(lambda (x) | |
(remove (pa$ < n) | |
(binary-tree x)))) | |
;; cost function | |
(define (diff num) | |
(compose abs (cut - <> num))) | |
(define (sorter cost-fn) | |
(lambda (new old) | |
(sort-by (append new old) cost-fn <))) | |
(define (price-is-right price) | |
(lambda (x) | |
(if (> x price) | |
(greatest-fixnum) | |
(- price x)))) | |
;; goal? | |
(define (is value) | |
(pa$ equal? value)) | |
;; combiner | |
(define (prepend x y) | |
(append y x)) |
(define (depth-first-search start goal? successors) | |
(tree-search (list start) goal? successors append)) | |
;; (depth-first-search 1 (is 12) binary-tree) | |
;; endless loop ... | |
(depth-first-search 1 (is 12)(finite-binary-tree 15)) | |
;; Search: (1) | |
;; Search: (2 3) | |
;; Search: (4 5 3) | |
;; Search: (8 9 5 3) | |
;; Search: (9 5 3) | |
;; Search: (5 3) | |
;; Search: (10 11 3) | |
;; Search: (11 3) | |
;; Search: (3) | |
;; Search: (6 7) | |
;; Search: (12 13 7)12 |
(define (breadth-first-search start goal? successors) | |
(tree-search (list start) goal? successors prepend)) | |
(breadth-first-search 1 (is 12) binary-tree) | |
;; Search: (1) | |
;; Search: (2 3) | |
;; Search: (3 4 5) | |
;; Search: (4 5 6 7) | |
;; Search: (5 6 7 8 9) | |
;; Search: (6 7 8 9 10 11) | |
;; Search: (7 8 9 10 11 12 13) | |
;; Search: (8 9 10 11 12 13 14 15) | |
;; Search: (9 10 11 12 13 14 15 16 17) | |
;; Search: (10 11 12 13 14 15 16 17 18 19) | |
;; Search: (11 12 13 14 15 16 17 18 19 20 21) | |
;; Search: (12 13 14 15 16 17 18 19 20 21 22 23)12 |
(define (best-first-search start goal? successors const-fn) | |
(tree-search (list start) goal? successors (sorter const-fn))) | |
(best-first-search 1 (is 12) binary-tree (diff 12)) | |
;; Search: (1) | |
;; Search: (3 2) | |
;; Search: (7 6 2) | |
;; Search: (14 15 6 2) | |
;; Search: (15 6 2 28 29) | |
;; Search: (6 2 28 29 30 31) | |
;; Search: (12 13 2 28 29 30 31)12 | |
(best-first-search 1 (is 12) binary-tree (price-is-right 12)) | |
;; Search: (1) | |
;; Search: (3 2) | |
;; Search: (7 6 2) | |
;; Search: (6 2 14 15) | |
;; Search: (12 2 13 14 15)12 |
(define (beam-search start goal? successors cost-fn beam-width) | |
(tree-search (list start) goal? successors | |
(lambda (old new) | |
(let1 sorted ((sorter cost-fn) old new) | |
(if (> beam-width (length sorted)) | |
sorted | |
(subseq sorted 0 beam-width)))))) | |
(beam-search 1 (is 12) binary-tree (price-is-right 12) 2) | |
;; Search: (1) | |
;; Search: (3 2) | |
;; Search: (7 6) | |
;; Search: (6 14) | |
;; Search: (12 13)12 |
;; debug tools | |
;; PAIP(実用 Common Lisp) - P.116 - 4.10 | |
(define-module liv.debugs | |
(use srfi-1) | |
(use gauche.parameter) | |
(export-all)) | |
(select-module liv.debugs) | |
(define *dbg-ids* (make-parameter '())) | |
;; (define (dbg id format-string . args) | |
;; (when (member id (*dbg-ids*)) | |
;; (let1 port (current-error-port) | |
;; (newline port) | |
;; (apply format port format-string args)))) | |
(define dbg (cut debug-indent <> 0 <> <...>)) | |
(define (debug . ids) | |
(*dbg-ids* (lset-union eq? ids (*dbg-ids*)))) | |
(define (undebug . ids) | |
(*dbg-ids* (if (null? ids) | |
'() | |
(lset-difference eq? (*dbg-ids*) ids)))) | |
(define (debug-indent id indent format-string . args) | |
(when (member id (*dbg-ids*)) | |
(let1 port (current-error-port) | |
(newline port) | |
;; (dotimes (i indent (display " " port))) | |
(display (apply string-append (make-list indent " ")) port) | |
(apply format port format-string args)))) | |
(provide "liv/debugs") |
;; macro reverse | |
(define-syntax mreverse | |
(syntax-rules () | |
((_ (arg ...)) | |
(mreverse "help" ()(arg ...))) | |
((_ "help" (acc ...)()) | |
(acc ...)) | |
((_ "help" (acc ...)(arg x ...)) | |
(mreverse "help" (arg acc ...)(x ...))))) | |
(mreverse (3 2 1 list)) | |
;; (1 2 3) |
(define-syntax mreverse | |
(syntax-rules () | |
((_ (arg ...)) | |
(mreverse-helper ()(arg ...))))) | |
(define-syntax mreverse-helper | |
(syntax-rules () | |
((_ (acc ...)()) | |
(acc ...)) | |
((_ (acc ...)(arg x ...)) | |
(mreverse-helper (arg acc ...)(x ...))))) |
(define-macro (& exp . body) | |
`(let1 <> ,exp ,@body)) | |
(& 2 | |
(& (* <> 2) | |
(list <> (+ 1 <>)))) |
(define-syntax cet-helper | |
(syntax-rules (cet <>) | |
;; base | |
((_ val (x ...)()) | |
(x ...)) | |
;; list | |
((_ val (x ...)((nest ...) rest ...)) | |
(cet-helper val (x ... (cet-helper val ()(nest ...)))(rest ...))) | |
((_ val (x ...)(<> rest ...)) | |
(cet-helper val (x ... val)(rest ...))) | |
((_ val (x ...)(a rest ...)) | |
(cet-helper val (x ... a)(rest ...))) | |
;; atom | |
((_ val (x ...) <>) | |
val) | |
((_ val (x ...) a) | |
a))) | |
(define-syntax cet | |
(syntax-rules () | |
((_ expr body ...) | |
(let ((tmp expr)) | |
(cet-helper tmp () body ...))))) | |
(cet (* 2 2) | |
(list <> <> <> <>)) | |
;; (4 4 4 4) | |
(cet 10 <>) | |
;; 10 | |
(use srfi-1) | |
(cet 10 (map list (iota <>))) | |
;; ((0) (1) (2) (3) (4) (5) (6) (7) (8) (9)) | |
(cet (* 2 2) | |
(apply + <> (list <> (+ 1 <>)))) | |
;; 13 | |
(cet 2 | |
(cet (* <> 2) | |
(list <> (+ 1 <>)))) | |
;; error |
(define-syntax cet-helper | |
(syntax-rules (cet <>) | |
;; base | |
((_ val (x ...)()) | |
(x ...)) | |
;; add | |
((_ val (x ...)((cet exp b ...) rest ...)) | |
(cet-helper val (x ... (cet (cet-helper val () exp) b ...))(rest ...))) | |
;; list | |
((_ val (x ...)((nest ...) rest ...)) | |
(cet-helper val (x ... (cet-helper val ()(nest ...)))(rest ...))) | |
((_ val (x ...)(<> rest ...)) | |
(cet-helper val (x ... val)(rest ...))) | |
((_ val (x ...)(a rest ...)) | |
(cet-helper val (x ... a)(rest ...))) | |
;; atom | |
((_ val (x ...) <>) | |
val) | |
((_ val (x ...) a) | |
a))) | |
(cet 2 | |
(cet (* <> 2) | |
(list <> (+ 1 <>)))) | |
;; error |
キー | 実行されるコマンド |
---|---|
C-c i | 編集.選択範囲のフォーマット |
C-h | 編集.一語削除 |
M-; | 編集.選択範囲のコメント |
M-+ | 編集.選択範囲のコメントを解除 |
C-, | ウィンドウ.前のドキュメントウィンドウ |
C-. | ウィンドウ.次のドキュメントウィンドウ |
実験室におけるよき習慣。ヒトは常に間違える。忘れる。混乱する。だから、それをしないよう注意するのではなく、それが起こらないための方法論を考えよ。あるいはミスが起こったとき、その被害が最小限にとどまるような仕組みを考えよ。それが君たちの仕事だ。
私の身体が、あるいは私の精神が不調なのは、何かが不足しているからかもしれない・・・・・・この強迫観念から逃れんがための反動として、私たちは時として、不必要な物質の大量摂取を無自覚に行なってしまうのです。↑を読んで↓を思い出しました。
英語でPlannerはプランする何かです。Conniverはスニーキー(こそこそする、卑劣)なプランナーです。だから、もっとスニーキーなプランナーを何と呼ぼうか。そりゃ、スキーマー(陰謀家、策略家)だ。それで、Schemerとつけたのです。
残念ながら、我々は60年代に設計されたOSを使っていたので、すべてのファイル名は6文字以下でなければなりませんでした。それで、ファイル名SCHEMERは最初の6文字だけに切り捨てられました。
Sussmanと私は、小さなインタプリタを書きました。言語を理解するもっとも簡単な方法はそのインタプリタを書くことです。インタプリタを書くもっともよい言語はLispです。
(require 'cl) (defvar a 100) a ;; 100 (defvar b 200) b ;; 200 (defun a+b () (+ a b)) (a+b) ;; 300 (let ((a 1)(b 2)) (values (a+b)(+ a b))) ;; (3 3) (lexical-let ((a 1)(b 2)) (values (a+b)(+ a b))) ;; (300 3)
(use srfi-15) (define a 100) a ;; 100 (define b 200) b ;; 200 (define (a+b) (+ a b)) (a+b) ;; 300 (let ((a 1)(b 2)) (values (a+b) a b)) ;; 300 ;; 1 ;; 2 (fluid-let ((a 1)(b 2)) (values (a+b) a b)) ;; 3 ;; 1 ;; 2
丸3年放置していましたが、2013/08/07辺りから再開しました。
;; 001 | |
;; http://projecteuler.net/index.php?section=problems&id=1 | |
;; If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. | |
;; Find the sum of all the multiples of 3 or 5 below 1000. | |
;; http://odz.sakura.ne.jp/projecteuler/index.php?Problem%201 | |
;; 10未満の自然数のうち、3 もしくは 5 の倍数になっているものは 3, 5, 6, 9 の4つがあり、 これらの合計は 23 になる。 | |
;; 同じようにして、1,000 未満の 3 か 5 の倍数になっている数字の合計を求めよ。 | |
(use srfi-1) | |
(apply + (filter (lambda (e) | |
(or (zero? (remainder e 3)) | |
(zero? (remainder e 5)))) | |
(iota 10))) | |
;; 23 | |
(define (filter-sum pred ls) | |
(apply + (filter pred ls))) | |
(filter-sum (lambda (e) | |
(or (zero? (remainder e 3)) | |
(zero? (remainder e 5)))) | |
(iota 1000)) | |
;; 233168 | |
(let1 f (compose zero? (pa$ remainder)) | |
(filter-sum (lambda (e) | |
(or (f e 3) | |
(f e 5))) | |
(iota 1000))) | |
(define (aliquant? n d) | |
(zero? (remainder n d))) | |
(filter-sum (lambda (e) | |
(or (aliquant? e 3) | |
(aliquant? e 5))) | |
(iota 1000)) | |
;; 233168 | |
(define (aliquant-any? n d . ds) | |
(any (lambda (d) | |
(aliquant? n d))(cons d ds))) | |
(filter-sum (cut aliquant-any? <> 3 5) | |
(iota 1000)) | |
;; 233168 |
(define-syntax def-let* | |
(syntax-rules () | |
((_ name let-macro-name) | |
(define-syntax name | |
(syntax-rules () | |
((_ ((var val)) body ...) | |
(let-macro-name ((var val)) | |
body ...)) | |
((_ ((var val) x ...) body ...) | |
(name ((var val)) | |
(name (x ...) body ...)))))))) | |
(def-let* my-fluid-let* fluid-let) |
@valvallow http://bit.ly/9Bvqri
@valvallow まず (use slib)(require 'repl)(require 'syntax-case) とします。 slib 環境内で評価したい式全体を quote して macro:eval 手続きに渡せばよいです。
@valvallow あるいは、 (repl:top-level macro:eval) とすると slib の repl が開始されるのでここに式を入力してもよいです。
(use slib) | |
(require 'repl) | |
(require 'syntax-case) | |
(macro:eval '(define-syntax def-let* | |
(syntax-rules () | |
((_ name let-macro-name) | |
(define-syntax name | |
(syntax-rules () | |
((_ ((var val)) body (... ...)) | |
(let-macro-name ((var val)) | |
body (... ...))) | |
((_ ((var val) x (... ...)) body (... ...)) | |
(name ((var val)) | |
(name (x (... ...)) body (... ...)))))))))) | |
(define a 1) | |
(define b 2) | |
(define c 3) | |
(define (a+b+c) | |
(+ a b c)) | |
(macro:eval '(def-let* my-fluid-let* fluid-let)) | |
(macro:eval '(begin | |
(my-fluid-let* ((a 100)(b 200)(c (+ a b))) | |
(print (a+b+c))) | |
(print (a+b+c)))) | |
;; 600 | |
;; 6 |
;; fluid-let* ;; ;; example ;; (define-values (a b c) ;; (values 1 2 3)) ;; (define (a+b+c) ;; (+ a b c)) ;; (a+b+c) ;; ;; 6 ;; (fluid-let* ((a 100) ;; (b (* a 2)) ;; (c (+ a b))) ;; (a+b+c)) ;; ;; 600
;; fluid-let* | |
;; ;; example | |
;; (define-values (a b c) | |
;; (values 1 2 3)) | |
;; (define (a+b+c) | |
;; (+ a b c)) | |
;; (a+b+c) | |
;; ;; 6 | |
;; (fluid-let* ((a 100) | |
;; (b (* a 2)) | |
;; (c (+ a b))) | |
;; (a+b+c)) | |
;; ;; 600 | |
(define-syntax fluid-let* | |
(syntax-rules () | |
((_ ((var val)) body ...) | |
(fluid-let ((var val)) | |
body ...)) | |
((_ ((var val) x ...) body ...) | |
(fluid-let* ((var val)) | |
(fluid-let* (x ...) body ...))))) | |
(fluid-let* ((a 100) | |
(b (* a 2)) | |
(c (+ a b))) | |
(a+b+c)) | |
;; 600 | |
(a+b+c) | |
;; 6 |
(define-syntax def-let* | |
(syntax-rules () | |
((_ name let-macro-name) | |
(define-syntax name | |
(syntax-rules () | |
((_ ((var val)) body ...) | |
(let-macro-name ((var val)) | |
body ...)) | |
((_ ((var val) x ...) body ...) | |
(name ((var val)) | |
(name (x ...) body ...)))))))) | |
(def-let* my-fluid-let* fluid-let) |
;; fluid-let ;; example (define-values (a b)(values 1 2)) (define (a+b) (+ a b)) (a+b) ;; 3 (fluid-let ((a 100)(b 200)) (a+b)) ;; 300 ;; fluid-let expand image (let ((tempa a)(tempb b)) (dynamic-wind (lambda () (set! a 100)(set! b 200)) (lambda () (a+b)) (lambda () (set! a tempa)(set! b tempb)))) ;; 300 (a+b) ;; 3独習 Scheme 三週間 Teach Yourself Scheme in Fixnum Days に伝統的なマクロを用いた例が載っています。
;; SRFI 15: Syntax for dynamic scoping - http://srfi.schemers.org/srfi-15/srfi-15.html (define-syntax fluid-let (syntax-rules () ((_ ((v1 e1) ...) b1 b2 ...) (fluid-let "temps" () ((v1 e1) ...) b1 b2 ...)) ((_ "temps" (t ...) ((v1 e1) x ...) b1 b2 ...) (let ((temp e1)) (fluid-let "temps" ((temp e1 v1) t ...) (x ...) b1 b2 ...))) ((_ "temps" ((t e v) ...) () b1 b2 ...) (let-syntax ((swap! (syntax-rules () ((swap! a b) (let ((tmp a)) (set! a b) (set! b tmp)))))) (dynamic-wind (lambda () (swap! t v) ...) (lambda () b1 b2 ...) (lambda () (swap! t v) ...))))))
(define-syntax swap! | |
(syntax-rules () | |
((_ a b) | |
(let1 temp a | |
(set! a b) | |
(set! b temp))))) | |
(define-syntax my-fluid-let | |
(syntax-rules () | |
((_ ((var val) ...) body ...) | |
(my-fluid-let-helper () ((var val) ...) body ...)))) | |
(define-syntax my-fluid-let-helper | |
(syntax-rules () | |
((_ (t ...)((var val) x ...) body ...) | |
(let1 temp val | |
(my-fluid-let-helper (t ... (temp var))(x ...) body ...))) | |
((_ ((temp var) ...)() body ...) | |
(dynamic-wind | |
(lambda () | |
(swap! temp var) ...) | |
(lambda () | |
body ...) | |
(lambda () | |
(swap! temp var) ...))))) | |
(my-fluid-let ((a 100)(b 200)) | |
(a+b)) | |
;; 300 | |
(a+b) | |
;; 3 |
(_ "temps" (t ...) ((v1 e1) x ...) b1 b2 ...) (let ((temp e1)) (fluid-let "temps" ((temp e1 v1) t ...) (x ...) b1 b2 ...)))この部分が素敵ですね!自分はこのテクニック(?)を知らなかったので、今まで以下のように書いていました。。
(define-syntax my-fluid-let-helper | |
(syntax-rules () | |
((_ (t ...)((var val)) body ...) | |
(let1 temp val | |
(my-fluid-let-helper ((temp val var) t ...)() body ...))) | |
((_ (t ...)((var1 val1)(var2 val2) ...) body ...) | |
(let ((temp1 val1)) | |
(my-fluid-let-helper ((temp1 val1 var1) t ...)((var2 val2) ...) body ...))) | |
((_ ((t val var) ...)() body ...) | |
(dynamic-wind | |
(lambda () | |
(swap! t var) ...) | |
(lambda () | |
body ...) | |
(lambda () | |
(swap! t var) ...))))) |
(define-syntax my-fluid-let | |
(syntax-rules () | |
((_ ((var val) ...) body ...) | |
(my-fluid-let "temp" () ((var val) ...) body ...)) | |
((_ "temp" (t ...)((var val) x ...) body ...) | |
(let1 temp val | |
(my-fluid-let-helper (t ... (temp var))(x ...) body ...))) | |
((_ "temp" ((temp var) ...)() body ...) | |
(let-syntax ((swap! (syntax-rules () | |
((swap! a b) | |
(let1 tmp a | |
(set! a b) | |
(set! b tmp)))))) | |
(dynamic-wind | |
(lambda () | |
(swap! temp var) ...) | |
(lambda () | |
body ...) | |
(lambda () | |
(swap! temp var) ...)))))) | |
(a+b) | |
;; 3 | |
(my-fluid-let ((a 100)(b 200)) | |
(a+b)) | |
;; 300 | |
(a+b) | |
;; 3 |
(define-syntax my-fluid-let | |
(syntax-rules () | |
((_ ((var val) ...) body ...) | |
(let-syntax | |
((swap! (syntax-rules () | |
((swap! a b) | |
(let1 temp a | |
(set! a b) | |
(set! b temp)))))) | |
(letrec-syntax | |
((helper (syntax-rules () | |
((helper (t ...)((var val) x ...) body ...) | |
(let1 temp val | |
(helper (t ... (temp var))(x ...) body ...))) | |
((helper ((temp var) ...)() body ...) | |
(dynamic-wind | |
(lambda () | |
(swap! temp var) ...) | |
(lambda () | |
body ...) | |
(lambda () | |
(swap! temp var) ...)))))) | |
(helper () ((var val) ...) body ...)))))) |
;; SRFI 15: Syntax for dynamic scoping - http://srfi.schemers.org/srfi-15/srfi-15.html (define-syntax fluid-let (syntax-rules () ((_ ((v1 e1) ...) b1 b2 ...) (fluid-let "temps" () ((v1 e1) ...) b1 b2 ...)) ((_ "temps" (t ...) ((v1 e1) x ...) b1 b2 ...) (let ((temp e1)) (fluid-let "temps" ((temp e1 v1) t ...) (x ...) b1 b2 ...))) ((_ "temps" ((t e v) ...) () b1 b2 ...) (let-syntax ((swap! (syntax-rules () ((swap! a b) (let ((tmp a)) (set! a b) (set! b tmp)))))) (dynamic-wind (lambda () (swap! t v) ...) (lambda () b1 b2 ...) (lambda () (swap! t v) ...))))))
;; Identifier Syntax - http://permalink.gmane.org/gmane.lisp.scheme.reports.wg1/148 (define-syntax fluid-let (syntax-rules () ((fluid-let ("step") bind ((var val) . rest) body ...) (fluid-let ("step") ((var old new val) . bind) rest body ...)) ((fluid-let ("step") ((var old new val) ...) () body ...) (let ((old var) ... (new val) ...) (dynamic-wind (lambda () (set! var new) ...) (lambda () body ...) (lambda () (set! var old) ...)))) ((fluid-let ((var val) ...) body ...) (fluid-let ("step") () ((var val) ...) body ...))))
;; http://www-pu.informatik.uni-tuebingen.de/users/knauel/sw/fffi/easyffi.scm (define-syntax fluid-let (syntax-rules () ((fluid-let ((var1 expr1) (var2 expr2)) body ...) (let ((old-var1 var1) (old-var2 var2)) (set! var1 expr1) (set! var2 expr2) (let ((res ((lambda () body ...)))) (set! var1 old-var1) (set! var2 old-var2) res))) ((fluid-let ((var1 expr1)) body ...) (let ((old-var1 var1)) (set! var1 expr1) (let ((res ((lambda () body ...)))) (set! var1 old-var1) res)))))
;; Control Operations - http://www.scheme.com/tspl4/control.html (define-syntax fluid-let (syntax-rules () [(_ ((x e)) b1 b2 ...) (let ([y e]) (let ([swap (lambda () (let ([t x]) (set! x y) (set! y t)))]) (dynamic-wind swap (lambda () b1 b2 ...) swap)))]))
(define-macro (aif test-form then-form . else-form) | |
`(let ((it ,test-form)) | |
(if it ,then-form ,@else-form))) | |
(define-macro (aand . args) | |
(cond ((null? args) #t) | |
((null? (cdr args))(car args)) | |
(else `(aif ,(car args) (aand ,@(cdr args)))))) | |
(aand (string-scan "aaa.el" ".elc" 'after) | |
(string=? it "")) | |
;; #<undef> | |
(macroexpand '(aand (string-scan "aaa.el" ".elc" 'after) | |
(string=? it "") "not found")) | |
(let ((it (string-scan "aaa.el" ".elc" 'after))) | |
(if it | |
(let ((it (string=? it ""))) | |
(if it | |
"not found")))) |
(define-macro (aand . args) | |
(cond ((null? args)) | |
((null? (cdr args))(car args)) | |
(else `(if-let1 it ,(car args) | |
(aand ,@(cdr args)) | |
#f)))) | |
(aand (string-scan "aaa.el" ".elc" 'after) | |
(string=? it "")) | |
;; #f |
(and-let* ((it (string-scan "aaa.el" ".elc" 'after)) | |
(it (string=? it ""))) | |
it) |
gauche で (append '() 1) を評価した結果が 1 になるのはなんとなく納得いかないなぁ...これを見て私もまんまと「え、なんでだろう?」と思いました。
shiro: R5RSでそう規定されてます RT: @yujiorama: gauche で (append '() 1) を評価した結果が 1 になるのはなんとなく納得いかないなぁ... http://bit.ly/atJY60で、実際 R5RS を見てみたら、そう書いてありました。そらそうですね。
shiro: appendは正式なリスト同士の演算じゃないんですね。むしろペアに対する演算の一種と考えた方がすっきりする。consやlist*の仲間。 http://bit.ly/9eMywh
@valvallow いや、一貫してるでしょう。 リストの最後 (null) を次のリストに置き換えた形にするものと考えれば。ここまで読んでもピンと来ませんでしたorz
(use srfi-1) | |
(define (my-append ls1 ls2) | |
(fold-right cons ls2 ls1)) | |
(my-append '(1 2 3)'(a b c)) | |
;; (1 2 3 a b c) | |
(my-append '() 'a)n | |
;; a | |
(my-append '(1) 2) | |
;; (1 . 2) | |
(define (my-append ls1 ls2) | |
(if (null? ls1) | |
ls2 | |
(cons (car ls1) | |
(my-append (cdr ls1) ls2)))) | |
(my-append '(1 2 3)'(a b c)) | |
;; (1 2 3 a b c) | |
(my-append '() 'a) | |
;; a | |
(my-append '(1) 2) | |
;; (1 . 2) | |
(define (my-append ls1 ls2) | |
(let rec ((ls (reverse ls1))(acc ls2)) | |
(if (null? ls) | |
acc | |
(rec (cdr ls)(cons (car ls) acc))))) | |
(my-append '(1 2 3)'(a b c)) | |
;; (1 2 3 a b c) | |
(my-append '() 'a) | |
;; a | |
(my-append '(1) 2) | |
;; (1 . 2) | |
(define (my-appends ls . lss) | |
(fold (lambda (e acc) | |
(my-append acc e)) '() (cons ls lss))) | |
(my-append '(1 2 3)'(a b c)) | |
;; (1 2 3 a b c) | |
(my-append '() 'a) | |
;; a | |
(my-append '(1) 2) | |
;; (1 . 2) | |
(my-appends '(1 2 3)'(4 5 6)'(7 8 9)'(10 11 12)) | |
;; (1 2 3 4 5 6 7 8 9 10 11 12) | |
(define (my-appends ls . lss) | |
(let rec ((ls (reverse (cons ls lss)))(acc '())) | |
(if (null? ls) | |
acc | |
(rec (cdr ls)(my-append (car ls) acc))))) | |
(my-append '(1 2 3)'(a b c)) | |
;; (1 2 3 a b c) | |
(my-append '() 'a) | |
;; a | |
(my-append '(1) 2) | |
;; (1 . 2) | |
(my-appends '(1 2 3)'(4 5 6)'(7 8 9)'(10 11 12)) | |
;; (1 2 3 4 5 6 7 8 9 10 11 12) |
;; PAIP excersise 3.1 | |
;; let*式と等価なラムダ式を示せ | |
(define-syntax let*->lambda | |
(syntax-rules () | |
((_ () body ...) | |
(let () | |
body ...)) | |
((_ ((var val)) body ...) | |
(let ((var val)) | |
body ...)) | |
((_ ((var1 val1)(var2 val2) ...) body ...) | |
(let*->lambda ((var1 val1)) | |
(let*->lambda ((var2 val2) ...) | |
body ...))))) | |
(macroexpand '(let*->lambda ((a 10)(b a)(c (+ a b))) | |
(print a b c))) | |
;; (#<identifier user#let> ((a 10)) | |
;; (#<identifier user#let*->lambda> ((b a) (c (+ a b))) | |
;; (print a b c))) | |
(define-syntax let->lambda | |
(syntax-rules () | |
((_ () body ...) | |
((lambda () | |
body ...))) | |
((_ ((var val)) body ...) | |
((lambda (var) | |
body ...) val)) | |
((_ ((var1 val1)(var2 val2) ...) body ...) | |
(let->lambda ((var1 val1)) | |
(let->lambda ((var2 val2) ...) | |
body ...))))) | |
(macroexpand '(let->lambda ((a 10)) | |
(print a))) | |
;; ((#<identifier user#lambda> (a) | |
;; (print a)) 10) | |
(define-syntax let*->lambda | |
(syntax-rules () | |
((_ () body ...) | |
(let->lambda () | |
body ...)) | |
((_ ((var val)) body ...) | |
(let->lambda ((var val)) | |
body ...)) | |
((_ ((var1 val1)(var2 val2) ...) body ...) | |
(let*->lambda ((var1 val1)) | |
(let*->lambda ((var2 val2) ...) | |
body ...))))) | |
(macroexpand '(let*->lambda ((a 10)(b a)(c (+ a b))) | |
(print a b c))) | |
;; ((#<identifier user#lambda> (a) | |
;; (#<identifier user#let*->lambda> ((b a) (c (+ a b))) | |
;; (print a b c))) 10) |
(define (cross-product proc xls yls) | |
(cross-combine xls yls proc)) | |
(define (combine-all xls yls) | |
(cross-product append xls yls)) | |
(print (combine-all (map list '(a b c))(map list '(1 2 3)))) | |
;; ((a 1) (b 1) (c 1) (a 2) (b 2) (c 2) (a 3) (b 3) (c 3)) | |
(cross-product + '(1 2 3)'(10 20 30)) | |
;; (11 12 13 21 22 23 31 32 33) | |
(cross-product list '(a b c d e f g h)'(1 2 3 4 5 6 7 8)) | |
;; ((a 1) (b 1) (c 1) (d 1) (e 1) (f 1) (g 1) (h 1) | |
;; (a 2) (b 2) (c 2) (d 2) (e 2) (f 2) (g 2) (h 2) | |
;; (a 3) (b 3) (c 3) (d 3) (e 3) (f 3) (g 3) (h 3) | |
;; (a 4) (b 4) (c 4) (d 4) (e 4) (f 4) (g 4) (h 4) | |
;; (a 5) (b 5) (c 5) (d 5) (e 5) (f 5) (g 5) (h 5) | |
;; (a 6) (b 6) (c 6) (d 6) (e 6) (f 6) (g 6) (h 6) | |
;; (a 7) (b 7) (c 7) (d 7) (e 7) (f 7) (g 7) (h 7) | |
;; (a 8) (b 8) (c 8) (d 8) (e 8) (f 8) (g 8) (h 8)) |
;; PAIP 2.6 P.41 | |
(define (combine-all xlis ylis) | |
(mappend (lambda (y) | |
(map (lambda (x) | |
(append x y)) xlis)) | |
ylis)) | |
(print (combine-all (map list '(a b c))(map list '(1 2 3)))) | |
;; ((a 1) (b 1) (c 1) (a 2) (b 2) (c 2) (a 3) (b 3) (c 3)) | |
;; (cross-combine '(1 2 3)'(a b c)) | |
;; ((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c)) | |
(define (cross-combine xlis ylis) | |
(mappend (lambda (y) | |
(map (lambda (x) | |
(list x y)) xlis)) | |
ylis)) | |
;; (add-combine-elements (cross-combine '(1 2 3)'(a b c)) | |
;; '(100 200 300)) | |
;; ((1 a 100) (2 a 100) (3 a 100) (1 b 100) (2 b 100) (3 b 100) (1 c 100) (2 c 100) (3 c 100) (1 a 200) (2 a 200) (3 a 200) (1 b 200) (2 b 200) (3 b 200) (1 c 200) (2 c 200) (3 c 200) (1 a 300) (2 a 300) (3 a 300) (1 b 300) (2 b 300) (3 b 300) (1 c 300) (2 c 300) (3 c 300)) | |
(define (add-combine-elements comb elements) | |
(mappend (lambda (c) | |
(map (lambda (e) | |
(append e (list c))) comb)) | |
elements)) | |
(define (cross-combine xls yls . opt) | |
(let-optionals* opt ((kons list)) | |
(mappend (lambda (y) | |
(map (lambda (x) | |
(kons x y)) xls)) | |
yls))) | |
(define (add-combine-elements comb elements) | |
(cross-combine comb elements (lambda (e c) | |
(append e (list c))))) | |
(define (cross-combines ls1 ls2 . lss) | |
(let rec ((lss lss)(comb (cross-combine ls1 ls2))) | |
(if (null? lss) | |
comb | |
(rec (cdr lss) | |
(add-combine-elements comb (car lss)))))) | |
;; (print (combine-all (map list '(a b c))(map list '(1 2 3)))) | |
;; ((a 1) (b 1) (c 1) (a 2) (b 2) (c 2) (a 3) (b 3) (c 3)) | |
(define (combine-all xlis ylis) | |
(cross-combine xlis ylis append)) | |
(print (cross-combines '(a b c)'(1 2 3)'(100 200 300))) | |
;; ((a 1 100) (b 1 100) (c 1 100) | |
;; (a 2 100) (b 2 100) (c 2 100) | |
;; (a 3 100) (b 3 100) (c 3 100) | |
;; (a 1 200) (b 1 200) (c 1 200) | |
;; (a 2 200) (b 2 200) (c 2 200) | |
;; (a 3 200) (b 3 200) (c 3 200) | |
;; (a 1 300) (b 1 300) (c 1 300) | |
;; (a 2 300) (b 2 300) (c 2 300) | |
;; (a 3 300) (b 3 300) (c 3 300)) | |
(print (cross-combines '(a b c)'(#f #t)'(1 2 3)'(100 200 300))) | |
;; ((a #f 1 100) (b #f 1 100) (c #f 1 100) | |
;; (a #t 1 100) (b #t 1 100) (c #t 1 100) | |
;; (a #f 2 100) (b #f 2 100) (c #f 2 100) | |
;; (a #t 2 100) (b #t 2 100) (c #t 2 100) | |
;; (a #f 3 100) (b #f 3 100) (c #f 3 100) | |
;; (a #t 3 100) (b #t 3 100) (c #t 3 100) | |
;; (a #f 1 200) (b #f 1 200) (c #f 1 200) | |
;; (a #t 1 200) (b #t 1 200) (c #t 1 200) | |
;; (a #f 2 200) (b #f 2 200) (c #f 2 200) | |
;; (a #t 2 200) (b #t 2 200) (c #t 2 200) | |
;; (a #f 3 200) (b #f 3 200) (c #f 3 200) | |
;; (a #t 3 200) (b #t 3 200) (c #t 3 200) | |
;; (a #f 1 300) (b #f 1 300) (c #f 1 300) | |
;; (a #t 1 300) (b #t 1 300) (c #t 1 300) | |
;; (a #f 2 300) (b #f 2 300) (c #f 2 300) | |
;; (a #t 2 300) (b #t 2 300) (c #t 2 300) | |
;; (a #f 3 300) (b #f 3 300) (c #f 3 300) | |
;; (a #t 3 300) (b #t 3 300) (c #t 3 300)) |
(define-macro (def-related-closures var-binds . proc-binds) | |
`(define-values ,(map car proc-binds) | |
(let ,var-binds | |
(values ,@(map cadr proc-binds))))) | |
(def-related-closures ((count 0)(step 1)) | |
(inc (lambda () | |
(set! count (+ count step)))) | |
(dec (lambda () | |
(set! count (- count step)))) | |
(reset (lambda () | |
(set! count 0)))) | |
(map (lambda (e) | |
(e)) | |
(list inc inc inc dec reset dec dec reset)) | |
;; (1 2 3 2 0 -1 -2 0) | |
(use srfi-27) | |
(define (sentence) | |
(append (noun-phrase)(verb-phrase))) | |
(define (noun-phrase) | |
(append (Article)(Noun))) | |
(define (verb-phrase) | |
(append (Verb)(noun-phrase))) | |
(define (Article) | |
(one-of '(the a))) | |
(define (Noun) | |
(one-of '(man ball woman table))) | |
(define (Verb) | |
(one-of '(hit took saw liked))) | |
(define (one-of set) | |
(list (random-elt set))) | |
(define (random-elt choices) | |
(list-ref choices (random-integer (length choices)))) | |
(sentence) | |
;; (a man liked a man) | |
(sentence) | |
;; (a table hit a ball) | |
(sentence) | |
;; (the woman took the woman) | |
(sentence) | |
;; (a table liked a table) | |
(sentence) | |
;; (the woman liked a table) |
(define-syntax def-phrase | |
(syntax-rules () | |
((_ (name proc exp1 exp2 ...)) | |
(define (name) | |
(proc exp1 exp2 ...))) | |
((_ (name11 proc11 exp11 exp12 ...) | |
(name21 proc21 exp21 exp22 ...) ...) | |
(begin | |
(def-phrase (name11 proc11 exp11 exp12 ...)) | |
(def-phrase (name21 proc21 exp21 exp22 ...) ...))))) | |
(define-macro (def-choice name proc ls) | |
(let ((varname (gensym))) | |
(let ((varname (string->symbol #`"*,|name|s*"))) | |
`(begin | |
(define ,varname ,ls) | |
(define (,name) | |
(,proc ,varname)))))) | |
(define-syntax def-choices | |
(syntax-rules () | |
((_ (name proc ls)) | |
(def-choice name proc ls)) | |
((_ (name1 proc1 ls1)(name2 proc2 ls2) ...) | |
(begin | |
(def-choices (name1 proc1 ls1)) | |
(def-choices (name2 proc2 ls2) ...))))) | |
(define (one-of set) | |
(list (random-elt set))) | |
(define (random-elt choices) | |
(list-ref choices (random-integer (length choices)))) | |
(def-phrase | |
(sentence append (noun-phrase)(verb-phrase)) | |
(noun-phrase append (article)(noun)) | |
(verb-phrase append (verb)(noun-phrase))) | |
(def-choices | |
(article one-of '(the a)) | |
(noun one-of '(man ball woman table)) | |
(verb one-of '(hit took saw liked))) | |
(sentence) | |
;; (the man saw a table) | |
(sentence) | |
;; (a table liked the woman) | |
(sentence) | |
;; (the ball took a man) | |
(sentence) | |
;; (a table took the man) | |
(sentence) | |
;; (the man liked a table) | |
(define (adj*) | |
(if (= (random-integer 2) 0) | |
'() | |
(append (adj)(adj*)))) | |
(define (pp*) | |
(if (random-elt '(#t #f)) | |
(append (pp)(pp*)) | |
'())) | |
(def-phrase | |
(noun-phrase append (article)(adj*)(noun)(pp*)) | |
(pp append (prep)(noun-phrase))) | |
(def-choices | |
(adj one-of '(big little blue green adiabatic)) | |
(prep one-of '(to in by with on))) | |
(sentence) | |
;; (a little blue little table took a adiabatic blue blue blue big table in the adiabatic little table in the little table on the green blue little table) | |
(sentence) | |
;; (a green woman took a little woman) | |
(sentence) | |
;; (the man by a little adiabatic man by the woman in the green ball hit the blue ball) |
(define-macro (def-choice name proc ls) | |
(let ((varname (gensym)) | |
(valname (gensym))) | |
(let1 varname (string->symbol #`",|name|s") | |
`(begin | |
(define-values (,name ,(string->symbol #`"push-,|varname|!")) | |
(let1 ,varname ,ls | |
(values (lambda () | |
(,proc ,varname)) | |
(lambda (,valname) | |
(push! ,varname ,valname))))))))) | |
(def-choice adj one-of '(big)) | |
(def-choice prep one-of '(to)) | |
(sentence) | |
;; (the big man to the ball to a big big big big big woman to a big woman to the table to a big big man to a big big big table to a big big man to the table to the big man to a ball to a table to a man saw a big big big big woman) | |
(sentence) | |
;; (the big big ball to a man took a big man) | |
(push-adjs! 'little) | |
;; (little big) | |
(push-adjs! 'blue) | |
;; (blue little big) | |
(push-adjs! 'red) | |
;; (red blue little big) | |
(sentence) | |
;; (the blue man to the big table liked the little little table to the big little big big blue little table) | |
(sentence) | |
;; (a red little woman hit the red table to a table to the ball to the blue ball) | |
(push-preps! 'by) | |
;; (by to) | |
(push-preps! 'in) | |
;; (in by to) | |
(push-preps! 'with) | |
;; (with in by to) | |
(push-preps! 'on) | |
;; (on with in by to) | |
(sentence) | |
;; (the table saw a little ball) | |
(sentence) | |
;; (the big table to the little man saw a little ball on the big table in the ball) | |
(sentence) | |
;; (a little table hit the woman with a table with the red little woman by the red big ball to a ball by the red big big ball with the red table on the big blue red red ball) |
ところで、LISPにはscanlに該当する関数ってあるんでしょうか? > valvallowさん正直わかりません、知りません、すみません。。Haskell 読めませんが、fold っぽいですね。取りあえず確認がてら同じようなものをでっち上げてみます。遅延評価でもなく Gauche 依存ですけれども。以下コード。
;; Prelude> scanl (+) 0 [] | |
;; [0] | |
;; Prelude> scanl (+) 0 [1] | |
;; [0,1] | |
;; Prelude> scanl (+) 0 [1,2] | |
;; [0,1,3] | |
;; Prelude> scanl (+) 0 [1..10] | |
;; [0,1,3,6,10,15,21,28,36,45,55] | |
;; (scanl + 0 '()) | |
;; (0) | |
;; (scanl + 0 '(1)) | |
;; (0 1) | |
;; (scanl + 0 '(1 2)) | |
;; (0 1 3) | |
;; (scanl + 0 (iota 10 1)) | |
;; (0 1 3 6 10 15 21 28 36 45 55) | |
(use srfi-1) | |
(use srfi-8) | |
(use gauche.collection) | |
(define (scanl proc seed ls) | |
(receive (n l) | |
(fold2 (lambda (ele acc-n acc-l) | |
(let1 n (proc ele acc-n) | |
(values n (cons n acc-l)))) | |
seed (cons seed '()) ls) | |
(reverse l))) | |
(scanl + 0 '()) | |
;; (0) | |
(scanl + 0 '(1)) | |
;; (0 1) | |
(scanl + 0 '(1 2)) | |
;; (0 1 3) | |
(scanl + 0 (iota 10 1)) | |
;; (0 1 3 6 10 15 21 28 36 45 55) |
(define (scanl p s ls) | |
(let rec ((ls (cons s ls))(accn s)(accl '())) | |
(if (null? ls) | |
(reverse accl) | |
(let1 n (p (car ls) accn) | |
(rec (cdr ls) n (cons n accl)))))) | |
(scanl + 0 '()) | |
;; (0) | |
(scanl + 0 '(1)) | |
;; (0 1) | |
(scanl + 0 '(1 2)) | |
;; (0 1 3) | |
(scanl + 0 (iota 10 1)) | |
;; (0 1 3 6 10 15 21 28 36 45 55) |
(use srfi-1) | |
(use srfi-8) | |
(use gauche.collection) | |
(define (scanl proc seed ls) | |
(reverse | |
(fold2 (lambda (ele acc-l acc-n) | |
(let1 n (proc ele acc-n) | |
(values (cons n acc-l) n))) | |
(cons seed '()) seed ls))) | |
(scanl + 0 '()) | |
;; (0) | |
(scanl + 0 '(1)) | |
;; (0 1) | |
(scanl + 0 '(1 2)) | |
;; (0 1 3) | |
(scanl + 0 (iota 10 1)) | |
;; (0 1 3 6 10 15 21 28 36 45 55) |
@valvallow (use gauche.collection)(define (scanl f x xs)(values-ref (map-accum (^(a acc)(let1 z (f a acc) (values z z))) x xs) 0))なるほど、map-accum ですかー!ちょっと写経。
;; https://twitter.com/SaitoAtsushi/statuses/20302777187 | |
(use gauche.collection) | |
(define (scanl f s ls) | |
(values-ref (map-accum (lambda (e acc) | |
(let1 n (f e acc) | |
(values n n))) s (cons s ls)) 0)) | |
(scanl + 0 '()) | |
;; (0) | |
(scanl + 0 '(1)) | |
;; (0 1) | |
(scanl + 0 '(1 2)) | |
;; (0 1 3) | |
(scanl + 0 (iota 10 1)) | |
;; (0 1 3 6 10 15 21 28 36 45 55) |
(use util.stream) | |
(define (scanl p s ls) | |
(let rec ((ls (stream-cons s (list->stream ls))) | |
(accn s) | |
(accl (list->stream '()))) | |
(if (stream-null? ls) | |
(stream-reverse accl) | |
(let1 n (p (stream-car ls) accn) | |
(rec (stream-cdr ls) n (stream-cons n accl)))))) | |
(stream->list (stream-take (scanl + 0 '()) 1)) | |
;; (0) | |
(stream->list (stream-take (scanl + 0 '(1)) 2)) | |
;; (0 1) | |
(stream->list (stream-take (scanl + 0 '(1 2)) 3)) | |
;; (0 1 3) | |
(stream->list (stream-take-while (pa$ > 1000) | |
(scanl + 0 (iota 1000 1)))) | |
;; (0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210 231 253 276 300 325 351 378 406 435 465 496 528 561 595 630 666 703 741 780 820 861 903 946 990) | |
(stream->list (stream-filter (lambda (n) | |
(and (< 5000 n) | |
(< n 10000))) | |
(scanl + 0 (iota 10000 1)))) | |
;; (5050 5151 5253 5356 5460 5565 5671 5778 5886 5995 6105 6216 6328 6441 6555 6670 6786 6903 7021 7140 7260 7381 7503 7626 7750 7875 8001 8128 8256 8385 8515 8646 8778 8911 9045 9180 9316 9453 9591 9730 9870) | |
@valvallow (use srfi-1)(use util.stream)(define(scanl f x xs)(iterator->stream(lambda(n e)(until(null? xs)(n x)(set! x(f x(pop! xs))))(e))))せっかくなので、インデント付けて gist に貼っつけました。
;; @valvallow (use srfi-1)(use util.stream)(define(scanl f x xs)(iterator->stream(lambda(n e)(until(null? xs)(n x)(set! x(f x(pop! xs))))(e)))) - https://twitter.com/SaitoAtsushi/statuses/20372687335 | |
(use srfi-1) | |
(use util.stream) | |
(define (scanl f x xs) | |
(iterator->stream (lambda (n e) | |
(until (null? xs) | |
(n x) | |
(set! x (f x (pop! xs)))) | |
(e)))) |