본문 바로가기
Dev/etc

함수형 프로그래밍

by 펭귄안에 온천 2023. 2. 23.
728x90
반응형

함수형 프로그래밍을 살펴보기 이전에 간단하게 객체지향 프로그래밍을 먼저

 

프로그래밍 패러다임 ( Programming Paradigm )

프로그래머에게 프로그래밍의 관점을 갖게하고 코드를 어떻게 작성할 것인지를 결정하는 역할을 한다.

 

 

객체지향 프로그래밍 ( Object-Oriented Programming, OOP )

프로그래밍 패러다임중 하나로 이 패러다임에서 모든 것이 객체(Object)로 표현된며

객체는 상태(State)와 행동(BeHavior)로 이루어 져 있다.

즉, 어떤 객체가 어떤 상태를 가지고 그 상태에 따라서 행동을 하는 것이다.

 

객체지향 프로그래밍에서는 클래스라는 개념을 이용해서 객체를 만든다.

클래스는 객체가 가지는 상태와 행동을 정의한다.

 

객체지향에서는 객체들 간의 상호작용이 중요한데 이를 위해서 상속, 다형성등이 이용되며

 

객체지향 프로그래밍은 재사용성과 유지보수성이 높은 코드를 작성하는데 적합하다.

 

// 클래스 정의
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  // 메서드 정의
  sayHello() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
}

// 인스턴스 생성
const person1 = new Person('John', 30);
const person2 = new Person('Jane', 25);

// 메서드 호출
person1.sayHello(); // 출력: Hello, my name is John and I'm 30 years old.
person2.sayHello(); // 출력: Hello, my name is Jane and I'm 25 years old.

 

 

 

함수형 프로그래밍 ( Functional Programming )

프로그램을 함수의 조합으로 만드는 방법을 중심으로 한다.

함수평 프로그래밍에서는 상태변화를 최소화하거나 없애고, 부작용(side effect)를 제거하는 것을 중요하게 생각한다.

 

FP에서는 함수가 값(value)처럼 취급된다. 즉 함수를 변수에 저장하거나 인자로 담아 다른 함수로 전달하거나

함수의 반환값으로도 함수를 반환 할 수 있다.

 

FP에서는 상태 변경을 허용하지 않는 것이 가장 중요한 특징이다.

이를 위해 불편성을 강조한다.

즉, 데이터가 한 번 생성되면 그 값이 바뀌지 않도록 보장하며 이를 통해 프로그램의 안정성을 높일 수 있다.

 

또한 순수함수를 중심으로 프로그램을 작성하므로 함수의 실행 순서나 실행 시점이 중요하지 않다.

이는 병렬처리와 분산 처리에 매우 유용하며 함수형 프로그래밍은 병렬처리, 분산 처리에 매우 적합하다.

 

 

부작용(side effect)

  • 변수의 값이 변경됨
  • 자료 구조를 제자리에서 수정함
  • 객체의 필드값을 설정함
  • 예외나 오류가 발생하여 실행이 중단됨

순수함수 : 위의 부작용을 제거한 함수를 순수함수라고 한다.

  • 함수의 실행이 외부에 영향을 끼치지 않는 함수(독립적)
  • 함수가 독립적이므로 부작용이 없기 때문에 쓰레드에 안정성을 보장받을 수 있다.
  • 쓰레드의 안정성을 보장받아 병렬처리를 동기화 없이 진행할 수 있다.
  • Memory or I/O의 관점에서 부작용이 없는 함수
// 순수 함수
function add(a, b) {
  return a + b;
}

// 부작용이 있는 함수  변수 x의 값이 increment()때문에 망가짐
let x = 0;
function increment() {
  x++;
}

불변성

// 배열의 push 메소드는 원본 배열을 변경합니다.
let arr1 = [1, 2, 3];
arr1.push(4); // arr1 = [1, 2, 3, 4]

// concat 메소드는 새로운 배열을 반환합니다.
let arr2 = [1, 2, 3];
let arr3 = arr2.concat(4); // arr2 = [1, 2, 3], arr3 = [1, 2, 3, 4]

 

고차함수

// 함수를 인자로 받는 고차 함수
function twice(f) {
  return function(x) {
    return f(f(x));
  };
}

let addTen = function(x) {
  return x + 10;
};
let result = twice(addTen)(3); // result = 23

// 함수를 반환하는 고차 함수
function multiplyBy(x) {
  return function(y) {
    return x * y;
  };
}

let multiplyByFive = multiplyBy(5);
let result = multiplyByFive(3); // result = 15

 

function start(car) {
  console.log('자동차 시동');

  return { ...car, power: true };
}

function moveTo(car, position) {
  console.log(`자동차 이동 = 현재 위치: {${car.position}}`);

  if (!car.power) {
    console.log('자동차의 시동이 꺼져있습니다.');
    return;
  }

  const newPosition = car.position + position;
  console.log(`자동차 이동 = 이동 위치: {${newPosition}}`);

  return { ...car, position: newPosition };
}

let car = { power: false, position: 0 };
car = start(car);
car = moveTo(car, 10);

 

OOP vs FP

// 객체지향 프로그래밍
car.start();
car.moveTo(10);

// 함수형 프로그래밍
start(car);
moveTo(car, 10);

객체지향 프로그래밍은 데이터와 해당 데이터를 조작하는 동작을 하나의 단위인 객체로 묶는 것입니다.

객체는 상태와 행동을 가지고 있으며, 다른 객체와 상호작용할 수 있습니다.

이 패러다임의 목표는 복잡한 시스템을 구성하고 유지보수하기 쉬운 모듈화된 코드를 작성하는 것입니다.

 

 

반면에,

함수형 프로그래밍은 데이터를 변경하지 않고 입력과 출력 사이의 관계에 초점을 맞춥니다.

함수형 프로그래밍에서 함수는 순수하며, 동일한 입력에 대해 항상 동일한 출력을 반환합니다.

이러한 함수를 조합하여 복잡한 동작을 구성하는 것이 함수형 프로그래밍의 목표입니다.

이 패러다임은 코드의 가독성과 재사용성을 높이며, 멀티스레드 환경에서 안전한 코드를 작성하는 데 도움을 줍니다.

 

따라서

객체지향 프로그래밍은 객체 간의 관계를 중심으로 한 반면,

함수형 프로그래밍은 함수 간의 관계를 중심으로 합니다. 

반응형