Lisper はじめました (再)
ひげ
Lisper やってた
DLisp
D言語で作った Lisp
D言語なのは使ってる人が近くにたまたま居たから
GFLの早期配属の関係で3年の後期に作った
Pure Lisp に算術論理演算とクロージャを加えた
クロージャは遅延評価をするため
継承とか多態性とかを駆使して作ってる
のであんまり一般的なLispっぽくないコード
Lisp is 何
1958 年に設計された2 番目に古い高級プログラミング言語
LISt Processing の略称
括弧によるシンプル(すぎる)なネスト構造で記述
手続きと引数はポーランド記法
数学を背景に持つ特殊な言語
; n までの総和を求める関数
(define (sum n) (if (eq n 0) 0 (+ (sum (- n 1)) 1)))
Pure Lisp
John McCarthy は論文で式を評価するための最小のLisp を示した
それを「Pure Lisp」という
Atom と List の2 種類のデータ構造を持つ
 atom ,  eq ,  cons ,  car ,  cdr  の5 つの基本関数を持つ
 cond ,  define ,  lambda ,  quote  の4つの特殊形式を持つ
しゅうかつでウケがいいので取りあえずあげた
https://github.com/matsubara0507/dlisp
ただしビルドしてみてない
作ったのは昔のPCで
手元のPCにはもうD言語が残ってないので
そこで
Docker イメージはある
Dockerfileを書く
FROM dlanguage/ldc:latest
WORKDIR /root/dlisp
COPY . /root/dlisp
RUN ldc2 -of/usr/local/bin/plisp *.d ./**/*.d ./**/**/*.d
CMD ["/bin/bash"]
いいかんじ
ネイピア数を求める
ネイピア数の表現方法はいろいろ
(Wkipediaより)
2つの方法を用いる
方法1
無限級数をそのまま+オイラートランスフォーム
e =
オイラートランスフォームは振動する級数の収束速度を速める
S −
[
k=0
∑
∞
k!
(−1)k
]
−1
n+1
S − 2S + Sn−1 n n+1
(S − S )n+1 n
2
方法1
無限級数をそのまま+オイラートランスフォーム
; e: (/ (stream-ref e-stream n))
(define (e-proc n)
(cond ((< n 0) (- (/ 1.0 (product (- n)))))
(#t (/ 1.0 (product n)))))
(define (e-summands n)
(cons (e-proc n)
(lambda () (stream-map - (e-summands (+ n 1))))))
(define e-stream (partial-sums (e-summands 0)))
; Euler Transform: (stream-ref (euler-transform pi-stream) n)
(define (euler-transform s)
((lambda (s0 s1 s2)
(cons (- s2 (/ (* (- s2 s1) (- s2 s1))
(+ s0 (* -2 s1) s2)))
(lambda () (euler-transform (stream-cdr s)))))
(stream-ref s 0) (stream-ref s 1) (stream-ref s 2)))
方法2
無限ストリームで模倣する
ネイピア数の任意桁目の数字を計算するので誤差とかは無い
eの無限級数
e = = 1 + 1 + + + ⋯
eの小数点第1位は次式の整数部分
10(e − 2) = + + ⋯
k=0
∑
∞
k!
1
2!
1
3!
1
2!
10
3!
10
4!
10
方法2
無限ストリームで模倣する
整数部分を求めるために各項10/k!の分子がk未満になるよう変形
10(e − 2) = + ⋯ + + + + + ⋯
2!
10
8!
10
9!
10 + 1
10!
0
11!
10
= + ⋯ + + + + + ⋯
2!
10
8!
10 + 1
9!
2
10!
0
11!
10
= 7 + + + + + + + + ⋯
2!
0
3!
1
4!
0
5!
1
6!
5
7!
4
8!
3
方法2
無限ストリームで模倣する
; napier: (stream-ref napier n)
(define ones (cons 1 (lambda () ones)))
(define nomalize (lambda (n stream)
((lambda (head right)
((lambda (carry)
(cons carry
(lambda () (cons (mod (+ head (stream-car (force right))) n)
(lambda () (stream-cdr (force right)))))))
(cond ((< (+ (mod head n) 9) n) (div head n))
(true (div (+ head (stream-car (force right))) n)))))
(stream-car stream)
(lambda () (nomalize (+ n 1) (stream-cdr stream))))))
(define convert (lambda (x)
(cons (stream-car x)
(lambda ()
(convert (nomalize 2 (scale-stream (stream-cdr x) 10)))))))
(define napier (convert (cons 2 (lambda () ones))))
おしまい

Lisper はじめました (再)