• 검색 결과가 없습니다.

15장 함수형 프로그래밍 언어

N/A
N/A
Protected

Academic year: 2022

Share "15장 함수형 프로그래밍 언어"

Copied!
55
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

15장 함수형 프로그래밍 언어

(2)

함수 프로그래밍의 개요 1

Scheme 2

3 Python

(3)

Scheme 이란?

2

1) 1975년 MIT에서 개발

2) Common LISP와 아주 유사 3) Common LISP 보다 더 간단 4) MIT 등에서 교육용으로 사용

5) 최근 Racket 언어로 발전 (LISP/Scheme과 비슷)

1) http//racket-lang.org/download 2) DrRacket 다운받고 실행

(IDE: Integrated Development Environment)

3) 언어설정: 왼쪽 아래 버튼-> use the lang. declared in the source

Scheme 사용법

(4)

01_함수 프로그래밍의 개요

 함수 프로그래밍

수학 함수와 같은 원리의 함수들로 프로그램을 구성하는 기법

함수는 부작용을 발생시키지 않고 단지 입력을 받아들여 출력을 구함

 예

정렬되지 않은 리스트에서 가장 작은 값의 데이터를 추출하는 과정]

• 입력 : list (X1, X2, ..., Xn)

• 출력 : (first (sort list))

(5)

02_Scheme

 Scheme 인터프리터

리스트 형태의 식에 대해 읽기-평가-쓰기를 반복

• 예

 식

Scheme은 식(expression)으로 이루어짐

• 식은 원자(atom)와 리스트(list)로 구분

• 원자의 종류

종류

숫자 21, 3.14

스트링 “hello”

> (+ 3 7) Value: 10

(6)

02_Scheme

리스트 : 식들을 괄호로 둘러싼 것

• 예 1

• 예 2

> (+ 1 3) Value: 4

> (* ( + 2 4) (-6 2)) Value: 24

(7)

02_Scheme

+, -, *, / : 두 개 이상의 인자를 가짐

수로만 이루어진 리스트

• 오류 : Scheme 인터프리터는 리스트 형태의 식을 읽으면 평가를 시도

• 해결책 : quote를 사용해서 평가하는 것을 막자!

> ( + 2 4 6 ) Value: 12

> (- 13 7 2 ) Value: 4

(1 3 5)

> (quote(1 3 5))

(8)

02_Scheme

 정의 함수: define

이름을 값으로 정의하거나 함수를 정의할 수 있음

예: 이름 x를 값 21로 정의한 예

• x를 정의한 후에 다음과 같이 실행하면 21이 반환

예: square 함수를 정의한 예

• square를 정의한 후에 다음과 같이 실행하면 25가 반환 (define x 21)

> x

Value: 21

(define (square x) (* x x))

> (square 5) Value: 25

(9)

02_Scheme

예: 원의 넓이를 구하는 circlearea 함수 정의

• 원주율에 해당하는 pi 정의

• square 정의

• pi와 square를 이용하여 circlearea 정의

• 실행

(define pi 3.14159265)

(define (square x) (* x x))

(define (circlearea radius) (* pi (square radius)))

> (circlearea 5)

Value: 78.53981625

(10)

03_람다 식

 람다 식(lambda expression)

이름을 부여하지 않고 함수를 생성하는 식

무명 함수 : 이와 같이 생성된 함수

x의 제곱을 반환하는 무명 함수

define을 이용하면 무명 함수에 이름을 부여

(lambda (x) (* x x))

((lambda (x) (* x x)) 5)

(define square (lambda (x) (* x x))) (define (square x) (* x x))

(11)

03_람다 식

 let 함수

식의 값에 임시로 이름을 바인딩

형식 : 식1의 값에 이름1이, 식2의 값에 이름2가, …, 그리고 식n의 값에 이름 n이 바인딩되고, let 본체에 해당하는 식 {식}이 실행

• 예 : 7에 x라는 이름이, 10에 y라는 이름이 임시로 바인딩되고, let 본체에 해당하는 식인 (+ x y)에서 x와 y라는 이름이 사용되는 예

(let (

(이름1 식1) (이름2 식2)

(이름n 식n)) 식 {식}

)

(12)

03_람다 식

 입출력 함수

‘읽기-평가-쓰기’를 하여 평가한 결과를 출력

display 함수 : 단순히 인자를 출력

• 예 : 21로 정의된 x를 출력

> (+ 2 3) Value: 5

> (display 21) 21

> (display "hello") hello

> (define x 21) Value: x

> (display x) 21

(13)

03_람다 식

read 함수 : 키보드에서 친 내용을 입력

• 예: 키보드에서 입력한 내용인 7을 x의 값으로 정의하고, x의 값을 출력

> (read) 123 ⋯ 입력 Value: 123

> (define x (read))

7 ⋯ 입력

Value: x

> x

Value: 7

(14)

04_리스트 함수

 리스트 함수(list function)

리스트 처리를 위한 함수

car : 주어진 리스트의 첫 번째 원자를 반환하는 함수

• 예: 리스트 (1 3 5)에서 첫 번째 원자인 1을 반환하는 예

함수 설명

car 리스트의 첫 번째 원자를 반환한다.

cdr 리스트에서 car를 제거한 후 나머지를 반환한다.

cons 첫 번째 인자를 두 번째 인자의 새로운 car로 삽입한다.

list 여러 개의 원자를 리스트로 만든다.

> (car '(1 3 5)) Value: 1

(15)

04_리스트 함수

• 예: 리스트 ((1 3) 5 7)에서 첫 번째 원자인 (1 3)을 반환하는 예

• 예: 1이 리스트가 아니므로 오류

> (car '((1 3) 5 7)) Value: (1 3)

> (car 1) ⋯ 오류

(16)

04_리스트 함수

cdr: 리스트에서 car을 제거한 후 나머지를 반환하는 함수

• 예: 리스트 (1 3 5)에서 car인 1을 제거한 나머지인 (3 5)를 반환

• 예: 리스트 ((1 3) 5 7)에서 car인 (1 3)을 제거한 나머지인 (5 7)을 반환

• 예: 1이 리스트가 아니므로 오류

• 예: second 함수로 정의한 예

> (cdr '(1 3 5)) Value: (3 5)

> (cdr '((1 3) 5 7)) Value: (5 7)

> (cdr 1) ⋯ 오류

> (define (second lst) (car (cdr lst))) Value: second

> (second '(1 3 5)) Value: 3

(17)

04_리스트 함수

• (second ‘(1 3 5))의 동작

(18)

04_리스트 함수

cons

• 첫 번째 인자를 두 번째 인자의 새로운 car로 삽입

• 첫 번째 인자는 원자거나 리스트가 될 수 있지만, 두 번째 인자는 반드시 리스트여야 함

• 예: 첫 번째 인자인 1을 두 번째 인자인 (2 3)의 새로운 car로 삽입하여 (1 2 3) 리스트를 반환

> (cons 1 '(2 3)) Value: (1 2 3)

(19)

04_리스트 함수

• 예: (2 3 4)로 정의된 lst에 1을 새로운 car로 삽입하는 예

• 예: 첫 번째 인자인 (1 2)를 두 번째 인자인 리스트 (3 4)의 새로운 car로 삽입

> (define lst '(2 3 4)) Value: lst

> (cons 1 lst) Value: (1 2 3 4)

(20)

04_리스트 함수

list: 여러 개의 원자를 리스트로 만드는 함수

• 예: 원자 1, 2, 3을 (1 2 3) 리스트로 만든 예

• 예: (1 2)와 (3 4)를 리스트로 만드는 예

> (list 1 2 3) Value: (1 2 3)

> (list '(1 2) '(3 4)) Value: ((1 2) (3 4))

(21)
(22)

05_술어 함수

 술어 함수(predicate function)

불린 값을 반환하는 함수로 참이면 #t를, 거짓이면 ()를 반환

대표적인 술어 함수

함수 설명

= 두 인자가 같으면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

> 첫 번째 인자가 두 번째 인자보다 크면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

< 첫 번째 인자가 두 번째 인자보다 작으면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

>= 첫 번째 인자가 두 번째 인자보다 크거나 같으면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

<= 첫 번째 인자가 두 번째 인자보다 작거나 같으면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

even? 인자가 짝수면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

odd? 인자가 홀수면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

zero? 인자가 0이면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

eq? 두 인자가 원자이고 같으면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

null? 인자가 공 리스트이면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

list? 인자가 리스트이면 #t를 반환하고, 그렇지 않으면 ()를 반환한다.

(23)

05_술어 함수

예: x를 11로 정의

• 11로 정의된 x가 11과 같으므로 #t가 반환

• x가 11보다 크지 않으므로 () 반환, x가 15보다 작으므로 #t 반환

> (define x 11) Value: x

> (= x 11) Value: #t

> (> x 11) Value: ()

> (< x 15) Value: #t

(24)

05_술어 함수

예: x가 짝수인지, 홀수인지를 파악하기

예: 주어진 값이 0인지 파악하기 ▪ 예: 두 값이 같은지 파악하기

예 : 리스트가 null인지 파악하기 ▪ 예: 리스트 유무 파악하기

> (even? x) Value: ()

> (odd? x) Value: #t

> (define y 0) Value: y

> (zero? y) Value: #t

> (eq? x y) Value: ()

> (eq? x x) Value: #t

> (null? '()) Value: #t

> (null? '(1 3)) Value: ()

> (list? '(1 3)) Value: #t

> (list? '1) Value: ()

(25)

05_술어 함수

 제어

프로그램 실행 순서를 제어하는 구조

• 조건 구조 : if 함수와 cond 함수

• 반복 구조 : 재귀 호출에 의해 제공

 조건 구조

if 함수: 조건이 참이면 식1을, 거짓이면 식2를 실행

• 예) (> 3 2)가 참이면 ‘yes’가, 거짓이면 ‘no’가 반환됨 (if 조건 식1 식2)

> (if (> 3 2) 'yes 'no) Value: yes

(26)

05_술어 함수

• 예) test는 인자 x가 70보다 크거나 같으면 ‘pass’를 출력하고, 그렇지 않으면

‘fail’을 출력

• 예) difference는 x와 y의 차이를 구하는 함수로, x가 y보다 크면 x에서 y를 뺀 값을, 그렇지 않으면 y에서 x를 뺀 값을 반환

> (define (test x) (if (>= x 70)

(display "pass") (display "fail")) )

> (test 75) pass

> (define (difference x y) (if (> x y)

(- x y) (- y x)) )

> (difference 7 10) Value: 3

(27)

05_술어 함수

cond 함수

• 조건1이 참이면 식1이 반환되고, 조건1이 거짓이고 조건2가 참이면 식2가

반환된다. 어떤 조건도 참이 아니면 else 절의 식인 식n이 반환되는데, else 절은 선택적

• 예) age가 6보다 작거나 같으면 0을, 그렇지 않고 60보다 작으면 5000을, 두 조건 모두 거짓이면 2500을 반환한다. age가 5이므로 0을 반환

> (define age 5)

> (cond (cond

(조건1 식1) (조건2 식2)

(else 식n))

(28)

05_술어 함수

• 예) age(나이)에 따른 입장료를 계산

> (define (admissionfee age) (cond

((<= age 6) 0) ((< age 60) 5000) (else 2500))

)

> (admissionfee 65) Value: 2500

(29)

05_술어 함수

• 예) compare는 x와 y 값의 크기를 비교하여 그 내용을 출력하는 함수 01 > (define (compare x y)

02 (cond

03 ((> x y) (display x)

04 (display " is greater than ")

05 (display y)

06 (newline))

07 ((< x y) (display y)

08 (display " is greater than ")

09 (display x)

10 (newline))

11 (else (display x)

12 (display " and ")

13 (display y)

14 (display " are equal")

15 (newline)))

(30)

05_술어 함수

• 예) 앞의 compare 함수에 키보드로부터 직접 두 개의 값을 입력받도록 하는 기능을 추가

01 > (define (compare)

02 (display "input two integer: ") 03 (newline)

04 (define x (read)) 05 (define y (read))

06 (cond

07 ((> x y) (display x)

08 (display " is greater than ")

09 (display y)

10 (newline))

11 ((< x y) (display y)

12 (display " is greater than ")

13 (display x)

14 (newline))

15 (else (display x) 16 (display " and ")

17 (display y)

18 (display " are equal")

19 (newline)))

20 )

21 > (compare)

22 input two integer:

(31)

06_재귀

 반복 구조: 재귀(recursion)

factorial 함수

> (define (factorial n) (if (= n 0)

1

(* n (factorial (- n 1)))) )

> (factorial 3) Value: 6

(32)

06_재귀

• 예) adder : lst에 속한 원자의 합을 구하는 함수로 lst가 공 리스트면 0을 반환

• 오류 : (2)가 리스트이기 때문

• 문제를 해결한 adder

> (define (adder lst) (if (null? lst)

0

(+ (car lst) (adder (cdr lst)))) )

> (adder '(1 2 3)) Value: 6

> (adder '(1 (2) 3)) ⋯ 오류

> (define (adder lst) (cond

((null? lst) 0)

((list? (car lst)) (+ (adder (car lst)) (adder (cdr lst)))) (else (+ (car lst) (adder (cdr lst)))))

)

(33)

06_재귀

 예제

정렬

• 원자를 리스트에 삽입하는 함수의 예

• sort를 이용해서 lst의 데이터를 정렬하는 함수 (define (insert atm lst)

(cond

((null? lst) (cons atm '()))

((< atm (car lst)) (cons atm lst))

(else (cons (car lst) (insert atm (cdr lst))))) )

(define (sort lst) (if (null? lst)

'()

(34)

06_재귀

3개의 원판을 옮기는 동작 살펴보기

① 왼쪽 기둥에 있는 가장 위의 원판을 오른쪽 기둥으로 옮긴다.

(35)

06_재귀

② 왼쪽 기둥에 있는 가장 위의 원판을 오른쪽 기둥으로 옮긴다.

③ 왼쪽 기둥 위에 있는 원판을 가운데 기둥으로 옮긴다.

(36)

06_재귀

④ 왼쪽 기둥의 원판을 오른쪽 기둥으로 옮긴다.

⑤ 가운데 기둥 위에 있는 원판을 왼쪽 기둥으로 옮긴다.

규칙 2 : 왼쪽 기둥의 원판을 오른쪽 기둥으로 옮긴다.

규칙 3 : 가운데 기둥의 2(=n-1)개의 원판을 오른쪽 기둥으로 옮긴다.

이때 왼쪽 기둥을 이용한다

(37)

06_재귀

⑥ 가운데 기둥의 원판을 오른쪽 기둥으로 옮긴다.

⑦ 왼쪽 기둥의 원판을 오른쪽 기둥으로 옮기면 모든 동작이 종료된다.

(38)

06_재귀

3개의 규칙을 일반화하여 n개의 원판에 적용

① 우선 왼쪽 기둥의 n-1개의 원판을 가운데 기둥으로 옮긴다. 이때 오른쪽 기둥을 이용한다.

(39)

06_재귀

② 왼쪽 기둥의 원판을 오른쪽 기둥으로 옮긴다.

③ 가운데 기둥의 n-1개의 원판을 오른쪽 기둥으로 옮긴다. 이때 왼쪽 기둥을 이용한다.

(40)

06_재귀

하노이탑 프로그램

01 (define (hanoi n a b c) 02 (cond

03 ((= n 1)

04 (display " move ") 05 (display n)

06 (display " from ") 07 (display a)

08 (display " to ") 09 (display c)

10 (newline))

11 (else

12 (hanoi (- n 1) a c b) 13 (display " move ") 14 (display n)

15 (display " from ") 16 (display a)

17 (display " to ") 18 (display c)

19 (newline)

(41)

06_재귀

하노이탑 실행 예

> (hanoi 3 "left" "middle" "right") move 1 from left to right

move 2 from left to middle move 1 from right to middle move 3 from left to right move 1 from middle to left move 2 from middle to right move 1 from left to right

(42)

07_예제 Scheme Function: member

 member takes an atom and a simple list; returns #T if the atom is in the list; () otherwise

DEFINE (member atm lis) (COND

((NULL? lis) '())

((EQ? atm (CAR lis)) #T)

((ELSE (member atm (CDR lis)))

))

(43)

07_예제 Scheme Function: equalsimp

 equalsimp takes two simple lists as parameters; returns #T if the two simple lists are equal; () otherwise

(DEFINE (equalsimp lis1 lis2) (COND

((NULL? lis1) (NULL? lis2)) ((NULL? lis2) '())

((EQ? (CAR lis1) (CAR lis2))

(equalsimp(CDR lis1)(CDR lis2))) (ELSE '())

))

(44)

07_예제 Scheme Function: equal

 equal takes two general lists as parameters; returns #T if the two lists are equal; ()otherwise

(DEFINE (equal lis1 lis2) (COND

((NOT (LIST? lis1))(EQ? lis1 lis2)) ((NOT (LIST? lis2)) '())

((NULL? lis1) (NULL? lis2)) ((NULL? lis2) '())

((equal (CAR lis1) (CAR lis2))

(equal (CDR lis1) (CDR lis2))) (ELSE '())

))

(45)

07_예제 Scheme Function: append

 append takes two lists as parameters; returns the first

parameter list with the elements of the second parameter list appended at the end

(DEFINE (append lis1 lis2) (COND

((NULL? lis1) lis2) (ELSE (CONS (CAR lis1)

(append (CDR lis1) lis2)))

))

(46)

07_예제 Scheme Function: LET

 General form:

(LET (

(name_1 expression_1) (name_2 expression_2) ...

(name_n expression_n)) body

)

 Evaluate all expressions, then bind the values to the names;

evaluate the body

(47)

07_예제 LET Example

(DEFINE (quadratic_roots a b c) (LET (

(root_part_over_2a

(/ (SQRT (- (* b b) (* 4 a c)))(* 2 a))) (minus_b_over_2a (/ (- 0 b) (* 2 a)))

(DISPLAY (+ minus_b_over_2a root_part_over_2a)) (NEWLINE)

(DISPLAY (- minus_b_over_2a root_part_over_2a)) ))

(48)

Scheme Functional Forms

 Composition

 The previous examples have used it

 (CDR (CDR ‘(A B C))) returns (C)

 Apply to All - one form in Scheme is mapcar

 Applies the given function to all elements of the given list;

(DEFINE (mapcar fun lis) (COND

((NULL? lis) '())

(ELSE (CONS (fun (CAR lis))

(mapcar fun (CDR lis)))) ))

(49)

Functions That Build Code

 It is possible in Scheme to define a function that builds Scheme code and requests its interpretation

 This is possible because the interpreter is a user-

available function, EVAL

(50)

08_예제 Lisp Function: append

(DEFINE (append lis1 lis2) (COND

((NULL? lis1) lis2)

(ELSE (CONS (CAR lis1)

(append (CDR lis1) lis2)))

))

(51)

08_예제 Lisp Function: equal_lists

; LISP Example

; The following code takes two general lists as parameters

; and returns True if the two lists are equal

; and NIL (false) otherwise

(DEFUN equal_lists (lis1 lis2) (COND

((ATOM lis1) (EQ lis1 lis2)) ((ATOM lis2) NIL)

((equal_lists (CAR lis1) (CAR lis2))

(equal_lists (CDR lis1) (CDR lis2))) (T NIL)

)

(52)

1) Python 설치

- https://www.python.org/downloads 에서 Window용 ver. 3.4.4(혹은 ver. 3.5.2)을 down받고 install

2) Editor 사용

- C:\python34 폴더가 생성 - IDLE(GUI editor) 사용 - python 3.4 manual 참조

3) Procedural Lang.의 특성, OOP의 특성, Functional Lang.의 특성을 골고루 갖추고 있음.

다음의 예들은 Functional Lang.의 특성을 나타낸 예.

(manual의 내용에 Functional Programming Module 참조)

09_Bonus Chapter: Python

(53)

Ex. 1)

>>> mins = [1, 2, 3]

>>> secs = [m*60 for m in mins]

>>> secs [60, 120, 180]

Ex. 2)

>>> lower = ["I", "don't", "like", "spam"]

>>> upper = [s.upper() for s in lower]

>>> upper

['I', "DON'T", 'LIKE', 'SPAM']

09_Bonus Chapter: Python

(54)

Ex. 4)

>>> def upper(s):

return s.upper()

>>> list(map(upper, ["sentence", "spam"])) ['SENTENCE', 'SPAM']

Ex. 5)

>>> def fib(n):

if n < 2:

return n

return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

09_Bonus Chapter: Python

(55)

Ex. 6)의 경우 reduce()가 Lib/functools.py 내에 다음과 같이 정의되어 있음

def reduce(function, iterable, initializer=None):

it = iter(iterable) if initializer is None:

value = next(it) else:

value = initializer for element in it:

value = function(value, element) return value

- 역시 operator.add() 도 Lib/operator.py 내에 다음과 같이 정의되어 있음

functio

n iterable Initializ

er

09_Bonus Chapter: Python

참조

관련 문서

1984년 317개 언어의 말소리를 분석한 통계)에 의하면 파열음의 경우 다음과 같이 나타난다고

심폐지구력/근력운동프로그램의 실제와 적용 Chapter 4. 유연성/이완 운동프로그램의 실제와 적용 Chapter 5. 영양과 체중조절 프로그램의 실제와 적용 Chapter

같은 분류군에 있어서도 연구자에 따라 중시하는 형질의 종류를 달리할 수 있으 며, 한 분류군을 분류하는데 사용된 형질이 다른 분류군을 분류하는 데는 전혀

– 대부분의 clipping algorithm들은 view volume 이 normalize 되어야 작동. – reduce the

Chapter 6 역함수: 지수함수, 로그함수, 역삼각 함수

• 인적자본의 수익율은 물적자본과 달리 계산하기 어려움 -임금으로 유추 가능... Copyright © 2009

5 Chapter 4: The Service Encounter Presentation / workshop 6 Chapter 5: Supporting Facility and Process Flows Presentation / workshop 7 Chapter 6: Service Quality

알버트 움직임 명령어를 다음과 같이 바꿔보세요.