λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
끄적끄적

ν•¨μˆ˜ν˜•μ€ μ™œ ν•¨μˆ˜μ§€ν–₯ν˜•μ΄ μ•„λ‹Œ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ΄λΌκ³  ν• κΉŒ?

by mingzoo 2024. 7. 2.

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°, μ™œ 'ν•¨μˆ˜μ§€ν–₯ν˜•'이 μ•„λ‹κΉŒ?

객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ€ 'Object-Oriented Programming'의 λ²ˆμ—­μ΄λ‹€. μ—¬κΈ°μ„œ 'Oriented'κ°€ '지ν–₯'으둜 λ²ˆμ—­λ˜μ–΄ μš°λ¦¬λŠ” '객체지ν–₯'이라 λΆ€λ₯Έλ‹€. 그런데 'Functional Programming'은 μ™œ 'ν•¨μˆ˜μ§€ν–₯ν˜•'이 μ•„λ‹Œ 'ν•¨μˆ˜ν˜•'일까?

κ°‘μžκΈ° λ“  의문인데, μ²˜μŒμ—λŠ” λ‹¨μˆœνžˆ λ²ˆμ—­μ˜ 차이라고 μƒκ°ν–ˆλ‹€. ν•˜μ§€λ§Œ 이λ₯Ό μ°Ύμ•„λ³΄λ©΄μ„œ ν₯미둜운 λ‚΄μš©λ“€μ„ λ°œκ²¬ν•  수 μžˆμ—ˆλ‹€.

차이점

  1. '지ν–₯'의 의미
    • '지ν–₯(ζŒ‡ε‘)'은 "μ–΄λ–€ λͺ©ν‘œλ‘œ λœ»μ΄λ‚˜ λ°©ν–₯을 ν–₯함"을 μ˜λ―Έν•œλ‹€.
    • 객체지ν–₯은 ν”„λ‘œκ·Έλž˜λ°μ˜ 쀑심을 '객체'에 두고, 이λ₯Ό ν–₯ν•΄ λ‚˜μ•„κ°€λŠ” 방법둠이닀.
  2. 'ν˜•'의 의미
    • 'ν˜•(εž‹)'은 "μƒκΉ€μƒˆλ‚˜ λͺ¨μ–‘"을 μ˜λ―Έν•œλ‹€.
    • ν•¨μˆ˜ν˜•μ€ μˆ˜ν•™μ  ν•¨μˆ˜λ₯Ό λ°”νƒ•μœΌλ‘œ ν•œ ν”„λ‘œκ·Έλž˜λ°μ˜ ν•œ 'ν˜•νƒœ'λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

순수 ν•¨μˆ˜λž€?

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œ κ°€μž₯ μ€‘μš”ν•œ κ°œλ… 쀑 ν•˜λ‚˜κ°€ λ°”λ‘œ '순수 ν•¨μˆ˜(Pure Function)'λ‹€. 순수 ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό 같은 νŠΉμ§•μ„ 가진닀:

  1. 같은 μž…λ ₯에 λŒ€ν•΄ 항상 같은 좜λ ₯을 λ°˜ν™˜ν•œλ‹€.
  2. μ™ΈλΆ€ μƒνƒœλ₯Ό λ³€κ²½ν•˜μ§€ μ•ŠλŠ”λ‹€. (λΆ€μˆ˜ νš¨κ³Όκ°€ μ—†μŒ)

예λ₯Ό λ“€μ–΄λ³΄μž:

// 순수 ν•¨μˆ˜μ˜ 예
function add(a, b) {
    return a + b;
}

// 순수 ν•¨μˆ˜κ°€ μ•„λ‹Œ 예
let total = 0;
function addToTotal(a) {
    total += a;  // μ™ΈλΆ€ λ³€μˆ˜λ₯Ό 변경함
    return total;
}

add ν•¨μˆ˜λŠ” 순수 ν•¨μˆ˜λ‹€. μž…λ ₯κ°’ a와 bκ°€ κ°™λ‹€λ©΄ 항상 같은 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•œλ‹€.
반면 addToTotal ν•¨μˆ˜λŠ” μ™ΈλΆ€ λ³€μˆ˜ total을 λ³€κ²½ν•˜λ―€λ‘œ 순수 ν•¨μˆ˜κ°€ μ•„λ‹ˆλ‹€.

객체지ν–₯ vs ν•¨μˆ˜ν˜•

같은 κΈ°λŠ₯을 κ΅¬ν˜„ν•  λ•Œ 두 νŒ¨λŸ¬λ‹€μž„μ€ μ–΄λ–»κ²Œ λ‹€λ₯Έμ§€ κ°„λ‹¨ν•œ μž₯λ°”κ΅¬λ‹ˆ 계산 μ˜ˆμ‹œλ₯Ό 톡해 μ‚΄νŽ΄λ³΄μž:

// 객체지ν–₯적 μ ‘κ·Ό
class ShoppingCart {
    constructor() {
        this.items = [];
    }

    addItem(item) {
        this.items.push(item);
    }

    calculateTotal() {
        return this.items.reduce((sum, item) => sum + item.price, 0);
    }

    applyDiscount(discount) {
        this.items.forEach(item => {
            item.price = item.price * (1 - discount);
        });
    }
}

// μ‚¬μš© μ˜ˆμ‹œ
const cart = new ShoppingCart();
cart.addItem({ name: "μ±…", price: 15000 });
cart.applyDiscount(0.1);
console.log(cart.calculateTotal());

// ν•¨μˆ˜ν˜• μ ‘κ·Ό
const addItem = (cart, item) => [...cart, item];

const calculateTotal = (items) => 
    items.reduce((sum, item) => sum + item.price, 0);

const applyDiscount = (items, discount) => 
    items.map(item => ({
        ...item,
        price: item.price * (1 - discount)
    }));

// μ‚¬μš© μ˜ˆμ‹œ
let items = [];
items = addItem(items, { name: "μ±…", price: 15000 });
const discountedItems = applyDiscount(items, 0.1);
console.log(calculateTotal(discountedItems));

μœ„ μ½”λ“œμ—μ„œ λ³Ό 수 μžˆλ“―μ΄

  • 객체지ν–₯μ—μ„œλŠ” μž₯λ°”κ΅¬λ‹ˆλΌλŠ” '객체'κ°€ μƒνƒœλ₯Ό 가지고, κ·Έ μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” λ©”μ„œλ“œλ“€μ„ 가진닀.
  • ν•¨μˆ˜ν˜•μ—μ„œλŠ” 순수 ν•¨μˆ˜λ“€μ΄ λΆˆλ³€μ„±(immutability)을 지킀며 μƒˆλ‘œμš΄ 값을 λ°˜ν™˜ν•œλ‹€.

 

μ™œ 'ν•¨μˆ˜ν˜•'일까?

μ΄λŠ” λ‹¨μˆœν•œ λ²ˆμ—­μ˜ 차이가 μ•„λ‹ˆμ—ˆλ‹€. ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ 본질적인 νŠΉμ„±κ³Ό 관련이 μžˆμ—ˆλ‹€.

  1. μˆ˜ν•™μ  ν•¨μˆ˜μ˜ νŠΉμ„± 반영
    • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μˆ˜ν•™μ˜ ν•¨μˆ˜ κ°œλ…μ„ κ·ΈλŒ€λ‘œ μ°¨μš©ν–ˆλ‹€.
    • μž…λ ₯이 κ°™μœΌλ©΄ 항상 같은 좜λ ₯이 λ‚˜μ˜€λŠ” μˆœμˆ˜ν•¨μˆ˜μ˜ νŠΉμ„±μ„ λ°˜μ˜ν•œλ‹€.
  2. ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ˜ 본질
    • 객체지ν–₯은 객체λ₯Ό μ€‘μ‹¬μœΌλ‘œ '지ν–₯'ν•˜λŠ” 방법둠이닀.
    • 반면 ν•¨μˆ˜ν˜•μ€ ν”„λ‘œκ·Έλž¨ μžμ²΄κ°€ ν•¨μˆ˜λ“€μ˜ μ§‘ν•©μ΄λΌλŠ” ν˜•νƒœλ₯Ό λˆλ‹€.

etc

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ μ—­μ‚¬λŠ” 객체지ν–₯보닀 더 μ˜€λž˜λ˜μ—ˆλ‹€κ³  ν•œλ‹€.
1950λ…„λŒ€ LISPλΌλŠ” μ–Έμ–΄λΆ€ν„° μ‹œμž‘λœ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€, μˆ˜ν•™μ  ν˜•νƒœ(mathematical form)λ₯Ό κ·ΈλŒ€λ‘œ ν”„λ‘œκ·Έλž˜λ°μ— μ μš©ν•˜λ € ν–ˆλ˜ μ‹œλ„μ˜€λ‹€.

 


 

이 글은 κ³΅λΆ€ν•˜λ©΄μ„œ μ΄ν•΄ν•œ λ‚΄μš©μ„ μ •λ¦¬ν•œ κ²ƒμœΌλ‘œ, 더 μ •ν™•ν•œ λ‚΄μš©μ΄λ‚˜ λ‹€λ₯Έ 의견이 μžˆλ‹€λ©΄ λŒ“κΈ€λ‘œ μ•Œλ €μ£Όμ„Έμš”.

728x90