Final Exam
1. Parameter Passing Methods
Semantics Models
- in mode: caller โ callee ๋ฐฉํฅ, ํจ์ ๋ด๋ถ์์ ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ
- out mode: callee โ caller ๋ฐฉํฅ, ํจ์ ์ข ๋ฃ ์ ๊ฒฐ๊ณผ ๋ณต์ฌ
- inout mode: ์๋ฐฉํฅ
Pass-by-value
caller์ ๊ฐ์ ๋ณต์ฌํด์ callee์ ์ ๋ฌ. callee์์ ๋ณ๊ฒฝํด๋ ์๋ณธ์ ์ํฅ ์์.
void add(int in) { in = in + 10; }
int a = 20;
add(a); // a = 20 ๊ทธ๋๋ก
์ฅ์ : ๋น ๋ฆ (scalar ๊ธฐ์ค) ๋จ์ : ํฌ๊ธฐ๊ฐ ํฐ ๋ฐ์ดํฐ๋ ๋ณต์ฌ ๋น์ฉ ์ฆ๊ฐ
Pass-by-result
ํจ์ ์ข ๋ฃ ์ callee์ ์ง์ญ ๋ณ์ ๊ฐ์ caller๋ก ๋ณต์ฌ (out mode). ํจ์ ๋ด์์ ์ด๊ธฐ๊ฐ์ ์ฝ์ง ์์.
void Fixer(out int x) { x = 17; }
๋ฌธ์ ์ 1: ๊ฐ์ ๋ณ์๋ฅผ ๋ ๋ฒ out์ผ๋ก ์ ๋ฌํ๋ฉด ๋ง์ง๋ง์ ๋ณต์ฌ๋๋ ๊ฐ์ ์์กด
f.Fixer(out a, out a); // a = 17 ๋๋ 35 โ ์์์ ์์กด
๋ฌธ์ ์ 2: ํ๊ฐ ์์ ์ฐจ์ด
DoIt(out list[sub], out sub);
// call-time ํ๊ฐ: list[3] = 17, sub = 5
// return-time ํ๊ฐ: sub๊ฐ ๋จผ์ 5๊ฐ ๋์ด list[5] = 17
Pass-by-value-result
์ง์ ์ ๊ฐ ๋ณต์ฌ + ์ข ๋ฃ ์ ๋ค์ ๋ณต์ฌ (inout mode). copy-in/copy-out์ด๋ผ๊ณ ๋ ํจ.
Pass-by-reference
์ฃผ์๋ฅผ ์ ๋ฌ. callee์์ ๋ณ๊ฒฝํ๋ฉด ์๋ณธ๋ ๋ฐ๋.
void add(int &in) { in = in + 10; }
int a = 20;
add(a); // a = 30
๋จ์ : ์๋์น ์์ ๋ณ๊ฒฝ, alias ์์ฑ ์ํ
fun(total, total); // first์ second๊ฐ ๊ฐ์ ๋ณ์ โ alias
Pass-by-name
์ค์ ๋งค๊ฐ๋ณ์์ ํํ์์ ๊ทธ๋๋ก ๋๊ฒจ ๋งค ์ ๊ทผ ์ ์ฌํ๊ฐ. Algol 60์์ ์ฌ์ฉ, ํ์ฌ๋ ๊ฑฐ์ ์ฐ์ด์ง ์์.
Pass-by-assignment (Python, Ruby)
๋ชจ๋ ๋ฐ์ดํฐ๊ฐ object.
- immutable object (str, int, tuple) โ call-by-value ํจ๊ณผ
- mutable object (list, dict, set) โ call-by-reference ํจ๊ณผ
def func(x):
x = x + 1 # int: ์๋ณธ ๋ณํ ์์
def func(x):
x.append(5) # list: ์๋ณธ ๋ณ๊ฒฝ๋จ
์ธ์ด๋ณ ์์ฝ
| ์ธ์ด | ๊ธฐ๋ณธ ๋ฐฉ์ | reference ๋ฐฉ๋ฒ |
|---|---|---|
| C | pass-by-value | ํฌ์ธํฐ ์ ๋ฌ |
| C++ | pass-by-value | & (reference), const & (in-mode) |
| Java | pass-by-value | ๊ฐ์ฒด๋ ์ฐธ์กฐ๊ฐ์ value๋ก ์ ๋ฌ |
| C# | pass-by-value | ref (inout), out (result) |
| Python/Ruby | pass-by-assignment | ํ์ ์ ๋ฐ๋ผ ๋ค๋ฆ |
swap ์์ ๋ถ์
void swap(int a, int b) {
int temp; temp = a; a = b; b = temp;
}
int value = 2, list[5] = {1, 3, 5, 7, 9};
swap(value, list[value]); // (3)
- pass-by-value: ๋ณํ ์์
- pass-by-reference: value=5, list={1,3,2,7,9}
- pass-by-value-result (call-time ์ฃผ์ ํ๊ฐ): value=5, list={1,3,2,7,9}
- pass-by-value-result (return-time ์ฃผ์ ํ๊ฐ): value=5 ํ list[5]์ ์ฐ๋ ค ํจ โ ๋ฒ์ ์ค๋ฅ ๊ฐ๋ฅ
2. Implementing Subprogram (ARI, Static Chain)
Activation Record (AR)
subprogram ํธ์ถ ์ runtime stack์ ์์ด๋ ํ๋ ์ ๊ตฌ์กฐ.
| ๊ตฌ์ฑ ์์ | ์ค์ ์ฃผ์ฒด | ์ญํ |
|---|---|---|
| Return address | Caller | ๋ณต๊ท ์์น |
| Dynamic link | Caller | caller์ ARI๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ |
| Actual parameters | Caller | ์ ๋ฌ๋ ์ธ์ |
| Local variables | Callee | ์ง์ญ ๋ณ์ ๊ณต๊ฐ |
- EP (Environment Pointer): ํ์ฌ ์คํ ์ค์ธ ARI์ base๋ฅผ ๊ฐ๋ฆฌํด
- ํธ์ถ ์ ํ์ฌ EP๋ฅผ new ARI์ dynamic link๋ก ์ ์ฅ ํ, EP๋ฅผ ์ ARI base๋ก ๋ณ๊ฒฝ
- ์ข ๋ฃ ์ EP๋ฅผ dynamic link๋ก ๋ณต์
Prologue / Epilogue
Prologue (Callee, ์คํ ์์):
- old EP๋ฅผ dynamic link๋ก ์ ์ฅ
- ์ง์ญ ๋ณ์ ๊ณต๊ฐ ํ ๋น
Epilogue (Callee, ์คํ ์ข ๋ฃ):
- out-mode ํ๋ผ๋ฏธํฐ ๊ฐ ๋ฐํ
- ํจ์ ๋ฐํ๊ฐ์ caller ์ ๊ทผ ๊ฐ๋ฅํ ์์น๋ก ์ด๋
- stack top์ EP-1๋ก ๋ณต์, EP๋ฅผ dynamic link๋ก ๋ณต์
- caller ์คํ ์ํ ๋ณต์
- caller์๊ฒ ์ ์ด ์ด์
Local Offset / Chain Offset
๋ณ์ ์ ๊ทผ ํ๊ธฐ: (chain_offset, local_offset)
- local_offset: ARI ์์๋ถํฐ ํด๋น ๋ณ์๊น์ง์ ๊ฑฐ๋ฆฌ (์ปดํ์ผ ํ์ ๊ฒฐ์ )
- chain_offset: ๋ช ๋ฒ static link๋ฅผ ๋ฐ๋ผ๊ฐ์ผ ํ๋์ง
static link๋ ARI์ ์ถ๊ฐ๋ ํฌ์ธํฐ๋ก, ์์ ์ ๊ฐ์ธ๋ lexical parent์ ARI๋ฅผ ๊ฐ๋ฆฌํด.
Bigsub: A(offset=3), B(offset=4), C(offset=5) [depth=0]
Sub1: A(offset=3) [depth=1]
Sub2: B(offset=4) [depth=1]
Sub3: E(offset=4) [depth=2]
Sub3์์:
- ์ง์ญ ๋ณ์ E: (0, 4)
- Sub2์ B: (1, 4) โ B๋ Sub2์ ์ฒซ ์ง์ญ ๋ณ์์ง๋ง Sub2์ parameter๊ฐ ์์ผ๋ฉด offset ๋ฐ๋ฆผ
- Bigsub์ A: (2, 3)
Sub2์์:
- Bigsub์ A: (1, 3)
- D๋ ์์ โ static semantic error
Simple vs Stack-Dynamic
- Simple subprogram: ์ฌ๊ท ์์, ์ง์ญ ๋ณ์๊ฐ ๋ชจ๋ static โ ARI ๊ณ ์ ํฌ๊ธฐ, ์ปดํ์ผ ํ์์ static ํ ๋น
- Stack-dynamic: ์ฌ๊ท ์ง์, ํธ์ถ๋ง๋ค ์ ARI ๋์ ์์ฑ
Dynamic Scoping
Deep access: dynamic chain(๋์ ๋งํฌ) ๋ฐ๋ผ ๊ฐ์ฅ ์ต๊ทผ ARI๋ถํฐ ๋ณ์ ํ์
- ์๋: O(depth)
- ๋จ์ : ์ปดํ์ผ ํ์์ chain ๊ธธ์ด ์ ์ ์์
Shallow access: ๋ณ์ ์ด๋ฆ๋ง๋ค ๋ณ๋ stack ์ ์ง, top์ด ํ์ฌ ๊ฐ
- ์๋: O(1)
- ๋จ์ : subprogram ์ง์ /์ข ๋ฃ ์ ๋ชจ๋ ๋ณ์ stack push/pop ๋น์ฉ
3. Concurrency
ํต์ฌ ์ฉ์ด
- Task/Process/Thread: ๋ค๋ฅธ ํ๋ก๊ทธ๋จ ๋จ์์ ๋์์ ์คํ๋ ์ ์๋ ๋จ์
- Physical concurrency: ์ค์ ์ฌ๋ฌ ํ๋ก์ธ์์์ ๋์ ์คํ
- Logical concurrency: ๋จ์ผ ํ๋ก์ธ์์์ time-sharing์ผ๋ก ๋์ ์คํ์ฒ๋ผ ๋ณด์
- Race condition: ๊ณต์ ์์์ ์์ ์์ด ์ ๊ทผํ์ฌ ์คํ ์์์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ ์ํฉ
- Deadlock: ๋ชจ๋ task๊ฐ ์์ํ ๋๊ธฐํ๋ ์ํ (liveness ์์ค)
- Liveness: task๊ฐ ์ธ์ ๊ฐ ์คํ์ ์๋ฃํ๋ค๋ ๋ณด์ฅ
- Mutual exclusion: ๊ณต์ ์์์ ํ ๋ฒ์ ํ๋์ task๋ง ์ ๊ทผ
Synchronization ์ข ๋ฅ
- Cooperation synchronization: task A๊ฐ ๊ณ์ ์คํ๋๋ ค๋ฉด task B์ ํน์ ์์ ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํจ (์: producer-consumer)
- Competition synchronization: ๋์์ ์ฌ์ฉํ ์ ์๋ ๊ณต์ ์์์ ๋ํ ๋ฐฐํ์ ์ ๊ทผ ๋ณด์ฅ
Task ์ํ
New โ Ready โ Running โ Blocked โ Dead
Semaphore
Dijkstra(1965). counter(์ ์) + ๋๊ธฐ queue๋ก ๊ตฌ์ฑ.
wait(s):
if s.counter > 0 then
s.counter--
else
task๋ฅผ s.queue์ ๋ฃ๊ณ block
release(s):
if s.queue is empty then
s.counter++
else
queue์์ task ํ๋๋ฅผ ready ์ํ๋ก ์ด๋
wait์ release๋ ๋ฐ๋์ atomicํ๊ฒ ์คํ๋์ด์ผ ํจ.
Cooperation synchronization ์์ (producer-consumer)
semaphore fullspots, emptyspots;
fullspots.count = 0;
emptyspots.count = BUFLEN;
task producer:
loop
wait(emptyspots)
DEPOSIT(VALUE)
release(fullspots)
end loop
task consumer:
loop
wait(fullspots)
FETCH(VALUE)
release(emptyspots)
end loop
Competition synchronization ์ถ๊ฐ (binary semaphore = mutex)
semaphore access, fullspots, emptyspots;
access.count = 1;
task producer:
loop
wait(emptyspots)
wait(access)
DEPOSIT(VALUE)
release(access)
release(fullspots)
end loop
task consumer:
loop
wait(fullspots)
wait(access)
FETCH(VALUE)
release(access)
release(emptyspots)
end loop
์ฃผ์: wait(emptyspots) โ wait(access) ์์์ฌ์ผ ํจ. ๋ฐ๋๋ก ํ๋ฉด deadlock.
Semaphore ์ค์ฉ ์ ๋ฌธ์
release(access)๋๋ฝ โ deadlockwait(fullspots)๋๋ฝ โ buffer underflow (๋น ๋ฒํผ์์ FETCH)release(fullspots)๋๋ฝ โ consumer๊ฐ ์์ํ ๋๊ธฐ
Monitor
๊ณต์ ๋ฐ์ดํฐ๋ฅผ encapsulate, ํ ๋ฒ์ ํ๋์ task๋ง ์ ๊ทผํ๋๋ก ๋ฐํ์์ด ๋ณด์ฅ.
- Competition synchronization: ์๋ ๋ณด์ฅ
- Cooperation synchronization: ํ๋ก๊ทธ๋๋จธ๊ฐ condition variable๋ก ์ง์ ๊ตฌํ
Java: synchronized ํค์๋
public synchronized void deposit(int item) { ... }
public synchronized int fetch() { ... }
Cooperation์ wait(), notify(), notifyAll() ์ฌ์ฉ (Object ํด๋์ค ๋ฉ์๋).
Monitor vs Semaphore:
- Monitor๊ฐ ๋ ์์ : ๊ณต์ ๋ฐ์ดํฐ๊ฐ monitor ๋ด๋ถ์๋ง ์๊ณ , competition sync๊ฐ ์๋
- Semaphore๋ ์ง์ ๊ด๋ฆฌํ๋ฏ๋ก ์ค์ ๊ฐ๋ฅ์ฑ ๋์
Message Passing (Ada)
Ada์ rendezvous ๋ชจ๋ธ: sender์ receiver ๋ชจ๋ ์ค๋น๋๋ฉด ๋๊ธฐ์ ์ผ๋ก ํต์ .
task body Buf_Task is
begin
loop
select
when Filled < Bufsize =>
accept Deposit(Item : in Integer) do
Buf(Next_In) := Item;
end Deposit;
Filled := Filled + 1;
or
when Filled > 0 =>
accept Fetch(Item : out Integer) do
Item := Buf(Next_Out);
end Fetch;
Filled := Filled - 1;
end select;
end loop;
end Buf_Task;
accept: ํด๋น entry๋ก ๋ฉ์์ง๊ฐ ์ฌ ๋๊น์ง blockselect: ์ฌ๋ฌ accept ์ค ํ๋๋ฅผ ์ ํ (๋น๊ฒฐ์ ์ )when ์กฐ๊ฑด =>: guarded accept โ ์กฐ๊ฑด์ด ์ฐธ์ผ ๋๋ง open
Java Threads
class MyThread extends Thread {
public void run() { ... }
}
Thread t = new MyThread();
t.start();
์ฃผ์ ๋ฉ์๋:
start(): run()์ ์ thread์์ ์คํyield(): ํ๋ก์ธ์ ์๋ฐ์ ์๋ณดsleep(ms): ์ง์ ์๊ฐ blockjoin(): ํด๋น thread ์๋ฃ๊น์ง ๋๊ธฐsetPriority(n): ์ฐ์ ์์ ์ค์ (1~10, ๊ธฐ๋ณธ 5)
Java Semaphore:
Semaphore emptyspots = new Semaphore(BUFLEN);
Semaphore fullspots = new Semaphore(0);
emptyspots.acquire(); // wait
fullspots.release(); // release
C# Threads
Thread t = new Thread(new ThreadStart(MyMethod));
t.Start();
๋๊ธฐํ ๋ฐฉ๋ฒ:
Interlocked.Increment(ref counter): ์ ์ atomic ์ฐ์ฐlock(obj) { ... }: critical sectionMonitorํด๋์ค
Ada 95 Protected Objects
rendezvous๋ณด๋ค ๊ฐ๋ฒผ์ด ๊ณต์ ๋ฐ์ดํฐ ๋ณดํธ ๋ฉ์ปค๋์ฆ.
protected Buffer is
entry Deposit(Item : in Integer);
entry Fetch(Item : out Integer);
private
...
end Buffer;
4. Scheme
๊ธฐ๋ณธ ํน์ง
- prefix ํ๊ธฐ๋ฒ:
(operator operand1 operand2 ...) - ์ฝ๋์ ๋ฐ์ดํฐ ๋ชจ๋ S-expression (๋ฆฌ์คํธ ๊ตฌ์กฐ)
- static scope, first-class function
- REPL: Read โ Eval โ Print โ Loop
ํต์ฌ ํจ์
| ํจ์ | ์ค๋ช | ์์ |
|---|---|---|
CAR | ๋ฆฌ์คํธ ์ฒซ ์์ | (CAR '(A B C)) โ A |
CDR | ๋๋จธ์ง ๋ฆฌ์คํธ | (CDR '(A B C)) โ (B C) |
CONS | ์์๋ฅผ ์์ ๋ถ์ | (CONS 'A '(B C)) โ (A B C) |
NULL? | ๋น ๋ฆฌ์คํธ ์ฌ๋ถ | (NULL? '()) โ #T |
EQ? | ํฌ์ธํฐ ๋์ผ์ฑ | atom/symbol ๋น๊ต |
EQV? | ๊ฐ ๋์ผ์ฑ | ์ซ์๋ ๋น๊ต ๊ฐ๋ฅ |
LIST? | ๋ฆฌ์คํธ ์ฌ๋ถ | (LIST? '(A B)) โ #T |
CAR/CDR ํฉ์ฑ ์ถ์ฝํ:
(CADR x) ; (CAR (CDR x)) -- ๋ ๋ฒ์งธ ์์
(CADDR x) ; (CAR (CDR (CDR x))) -- ์ธ ๋ฒ์งธ ์์
(CAAR x) ; (CAR (CAR x))
(CDAR x) ; (CDR (CAR x))
DEFINE
(DEFINE pi 3.14159)
(DEFINE (square x) (* x x))
; ์๋์ ๋์ผ
(DEFINE square (LAMBDA (x) (* x x)))
DEFINE์ผ๋ก ๋ฐ์ธ๋ฉ๋ ์ด๋ฆ์ Java์ final์ฒ๋ผ ์ฌ๋ฐ์ธ๋ฉ ๋ถ๊ฐ.
์กฐ๊ฑด๋ฌธ
(IF predicate then_expr else_expr)
(COND
(predicate1 expr1)
(predicate2 expr2)
(ELSE default_expr))
์์ -- ์ ์ฅ๋ฃ:
(DEFINE (admissionfee age)
(COND
((<= age 6) 0)
((< age 60) 5000)
(ELSE 2500)))
(admissionfee 65) ; โ 2500
์์ -- ์ค๋ ํ๋ณ:
(DEFINE (leap? year)
(COND
((ZERO? (MODULO year 400)) #T)
((ZERO? (MODULO year 100)) #F)
(ELSE (ZERO? (MODULO year 4)))))
(leap? 2024) ; โ #T
๊ธฐ๋ณธ ์ฌ๊ท ํจํด
; ๋ฆฌ์คํธ ๊ธธ์ด
(DEFINE (length lst)
(COND
((NULL? lst) 0)
(ELSE (+ 1 (length (CDR lst))))))
; ๋ฆฌ์คํธ ํฉ์ฐ
(DEFINE (adder lst)
(COND
((NULL? lst) 0)
(ELSE (+ (CAR lst) (adder (CDR lst))))))
; ๋ฆฌ์คํธ ์ด์ด๋ถ์ด๊ธฐ
(DEFINE (append list1 list2)
(COND
((NULL? list1) list2)
(ELSE (CONS (CAR list1) (append (CDR list1) list2)))))
; ๋ฆฌ์คํธ ๋ค์ง๊ธฐ
(DEFINE (my-reverse lst)
(COND
((NULL? lst) '())
(ELSE (append (my-reverse (CDR lst)) (LIST (CAR lst))))))
๋ฆฌ์คํธ ํ์
; ๋ฆฌ์คํธ์ ์์๊ฐ ์๋์ง ํ์ธ
(DEFINE (member atm lst)
(COND
((NULL? lst) #F)
((EQ? atm (CAR lst)) #T)
(ELSE (member atm (CDR lst)))))
(member 'B '(A B C)) ; โ #T
(member 'B '(A C D)) ; โ #F
๋ฆฌ์คํธ ๋น๊ต
; ๋จ์ ๋ฆฌ์คํธ(atom๋ง ํฌํจ) ๋น๊ต
(DEFINE (equalsimp list1 list2)
(COND
((NULL? list1) (NULL? list2))
((NULL? list2) #F)
((EQ? (CAR list1) (CAR list2))
(equalsimp (CDR list1) (CDR list2)))
(ELSE #F)))
; ์ค์ฒฉ ๋ฆฌ์คํธ๋ ๋น๊ต (์ผ๋ฐ)
(DEFINE (equal list1 list2)
(COND
((NOT (LIST? list1)) (EQ? list1 list2))
((NOT (LIST? list2)) #F)
((NULL? list1) (NULL? list2))
((NULL? list2) #F)
((equal (CAR list1) (CAR list2))
(equal (CDR list1) (CDR list2)))
(ELSE #F)))
์งํฉ ์ฐ์ฐ
; ๊ต์งํฉ (๋ ๋ฆฌ์คํธ์ ๊ณตํต ์์)
(DEFINE (guess list1 list2)
(COND
((NULL? list1) '())
((member (CAR list1) list2)
(CONS (CAR list1) (guess (CDR list1) list2)))
(ELSE (guess (CDR list1) list2))))
(guess '(A B C D) '(B D F)) ; โ (B D)
์ ๋ ฌ
; ์ฝ์
์ ๋ ฌ -- insert: ์ ๋ ฌ๋ ๋ฆฌ์คํธ์ ์์ ์ฝ์
(DEFINE (insert atm lst)
(COND
((NULL? lst) (CONS atm '()))
((< atm (CAR lst)) (CONS atm lst))
(ELSE (CONS (CAR lst) (insert atm (CDR lst))))))
; sort: insert๋ฅผ ์ด์ฉํ ์ ๋ ฌ
(DEFINE (sort lst)
(IF (NULL? lst)
'()
(insert (CAR lst) (sort (CDR lst)))))
(sort '(3 7 5 1 9)) ; โ (1 3 5 7 9)
์ด์ง ํธ๋ฆฌ
ํธ๋ฆฌ๋ฅผ (๊ฐ ์ผ์ชฝ ์ค๋ฅธ์ชฝ) ํํ์ ๋ฆฌ์คํธ๋ก ํํ.
(CAR t): ๋ฃจํธ ๊ฐ(CADR t): ์ผ์ชฝ subtree(CADDR t): ์ค๋ฅธ์ชฝ subtree
; ๋
ธ๋ ์ ๊ณ์ฐ
(DEFINE (count-nodes t)
(IF (NULL? t)
0
(+ 1
(count-nodes (CADR t))
(count-nodes (CADDR t)))))
; ํธ๋ฆฌ ๋์ด
(DEFINE (tree-height t)
(IF (NULL? t)
0
(+ 1 (MAX (tree-height (CADR t))
(tree-height (CADDR t))))))
; ์ต๋๊ฐ (์ผ๋ฐ ํธ๋ฆฌ)
(DEFINE (tree-max t)
(IF (NULL? t)
-999999
(MAX (CAR t)
(tree-max (CADR t))
(tree-max (CADDR t)))))
ํธ๋ฆฌ ์์: '(5 (3 (1 () ()) (4 () ())) (8 (7 () ()) ()))
LET
(LET ((alpha 7) (beta 3))
(* alpha beta))
; โ 21
; ์ค์ ๋ก๋: ((LAMBDA (alpha beta) (* alpha beta)) 7 3)
; ๊ทผ์ ๊ณต์ ์์
(DEFINE (quadratic_roots a b c)
(LET ((root_part (/ (SQRT (- (* b b) (* 4 a c))) (* 2 a)))
(minus_b (/ (- 0 b) (* 2 a))))
(LIST (+ minus_b root_part)
(- minus_b root_part))))
map / fold / filter
; map: ๋ฆฌ์คํธ ๊ฐ ์์์ ํจ์ ์ ์ฉ
(DEFINE (map fun lst)
(COND
((NULL? lst) '())
(ELSE (CONS (fun (CAR lst)) (map fun (CDR lst))))))
(map (LAMBDA (x) (* x x)) '(1 2 3)) ; โ (1 4 9)
(map (LAMBDA (x) (* x x x)) '(3 4 2 6)) ; โ (27 64 8 216)
; fold: ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก ๋์
(DEFINE (FOLD f base lst)
(COND
((NULL? lst) base)
(ELSE (f (CAR lst) (FOLD f base (CDR lst))))))
(FOLD + 0 '(1 2 3 4)) ; โ 10
(FOLD * 1 '(2 3 4)) ; โ 24
; filter: ์กฐ๊ฑด ๋ง์กฑ ์์๋ง ์ถ์ถ
(DEFINE (FILTER pred lst)
(COND
((NULL? lst) '())
((pred (CAR lst)) (CONS (CAR lst) (FILTER pred (CDR lst))))
(ELSE (FILTER pred (CDR lst)))))
(FILTER EVEN? '(1 2 3 4)) ; โ (2 4)
(FILTER ODD? '(1 2 3 4)) ; โ (1 3)
ํจ์ ํฉ์ฑ
(DEFINE (compose f g)
(LAMBDA (x) (f (g x))))
((compose CAR CDR) '((a b) c d)) ; โ c (CADR)
((compose CDR CAR) '((a b) c d)) ; โ (b) (CDAR)
; third = CADDR
(DEFINE (third lst)
((compose CAR (compose CDR CDR)) lst))
(third '(1 2 3 4)) ; โ 3
Tail Recursion
๋ง์ง๋ง ์ฐ์ฐ์ด ์ฌ๊ท ํธ์ถ โ ์ปดํ์ผ๋ฌ๊ฐ ๋ฐ๋ณต๋ฌธ์ผ๋ก ๋ณํ ๊ฐ๋ฅ. Scheme์ tail call optimization์ ์ธ์ด ๋ช ์ธ์์ ์๊ตฌํจ.
; ์ผ๋ฐ ์ฌ๊ท (tail recursive ์๋: * n์ด ์ฌ๊ท ์ดํ์ ์คํ๋จ)
(DEFINE (factorial n)
(IF (<= n 1) 1 (* n (factorial (- n 1)))))
; tail recursive ๋ฒ์ (accumulator ํจํด)
(DEFINE (factorial n)
(DEFINE (facthelper n acc)
(IF (<= n 0)
acc
(facthelper (- n 1) (* n acc))))
(facthelper n 1))
; member๋ tail recursive: ์ฌ๊ท ํธ์ถ์ด ๋ง์ง๋ง ์ฐ์ฐ
(DEFINE (member atm lst)
(COND
((NULL? lst) #F)
((EQ? atm (CAR lst)) #T)
(ELSE (member atm (CDR lst)))))
์ค์ฒฉ ๋ฆฌ์คํธ ํฉ์ฐ
; ์ค์ฒฉ ๋ฆฌ์คํธ๋ ์ฒ๋ฆฌํ๋ adder
(DEFINE (adder lst)
(COND
((NULL? lst) 0)
((LIST? (CAR lst))
(+ (adder (CAR lst)) (adder (CDR lst))))
(ELSE (+ (CAR lst) (adder (CDR lst))))))
(adder '(1 (2 3) (4 (5)))) ; โ 15
QUOTE
(QUOTE (A B C)) ; โ (A B C)
'(A B C) ; ์์ ๋์ผ (์ถ์ฝํ)
(+ 1 2) ; โ 3 (ํ๊ฐ๋จ)
'(+ 1 2) ; โ (+ 1 2) (ํ๊ฐ ์ ๋จ)
5. ML
๊ธฐ๋ณธ ํน์ง
- ์ ์ ์ค์ฝํ, ๊ฐํ ํ์ , ํ์ ์ถ๋ก (type inferencing)
- ํ์ ๊ฐ ์๋ฌต์ ๋ณํ(coercion) ์์
- immutable ๋ณ์
- ์ฌ์ฉ์ ์ ์ ํจ์ ์ค๋ฒ๋ก๋ฉ ๋ถ๊ฐ โ ๋ค๋ฅธ ์ด๋ฆ ์ฌ์ฉ
ํจ์ ์ ์
fun cube(x : int) = x * x * x;
fun fact(n : int) : int =
if n <= 1 then 1
else n * fact(n - 1);
๋ฐํ๊ฐ: ๋ง์ง๋ง ํํ์์ ๊ฐ.
ํจํด ๋งค์นญ
fun fact(0) = 1
| fact(1) = 1
| fact(n : int) : int = n * fact(n - 1);
fun length([]) = 0
| length(h :: t) = 1 + length(t);
fun append([], lis2) = lis2
| append(h :: t, lis2) = h :: append(t, lis2);
fun reverse([]) = []
| reverse(h :: t) = append(reverse(t), [h]);
(* member: ๋ฆฌ์คํธ์ ์์๊ฐ ์๋์ง *)
fun member(atm, []) = false
| member(atm, h :: t) =
if atm = h then true
else member(atm, t);
๋ฆฌ์คํธ ์ฐ์ฐ
| ML | Scheme | ์ค๋ช |
|---|---|---|
hd | CAR | ์ฒซ ๋ฒ์งธ ์์ |
tl | CDR | ๋๋จธ์ง |
:: | CONS | ์์ ๋ถ์ด๊ธฐ |
[3, 5, 7] | '(3 5 7) | ๋ฆฌ์คํธ ๋ฆฌํฐ๋ด |
[] | '() | ๋น ๋ฆฌ์คํธ |
@ | append | ๋ฆฌ์คํธ ์ฐ๊ฒฐ |
ํ์ ์ถ๋ก
fun circumf(r) = 3.14159 * r * r;
(* 3.14159๊ฐ real โ r: real, ๋ฐํ๊ฐ: real *)
fun square(x) = x * x;
(* ๋ฆฌํฐ๋ด ์์ โ ๊ธฐ๋ณธ๊ฐ int โ int โ int *)
(* square(2.75); โ ์๋ฌ (real์ int ํจ์ ์ ์ฉ) *)
fun square(x : real) = x * x;
(* ๋ช
์์ ์ผ๋ก real ์ง์ *)
val / let
val distance = time * speed;
let
val pi = 3.14159
val r = 2.0
in
pi * r * r
end;
๊ฐ์ ์ด๋ฆ์ ๋ ๋ฒ valํ๋ฉด ์ด์ ๊ฒ์ด ์จ๊ฒจ์ง (shadowing).
Lambda
fn(x) => x * x
filter(fn(x) => x < 100, [25, 1, 711, 50, 100]);
(* [25, 1, 50] *)
map(fn(x) => x * x * x, [1, 3, 5]);
(* [1, 27, 125] *)
map / filter
(* map: ๋ฆฌ์คํธ ๊ฐ ์์์ ํจ์ ์ ์ฉ *)
fun cube x = x * x * x;
val cubeList = map cube;
val newList = cubeList [1, 3, 5]; (* [1, 27, 125] *)
(* filter: ์กฐ๊ฑด ๋ง์กฑ ์์๋ง ์ถ์ถ *)
filter(fn(x) => x mod 2 = 0, [1, 2, 3, 4, 5]);
(* [2, 4] *)
Currying / Partial Application
fun add a b = a + b;
(* add: int โ int โ int *)
val add5 = add 5;
(* add5: int โ int *)
val result = add5 10; (* 15 *)
(* ์ปค๋ง vs ํํ *)
fun add_tuple(a, b) = a + b; (* int * int โ int *)
fun add_curried a b = a + b; (* int โ int โ int *)
val add3 = add_curried 3; (* ๋ถ๋ถ ์ ์ฉ โ int โ int *)
add3 10; (* 13 *)
ํจ์ ํฉ์ฑ
fun double x = 2 * x;
fun square x = x * x;
val doubleThenSquare = square o double;
val result = doubleThenSquare 3; (* square(double(3)) = 36 *)
6. Haskell
ML๊ณผ ๊ณตํต์
์ ์ ์ค์ฝํ, ๊ฐํ ํ์ , ํ์ ์ถ๋ก , ํจํด ๋งค์นญ
ML๊ณผ ์ฐจ์ด์
- Lazy evaluation: ๊ฐ์ด ์ค์ ๋ก ํ์ํ ๋๊น์ง ํ๊ฐ ๋ฏธ๋ฃธ
- ์์ ํจ์ํ: ๋ณ์ ์์, ๋์ ๋ฌธ ์์, side effect ์์
- type class: ์ค๋ฒ๋ก๋ฉ ์ง์
- ๋ฌดํ ๋ฆฌ์คํธ ๊ฐ๋ฅ
๊ธฐ๋ณธ ๋ฆฌ์คํธ ํจ์
head [1,2,3] -- 1
tail [1,2,3] -- [2,3]
init [1,2,3] -- [1,2]
last [1,2,3] -- 3
take 2 [1,2,3] -- [1,2]
drop 2 [1,2,3] -- [3]
length [1,2,3] -- 3
reverse [1,2,3] -- [3,2,1]
sum [1,2,3] -- 6
product [1,2,3] -- 6
[1,2] ++ [3,4] -- [1,2,3,4]
1 : [2,3] -- [1,2,3]
[1..5] -- [1,2,3,4,5]
[2,4..10] -- [2,4,6,8,10]
[1,2,3,4] !! 2 -- 3 (์ธ๋ฑ์ค ์ ๊ทผ, 0๋ถํฐ)
ํจํด ๋งค์นญ
fact 0 = 1
fact 1 = 1
fact n = n * fact (n - 1)
length [] = 0
length (a:x) = 1 + length x
reverse [] = []
reverse (a:x) = reverse x ++ [a]
product [] = 1
product (a:x) = a * product x
-- drop: ์์์ n๊ฐ ์ ๊ฑฐ
drop 0 x = x
drop _ [] = []
drop n (a:x) = drop (n-1) x
-- ++ ์ง์ ๊ตฌํ
[] ++ y = y
(a:x) ++ y = a : (x ++ y)
Guards
fact n
| n == 0 = 1
| n == 1 = 1
| otherwise = n * fact (n - 1)
sub n
| n < 10 = 0
| n > 100 = 2
| otherwise = 1
foldr
์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก ๋์ .
foldr f v [x1, x2, x3] = x1 \f` (x2 `f` (x3 `f` v))`
sum = foldr (+) 0
product = foldr (*) 1
and = foldr (&&) True
length = foldr (\_ n -> 1 + n) 0
reverse = foldr (\x xs -> xs ++ [x]) []
-- ๊ณ์ฐ ๊ณผ์ ์ถ์
foldr (+) 0 [1,2,3,4]
= 1 + (2 + (3 + (4 + 0)))
= 10
foldr (*) 1 [1,2,3,4]
= 1 * (2 * (3 * (4 * 1)))
= 24
foldr (\_ n -> 1+n) 0 [10,20,30]
= 1 + (1 + (1 + 0))
= 3
foldr (\x xs -> xs ++ [x]) [] [1,2,3]
= (foldr ... [] [2,3]) ++ [1]
= ([3,2] ++ [1])
= [3,2,1]
map
map (+1) [1,2,3] -- [2,3,4]
map (*2) [1,2,3] -- [2,4,6]
map negate [1,2,3] -- [-1,-2,-3]
-- ์ฌ๊ท ์ ์
map f [] = []
map f (x:xs) = f x : map f xs
List Comprehension
[n*n | n <- [1..5]]
-- [1,4,9,16,25]
[n*n*n | n <- [1..50]]
-- 1๋ถํฐ 50๊น์ง ์ธ์ ๊ณฑ
[x | x <- [1..20], even x]
-- [2,4,6,8,10,12,14,16,18,20]
-- ์ฝ์ ๊ตฌํ๊ธฐ
factors n = [x | x <- [1..n], n `mod` x == 0]
factors 15 -- [1,3,5,15]
-- ์์ ํ๋ณ
prime n = factors n == [1, n]
prime 17 -- True
-- ์ ์์ฑ
[(x,y) | x <- [1..3], y <- [4..5]]
-- [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
-- concat (๋ฆฌ์คํธ ํํํ)
concat xss = [x | xs <- xss, x <- xs]
concat [[1,2],[3],[4,5]] -- [1,2,3,4,5]
ํจ์ ํฉ์ฑ
(f . g) x = f (g x) -- ์ค๋ฅธ์ชฝ๋ถํฐ ์ผ์ชฝ์ผ๋ก ์ ์ฉ
odd = not . even
zip / pairs / sorted / positions
-- zip: ๋ ๋ฆฌ์คํธ ์์๋ฅผ ์์ผ๋ก ๋ฌถ์ (์งง์ ์ชฝ ๊ธฐ์ค)
zip [1,2,3] ['a','b','c','d'] -- [(1,'a'),(2,'b'),(3,'c')]
zip "abc" [1,2,3] -- [('a',1),('b',2),('c',3)]
-- pairs: ์ธ์ ์์ ์
pairs xs = zip xs (tail xs)
pairs [1,2,3,4] -- [(1,2),(2,3),(3,4)]
-- sorted: ์ ๋ ฌ ์ฌ๋ถ ํ์ธ
sorted xs = and [x <= y | (x,y) <- pairs xs]
sorted [1,2,3,4] -- True
sorted [1,2,5,3,4] -- False
-- positions: ํน์ ๊ฐ์ ์ธ๋ฑ์ค ๋ชฉ๋ก
positions x xs = [i | (x',i) <- zip xs [0..n], x == x']
where n = length xs - 1
positions 0 [0,1,0,1,1,0] -- [0,2,5]
all / any
all p xs = and [p x | x <- xs]
all even [2,4,6] -- True
all even [2,3,6] -- False
any p xs = or [p x | x <- xs]
any odd [2,4,6] -- False
any odd [2,3,6] -- True
Lazy Evaluation
positives = [0..]
take 5 [1,3..] -- [1,3,5,7,9]
squares = [n*n | n <- [0..]]
-- ๋ฌดํ ๋ฆฌ์คํธ์์ ์์ ํ ํ์ (์ ๋ ฌ๋ ๋ฆฌ์คํธ ๊ฐ์ )
member2 n (m:x)
| m < n = member2 n x
| m == n = True
| otherwise = False
member2 16 squares -- True
member2 5 squares -- False (๋น ๋ฅด๊ฒ ์ข
๋ฃ)
Quicksort
sort [] = []
sort (h:t) =
sort [b | b <- t, b <= h]
++ [h] ++
sort [b | b <- t, b > h]
Insertion Sort
insert x [] = [x]
insert x (y:ys)
| x <= y = x : y : ys
| otherwise = y : insert x ys
isort [] = []
isort (x:xs) = insert x (isort xs)
Merge Sort
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) =
if x <= y then x : merge xs (y:ys)
else y : merge (x:xs) ys
halve xs = splitAt (length xs `div` 2) xs
msort [] = []
msort [x] = [x]
msort xs = merge (msort ys) (msort zs)
where (ys, zs) = halve xs
let / where
-- let ... in
quadratic a b c =
let minus_b = -b / (2.0 * a)
disc = sqrt(b^2 - 4.0*a*c) / (2.0*a)
in [minus_b - disc, minus_b + disc]
-- where
quadratic a b c =
[minus_b - disc, minus_b + disc]
where
minus_b = -b / (2.0 * a)
disc = sqrt(b^2 - 4.0*a*c) / (2.0*a)
7. Common Lisp / F#
Common Lisp
- Scheme๋ณด๋ค ํฌ๊ณ ๋ณต์กํ ์ธ์ด
- static scoping ๊ธฐ๋ณธ,
special์ ์ธ์ผ๋ก dynamic scoping ๊ฐ๋ฅ DEFUN: ํจ์ ์ ์,SETF: ๊ฐ ํ ๋น
(DEFUN square (x) (* x x))
(SETF A 10)
(LOOP FOR I FROM 1 TO 5 DO (FORMAT T "~A " I))
Backquote: ` + ,๋ก ์ผ๋ถ๋ง ํ๊ฐ ๊ฐ๋ฅ
`(a (* 3 4) c) ; โ (a (* 3 4) c) -- ํ๊ฐ ์ ๋จ
`(a ,(* 3 4) c) ; โ (a 12 c) -- , ๋ค๋ง ํ๊ฐ๋จ
member ํจ์:
(DEFUN recursive_member (atm lst)
(COND
((NULL lst) NIL)
((EQUAL atm (CAR lst)) T)
(T (recursive_member atm (CDR lst)))))
F#
- ML/OCaml ๊ณ์ด, .NET ๊ธฐ๋ฐ
- ํจ์ํ + ๋ช ๋ นํ + OOP ์ง์
let: ๊ฐ ๋ฐ์ธ๋ฉ,let mutable: ๊ฐ๋ณ ๋ณ์,let rec: ์ฌ๊ท ํจ์fun: lambda ํํ์,>>: ํจ์ ํฉ์ฑ,|>: pipeline
์ฌ๊ท ํจ์ (ํจํด ๋งค์นญ)
let rec factorial n =
match n with
| 0 -> 1
| 1 -> 1
| _ -> n * factorial (n - 1)
Pipeline |>
let myNums = [1; 2; 3; 4; 5]
let result =
myNums
|> List.filter (fun n -> n % 2 = 0)
|> List.map (fun n -> n * 5)
// result = [10; 20]
ํจ์ ํฉ์ฑ >>
let negate x = -1 * x
let square x = x * x
let negateSquare = square >> negate // (f >> g) x = g(f(x))
negateSquare 3 // square(3)=9, negate(9)=-9
Quicksort
let rec quicksort list =
match list with
| [] -> []
| firstElem :: otherElements ->
let smaller =
otherElements
|> List.filter (fun e -> e < firstElem)
|> quicksort
let larger =
otherElements
|> List.filter (fun e -> e >= firstElem)
|> quicksort
smaller @ [firstElem] @ larger
Insertion Sort
let rec insert n ls =
match ls with
| [] -> [n]
| x :: xs ->
if n > x then x :: insert n xs
else n :: ls
let rec insertSort ls =
match ls with
| [] -> []
| x :: xs -> insert x (insertSort xs)
// insertSort [3; 1; 4; 2] --> [1; 2; 3; 4]
List ๊ณ ์ฐจ ํจ์
let l = [1; 2; 3; 4; 5]
List.map (fun x -> x * x) l // [1;4;9;16;25]
List.filter (fun x -> x % 2 = 0) l // [2;4]
List.fold (fun acc x -> acc + x) 0 l // 15
7.5. FPL 4-Language Full Comparison
๊ธฐ๋ณธ ์ ๋ณด
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ์ถ์ | 1975 | 1984 | 1973 | 1990 |
| ๊ณ๋ณด | Lisp ๋ฐฉ์ธ | ์ฌ๋ฌ Lisp ๋ฐฉ์ธ ํตํฉ | ๋ ๋ฆฝ ์ค๊ณ | ML ๊ณ์ด |
| ํฌ๊ธฐ | ์๊ณ ๊ฐ๊ฒฐ | ํฌ๊ณ ๋ณต์ก | ์ค๊ฐ | ์ค๊ฐ |
| ์์ ํจ์ํ | ์๋ | ์๋ | ์๋ | ์ |
ํ์ ์์คํ
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ํ์ ์์คํ | untyped | untyped | strongly typed | strongly typed |
| ํ์ ์ถ๋ก | ์์ | ์์ | ์์ | ์์ |
| ํ์ coercion | ์์ | ์์ | ์์ | ์์ |
| ์ค๋ฒ๋ก๋ฉ | ์์ | ์์ | ์์ | type class๋ก ์ง์ |
| ๊ธฐ๋ณธ ์ซ์ ํ์ | ํตํฉ (dynamic) | ํตํฉ (dynamic) | int / real ๊ตฌ๋ถ | Int / Float ๊ตฌ๋ถ |
์ค์ฝํ / ๋ณ์
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ์ค์ฝํ | static only | static ๊ธฐ๋ณธ, dynamic ์ ํ | static only | static only |
| ๋์ ์ค์ฝํ | ์์ | special ์ ์ธ์ผ๋ก ๊ฐ๋ฅ | ์์ | ์์ |
| ๋ณ์ ํน์ฑ | immutable | mutable (SETF) | immutable (val) | immutable |
| ์ฌ์ ์ | DEFINE ์ฌํธ์ถ๋ก shadowing | SETF๋ก ๋ณ๊ฒฝ ๊ฐ๋ฅ | val ์ฌ์ ์ธ์ผ๋ก shadowing | ์ฌ์ ์ ๋ถ๊ฐ |
ํ๊ฐ ๋ฐฉ์
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ํ๊ฐ ๋ฐฉ์ | strict | strict | strict | nonstrict (lazy) |
| ๋ฌดํ ๋ฆฌ์คํธ | ๋ถ๊ฐ | ๋ถ๊ฐ | ๋ถ๊ฐ | ๊ฐ๋ฅ |
| Tail call ์ต์ ํ | ์ธ์ด ๋ช ์ธ์์ ์๊ตฌ | ๊ตฌํ ์์กด | ๊ตฌํ ์์กด | ์์ |
| Side effect | ๊ฐ๋ฅ (set!, I/O) | ๊ฐ๋ฅ (SETF, I/O) | ๊ฐ๋ฅ (ref, I/O) | IO ๋ชจ๋๋๋ก๋ง ํ์ฉ |
๋ฌธ๋ฒ โ ํจ์ ์ ์
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ํจ์ ์ ์ | (DEFINE (f x) ...) | (DEFUN f (x) ...) | fun f x = ... | f x = ... |
| ์ฌ๊ท ํค์๋ | ๋ถํ์ | ๋ถํ์ | ๋ถํ์ | ๋ถํ์ |
| Lambda | (LAMBDA (x) ...) | (LAMBDA (x) ...) | fn x => ... | \x -> ... |
| ํจํด ๋งค์นญ | ์์ (COND/IF๋ก๋ง) | ์์ (COND/IF๋ก๋ง) | ์์ (` | `) |
| ํจ์ ํฉ์ฑ | compose ์ง์ ์ ์ | compose ์ง์ ์ ์ | o ์ฐ์ฐ์ | . ์ฐ์ฐ์ |
| ์ฃผ์ | ; | ; | (* ... *) | -- ๋๋ {- -} |
๋ฌธ๋ฒ โ ์กฐ๊ฑด๋ฌธ
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| 2๋ถ๊ธฐ | (IF pred t f) | (IF pred t f) | if ... then ... else ... | if ... then ... else ... |
| ๋ค๋ถ๊ธฐ | (COND ...) | (COND ...) | ํจํด ๋งค์นญ | guards (` |
| ๊ธฐ๋ณธ๊ฐ (else) | (ELSE ...) | (T ...) | ํจํด์ ๋ง์ง๋ง ์ | otherwise |
๋ฌธ๋ฒ โ ๋ฆฌ์คํธ ์ฐ์ฐ
| ์ฐ์ฐ | Scheme | Common Lisp | ML | Haskell |
|---|---|---|---|---|
| ๋ฆฌ์คํธ ๋ฆฌํฐ๋ด | '(1 2 3) | '(1 2 3) | [1, 2, 3] | [1, 2, 3] |
| ๋น ๋ฆฌ์คํธ | '() | NIL ๋๋ '() | [] | [] |
| ๋น ๋ฆฌ์คํธ ๊ฒ์ฌ | (NULL? lst) | (NULL lst) | lst = [] | null lst |
| CONS | (CONS x lst) | (CONS x lst) | x :: lst | x : lst |
| CAR (์ฒซ ์์) | (CAR lst) | (CAR lst) | hd lst | head lst |
| CDR (๋๋จธ์ง) | (CDR lst) | (CDR lst) | tl lst | tail lst |
| ๋ฆฌ์คํธ ์ฐ๊ฒฐ | (append l1 l2) | (append l1 l2) | l1 @ l2 | l1 ++ l2 |
| ๊ธธ์ด | (length lst) | (length lst) | length lst | length lst |
๋ฌธ๋ฒ โ ๊ณ ์ฐจ ํจ์
| ์ฐ์ฐ | Scheme | Common Lisp | ML | Haskell |
|---|---|---|---|---|
| map | (map f lst) | (mapcar f lst) | map f lst | map f lst |
| filter | (FILTER pred lst) | (remove-if-not pred lst) | filter pred lst | filter pred lst |
| fold | (FOLD f base lst) | (reduce f lst) | foldl f base lst | foldr f v lst |
๋ฌธ๋ฒ โ ์ง์ญ ๋ฐ์ธ๋ฉ
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ์ง์ญ ๋ฐ์ธ๋ฉ | (LET ((x 1)) ...) | (LET ((x 1)) ...) | let val x=1 in ... end | let x=1 in ... |
| ํจ์ ์๋ ์ ์ | ์์ | ์์ | ์์ | where ๊ตฌ๋ฌธ |
| ํํ์ ์ ์ ์ | LET | LET | let ... in ... end | let ... in ... |
๋ถ๋ฆฌ์ธ
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ์ฐธ | #T | T | true | True |
| ๊ฑฐ์ง | #F | NIL | false | False |
| AND | (AND ...) | (AND ...) | andalso | && |
| OR | (OR ...) | (OR ...) | orelse | ` |
| NOT | (NOT ...) | (NOT ...) | not | not |
์์ธ ์ฒ๋ฆฌ
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ์์ธ ์ ์ | ๊ตฌํ ์์กด | (define-condition ...) | exception E | data MyE = ... |
| ์์ธ ๋ฐ์ | (raise ...) | (error ...) | raise E | throw e |
| ์์ธ ์ฒ๋ฆฌ | (with-exception-handler ...) | (handler-case ...) | handle E => ... | catch action handler |
| ์ ๋ฆฌ ์ฝ๋ | ๊ตฌํ ์์กด | (unwind-protect ...) | ์์ | bracket ํจํด |
ํ์ฅ ๊ธฐ๋ฅ
| Scheme | Common Lisp | ML | Haskell | |
|---|---|---|---|---|
| ๋งคํฌ๋ก | define-syntax (hygienic) | DEFMACRO (๊ฐ๋ ฅ) | ์์ | Template Haskell (๋ณ๋) |
| ๋ฐฐ์ด | ์์ (๊ธฐ๋ณธ) | MAKE-ARRAY | array ํ์ | Data.Array (๋ณ๋) |
| ๊ตฌ์กฐ์ฒด | ์์ (๊ธฐ๋ณธ) | DEFSTRUCT | record ํ์ | data ํ์ |
| ๋ฐ๋ณต๋ฌธ | ์์ (์ฌ๊ท๋ง) | LOOP, DOTIMES, DOLIST | ์์ (์ฌ๊ท๋ง) | ์์ (์ฌ๊ท๋ง) |
| Currying | ์๋ (LAMBDA ์ค์ฒฉ) | ์๋ | ์๋ (์ผํ ์์ด) | ์๋ |
ํ ๋ฌธ์ฅ ์์ฝ
| ์์ฝ | |
|---|---|
| Scheme | ์๊ณ ์์ํ Lisp. ๋๋ค ๊ณ์ฐ๋ฒ์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฏธ๋๋ฉํ ์ค๊ณ. |
| Common Lisp | ๊ธฐ๋ฅ์ด ํ๋ถํ ์ค์ฉ Lisp. ๋ช ๋ นํ๊ณผ ํจ์ํ์ด ํผ์ฌ. |
| ML | ํจ์ํ ๊ธฐ๋ฐ์ ์ ์ ํ์ ์ธ์ด. ํ์ ์ถ๋ก ๊ณผ ํจํด ๋งค์นญ์ด ํต์ฌ. |
| Haskell | ์ ์ผํ ์์ ํจ์ํ. lazy evaluation, ๋ฌดํ ๋ฆฌ์คํธ, type class. |
ํต์ฌ ํน์ฑ ๋น๊ต
| ํญ๋ชฉ | Scheme | Common Lisp | ML | Haskell | F# |
|---|---|---|---|---|---|
| ์ค์ฝํ | static | static (๊ธฐ๋ณธ) / dynamic ์ ํ | static | static | static |
| ํ์ ์์คํ | untyped | untyped | strongly typed | strongly typed | strongly typed |
| ํ์ ์ถ๋ก | ์์ | ์์ | ์์ | ์์ | ์์ |
| ํ์ coercion | ์์ | ์์ | ์์ | ์์ | ์์ |
| ๋ณ์ | immutable | mutable ๊ฐ๋ฅ (SETF) | immutable (val) | immutable | immutable (๊ธฐ๋ณธ) / mutable ์ ํ |
| ์ค๋ฒ๋ก๋ฉ | ์์ | ์์ | ์์ | type class๋ก ์ง์ | inline์ผ๋ก ํ๋ด |
| ํจํด ๋งค์นญ | COND/IF | COND/IF | ์์ | ์์ | ์์ (match) |
| Lazy evaluation | ์์ (strict) | ์์ (strict) | ์์ (strict) | ๊ธฐ๋ณธ (nonstrict) | ์ ํ์ (seq) |
| ์์ ํจ์ํ | ์๋ (side effect ๊ฐ๋ฅ) | ์๋ | ์๋ | ์ | ์๋ |
| ์ฌ๊ท ํค์๋ | ์์ (DEFINE์ผ๋ก ์๋) | ์์ (DEFUN์ผ๋ก ์๋) | ์์ (์๋) | ์์ (์๋) | rec ํ์ |
| ๋ฌดํ ๋ฆฌ์คํธ | ๋ถ๊ฐ | ๋ถ๊ฐ | ๋ถ๊ฐ | ๊ฐ๋ฅ | seq๋ก ๊ฐ๋ฅ |
| ํจ์ ํฉ์ฑ | compose ์ง์ ์ ์ | ์ง์ ์ ์ | o ์ฐ์ฐ์ | . ์ฐ์ฐ์ | >> ์ฐ์ฐ์ |
| Lambda | LAMBDA | LAMBDA | fn | \x -> | fun |
| ๋ฆฌ์คํธ ๊ตฌ๋ถ์ | ๊ณต๋ฐฑ (1 2 3) | ๊ณต๋ฐฑ (1 2 3) | ์ผํ [1, 2, 3] | ์ผํ [1, 2, 3] | ์ธ๋ฏธ์ฝ๋ก [1; 2; 3] |
| CONS | CONS | CONS | :: | : | :: |
| CAR | CAR | CAR | hd | head | .Head |
| CDR | CDR | CDR | tl | tail | .Tail |
| ๋ฆฌ์คํธ ์ฐ๊ฒฐ | append | append | @ | ++ | @ |
์ธ์ด ๊ณ๋ณด
LISP (1958)
โโโ Common Lisp (1984) โ ์ฌ๋ฌ LISP ๋ฐฉ์ธ ํตํฉ, ๋ํ ์ธ์ด
โโโ Scheme (1975) โ ์๊ณ ์์ํ static scope LISP
ML (1973)
โโโ SML (Standard ML)
โโโ OCaml
โ โโโ F# (2005) โ .NET ๊ธฐ๋ฐ, ํจ์ํ+๋ช
๋ นํ+OOP
โโโ Haskell (1990) โ ์์ ํจ์ํ, lazy evaluation
์กฐ๊ฑด๋ฌธ ๋น๊ต
| ์ธ์ด | 2๋ถ๊ธฐ | ๋ค๋ถ๊ธฐ |
|---|---|---|
| Scheme | (IF pred t f) | (COND ...) |
| Common Lisp | (IF pred t f) | (COND ...) |
| ML | if ... then ... else ... | ํจํด ๋งค์นญ |
| Haskell | if ... then ... else ... | guards (|) ๋๋ ํจํด ๋งค์นญ |
| F# | if ... then ... else ... | match ... with |
ํจ์ ์ ์ ๋น๊ต
| ์ธ์ด | ์ฝ๋ |
|---|---|
| Scheme | (DEFINE (square x) (* x x)) |
| Common Lisp | (DEFUN square (x) (* x x)) |
| ML | fun square(x : int) = x * x; |
| Haskell | square x = x * x |
| F# | let square x = x * x |
๋ฆฌ์คํธ ์ฐ์ฐ ๋น๊ต
| ์ฐ์ฐ | Scheme | ML | Haskell | F# |
|---|---|---|---|---|
| ๋น ๋ฆฌ์คํธ | '() | [] | [] | [] |
| ๋ฆฌ์คํธ ๋ฆฌํฐ๋ด | '(1 2 3) | [1, 2, 3] | [1, 2, 3] | [1; 2; 3] |
| ์ฒซ ์์ | (CAR lst) | hd lst | head lst | lst.Head |
| ๋๋จธ์ง | (CDR lst) | tl lst | tail lst | lst.Tail |
| ์์ ์ถ๊ฐ | (CONS x lst) | x :: lst | x : lst | x :: lst |
| ์ด์ด๋ถ์ด๊ธฐ | (append l1 l2) | l1 @ l2 | l1 ++ l2 | l1 @ l2 |
| ๋น ๋ฆฌ์คํธ ๊ฒ์ฌ | (NULL? lst) | lst = [] | null lst | List.isEmpty lst |
map / filter / fold ๋น๊ต
| ์ฐ์ฐ | Scheme | ML | Haskell | F# |
|---|---|---|---|---|
| map | (map f lst) | map f lst | map f lst | List.map f lst |
| filter | (FILTER pred lst) | filter pred lst | filter pred lst | List.filter pred lst |
| fold | (FOLD f base lst) | foldl f base lst | foldr f v lst | List.fold f acc lst |
| lambda | (LAMBDA (x) ...) | fn x => ... | \x -> ... | fun x -> ... |
๊ณตํต ํน์ฑ (๋ชจ๋ FPL)
- first-class function: ํจ์๋ฅผ ๊ฐ์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅ (๋ณ์ ํ ๋น, ์ธ์ ์ ๋ฌ, ๋ฐํ)
- ์ฌ๊ท๋ก ๋ฐ๋ณต ํํ (loop ๋์ )
- referential transparency ์งํฅ: ๊ฐ์ ์ ๋ ฅ โ ํญ์ ๊ฐ์ ์ถ๋ ฅ
- higher-order function ์ง์: map, filter, fold ๋ฑ
ML vs Haskell ํต์ฌ ์ฐจ์ด
| ํญ๋ชฉ | ML | Haskell |
|---|---|---|
| ํ๊ฐ ๋ฐฉ์ | strict (์ฆ์ ํ๊ฐ) | nonstrict (lazy evaluation) |
| ์์์ฑ | ์๋ (side effect ๊ฐ๋ฅ) | ์์ ํจ์ํ |
| ์ค๋ฒ๋ก๋ฉ | ๋ถ๊ฐ (์ด๋ฆ์ ๋ฌ๋ฆฌํด์ผ ํจ) | type class๋ก ์ง์ |
| ๋ฌดํ ๋ฆฌ์คํธ | ๋ถ๊ฐ | ๊ฐ๋ฅ |
| ํจ์ ์ด๋ฆ ๋ฐ๋ณต | | ๊ตฌ๋ถ | ์ค๋ง๋ค ํจ์ ์ด๋ฆ ๋ฐ๋ณต |
Scheme vs Common Lisp ํต์ฌ ์ฐจ์ด
| ํญ๋ชฉ | Scheme | Common Lisp |
|---|---|---|
| ํฌ๊ธฐ | ์๊ณ ๊ฐ๊ฒฐ | ํฌ๊ณ ๋ณต์ก |
| ์ค์ฝํ | static only | static ๊ธฐ๋ณธ, dynamic ์ ํ |
| ๋ณ์ | immutable | mutable (SETF) |
| ๋ฐฐ์ด/๊ตฌ์กฐ์ฒด | ๊ธฐ๋ณธ ๋ฏธ์ง์ | MAKE-ARRAY, DEFSTRUCT |
| ๋ฐ๋ณต๋ฌธ | ์ฌ๊ท๋ง ๊ถ์ฅ | LOOP, DOTIMES, DOLIST |
| ๋งคํฌ๋ก | ๊ธฐ๋ณธ ์ง์ | DEFMACRO๋ก ๊ฐ๋ ฅ ์ง์ |
8. Exception Handling
ํต์ฌ ๊ฐ๋
- exception: ํ๋์จ์ด๋ ์ํํธ์จ์ด๊ฐ ๊ฐ์งํ๋ ๋น์ ์์ /ํน๋ณํ ์ฌ๊ฑด
- exception handler: exception ๋ฐ์ ์ ์คํ๋๋ ์ฒ๋ฆฌ ์ฝ๋
- raising: exception ๋ฐ์์ํค๊ธฐ
- propagation: handler๊ฐ ์์ผ๋ฉด ํธ์ถ์์๊ฒ exception ์ ๋ฌ
- termination: handler ์๋ฃ ํ raising ๋ธ๋ก์ผ๋ก ๋์๊ฐ์ง ์์
- resumption: handler ์๋ฃ ํ raising ์ง์ ์์ ๊ณ์ ์คํ (Ruby์
retry)
์ธ์ด๋ณ Syntax ๋น๊ต
| ์ธ์ด | try ์์ | catch/except | throw/raise | ์ ๋ฆฌ ์ฝ๋ |
|---|---|---|---|---|
| Ada | begin | exception when E => | raise E | ์์ |
| C++ | try | catch(Type e) | throw expr | ์์ |
| Java | try | catch(ExType e) | throw new E() | finally |
| Python | try: | except ExType: | raise E | finally: |
| Ruby | begin | rescue ExType | raise | ensure |
Ada
begin
-- ์ฝ๋
exception
when Constraint_Error =>
Put_Line("๋ฒ์ ์ด๊ณผ");
when Data_Error =>
Put_Line("๋ฐ์ดํฐ ์ค๋ฅ");
when others =>
Put_Line("๊ธฐํ ์ค๋ฅ");
end;
์ฌ์ ์ ์ ์์ธ: Constraint_Error, Program_Error, Storage_Error, Tasking_Error
์ฌ์ฉ์ ์ ์:
My_Error : exception;
raise My_Error;
raise; -- handler ๋ด์์: ๊ฐ์ exception ์ฌ๋ฐ์
exception ๋นํ์ฑํ: pragma Suppress(check_name);
C++
try {
throw 42;
throw MyException("message");
}
catch (int e) {
// int ํ์
exception ์ฒ๋ฆฌ
}
catch (MyException& e) {
// MyException ์ฒ๋ฆฌ
}
catch (...) {
// ๋ชจ๋ ๋๋จธ์ง ์ฒ๋ฆฌ
}
- ์ฌ์ ์ ์ ์์ธ ์์ (ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ธ๋ ์์)
- handler๋ ์์๋๋ก ๋งค์นญ, ๋จผ์ ๋งค์นญ๋ ๊ฒ ์ฌ์ฉ
throw;โ ํ์ฌ exception ์ฌ๋ฐ์
Java
try {
throw new MyException("message");
}
catch (MyException e) {
// ์ฒ๋ฆฌ
}
catch (Exception e) {
// ๋ชจ๋ Exception ํ์ ํด๋์ค ์ฒ๋ฆฌ (๋ง์ง๋ง์)
}
finally {
// ํญ์ ์คํ (์์ธ ์ฌ๋ถ ๋ฌด๊ด)
}
๊ณ์ธต ๊ตฌ์กฐ:
ThrowableโError(JVM ๋ฐ์, ์ฒ๋ฆฌ ๋ถํ์)ThrowableโExceptionโRuntimeException(unchecked)ThrowableโExceptionโ ๊ทธ ์ธ (checked)
checked exception: throws ์ ์ ์ ์ธํ๊ฑฐ๋ ์ง์ ์ฒ๋ฆฌํด์ผ ํจ
void buildDist() throws IOException {
in.readLine(); // IOException ๋ฐ์ ๊ฐ๋ฅ
}
unchecked exception: RuntimeException, Error ํ์ โ ์ปดํ์ผ๋ฌ๊ฐ ๊ฐ์ ํ์ง ์์
Python
try:
raise ValueError("์๋ชป๋ ๊ฐ")
except ValueError as e:
print(e)
except Exception:
pass # ๋ชจ๋ Exception ์ฒ๋ฆฌ
else:
pass # ์์ธ ์์ ๋ ์คํ
finally:
pass # ํญ์ ์คํ
๊ณ์ธต: BaseException โ Exception โ ArithmeticError, LookupError ๋ฑ
Ruby
begin
raise "์๋ฌ ๋ฐ์"
rescue RuntimeError => e
puts e.message
rescue => e
# ๋ชจ๋ StandardError ์ฒ๋ฆฌ
ensure
# ํญ์ ์คํ (Java์ finally)
retry # rescue ๋ธ๋ก ๋ด์์๋ง: raising ์ง์ ๋ถํฐ ์ฌ์คํ
end
9. Polymorphism and OOP
Polymorphism ์ข ๋ฅ
- Ad hoc polymorphism: ์ค๋ฒ๋ก๋ฉ. ๊ฐ ํ์ ๋ง๋ค ๋ณ๋ ๊ตฌํ. ๊ฐ์ ์ด๋ฆ, ๋ค๋ฅธ protocol.
- Subtype polymorphism: ์์ ๊ธฐ๋ฐ. ๋ถ๋ชจ ํ์ ๋ณ์๊ฐ ์์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ.
- Parametric polymorphism: generic. ํ์ ์ ๋งค๊ฐ๋ณ์ํ.
Polymorphic Variable ์ ์ธ ๋ฐฉ๋ฒ (์ธ์ด๋ณ)
C++ (pointer ๊ธฐ๋ฐ, virtual ํ์)
Shape* ptr = new Circle();
ptr->draw(); // virtual์ผ ๋ dynamic binding
Java (reference ๊ธฐ๋ฐ, ๊ธฐ๋ณธ dynamic)
Animal a = new Dog();
a.speak(); // ํญ์ dynamic (final/static/private ์ ์ธ)
C# (virtual + override ํ์)
Shape s = new Circle();
s.Draw(); // virtual + override์ผ ๋ dynamic
Python (ํ์ ์๋ ๋ณ์)
x = Dog()
x.speak()
Ruby (๋ชจ๋ ๋ณ์๊ฐ typeless)
x = Dog.new
x.speak
Smalltalk
x := Dog new.
x speak. "๋ชจ๋ ๋ฉ์์ง๊ฐ dynamic binding"
Dynamic Binding
- ๋ฐํ์์ ์ด๋ค ๋ฉ์๋๊ฐ ํธ์ถ๋ ์ง ๊ฒฐ์
- virtual method table (vtable)์ ํตํด ๊ตฌํ: ๋์ ์ผ๋ก ๋ฐ์ธ๋ฉ๋๋ ๋ฉ์๋ ํฌ์ธํฐ ๋ชฉ๋ก
C++
class Shape {
public:
virtual void draw() = 0; // pure virtual โ abstract class
};
class Circle : public Shape {
public:
void draw() override { ... }
};
Shape* s = new Circle();
s->draw(); // vtable์ ํตํด Circle::draw() ํธ์ถ
stack ํ ๋น ์:
Square sq;
Rectangle rect;
rect = sq; // object slicing: Square์ ์ถ๊ฐ ๋ณ์ ๋ ์๊ฐ
rect.draw(); // Rectangle::draw() ์ ์ ๋ฐ์ธ๋ฉ
Java: final, static, private ๋ฉ์๋๋ static binding, ๋๋จธ์ง๋ ๋ชจ๋ dynamic binding
C#: virtual + override ์กฐํฉ. new ํค์๋๋ ๋ถ๋ชจ ๋ฉ์๋ ์จ๊น (static binding)
Abstract Class vs Interface (Java)
- abstract class:
abstractํค์๋, ์ผ๋ถ ๋ฉ์๋ ๊ตฌํ ๊ฐ๋ฅ, ๋จ์ผ ์์ - interface: ๋ฉ์๋ ์ ์ธ๋ง, ๋ค์ค ๊ตฌํ ๊ฐ๋ฅ, ๋ณ์ ์์ (์์๋ง)
interface Animal { void bark(); }
class Dog implements Animal {
public void bark() { System.out.println("Woof"); }
}
์์ ์ ๊ทผ ์ ์ด (C++)
public์์: ๋ถ๋ชจ์ public/protected ๊ทธ๋๋ก ์ ์ง โ subtype ๊ด๊ณprivate์์: ๋ถ๋ชจ์ ๋ชจ๋ ๋ฉค๋ฒ๊ฐ private โ subtype ๊ด๊ณ ์๋, ๊ตฌํ๋ง ์ฌ์ฌ์ฉ
Ruby Mixin
module Flyable
def fly
puts "flying"
end
end
class Bird
include Flyable # ์ธ์คํด์ค ๋ฉ์๋๋ก ์ถ๊ฐ
end
include: ์ธ์คํด์ค ๋ฉ์๋๋ก ์ฃผ์prepend: ์ธ์คํด์ค ๋ฉ์๋๋ก ์ฃผ์ , ํด๋์ค ์์ ์ ๋ฉ์๋๋ณด๋ค ์ฐ์extend: ํด๋์ค ๋ฉ์๋๋ก ์ฃผ์
ADT ํต์ฌ ๊ฐ๋
- ๋ฐ์ดํฐ์ operation์ ํ๋์ ๋จ์๋ก ๋ฌถ์
- ๋ด๋ถ ํํ ์จ๊น (information hiding)
- getter/setter๋ฅผ ํตํ ๊ฐ์ ์ ๊ทผ
Java ์ ๊ทผ ์ ์ด:
| modifier | ๊ฐ์ ํด๋์ค | ๊ฐ์ ํจํค์ง | ์์ | ์ธ๋ถ |
|---|---|---|---|---|
public | O | O | O | O |
protected | O | O | O | X |
| package-private | O | O | X | X |
private | O | X | X | X |
C# ์ถ๊ฐ: internal (๊ฐ์ assembly), protected internal
10. Generic Subprograms
C++ Template
template <class Type>
Type max(Type first, Type second) {
return first > second ? first : second;
}
max(1, 2); // 2 (int)
max(1.0, 2.0); // 2.0 (double)
- ํนํ๋ ํจ์๊ฐ template๋ณด๋ค ์ฐ์
- ์ฌ๋ฌ ํ์
ํ๋ผ๋ฏธํฐ:
template <class T1, class T2>
Java Generics
public class Stack<T> {
private ArrayList<T> stackRef;
...
}
Stack<Integer> s = new Stack<Integer>();
- primitive type ์ง์ ์ฌ์ฉ ๋ถ๊ฐ โ Integer, Double ๋ฑ wrapper class ์ฌ์ฉ
- wildcard:
Collection<?>โ ์ฝ๊ธฐ ๊ฐ๋ฅ, ์ฐ๊ธฐ ์ ํ
Ada Generic
generic
Max_Size : Positive;
type Elem_Type is private;
package Generic_Stack is
...
end Generic_Stack;
-- ์ธ์คํด์คํ
package Integer_Stack is new Generic_Stack(100, Integer);
Quick Reference
ARI ์ ๊ทผ ํ๊ธฐ
(chain_offset, local_offset)
- chain_offset = 0: ํ์ฌ ์๋ธํ๋ก๊ทธ๋จ์ ์ง์ญ ๋ณ์
- chain_offset = 1: ์ง์ ์์(๋ถ๋ชจ) ์๋ธํ๋ก๊ทธ๋จ์ ๋ณ์
- local_offset: ARI ๋ด ์คํ์ (์ปดํ์ผ ํ์ ๊ฒฐ์ )
Scheme ์ด์ง ํธ๋ฆฌ ํต์ฌ ์ฝ๋
(DEFINE (tree-height t)
(IF (NULL? t)
0
(+ 1 (MAX (tree-height (CADR t))
(tree-height (CADDR t))))))
(DEFINE (count-nodes t)
(IF (NULL? t)
0
(+ 1 (count-nodes (CADR t))
(count-nodes (CADDR t)))))
Haskell foldr ๊ณ์ฐ ๊ณผ์
foldr (+) 0 [1,2,3,4]
= 1 + foldr (+) 0 [2,3,4]
= 1 + (2 + foldr (+) 0 [3,4])
= 1 + (2 + (3 + (4 + 0)))
= 10
foldr (\_ n -> 1+n) 0 [10,20,30]
= 1 + (1 + (1 + 0))
= 3 -- length์ ๋์ผ
Exception Keywords ํ๋์
| ์ธ์ด | try ์์ | catch | throw | ์ ๋ฆฌ |
|---|---|---|---|---|
| Ada | begin | exception when | raise | โ |
| C++ | try | catch | throw | โ |
| Java | try | catch | throw | finally |
| Python | try: | except | raise | finally: |
| Ruby | begin | rescue | raise | ensure |
Ruby ์ถ๊ฐ: retry (์ฌ์๋), Java ์ถ๊ฐ: throws (๋ฉ์๋ ์ ์ธ์ checked exception ๋ช
์)
Semaphore vs Monitor
| ํญ๋ชฉ | Semaphore | Monitor |
|---|---|---|
| ์ถ์ํ ์์ค | ์ ์์ค | ๊ณ ์์ค |
| ์ํธ ๋ฐฐ์ | ์๋ (wait/release) | ์๋ |
| ์ค์ ๊ฐ๋ฅ์ฑ | ๋์ | ๋ฎ์ |
| ํ๋ ฅ ๋๊ธฐํ | ์ง์ ๊ตฌํ | ์ง์ ๊ตฌํ (wait/notify) |
| ๊ตฌํ ๊ด๊ณ | Monitor๋ก ๊ตฌํ ๊ฐ๋ฅ | Semaphore๋ก ๊ตฌํ ๊ฐ๋ฅ |
์ธ์ด๋ณ ๋คํ์ฑ ์ ์ธ ํค์๋
| ์ธ์ด | ๋ถ๋ชจ | ์์ |
|---|---|---|
| C++ | virtual | (์๋) |
| Java | (๊ธฐ๋ณธ virtual) | @Override (์ ํ) |
| C# | virtual | override |
| Python | (๋ชจ๋ virtual) | (์๋) |
| Ruby | (๋ชจ๋ virtual) | (์๋) |

