• Mindscape ๐Ÿ”ฅ
    • Playlist ๐ŸŽง
  • Algorithm

    • 1018๋ฒˆ: ์ฒด์ŠคํŒ ๋‹ค์‹œ ์น ํ•˜๊ธฐ
    • 1966๋ฒˆ: ํ”„๋ฆฐํ„ฐ ํ
    • Python ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ํŒ
    • C++ std::vector ์‚ฌ์šฉ๋ฒ• ์ •๋ฆฌ
    • Vim ์‚ฌ์šฉ ๋งค๋‰ด์–ผ
  • Ubuntu

    • ๋ฆฌ๋ˆ…์Šค ์šฐ๋ถ„ํˆฌ GRUB ํฐํŠธ ๋ณ€๊ฒฝ
    • ์šฐ๋ถ„ํˆฌ ์ด๋ฏธ์ง€ ๋น„๋””์˜ค ์ธ๋„ค์ผ(๋ฏธ๋ฆฌ๋ณด๊ธฐ) ์•ˆ ๋ณด์ž„ ๋ฌธ์ œ ํ•ด๊ฒฐ
    • Wine ํ™˜๊ฒฝ์—์„œ ์นด์นด์˜คํ†ก ์‹คํ–‰ ์‹œ explorer.exe ๋œจ์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ๋ฒ•
    • ์šฐ๋ถ„ํˆฌ Wine ์นด์นด์˜คํ†ก ์‚ฌ์ง„ ์ด๋ฏธ์ง€ ์Šคํฌ๋ฆฐ์ƒท ๋ถ™์—ฌ๋„ฃ๊ธฐ
    • Wine ์นด์นด์˜คํ†ก ์ด๋ชจ์ง€ ๊นจ์ง ๋ฌธ์ œ ํ•ด๊ฒฐ
    • Ubuntu ์œˆ๋„์šฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋„๊ธฐ
  • Wellness

    • ์ฐจ์ „์žํ”ผ (Psyllium Husk)
    • ์—‘์ŠคํŠธ๋ผ ๋ฒ„์ง„ ์˜ฌ๋ฆฌ๋ธŒ์œ  (Extra Virgin Olive Oil)
    • ์ž๊ฐ€๋น„๊ฐ•์„ธ์ฒ™ (Nasal Irrigation)
    • QCY HT08 (MeloBuds Pro Plus)
    • ์ฝ˜์„œํƒ€ (Concerta)
    • ์ธ๋ฐ๋†€ (Inderal)
    • ์„คํŠธ๋ž„๋ฆฐ (Sertraline)
    • ๋ฉœ๋ผํ† ๋‹Œ (Melatonin)
    • ์น˜๊ฒฝ๋ถ€ ๋งˆ๋ชจ์ฆ
    • ๋ฐ”๋ฒจ ์Šค์ฟผํŠธ (Barbell Squat)
  • Humanities

    • Nordvik, Russia
    • North Sentinel Island
    • ๋กฑ๊ณ ๋กฑ๊ณ (Rongorongo)
    • ๋ฐ”๋กœํฌ ์Œ์•… (Baroque Music)
  • Design

    • ๊ตฌ๊ธ€์˜ ์•„์ด์ฝ˜ ๋Œ€๊ฐœํŽธ โ€” 6๋…„ ๋งŒ์˜ ์‹ค์ˆ˜ ์ธ์ •
    • ์ œ๋Ÿด๋“œ ์  ํƒ€ โ€” ๋Ÿญ์…”๋ฆฌ ์Šคํฌ์ธ  ์›Œ์น˜์˜ ์ฐฝ์‹œ์ž
    • ๋ฐ”์šฐํ•˜์šฐ์Šค โ€” ํ˜„๋Œ€ ๋””์ž์ธ์˜ ์›์ 
  • Brands

    • NOMOS Glashรผtte
    • Frรฉdรฉrique Constant
    • KZ (Knowledge Zenith)
    • ์—์ŠคํŠธ๋ผ (AESTURA)
    • JINHAO (้‡‘่ฑช)
    • Herman Miller
    • ๋ฐ์Šค์ปค (DESKER)
    • ๋ฌด์‹ ์‚ฌ ์Šคํƒ ๋‹ค๋“œ (Musinsa Standard)
  • Finance

    • ํ˜„๋Œ€์นด๋“œ ZERO โ€” Edition2 vs Edition3 ๋น„๊ต
    • ์‹ ํ•œ์นด๋“œ ์ฒ˜์Œ
    • S&P 500 ETF ํˆฌ์ž ๊ฐ€์ด๋“œ
    • ํŒŒํ‚นํ†ต์žฅ vs CMA ํ†ต์žฅ
    • ๋ฒ„ํฌ์…” ํ•ด์„œ์›จ์ด (Berkshire Hathaway)
    • ๋น„ํŠธ์ฝ”์ธ(Bitcoin)
  • Products

    • ์˜ค๋””์˜ค ์ธํ„ฐํŽ˜์ด์Šค (Audio Interface)
    • ์ฟ ๋ฃจํ† ๊ฐ€ (KURUTOGA)
    • CX31993 DAC ๋™๊ธ€
    • ํด๋ Œ์ง• ๋ฐ€ํฌ (Cleansing Milk)
    • ํ”ผ์ ฏ ํ† ์ด (Fidget Toy)
    • ThinkPad
  • Programming Languages

    • 8.0. Statement Level Control Structures
    • 8. Subprogram
    • 9. Implementing Subprogram
    • 10.1. Abstract Data Types and Encapsulation Constructs
    • 10.2. Support for Object Oriented Programming
    • 11. Concurrency
    • 12. FPL (1)
    • 13. FPL (2)
    • 14. Exception Handling and Event Handling
    • Final Exam

Final Exam

์ž‘์„ฑ 2026. 6. 12.ยท์ˆ˜์ • 2026. 6. 12.

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 ๋ฐฉ๋ฒ•
Cpass-by-valueํฌ์ธํ„ฐ ์ „๋‹ฌ
C++pass-by-value& (reference), const & (in-mode)
Javapass-by-value๊ฐ์ฒด๋Š” ์ฐธ์กฐ๊ฐ’์„ value๋กœ ์ „๋‹ฌ
C#pass-by-valueref (inout), out (result)
Python/Rubypass-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 addressCaller๋ณต๊ท€ ์œ„์น˜
Dynamic linkCallercaller์˜ ARI๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
Actual parametersCaller์ „๋‹ฌ๋œ ์ธ์ž
Local variablesCallee์ง€์—ญ ๋ณ€์ˆ˜ ๊ณต๊ฐ„
  • EP (Environment Pointer): ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ARI์˜ base๋ฅผ ๊ฐ€๋ฆฌํ‚ด
  • ํ˜ธ์ถœ ์‹œ ํ˜„์žฌ EP๋ฅผ new ARI์— dynamic link๋กœ ์ €์žฅ ํ›„, EP๋ฅผ ์ƒˆ ARI base๋กœ ๋ณ€๊ฒฝ
  • ์ข…๋ฃŒ ์‹œ EP๋ฅผ dynamic link๋กœ ๋ณต์›

Prologue / Epilogue

  • Prologue (Callee, ์‹คํ–‰ ์‹œ์ž‘):

    1. old EP๋ฅผ dynamic link๋กœ ์ €์žฅ
    2. ์ง€์—ญ ๋ณ€์ˆ˜ ๊ณต๊ฐ„ ํ• ๋‹น
  • Epilogue (Callee, ์‹คํ–‰ ์ข…๋ฃŒ):

    1. out-mode ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’ ๋ฐ˜ํ™˜
    2. ํ•จ์ˆ˜ ๋ฐ˜ํ™˜๊ฐ’์„ caller ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์œ„์น˜๋กœ ์ด๋™
    3. stack top์„ EP-1๋กœ ๋ณต์›, EP๋ฅผ dynamic link๋กœ ๋ณต์›
    4. caller ์‹คํ–‰ ์ƒํƒœ ๋ณต์›
    5. 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) ๋ˆ„๋ฝ โ†’ deadlock
  • wait(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๋กœ ๋ฉ”์‹œ์ง€๊ฐ€ ์˜ฌ ๋•Œ๊นŒ์ง€ block
  • select: ์—ฌ๋Ÿฌ 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): ์ง€์ • ์‹œ๊ฐ„ block
  • join(): ํ•ด๋‹น 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 section
  • Monitor ํด๋ž˜์Šค

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);

๋ฆฌ์ŠคํŠธ ์—ฐ์‚ฐ

MLScheme์„ค๋ช…
hdCAR์ฒซ ๋ฒˆ์งธ ์›์†Œ
tlCDR๋‚˜๋จธ์ง€
::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

๊ธฐ๋ณธ ์ •๋ณด

SchemeCommon LispMLHaskell
์ถœ์‹œ1975198419731990
๊ณ„๋ณดLisp ๋ฐฉ์–ธ์—ฌ๋Ÿฌ Lisp ๋ฐฉ์–ธ ํ†ตํ•ฉ๋…๋ฆฝ ์„ค๊ณ„ML ๊ณ„์—ด
ํฌ๊ธฐ์ž‘๊ณ  ๊ฐ„๊ฒฐํฌ๊ณ  ๋ณต์žก์ค‘๊ฐ„์ค‘๊ฐ„
์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•์•„๋‹˜์•„๋‹˜์•„๋‹˜์˜ˆ

ํƒ€์ž… ์‹œ์Šคํ…œ

SchemeCommon LispMLHaskell
ํƒ€์ž… ์‹œ์Šคํ…œuntypeduntypedstrongly typedstrongly typed
ํƒ€์ž… ์ถ”๋ก ์—†์Œ์—†์Œ์žˆ์Œ์žˆ์Œ
ํƒ€์ž… coercion์—†์Œ์—†์Œ์—†์Œ์—†์Œ
์˜ค๋ฒ„๋กœ๋”ฉ์—†์Œ์—†์Œ์—†์Œtype class๋กœ ์ง€์›
๊ธฐ๋ณธ ์ˆซ์ž ํƒ€์ž…ํ†ตํ•ฉ (dynamic)ํ†ตํ•ฉ (dynamic)int / real ๊ตฌ๋ถ„Int / Float ๊ตฌ๋ถ„

์Šค์ฝ”ํ”„ / ๋ณ€์ˆ˜

SchemeCommon LispMLHaskell
์Šค์ฝ”ํ”„static onlystatic ๊ธฐ๋ณธ, dynamic ์„ ํƒstatic onlystatic only
๋™์  ์Šค์ฝ”ํ”„์—†์Œspecial ์„ ์–ธ์œผ๋กœ ๊ฐ€๋Šฅ์—†์Œ์—†์Œ
๋ณ€์ˆ˜ ํŠน์„ฑimmutablemutable (SETF)immutable (val)immutable
์žฌ์ •์˜DEFINE ์žฌํ˜ธ์ถœ๋กœ shadowingSETF๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅval ์žฌ์„ ์–ธ์œผ๋กœ shadowing์žฌ์ •์˜ ๋ถˆ๊ฐ€

ํ‰๊ฐ€ ๋ฐฉ์‹

SchemeCommon LispMLHaskell
ํ‰๊ฐ€ ๋ฐฉ์‹strictstrictstrictnonstrict (lazy)
๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ๋ถˆ๊ฐ€๋ถˆ๊ฐ€๋ถˆ๊ฐ€๊ฐ€๋Šฅ
Tail call ์ตœ์ ํ™”์–ธ์–ด ๋ช…์„ธ์—์„œ ์š”๊ตฌ๊ตฌํ˜„ ์˜์กด๊ตฌํ˜„ ์˜์กด์žˆ์Œ
Side effect๊ฐ€๋Šฅ (set!, I/O)๊ฐ€๋Šฅ (SETF, I/O)๊ฐ€๋Šฅ (ref, I/O)IO ๋ชจ๋‚˜๋“œ๋กœ๋งŒ ํ—ˆ์šฉ

๋ฌธ๋ฒ• โ€” ํ•จ์ˆ˜ ์ •์˜

SchemeCommon LispMLHaskell
ํ•จ์ˆ˜ ์ •์˜(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 ์—ฐ์‚ฐ์ž. ์—ฐ์‚ฐ์ž
์ฃผ์„;;(* ... *)-- ๋˜๋Š” {- -}

๋ฌธ๋ฒ• โ€” ์กฐ๊ฑด๋ฌธ

SchemeCommon LispMLHaskell
2๋ถ„๊ธฐ(IF pred t f)(IF pred t f)if ... then ... else ...if ... then ... else ...
๋‹ค๋ถ„๊ธฐ(COND ...)(COND ...)ํŒจํ„ด ๋งค์นญguards (`
๊ธฐ๋ณธ๊ฐ’ (else)(ELSE ...)(T ...)ํŒจํ„ด์˜ ๋งˆ์ง€๋ง‰ ์ ˆotherwise

๋ฌธ๋ฒ• โ€” ๋ฆฌ์ŠคํŠธ ์—ฐ์‚ฐ

์—ฐ์‚ฐSchemeCommon LispMLHaskell
๋ฆฌ์ŠคํŠธ ๋ฆฌํ„ฐ๋Ÿด'(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 :: lstx : lst
CAR (์ฒซ ์›์†Œ)(CAR lst)(CAR lst)hd lsthead lst
CDR (๋‚˜๋จธ์ง€)(CDR lst)(CDR lst)tl lsttail lst
๋ฆฌ์ŠคํŠธ ์—ฐ๊ฒฐ(append l1 l2)(append l1 l2)l1 @ l2l1 ++ l2
๊ธธ์ด(length lst)(length lst)length lstlength lst

๋ฌธ๋ฒ• โ€” ๊ณ ์ฐจ ํ•จ์ˆ˜

์—ฐ์‚ฐSchemeCommon LispMLHaskell
map(map f lst)(mapcar f lst)map f lstmap f lst
filter(FILTER pred lst)(remove-if-not pred lst)filter pred lstfilter pred lst
fold(FOLD f base lst)(reduce f lst)foldl f base lstfoldr f v lst

๋ฌธ๋ฒ• โ€” ์ง€์—ญ ๋ฐ”์ธ๋”ฉ

SchemeCommon LispMLHaskell
์ง€์—ญ ๋ฐ”์ธ๋”ฉ(LET ((x 1)) ...)(LET ((x 1)) ...)let val x=1 in ... endlet x=1 in ...
ํ•จ์ˆ˜ ์•„๋ž˜ ์ •์˜์—†์Œ์—†์Œ์—†์Œwhere ๊ตฌ๋ฌธ
ํ‘œํ˜„์‹ ์•ˆ ์ •์˜LETLETlet ... in ... endlet ... in ...

๋ถˆ๋ฆฌ์–ธ

SchemeCommon LispMLHaskell
์ฐธ#TTtrueTrue
๊ฑฐ์ง“#FNILfalseFalse
AND(AND ...)(AND ...)andalso&&
OR(OR ...)(OR ...)orelse`
NOT(NOT ...)(NOT ...)notnot

์˜ˆ์™ธ ์ฒ˜๋ฆฌ

SchemeCommon LispMLHaskell
์˜ˆ์™ธ ์ •์˜๊ตฌํ˜„ ์˜์กด(define-condition ...)exception Edata MyE = ...
์˜ˆ์™ธ ๋ฐœ์ƒ(raise ...)(error ...)raise Ethrow e
์˜ˆ์™ธ ์ฒ˜๋ฆฌ(with-exception-handler ...)(handler-case ...)handle E => ...catch action handler
์ •๋ฆฌ ์ฝ”๋“œ๊ตฌํ˜„ ์˜์กด(unwind-protect ...)์—†์Œbracket ํŒจํ„ด

ํ™•์žฅ ๊ธฐ๋Šฅ

SchemeCommon LispMLHaskell
๋งคํฌ๋กœdefine-syntax (hygienic)DEFMACRO (๊ฐ•๋ ฅ)์—†์ŒTemplate Haskell (๋ณ„๋„)
๋ฐฐ์—ด์—†์Œ (๊ธฐ๋ณธ)MAKE-ARRAYarray ํƒ€์ž…Data.Array (๋ณ„๋„)
๊ตฌ์กฐ์ฒด์—†์Œ (๊ธฐ๋ณธ)DEFSTRUCTrecord ํƒ€์ž…data ํƒ€์ž…
๋ฐ˜๋ณต๋ฌธ์—†์Œ (์žฌ๊ท€๋งŒ)LOOP, DOTIMES, DOLIST์—†์Œ (์žฌ๊ท€๋งŒ)์—†์Œ (์žฌ๊ท€๋งŒ)
Currying์ˆ˜๋™ (LAMBDA ์ค‘์ฒฉ)์ˆ˜๋™์ž๋™ (์‰ผํ‘œ ์—†์ด)์ž๋™

ํ•œ ๋ฌธ์žฅ ์š”์•ฝ

์š”์•ฝ
Scheme์ž‘๊ณ  ์ˆœ์ˆ˜ํ•œ Lisp. ๋žŒ๋‹ค ๊ณ„์‚ฐ๋ฒ•์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ฏธ๋‹ˆ๋ฉ€ํ•œ ์„ค๊ณ„.
Common Lisp๊ธฐ๋Šฅ์ด ํ’๋ถ€ํ•œ ์‹ค์šฉ Lisp. ๋ช…๋ นํ˜•๊ณผ ํ•จ์ˆ˜ํ˜•์ด ํ˜ผ์žฌ.
MLํ•จ์ˆ˜ํ˜• ๊ธฐ๋ฐ˜์˜ ์ •์  ํƒ€์ž… ์–ธ์–ด. ํƒ€์ž… ์ถ”๋ก ๊ณผ ํŒจํ„ด ๋งค์นญ์ด ํ•ต์‹ฌ.
Haskell์œ ์ผํ•œ ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•. lazy evaluation, ๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ, type class.

ํ•ต์‹ฌ ํŠน์„ฑ ๋น„๊ต

ํ•ญ๋ชฉSchemeCommon LispMLHaskellF#
์Šค์ฝ”ํ”„staticstatic (๊ธฐ๋ณธ) / dynamic ์„ ํƒstaticstaticstatic
ํƒ€์ž… ์‹œ์Šคํ…œuntypeduntypedstrongly typedstrongly typedstrongly typed
ํƒ€์ž… ์ถ”๋ก ์—†์Œ์—†์Œ์žˆ์Œ์žˆ์Œ์žˆ์Œ
ํƒ€์ž… coercion์—†์Œ์—†์Œ์—†์Œ์—†์Œ์—†์Œ
๋ณ€์ˆ˜immutablemutable ๊ฐ€๋Šฅ (SETF)immutable (val)immutableimmutable (๊ธฐ๋ณธ) / mutable ์„ ํƒ
์˜ค๋ฒ„๋กœ๋”ฉ์—†์Œ์—†์Œ์—†์Œtype class๋กœ ์ง€์›inline์œผ๋กœ ํ‰๋‚ด
ํŒจํ„ด ๋งค์นญCOND/IFCOND/IF์žˆ์Œ์žˆ์Œ์žˆ์Œ (match)
Lazy evaluation์—†์Œ (strict)์—†์Œ (strict)์—†์Œ (strict)๊ธฐ๋ณธ (nonstrict)์„ ํƒ์  (seq)
์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•์•„๋‹˜ (side effect ๊ฐ€๋Šฅ)์•„๋‹˜์•„๋‹˜์˜ˆ์•„๋‹˜
์žฌ๊ท€ ํ‚ค์›Œ๋“œ์—†์Œ (DEFINE์œผ๋กœ ์ž๋™)์—†์Œ (DEFUN์œผ๋กœ ์ž๋™)์—†์Œ (์ž๋™)์—†์Œ (์ž๋™)rec ํ•„์š”
๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ๋ถˆ๊ฐ€๋ถˆ๊ฐ€๋ถˆ๊ฐ€๊ฐ€๋Šฅseq๋กœ ๊ฐ€๋Šฅ
ํ•จ์ˆ˜ ํ•ฉ์„ฑcompose ์ง์ ‘ ์ •์˜์ง์ ‘ ์ •์˜o ์—ฐ์‚ฐ์ž. ์—ฐ์‚ฐ์ž>> ์—ฐ์‚ฐ์ž
LambdaLAMBDALAMBDAfn\x ->fun
๋ฆฌ์ŠคํŠธ ๊ตฌ๋ถ„์ž๊ณต๋ฐฑ (1 2 3)๊ณต๋ฐฑ (1 2 3)์‰ผํ‘œ [1, 2, 3]์‰ผํ‘œ [1, 2, 3]์„ธ๋ฏธ์ฝœ๋ก  [1; 2; 3]
CONSCONSCONS:::::
CARCARCARhdhead.Head
CDRCDRCDRtltail.Tail
๋ฆฌ์ŠคํŠธ ์—ฐ๊ฒฐappendappend@++@

์–ธ์–ด ๊ณ„๋ณด

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 ...)
MLif ... then ... else ...ํŒจํ„ด ๋งค์นญ
Haskellif ... then ... else ...guards (|) ๋˜๋Š” ํŒจํ„ด ๋งค์นญ
F#if ... then ... else ...match ... with

ํ•จ์ˆ˜ ์ •์˜ ๋น„๊ต

์–ธ์–ด์ฝ”๋“œ
Scheme(DEFINE (square x) (* x x))
Common Lisp(DEFUN square (x) (* x x))
MLfun square(x : int) = x * x;
Haskellsquare x = x * x
F#let square x = x * x

๋ฆฌ์ŠคํŠธ ์—ฐ์‚ฐ ๋น„๊ต

์—ฐ์‚ฐSchemeMLHaskellF#
๋นˆ ๋ฆฌ์ŠคํŠธ'()[][][]
๋ฆฌ์ŠคํŠธ ๋ฆฌํ„ฐ๋Ÿด'(1 2 3)[1, 2, 3][1, 2, 3][1; 2; 3]
์ฒซ ์›์†Œ(CAR lst)hd lsthead lstlst.Head
๋‚˜๋จธ์ง€(CDR lst)tl lsttail lstlst.Tail
์•ž์— ์ถ”๊ฐ€(CONS x lst)x :: lstx : lstx :: lst
์ด์–ด๋ถ™์ด๊ธฐ(append l1 l2)l1 @ l2l1 ++ l2l1 @ l2
๋นˆ ๋ฆฌ์ŠคํŠธ ๊ฒ€์‚ฌ(NULL? lst)lst = []null lstList.isEmpty lst

map / filter / fold ๋น„๊ต

์—ฐ์‚ฐSchemeMLHaskellF#
map(map f lst)map f lstmap f lstList.map f lst
filter(FILTER pred lst)filter pred lstfilter pred lstList.filter pred lst
fold(FOLD f base lst)foldl f base lstfoldr f v lstList.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 ํ•ต์‹ฌ ์ฐจ์ด

ํ•ญ๋ชฉMLHaskell
ํ‰๊ฐ€ ๋ฐฉ์‹strict (์ฆ‰์‹œ ํ‰๊ฐ€)nonstrict (lazy evaluation)
์ˆœ์ˆ˜์„ฑ์•„๋‹˜ (side effect ๊ฐ€๋Šฅ)์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•
์˜ค๋ฒ„๋กœ๋”ฉ๋ถˆ๊ฐ€ (์ด๋ฆ„์„ ๋‹ฌ๋ฆฌํ•ด์•ผ ํ•จ)type class๋กœ ์ง€์›
๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ๋ถˆ๊ฐ€๊ฐ€๋Šฅ
ํ•จ์ˆ˜ ์ด๋ฆ„ ๋ฐ˜๋ณต| ๊ตฌ๋ถ„์ค„๋งˆ๋‹ค ํ•จ์ˆ˜ ์ด๋ฆ„ ๋ฐ˜๋ณต

Scheme vs Common Lisp ํ•ต์‹ฌ ์ฐจ์ด

ํ•ญ๋ชฉSchemeCommon Lisp
ํฌ๊ธฐ์ž‘๊ณ  ๊ฐ„๊ฒฐํฌ๊ณ  ๋ณต์žก
์Šค์ฝ”ํ”„static onlystatic ๊ธฐ๋ณธ, dynamic ์„ ํƒ
๋ณ€์ˆ˜immutablemutable (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/exceptthrow/raise์ •๋ฆฌ ์ฝ”๋“œ
Adabeginexception when E =>raise E์—†์Œ
C++trycatch(Type e)throw expr์—†์Œ
Javatrycatch(ExType e)throw new E()finally
Pythontry:except ExType:raise Efinally:
Rubybeginrescue ExTyperaiseensure

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๊ฐ™์€ ํด๋ž˜์Šค๊ฐ™์€ ํŒจํ‚ค์ง€์ƒ์†์™ธ๋ถ€
publicOOOO
protectedOOOX
package-privateOOXX
privateOXXX

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 ์‹œ์ž‘catchthrow์ •๋ฆฌ
Adabeginexception whenraiseโ€”
C++trycatchthrowโ€”
Javatrycatchthrowfinally
Pythontry:exceptraisefinally:
Rubybeginrescueraiseensure

Ruby ์ถ”๊ฐ€: retry (์žฌ์‹œ๋„), Java ์ถ”๊ฐ€: throws (๋ฉ”์„œ๋“œ ์„ ์–ธ์— checked exception ๋ช…์‹œ)

Semaphore vs Monitor

ํ•ญ๋ชฉSemaphoreMonitor
์ถ”์ƒํ™” ์ˆ˜์ค€์ €์ˆ˜์ค€๊ณ ์ˆ˜์ค€
์ƒํ˜ธ ๋ฐฐ์ œ์ˆ˜๋™ (wait/release)์ž๋™
์‹ค์ˆ˜ ๊ฐ€๋Šฅ์„ฑ๋†’์Œ๋‚ฎ์Œ
ํ˜‘๋ ฅ ๋™๊ธฐํ™”์ง์ ‘ ๊ตฌํ˜„์ง์ ‘ ๊ตฌํ˜„ (wait/notify)
๊ตฌํ˜„ ๊ด€๊ณ„Monitor๋กœ ๊ตฌํ˜„ ๊ฐ€๋ŠฅSemaphore๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

์–ธ์–ด๋ณ„ ๋‹คํ˜•์„ฑ ์„ ์–ธ ํ‚ค์›Œ๋“œ

์–ธ์–ด๋ถ€๋ชจ์ž์‹
C++virtual(์ž๋™)
Java(๊ธฐ๋ณธ virtual)@Override (์„ ํƒ)
C#virtualoverride
Python(๋ชจ๋‘ virtual)(์ž๋™)
Ruby(๋ชจ๋‘ virtual)(์ž๋™)
์ตœ๊ทผ ์ˆ˜์ •: 26. 6. 12. ์˜คํ›„ 3:28
Contributors: kmbzn, Claude Sonnet 4.6
Prev
14. Exception Handling and Event Handling

BUILT WITH

CloudflareNode.jsGitHubGitVue.jsJavaScriptVSCodenpm

All trademarks and logos are property of their respective owners.
ยฉ 2026 kmbzn ยท MIT License