선언형 프로그래밍
선언적 프로그래밍은 흔히 명령형이 아닌 모든 프로그래밍 스타일로 정의된다. 다른 많은 일반적인 정의는 명령형 프로그래밍과 단순히 대조하여 선언형 프로그래밍을 정의하려고 시도한다. 예를 들어
- 계산이 수행해야 하는 작업을 설명하는 고수준 프로그램이다
- 부작용이 없는(또는 더 구체적으로 말하면 참조적으로 투명한) 모든 프로그래밍 언어
- 수학적 논리에 명확하게 대응하는 언어
선언적 프로그래밍은 프로그램이 수행해야 하는 명령이나 단계(How do)를 명시적으로 나열하지 않고 원하는 결과(What do)를 설명하는 비명령형 프로그래밍 스타일이다. 함수형 및 논리 프로그래밍 언어는 선언적 프로그래밍 스타일이 특징이다. 논리 프로그래밍에서 프로그램은 논리적 형식으로 표현된 문장으로 구성되며, 계산은 이러한 문장을 사용하여 문제를 해결하는데, 이 역시 논리적 형식으로 표현된다.
선언형 프로그래밍 예시
var results = collection.Where( num => num % 2 != 0);
- 예시에서 원하는 결과
collection
에서 홀수인 부분
서브 패러다임
- Domain-specific languages (도메인 특화 언어)
- 선언형 도메인 특화 언어(DSL)의 잘 알려진 예로는 yacc의 입력 언어, QML, Make 빌드 명세 언어, Puppet의 구성 관리 언어, 정규 표현식, Datalog, answer set programming, SQL의 하위 집합(예: SELECT 쿼리)이 있다. 이러한 DSL은 반드시 튜링 완전(Turing-complete)할 필요가 없기 때문에 선언형으로 만들기 용이하다는 장점이 있다. 많은 마크업 언어들(HTML, MXML, XAML, XSLT 등)은 선언형이다. 예를 들어 HTML은 웹페이지에 무엇이 표시되어야 하는지만 기술하며, 페이지를 어떻게 그릴지 또는 사용자와 어떤 상호작용이 가능한지는 명시하지 않는다. 2013년 기준으로 일부 소프트웨어 시스템은 전통적인 사용자 인터페이스 마크업 언어(HTML 등)와 함께 백엔드 서버가 무엇을 해야 하는지를 선언적으로 기술하는 마크업을 결합하고 있다. 이러한 시스템은 보통 도메인 특화 XML 네임스페이스를 사용하며, SQL 구문이나 REST, SOAP을 통한 웹 서비스 호출을 추상화한 형태를 포함할 수 있다.
- Functional programming (함수형 프로그래밍)
- Haskell, Scheme, ML과 같은 함수형 언어는 함수 적용(function application)을 통해 식(expression)을 평가한다. 절차형 프로그래밍과는 달리, 함수형 프로그래밍은 명시적인 실행 순서를 강조하지 않는다. 대신, 재귀적 고차 함수(higher-order functions)의 적용과 합성을 통해 계산을 수행하며, 이는 수학적 의미에서 도메인(domain)과 코도메인(codomain) 간의 매핑으로 볼 수 있다. 많은 함수형 언어들(특히 ML, Lisp 계열)은 순수 함수형이 아니기 때문에, 프로그램 내에 상태(state)를 도입할 수 있다.
절차형 프로그래밍
절차형 프로그래밍은 명령형 프로그래밍의 한 형태로, 프로그램이 하나 이상의 절차(How do), 다른 말로는 서브루틴 또는 함수로 구성된다. 이 용어들은 종종 동의어로 사용되지만, 절차를 사용하면 명령형 프로그램의 형태와 구조가 크게 달라진다. 즉, 상태의 변경이 절차 내부로 국한되거나, 절차의 인자와 반환값을 통해서만 명시적으로 이뤄지도록 강제하는 강한 절차형 프로그래밍은 일종의 구조적 프로그래밍으로 간주될 수 있다. 1960년대 이후로, 구조적 프로그래밍 및 일반적인 모듈화 프로그래밍은 명령형 프로그램의 유지보수성과 전반적인 품질 향상을 위한 기술로 적극적으로 권장되어 왔다. 이러한 접근 방식을 확장하려는 시도가 바로 객체지향 프로그래밍 개념이다.
절차형 프로그래밍 예
List<int> results = new List<int>();
foreach(var num in collection)
{
if (num % 2 != 0)
results.Add(num);
}
- 예시를 구성하는 절차
result
컬렉션을 만든다.collection
에 속한num
을 단계별로 확인한다.num
을 확인한다. 만약 그것이 홀수라면result
에 추가한다.
절차형 프로그래밍과 선언형 프로그래밍의 관계
절차형 프로그래밍은 선언형 프로그래밍으로 향해가는 중간 단계로 볼 수 있다. 왜냐하면, 프로그래머는 종종 절차(또는 함수)의 이름, 인자, 반환 타입, 그리고 주석만 보더라도 그 절차가 무엇을 하는지는 이해할 수 있기 때문이다. 어떻게 결과를 얻는지(=구현 세부사항)까지 보지 않더라도 말이다. 그러나 동시에, 절차형 프로그래밍은 여전히 명령형이다. 그 이유는 어떤 문장이 실행될지와 그 실행 순서가 명확히 고정되어 있기 때문이다.
명령형 프로그래밍의 핵심 구성 요소들
- 할당: 메모리에 저장된 정보를 조작한 뒤, 그 결과를 메모리에 다시 저장한다.
- 고급 명령형 언어는 산술 연산, 함수 호출 등을 조합한 복합 표현식을 계산하고, 그 결과를 메모리에 저장하는 것도 허용한다.
- 반복문:
while
,do while
,for
와 같은 반복문은 문장들의 실행을 여러 번 반복하게 해 준다.- 반복 횟수가 사전에 정해질 수도 있고, 어떤 조건이 만족될 때까지 계속될 수도 있다.
- 조건 분기문:
- 어떤 조건이 참일 경우에만 문장을 실행하고, 그렇지 않으면 생략하여 다음 문장으로 넘어간다.
- 무조건 분기문:
- 실행 흐름을 프로그램의 다른 부분으로 강제로 이동시킨다.
- 대표적인 예:
goto
,switch
, 그리고 서브루틴 호출(call
) (일반적으로 호출 이후 원래 위치로 복귀)
- 참고자료
- Declarative programming wiki: https://en.wikipedia.org/wiki/Declarative_programming
- Imperative programming wiki: https://en.wikipedia.org/wiki/Imperative_programming
- What is the difference between declarative and imperative paradigm in programming?: https://stackoverflow.com/questions/1784664/what-is-the-difference-between-declarative-and-imperative-paradigm-in-programmin
'개발' 카테고리의 다른 글
Many to Many Relations (0) | 2025.05.19 |
---|---|
Spring Data Redis Serializers 정리 (0) | 2025.05.16 |
이벤트 소싱 정리 (0) | 2025.05.14 |
이벤트 드리븐 패턴 정리 (0) | 2025.05.13 |
레디스 클러스터 정리 (1) | 2025.05.12 |