Java

[Java] Java 8에서 함수형 프로그래밍이 도입된 이유

lala9663 2023. 7. 18. 00:57

CS 공부를 하고 있는데 Stream은 함수형 프로그래밍이란 것을 알게 되었다.

그때 든 생각이 어 왜 자바는 명령형 프로그래밍인데 Stream은 함수형 프로그래밍이지?라는 궁금증이 들어서 찾아보았다.

 

그럼 일단 명령형 프로그래밍부터 알아보자

명령형(Imperative) 프로그래밍

명령형 프로그래밍이란 프로그램의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 프로그래밍 패러다임의 일종이다.
이 패러다임에서는 프로그램의 상태를 변경하기 위해 명령어를 사용하며, 명령문이 순차적으로 실행되면서 프로그램의 상태가 변화한다.

 

쉽게 설명하자면, 컴퓨터가 수행할 명령들을 순서대로 써 놓은 것이라고 볼 수 있다.

명령형 프로그래밍에서는 프로그램이 수행해야 할 작업을 명시적으로 기술하며, 명령문의 순서에 따라 프로그램이 실행된다.


프로그래머는 변수, 할당문, 반복문, 조건문 등을 사용하여 프로그램의 동작을 명확하게 표현한다.
이러한 접근 방식은 컴퓨터의 하드웨어와 밀접하게 관련되어 있다.

거의 대부분의 컴퓨터 하드웨어는 명령형으로 구현된다. 거의 모든 컴퓨터 하드웨어들은 기계어를 실행하도록 설계되어 있는데, 보통 이것이 명령형으로 써져 있다.

 

명령형 프로그래밍은 대부분의 일반적인 프로그래밍 언어에서 사용되는 프로그래밍 스타일이다. C, Java, Python 등의 언어에서 명령형 프로그래밍을 사용하여 프로그램을 작성할 수 있다.

 

명령형 프로그래밍은 프로그램의 상태를 직접 변경하고, 명시적인 제어 흐름을 다루는 특징이 있다. 이를 통해 세밀한 제어와 반복적인 작업을 수행할 수 있다. 하지만 프로그램의 상태를 변경하는 부작용이 발생할 수 있고, 코드의 가독성과 유지보수성이 저하될 수 있다.

선언형(Declarative) 프로그래밍

선언형 프로그래밍은 "무엇(What)"을 할 것인지를 명시하며, "어떻게(How)" 할 것인지에 대한 세부적인 구현은 숨기는 프로그래밍 패러다임이다.

프로그래머는 원하는 결과를 선언하고, 시스템이 해당 결과를 얻기 위해 필요한 단계를 알아서 처리하도록 한다.

 

선언형 프로그래밍에서는 프로그램의 상태 변경을 감추고, 문제 해결에 집중한다. 프로그래머는 목표와 제약 조건을 기술하고, 컴퓨터가 이를 해석하고 실행하는 방법은 추상화되어 있다. 이를 통해 코드의 가독성과 이해도를 높이며, 생산성을 향상할 수 있다.

 

선언형 프로그래밍은 함수형 프로그래밍과 밀접한 관련이 있다. 함수형 프로그래밍은 선언형 프로그래밍의 한 형태로 볼 수 있다. 선언형 프로그래밍은 문제를 작은 조각으로 분해하고, 추상화를 통해 문제를 해결하기 위한 도구를 제공한다. 이러한 추상화 도구는 함수, 데이터 구조, 도메인 특화 언어 등이 될 수 있다.

 

자바에서는 Java 8부터 람다 표현식과 스트림(Stream) API를 도입하여 선언형 프로그래밍 스타일을 지원하였다. 이를 통해 코드의 가독성과 간결성이 향상되고, 병렬 처리와 비동기 프로그래밍을 보다 쉽게 다룰 수 있게 되었다.

명령형 VS 선언형

함수형 프로그래밍이 도입된 이유

  1. 병렬 처리와 멀티코어 활용의 필요성
    기존의 명령형 프로그래밍에서는 스레드와 락을 사용하여 병렬 처리를 구현했었다. 하지만 이는 복잡하고 오류를 발생시킬 수 있다. 함수형 프로그래밍은 상태 변경을 제어하고 부작용을 줄이기 때문에 병렬 처리와 멀티코어 활용에 더 적합하다.
  2. 코드의 간결성과 가독성
    함수형 프로그래밍은 불변성과 순수 함수를 강조하기 때문에 코드가 간결하고 가독성이 좋다. 또한, 람다 표현식과 스트림 API를 이용하여 코드를 표현할 수 있어, 반복문과 조건문이 줄어들고 선언적인 스타일로 코드를 작성할 수 있다.
  3. 다른 언어들도 사용중
    함수형 프로그래밍은 다른 언어들에서 이미 사용되고 있었다. 상황에 대응하기 위해 함수형 프로그래밍을 도입하여 개발자들에게 더 많은 선택지와 유연성을 제공하고자 했다.
  4. 함수형 프로그래밍의 장점
    함수형 프로그래밍은 부작용을 줄이고, 상태 변경을 제어함으로써 코드의 안정성과 예측 가능성을 높인다. 또한, 테스트와 디버깅이 더 쉬워지며, 모듈화와 재사용성이 용이해진다.

자바 8에서의 함수형 프로그래밍 요소

  1. 람다 표현식(Lambda Expressions)
    자바 8에서는 람다 표현식을 통해 익명 함수를 생성할 수 있게 되었다. 람다 표현식은 간단하고 강력한 방식으로 함수를 정의하고 전달할 수 있게 해 준다. 이를 통해 코드의 간결성과 가독성을 높일 수 있다.
  2. 스트림 API (Stream API)
    스트림 API는 자바 8에서 추가된 강력한 컬렉션 처리 기능이다. 스트림은 데이터의 흐름을 나타내며, 다양한 데이터 처리 연산을 지원한다. 스트림을 활용하여 컬렉션의 요소를 필터링, 변환, 정렬, 그룹화 등의 작업을 수행할 수 있다. 이를 통해 코드를 간결하게 작성하고 병렬 처리를 쉽게 구현할 수 있다.
  3. 함수형 인터페이스 (Functional Interfaces)
    함수형 인터페이스는 하나의 추상 메서드만을 가지는 인터페이스를 말한다. 자바 8에서는 @FunctionalInterface 어노테이션을 이용하여 함수형 인터페이스임을 명시할 수 있게 되었다. 이러한 함수형 인터페이스를 활용하여 람다 표현식을 전달하고 사용할 수 있다.
  4. 기본 메서드와 정적 메서드 (Default and Static Methods)
    자바 8에서는 인터페이스에 기본 메서드와 정적 메서드를 추가할 수 있게 되었다. 이를 활용하여 함수형 인터페이스에 유용한 메서드를 미리 구현할 수 있다.

 

아직 람다와 스트림에 대해서는 잘 몰라서...

다음에 람다와 스트림에 대해 공부 후에 한 번 더 포스팅해야겠다.





참고:
명령형(Imperative)프로그래밍과 선언형(Declarative)프로그래밍