2010/04/10

LOL mkstr, symb, group

mkstr, symb, groupはLet Over Lambdaで必要になるユーティリティ関数です。On Lispよりのものだそうです。On Lispは見事に積読中。
LOLはあの調子ですから読むのはサクサクなのですが、書くのが全然追いつきません。

internってなんぞ。symbの最後がvaluesなのもなぜだろう。わからないけど取り合えず放っておきます。以下コードはOn Lispより。
(defun mkstr (&rest args)
(with-output-to-string (s)
(dolist (a args)(princ a s))))
(mkstr pi " pieces of " 'pi)
(defun symb (&rest args)
(values (intern (apply #'mkstr args))))
(symb 'ar "Madi" #\L #\L 0)
(defun group (source n)
(if (zerop n) (error "zero length"))
(labels ((rec (source acc)
(let ((rest (nthcdr n source)))
(if (consp rest)
(rec rest (cons
(subseq source 0 n)
acc))
(nreverse
(cons source acc))))))
(if source (rec source nil) nil)))
(group '(a b c d e f g) 2)
view raw utils.lisp hosted with ❤ by GitHub

Gaucheで。(util.listに、groupと同等のslicesがあるそうです)
;; utilities
;; mkstr
(define (mkstr . args)
(with-output-to-string
(lambda ()
(dolist (a args)
(display a)))))
(use math.const)
(mkstr pi " pieces of " 'pi)
; -> "3.141592653589793 pieces of pi"
;; symb
(define (symb . args)
(string->symbol (apply mkstr args)))
(symb 'ar "Madi" #\L #\L 0)
; -> arMadiLL0
;; group
;; (group '(a b c d e f g) 2)
;; -> ((a b)(c d)(e f)(g))
(use gauche.sequence)
(define (group source n)
(if (or (null? source)
(not (positive? n)))
(error "zero length")
(letrec
((rec (lambda (ls acc)
(if (> (length ls) n)
(rec (list-tail ls n)(cons (subseq ls 0 n)
acc))
(reverse (cons ls acc))))))
(rec source '()))))
(group '(a b c d e f g) 2)
; -> ((a b) (c d) (e f) (g))
(group '(a b c d e f g) 3)
; -> ((a b c) (d e f) (g))
(group '(a b c d e f g) 5)
; -> ((a b c d e) (f g))
view raw utils.scm hosted with ❤ by GitHub

call-with-string-output-port・・・ってどこにあるんだろう。
;; mkstr - http://d.hatena.ne.jp/leque/20090726
(define (mkstr . args)
(call-with-string-output-port
(lambda (s)
(for-each (cut display <> s) args))))
(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)
view raw temp.scm hosted with ❤ by GitHub


(cut cons (+ a 1) <>) ≡ (lambda (x2) (cons (+ a 1) x2))
(cut list 1 <> 3 <> 5) ≡ (lambda (x2 x4) (list 1 x2 3 x4 5))
(cut list) ≡ (lambda () (list))
(cut list 1 <> 3 <...>)
≡ (lambda (x2 . xs) (apply list 1 x2 3 xs))
(cut <> a b) ≡ (lambda (f) (f a b))
部分適用便利だなー!

参考


追記

internの解説を教えていただきました。

プログラミングGaucheLET OVER LAMBDA Edition 1.0On Lisp

0 件のコメント:

コメントを投稿