SICPを読む(37) 問題 2.4 consの別の表現。
問題2.4
consの別の表現。何故xを返すことが出来るのか。
(define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) (cons 1 2) (car (cons 1 2)) ; 1
展開してみよう。
(car (cons 1 2)) ; (cons 1 2)を(cons x y)で展開。 (car (lambda (m) (m 1 2))) ; carを展開。 ((lambda (m) (m 1 2)) (lambda (p q) p)) ; mに代入する。 ((lambda (p q) p) 1 2) ; (p q)に1 2を代入するとpを返すから、 1
でた。zの所が逆になるのでややこしい。
一番のポイントは最初の展開、x yは1 2で束縛されてる。
cdrは簡単。
(define (cdr z) (z (lambda (p q) q)))
直感的に捉えるのはちょっとムズい。
K&Rを読もう(3) 1.5(1) catを作ろう。再帰と関数のネストのテストも兼ねて。
またまた定番。catを作ろうのコーナー。
定番過ぎるので、再帰と関数のネストを使ってみました。
バリバリgccオンリーのCコードデス。
#include <stdio.h> #include <stdlib.h> int main(void) { int (*f)(int) = putchar; void read_char(void) { int c; if ((c = getchar()) != EOF) { f(c); return read_char(); } else return; } read_char(); exit(EXIT_SUCCESS); }
コンパイルとテスト。
% gcc -Wextra -O2 -o cat 1.5.1.c % ./cat Hello, K&R cat world!! Hello, K&R cat world!!
スコープの確認も出来ました。
ま、普通のcatですね・・・。
演習 1-6
括弧を除くと、111...最後が0であることが確認できた。よく忘れるので注意したい。
演習 1-7
EOFを印字せよ。
#include <stdio.h> #include <stdlib.h> int main(void) { int (*middle_f)(int); int (*end_f)(int); void read_char(void) { int c; if ((c = getchar()) != EOF) { middle_f(c); return read_char(); } else { end_f(c); return; } } int print_eof(int c) { return printf("EOF -- getchar returned %d --\n", c); } middle_f = putchar; end_f = print_eof; read_char(); exit(EXIT_SUCCESS); }
middle_f,end_fを定義した。
% gcc -Wextra -O2 -o cat ex-1-7.c % ./cat test test EOF -- getchar returned -1 --
EOFが-1であることも確認できた。詳しくは、man readcharか、/usr/include/stdio.h
/* End of file character. Some things throughout the library rely on this being -1. */ #ifndef EOF # define EOF (-1) #endif
(-1)となってる理由がイマイチ不明。