코딩 공부/React

[React] 3.1 함수형이란 무엇인가? - 가온 코딩

Cosmic-dust 2022. 7. 25. 13:08
728x90
반응형

함수형 프로그래밍이라는 개념은 1930년대에 발명된 람다 계산법(lambda calculus)이 시작이라 할 수 있다.

17세기 함수가 등장한 이래 함수는 계속해서 계산법(calculus)의 일부였다. 함수를 함수에 넘기거나 함수가 함수를 결과로 내놓는 것도 가능하다. 다른 함수를 조작하고, 함수를 인자로 받거나 반환하는 것이 가능한 복잡한 함수를 고차 함수(high order function)라고 부른다. 1930년대에 알론조 처치(Alonzo Church)는 미국 프린스턴 대학교에서 람다 계산법을 발명하고, 고차 함수를 활용한 여러 가지 연구를 진행했다.

1950년대 말 존 맥카시(John McCarthy)는 람다 계산법에서 비롯된 개념을 활용해 새로운 프로그래밍 언어를 만들었는데, 바로 그 언어가 리스프(Lisp)이다. 리스프는 고차 함수라는 개념과 함수가 1급 시민(first class citizen) 혹은 1급 멤버(first class member)라는 개념을 구현했다. 함수가 1급 시민이 되려면 변수에 함수를 대입할 수 있고, 함수를 다른 함수에 인자로 넘길 수 있으며, 함수에서 함수를 만들어서 반환할 수 있어야 한다.

 

이번 글에서는 함수형 프로그래밍의 핵심 개념을 몇 가지 살펴보고 자바스크립트에서 함수형 기법을 구현하는 방법을 알아볼 것이다.

 

함수형이란 무엇인가?

자바스크립트에서는 함수가 1급 시민이기 때문에, 자바스크립트가 함수형 프로그래밍을 지원한다고 말할 수 있다. 1급 시민이라는 말은 정수나 문자열 같은 다른 일반적인 값과 마찬가지로 함수를 취급할 수 있다는 뜻이다. 최신 자바스크립트에는 함수형 프로그래밍 기법을 더 풍부하게 해주는 화살표 함수, 프라미스, 스프레드 연산자 등의 개선이 추가되었다.

 

1. Functions as Variables(함수 기능)

자바스크립트에서는 함수가 애플리케이션의 데이터를 표현할 수도 있다. 문자열이나 수, 또는 다른 모든 값과 마찬가지로 var 키워드를 사용해서 함수를 정의할 수 있다.

    var log = function(message) {
      console.log(message)
    };

    log("자바스크립트에서는 함수를 변수에 넣을 수 있습니다.");
    
    // 자바스크립트에서는 함수를 변수에 넣을 수 있습니다.
 var log = function(message) {
      console.log(message)
    }

    log("In JavaScript functions are variables")

 

2. Arrow Functions(화살표 함수)

화살표 함수를 사용해 같은 함수를 정의할 수 있다. 함수형 프로그래머들은 작은 함수를 아주 많이 작성하기 때문에 화살표 함수 구문을 사용할 수 있으면 훨씬 더 코딩이 간편해진다.

  const log = message => console.log(message)

    log("ES6 화살표 함수")	// ES6 화살표 함수

1, 2 두 문장은 같은 일을 한다. 두 문장 다 함수를 log라는 변수에 넣는다. 추가로 2에서는 const 키워드를 사용했기 때문에 log를 덮어쓰지 못하게 막아준다.

 

3. Object Methods(개체 메서드)

함수를 변수에 넣을 수 있는 것과 마찬가지로, 함수를 객체에 넣을 수도 있다.

const obj = {
    message: "함수를 다른 값과 마찬가지로 객체에 추가할 수도 있습니다.",
    log(message) {
        console.log(message);
    }
}

obj.log(obj.message); // 함수를 다른 값과 마찬가지로 객체에 추가할 수도 있습니다.
    const obj = {
        message: "They can be added to objects like variables",
        log(message) {
            console.log(message)
        }
    }

    obj.log(obj.message)

 

4. Functions within Arrays(배열 내의 함수)

심지어 함수에 배열을 넣을 수도 있다.

const messages = [
    "함수를 배열에 넣을 수도 있습니다.",
    message => console.log(message),
    "일반적인 값과 마찬가지입니다.",
    message => console.log(message)
]


messages[1](messages[0]) // 함수를 배열에 넣을 수도 있습니다.
messages[3](messages[2]) // 일반적인 값과 마찬가지입니다.
    const messages = [
      "They can be inserted into arrays",
      message => console.log(message),
      "like variables",
      message => console.log(message)
    ]

    messages[1](messages[0])
    messages[3](messages[2])

 

 

5. Functions as Arguments(인수하는 함수)

다른 값들과 마찬가지로 함수를 다른 함수에 인자로 넘길 수도 있다.

    const insideFn = logger => 
      logger("함수를 다른 함수에 인자로 넘길수도 있습니다.")


    insideFn(message => console.log(message))
    //함수를 다른 함수에 인자로 넘길수도 있습니다.
    const insideFn = logger => 
      logger("They can be sent to other functions as arguments")


    insideFn(message => console.log(message))

 

 

6. Returned Functions(반환된 함수)

함수가 함수를 반환할 수도 있다. 이 또한 일반적인 값과 마찬가지이다.

var createScream = function(logger) {
    return function(message) {
        logger(message.toUpperCase() + "!!!")
    }
}

const scream = createScream(message => console.log(message))

scream('함수가 함수를 반환할 수도 있습니다.')   // 함수가 함수를 반환할 수도 있습니다.!!!
scream('createScream은 함수를 반환합니다.') // CREATESCREAM은 함수를 반환합니다.!!!
scream('scream은 createScream이 반환한 함수를 가리킵니다.') // SCREAM은 CREATESCREAM이 반환한 함수를 가리킵니다.!!!
    var createScream = function(logger) {
        return function(message) {
            logger(message.toUpperCase() + "!!!")
        }
    }

    const scream = createScream(message => console.log(message))

    scream('functions can be returned from other functions')
    scream('createScream returns a function')
    scream('scream invokes that returned function')

 

7. ES6 Enhancements

함수가 함수를 인자로 받은 경우와 함수가 함수를 반환하는 경우를 고차함수라고 부른다. createScream 고차 함수를 화살표 함수로 표현할 수도 있다.

const createScream = logger => message => 
logger(message.toUpperCase() + "!!!")

const scream = createScream(message => console.log(message))

scream('ES6는 더 작게 createScream을 만들 수 있다')
    const createScream = logger => message => 
        logger(message.toUpperCase() + "!!!")

    const scream = createScream(message => console.log(message))

    scream('ES6 can createScream with less')

 

함수를 선언할 때 사용한 화살표의 개수에 주의를 기울일 필요가 있다. 2개 이상의 화살표가 있다면 고차 함수를 사용하고 있다는 뜻이다.

 

자바스크립트에서는 함수가 1등 시민이기 때문에, 자바스크립트를 함수형 언어라고 말할 수 있다. 함수가 1등시민이라는 말은 함수를 일반적인 데이터와 마찬가지로 취급한다는 뜻이다. 그래서 함수를 일반적인 값과 마찬가지로 저장하거나 읽어오거나, 애플리케이션에서 흘려보낼 수 있다.

 

 

참고자료

러닝 리액트(Learning React), 알렉스 뱅크스, 한빛미디어 (2021)

728x90
반응형