1.3장 차수 높은 프로시저(higher order procedure)로...

Post on 02-Jul-2015

109 Views

Category:

Engineering

8 Downloads

Preview:

Click to see full reader

DESCRIPTION

sicp

TRANSCRIPT

1.3장 차수 높은 프로시저(higher order procedure)

로 요약하는 방법SICP

아꿈사 - 우주미아홍구

1.3장 차수 높은 프로시저(higher order procedure)로 요약하는 방법

되풀이 되는 계산 방법을 간추리거나,

프로시저를 인자로 받거나,

프로시저를 결과 값으로 되돌려 주는,

차수 높은 프로시저 : 데이터 처럼 사용하는 프로시저 계산 방법을 요약 간추리는 프로시저 (제네릭?,STL?,NS?)

1.3.1 프로시저를 인자로 받는 프로시저

(define (만드려는프로시저명 인자 인자)

프로시저 프로시저 인자 프로시저 인자)

1.3.1 프로시저를 인자로 받는 프로시저

a~b 까지 정수의 합을 계산하는 프로시저

(define (sum-integers a b))

(if (> a b)

0

(+ a (sum-integers (+ a 1) b))))

1.3.1 프로시저를 인자로 받는 프로시저

시그마 ( 수열의 덧셈 ) 프로시저

(define (<name> a b))

(if (> a b)

0

(+ (<term> a)

(<name> (<next> a) b))))

1.3.1 프로시저를 인자로 받는 프로시저

(define (identity x) x)

(define (inc n) (+n 1))

(define (sum term a next b)

(if (> a b)

0

(+ (term a)

(sum term (next a) next b))))

(define (sum-intergers a b))

(sum identity a inc b))

1.3.1 프로시저를 인자로 받는 프로시저

(define (identity x) x)

(define (inc n) (+n 1))

(define (sum term a next b)

(if (> a b)

0

(+ (term a)

(sum term (next a) next b))))

(define (sum-intergers a b))

(sum identity a inc b))

1.3.1 프로시저를 인자로 받는 프로시저

(define (identity x) x)

(define (inc n) (+n 1))

(define (sum term a next b)

(if (> a b)

0

(+ (term a)

(sum term (next a) next b))))

(define (sum-intergers a b))

(sum identity a inc b))

1.3.1 프로시저를 인자로 받는 프로시저

(define (identity x) x)

(define (inc n) (+n 1))

(define (sum term a next b)

(if (> a b)

0

(+ (term a)

(sum term (next a) next b))))

(define (sum-intergers a b))

(sum identity a inc b))

1.3.2 lambda로 나타내는 프로시저

임시 함수

ex) (define (identity x) x)

define 해서 하나하나 만들기 귀찮다!

lambda를 쓰면 작은 프로시저는 따로 만들지 않아도!!

1.3.2 lambda로 나타내는 프로시저

(define (plus4 x) (+ x 4))

(define plus4 (lambda (x) (+ x 4)))

(lambda (<parameters>) <body>)

1.3.2 lambda로 나타내는 프로시저

간단히 연습 lambda

(define (square z) (z x z))

((lambda (x y z) (+ x y (square z))) 1 2 3)

= ?

1.3.2 lambda로 나타내는 프로시저

간단히 연습 lambda

(define (square z) (z x z))

((lambda (x y z) (+ x y (square z))) 1 2 3)

= ?

1.3.2 lambda로 나타내는 프로시저

간단히 연습 lambda

(define (square z) (x z z))

((lambda (x y z) (+ x y (square z))) 1 2 3)

= (+ 1 2 (x 3 3))

= 12

1.3.2 lambda로 나타내는 프로시저 let으로 갇힌 변수 만들기

프로시저 안에서만 쓰는 변수(로컬변수)

각각의 리스트가 값을 가지고 바디에 적용

(let ((<var1> <exp1>) (<var2> <exp2>) … (<varn> <expn>)) <body>)

1.3.2 lambda로 나타내는 프로시저 let으로 갇힌 변수 만들기

각각의 리스트가 값을 가지고 바디에 적용

let 외부에서 x는 2라면

(let (x 3) (y (+ x 2)) (* x y)) let 안에서 첫번째 리스트 x는 3 y는 외부의 x를 사용해서 2

1.3.2 lambda로 나타내는 프로시저 let으로 갇힌 변수 만들기

각각의 리스트가 값을 가지고 바디에 적용

let 외부에서 x는 2라면

(let (x 3) //x = 3 (y (+ x 2)) //x = 2 (외부) (* x y)) let 안에서 첫번째 리스트 x는 3 y는 외부의 x를 사용해서 2

1.3.2 lambda로 나타내는 프로시저 let으로 갇힌 변수 만들기

각각의 리스트가 값을 가지고 바디에 적용

let 외부에서 x는 2라면

(let (x 3) //x = 3 (y (+ x 2)) //x = 2 (외부) (* x y)) let 안에서 첫번째 리스트 x는 3 y는 외부의 x를 사용해서 2 결국 body 에는 (* 3 4) => 12

1.3.3 일반적인 방법을 표현하는 프로시저

수뿐 아니라 함수까지 인자로 받아

계산하는 방법만 도려내어 프로시저로 간추림

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b)

f(x) > 0 일때 f의 근은 a와 x 사이에 있음

f(x) < 0 일때 f의 근은 b와 x 사이에 있음

분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (serarch f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) //가운데 값 정의 (if (close-enough? neg-point pos-point) //값이 근사치인가 midpoint //맞으면 리턴 (let ((test-value (f midpoint))) //아니면 중간값 사용 (cond ((positive? test-value) //0보다 큰가 (serarch f neg-point midpoint) //가까운값 ((negative? test-value) //0보다 작은가 (serarch f midpoint pos-point)) //먼값 (else midpoint)))))) //둘다 아니면 중간값

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (serarch f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) //가운데 값 정의 (if (close-enough? neg-point pos-point) //값이 근사치인가 midpoint //맞으면 리턴 (let ((test-value (f midpoint))) //아니면 중간값 사용 (cond ((positive? test-value) //0보다 큰가 (serarch f neg-point midpoint) //가까운값 ((negative? test-value) //0보다 작은가 (serarch f midpoint pos-point)) //먼값 (else midpoint)))))) //둘다 아니면 중간값

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (close-enough? x y) // 근접 한가 (< (abs (- x y)) 0.001))

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (serarch f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) //가운데 값 정의 (if (close-enough? neg-point pos-point) //값이 근사치인가 midpoint //맞으면 리턴 (let ((test-value (f midpoint))) //아니면 중간값 사용 (cond ((positive? test-value) //0보다 큰가 (serarch f neg-point midpoint) //가까운값 ((negative? test-value) //0보다 작은가 (serarch f midpoint pos-point)) //먼값 (else midpoint)))))) //둘다 아니면 중간값

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (serarch f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) //가운데 값 정의 (if (close-enough? neg-point pos-point) //값이 근사치인가 midpoint //맞으면 리턴 (let ((test-value (f midpoint))) //아니면 중간값 사용 (cond ((positive? test-value) //0보다 큰가 (serarch f neg-point midpoint) //가까운값 ((negative? test-value) //0보다 작은가 (serarch f midpoint pos-point)) //먼값 (else midpoint)))))) //둘다 아니면 중간값

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (serarch f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) //가운데 값 정의 (if (close-enough? neg-point pos-point) //값이 근사치인가 midpoint //맞으면 리턴 (let ((test-value (f midpoint))) //아니면 중간값 사용 (cond ((positive? test-value) //0보다 큰가 (serarch f neg-point midpoint) //가까운값 ((negative? test-value) //0보다 작은가 (serarch f midpoint pos-point)) //먼값 (else midpoint)))))) //둘다 아니면 중간값

1.3.3 일반적인 방법을 표현하는 프로시저 이분법으로 방정식의 근 찾기

f(a) < 0 < f(b) f(x) > 0 일때 f의 근은 a와 x 사이에 있음 f(x) < 0 일때 f의 근은 b와 x 사이에 있음 분할 탐색 같은 느낌? 이진트리? 처럼 가서 근접점,값

(define (serarch f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) //가운데 값 정의 (if (close-enough? neg-point pos-point) //값이 근사치인가 midpoint //맞으면 리턴 (let ((test-value (f midpoint))) //아니면 중간값 사용 (cond ((positive? test-value) //0보다 큰가 (serarch f neg-point midpoint) //가까운값 ((negative? test-value) //0보다 작은가 (serarch f midpoint pos-point)) //먼값 (else midpoint)))))) //둘다 아니면 중간값

1.3.4 프로시저를 만드는 프로시저

프로시저를 프로시저의 결과 값으로 돌려주는

표현력의 상승 효과!!

(define average-dump f)

(lambda (x) (average x (f x))))

((average-dump square) 10)

1.3.4 프로시저를 만드는 프로시저

프로시저를 프로시저의 결과 값으로 돌려주는

표현력의 상승 효과!!

(define average-dump f)

(lambda (x) (average x (f x))))

((average-dump square) 10)

(10 + 100) / 2 => 55

벌써 마무으리…

프로그래머는 언제나 스스로 짠 프로그램을 놓고 그 속에서 간추릴 게 무엇인지 찾아내어(리팩토링-냄새?),

이로부터 더 수준 높은 표현 수단을 만들어 내려고 애써야 한다(추상화?)

벌써 마무으리…

몇 가지 문제 풀이 방법을 간추려서 다른 문제 풀이에도 다시 쓸수 있도록

일반적인 표현 수단을 만들려고 애쓰는 버릇은 정말 중요하다 (재사용?,일반화?,제네릭?)

정리

프로그래밍 언어의 일등급(first class)

(프로시저가) 변수의 값(처럼 사용될 수)이 될 수 있다. 다시 말해, 이름이 붙을 수 있다.

(프로시저가) 프로시저의 인자로 쓸 수 있다.

(프로시저가) 프로시저의 결과로 만들어질 수 있다.

(프로시저가) 데이터 구조속에 집어 넣을수 있다.

top related