{
  "title": "선언형 vs 명령형 입문",
  "description": "'무엇(what)'과 '어떻게(how)'로 갈라 보는 두 패러다임 — 그 경계가 왜 생각만큼 또렷하지 않은지부터 짚습니다.",
  "languageCode": "ko",
  "cards": [
    {
      "type": "ox",
      "prompt": "명령형 프로그래밍은 '무엇을 원하는가'보다 '어떻게 계산하는가'를 단계적으로 기술한다.",
      "answer": true,
      "explanation": "명령형(imperative)은 상태를 바꾸는 명령을 순서대로 나열해 '어떻게(how)'를 직접 지시합니다. C·어셈블리가 대표적입니다."
    },
    {
      "type": "ox",
      "prompt": "선언형 언어는 목표(what)를 기술하고, 그것을 달성하는 구체적 실행 절차(how)는 대체로 언어 구현·런타임에 맡긴다.",
      "answer": true,
      "explanation": "SQL·Prolog·HTML/CSS처럼 '원하는 결과·규칙'을 선언하면 실행 방법은 구현이 정합니다."
    },
    {
      "type": "choice",
      "prompt": "다음 중 일반적으로 '선언형'으로 분류되지 않는 것은?",
      "choices": [
        "SQL",
        "Prolog",
        "HTML/CSS",
        "어셈블리어"
      ],
      "answer": 4,
      "explanation": "어셈블리어는 CPU 명령을 직접 나열하는 가장 명령형에 가까운 언어입니다. 나머지는 통상 선언형으로 분류됩니다."
    },
    {
      "type": "ox",
      "prompt": "SQL의 SELECT 문은 원하는 결과의 조건을 기술할 뿐, 조인 순서나 인덱스 사용 같은 실행 계획을 직접 지정하지 않는다.",
      "answer": true,
      "explanation": "실행 계획은 쿼리 옵티마이저가 결정합니다. 그래서 SQL은 선언형의 대표 예로 꼽힙니다."
    },
    {
      "type": "ox",
      "prompt": "'선언형 vs 명령형'의 경계는 형식적으로 엄밀히 정의된 기준이라기보다, 상당 부분 관례적·사회문화적 분류에 가깝다.",
      "answer": true,
      "explanation": "이 커리큘럼 전체의 결론이기도 합니다. 뒤에서 '왜 형식 정의가 어긋나는지'를 단계적으로 봅니다."
    },
    {
      "type": "choice",
      "prompt": "관계형 DB에서 SQL 질의를 받아 실제 실행 절차(조인 방법·순서 등)를 결정하는 구성요소는?",
      "choices": [
        "쿼리 옵티마이저",
        "링커",
        "가비지 컬렉터",
        "전처리기"
      ],
      "answer": 1,
      "explanation": "쿼리 옵티마이저가 '어떻게 실행할지'를 정하므로, 사용자는 '무엇을 원하는지'만 선언하면 됩니다."
    },
    {
      "type": "ox",
      "prompt": "함수형 언어는 흔히 선언형으로 분류되지만, 상태·이펙트·do 표기처럼 명령형적 요소를 포함하기도 한다.",
      "answer": true,
      "explanation": "예컨대 Haskell의 IO/do 표기는 순서 있는 계산을 기술합니다. 패러다임은 깔끔히 배타적이지 않습니다."
    },
    {
      "type": "text",
      "prompt": "'무엇(what)을 기술하고 어떻게(how)는 위임한다'는 특징으로 요약되는 프로그래밍 패러다임은?",
      "answers": [
        "선언형",
        "선언형 프로그래밍",
        "declarative",
        "선언적"
      ],
      "explanation": "선언형(declarative)입니다. 목표·규칙·제약을 선언하고 실행 방법은 구현에 맡깁니다."
    },
    {
      "type": "ox",
      "prompt": "정규표현식(regex)은 '매칭할 문자열의 패턴'을 기술한다는 점에서 선언형적 성격을 가진다.",
      "answer": true,
      "explanation": "어떻게 매칭할지(백트래킹 등)는 엔진이 정하고, 사용자는 패턴만 선언합니다."
    },
    {
      "type": "ox",
      "prompt": "어셈블리어는 대표적인 선언형 언어다.",
      "answer": false,
      "explanation": "어셈블리어는 CPU 명령을 직접 순서대로 지시하는 가장 명령형적인 언어입니다."
    },
    {
      "type": "ox",
      "prompt": "한 언어는 항상 명령형이거나 항상 선언형이며, 같은 언어를 두 스타일로 쓸 수는 없다.",
      "answer": false,
      "explanation": "같은 언어라도 코드 스타일에 따라 더 명령형처럼도, 더 선언형처럼도 쓸 수 있습니다(예: 반복문 vs map/filter)."
    },
    {
      "type": "ox",
      "prompt": "선언형 언어는 명령형 언어보다 항상 실행 속도가 빠르다.",
      "answer": false,
      "explanation": "선언형/명령형은 '표현 방식'의 분류이지 성능 보장이 아닙니다. 성능은 구현·최적화에 달렸습니다."
    },
    {
      "type": "ox",
      "prompt": "Prolog에서는 '무엇이 참인가'를 사실(fact)과 규칙(rule)으로 선언하고, 답을 찾는 탐색은 처리계가 단일화(unification)와 백트래킹으로 수행한다.",
      "answer": true,
      "explanation": "논리형(logic) 프로그래밍의 기본 구조입니다. 사용자는 관계를 선언하고, 해를 찾는 절차는 처리계가 담당합니다."
    },
    {
      "type": "ox",
      "prompt": "선언형 프로그래밍은 함수형 프로그래밍의 다른 이름이다.",
      "answer": false,
      "explanation": "흔한 오해입니다. 선언형은 함수형뿐 아니라 논리형(Prolog), 제약형, 질의 언어(SQL), 마크업(HTML/CSS) 등을 아우르는 더 넓은 범주입니다."
    },
    {
      "type": "ox",
      "prompt": "Makefile은 '어떤 산출물이 어떤 파일에 의존하는지'를 규칙으로 선언하고, 실제 빌드 순서는 make가 의존 그래프에서 계산한다.",
      "answer": true,
      "explanation": "빌드 도구는 목표와 의존 관계만 선언받고, 무엇을 어떤 순서로 다시 만들지는 스스로 결정합니다. 규칙 안의 명령줄은 여전히 명령형이라는 점에서 혼합적입니다."
    },
    {
      "type": "choice",
      "prompt": "다음 중 논리형(logic) 프로그래밍의 대표 언어는?",
      "choices": [
        "Fortran",
        "Pascal",
        "Prolog",
        "COBOL"
      ],
      "answer": 3,
      "explanation": "Prolog가 논리형 프로그래밍의 대표 언어입니다. Fortran·Pascal·COBOL은 모두 전형적인 명령형 언어입니다."
    },
    {
      "type": "ox",
      "prompt": "HTML은 화면을 그리는 절차를 단계별 명령으로 나열하는 명령형 언어다.",
      "answer": false,
      "explanation": "HTML은 문서의 구조와 의미를 선언하는 마크업이며, 실제 레이아웃과 그리기는 브라우저 렌더링 엔진이 결정합니다."
    },
    {
      "type": "ox",
      "prompt": "스프레드시트의 수식은 셀들 사이의 관계를 선언하는 것에 가깝고, 어떤 셀을 먼저 계산할지는 계산 엔진이 의존 관계를 보고 정한다.",
      "answer": true,
      "explanation": "사용자는 'C1 = A1 + B1'이라는 관계만 적고, 재계산 순서는 엔진이 의존 그래프로 결정합니다. 널리 쓰이는 선언형 도구의 예입니다."
    },
    {
      "type": "text",
      "prompt": "함수가 값을 돌려주는 것 외에 변수 대입·입출력처럼 외부 상태를 변화시키는 작용을 통틀어 무엇이라 하는가?",
      "answers": [
        "부수효과",
        "부작용",
        "사이드 이펙트",
        "side effect",
        "side-effect"
      ],
      "explanation": "부수효과(side effect)입니다. 부수효과가 많을수록 코드는 '어떻게'에 의존하게 되어 명령형 성격이 강해집니다."
    },
    {
      "type": "ox",
      "prompt": "CSS는 '어떤 요소가 어떤 스타일을 갖는지'를 선언하고, 실제 레이아웃 계산과 그리기 순서는 렌더링 엔진이 정한다.",
      "answer": true,
      "explanation": "선택자와 속성으로 원하는 결과를 선언할 뿐, 픽셀을 찍는 절차는 기술하지 않습니다."
    },
    {
      "type": "ox",
      "prompt": "선언형 코드는 실행 방법을 구현에 맡기므로, 개발자가 성능을 신경 쓸 필요가 전혀 없다.",
      "answer": false,
      "explanation": "실행 방법을 맡긴다고 결과가 항상 빠른 것은 아닙니다. 같은 SQL도 인덱스·통계·질의 작성 방식에 따라 실행 계획이 크게 달라집니다."
    },
    {
      "type": "choice",
      "prompt": "다음 중 '무엇을 원하는가'보다 '어떻게 할 것인가'를 가장 직접적으로 기술하는 코드는?",
      "choices": [
        "SQL의 SELECT ... WHERE 절",
        "CSS의 선택자와 속성 선언",
        "Prolog의 사실과 규칙",
        "포인터를 증가시키며 배열을 순회하는 C 루프"
      ],
      "answer": 4,
      "explanation": "포인터를 증가시키며 메모리를 순회하는 루프는 실행 절차 자체를 지시합니다. 나머지는 원하는 결과·규칙을 선언하는 쪽입니다."
    },
    {
      "type": "ox",
      "prompt": "제약 프로그래밍(constraint programming)은 변수들이 만족해야 할 제약을 선언하면, 해를 찾는 탐색은 솔버가 담당하는 방식이다.",
      "answer": true,
      "explanation": "스케줄링·배치 문제에서 널리 쓰이며, '조건을 선언하고 탐색은 위임한다'는 점에서 선언형의 전형입니다."
    },
    {
      "type": "ox",
      "prompt": "선언형 언어에서는 코드에 적은 순서가 실행 결과에 절대 영향을 주지 않는다.",
      "answer": false,
      "explanation": "Prolog는 절과 목표의 순서가 탐색 순서와 종료 여부를 바꾸고, CSS도 같은 우선순위 규칙끼리는 나중에 선언한 것이 이깁니다. 선언형이라고 순서가 무의미한 것은 아닙니다."
    },
    {
      "type": "ox",
      "prompt": "참조 투명성(referential transparency)은 어떤 표현식을 그 값으로 바꿔 써도 프로그램의 의미가 변하지 않는 성질을 말한다.",
      "answer": true,
      "explanation": "부수효과가 없을 때 성립하며, 컴파일러가 계산 순서를 자유롭게 바꾸거나 결과를 재사용할 여지를 만들어 줍니다."
    },
    {
      "type": "ox",
      "prompt": "SQL이나 Datalog 같은 질의 언어에서는 재귀적인 질의를 표현할 수 없다.",
      "answer": false,
      "explanation": "재귀는 Datalog의 핵심 기능이며, 표준 SQL도 WITH RECURSIVE(재귀 CTE)로 재귀 질의를 지원합니다."
    },
    {
      "type": "ox",
      "prompt": "Verilog·VHDL 같은 하드웨어 기술 언어(HDL)의 코드는 CPU가 한 줄씩 실행하는 명령의 나열이 아니라, 동시에 동작하는 회로를 기술한 것이다.",
      "answer": true,
      "explanation": "HDL 기술은 합성 도구가 실제 게이트로 바꿔 줍니다. '순차 실행 명령의 나열'이라는 명령형의 기본 그림이 여기서는 맞지 않습니다."
    },
    {
      "type": "ox",
      "prompt": "선언형으로 쓴 코드는 명령형으로 쓴 코드보다 항상 줄 수가 짧다.",
      "answer": false,
      "explanation": "많은 경우 간결해지지만 '항상'은 아닙니다. 제약을 빠짐없이 선언해야 하는 문제에서는 오히려 더 길어질 수 있습니다."
    },
    {
      "type": "choice",
      "prompt": "React 같은 UI 라이브러리를 '선언형 UI'라고 부르는 이유로 가장 적절한 것은?",
      "choices": [
        "DOM 조작 명령을 개발자가 직접 순서대로 적기 때문",
        "원하는 화면 상태를 기술하면 DOM 갱신 절차는 라이브러리가 계산하기 때문",
        "자바스크립트를 쓰지 않기 때문",
        "브라우저 없이 동작하기 때문"
      ],
      "answer": 2,
      "explanation": "개발자는 '이 상태일 때 화면은 이렇다'를 기술하고, 실제 DOM을 어떤 순서로 고칠지는 라이브러리가 계산합니다."
    },
    {
      "type": "ox",
      "prompt": "코왈스키(Kowalski)의 '알고리즘 = 논리 + 제어'라는 표현은, 무엇을 계산할지(논리)와 어떻게 계산할지(제어)를 분리해 볼 수 있다는 관점을 담고 있다.",
      "answer": true,
      "explanation": "논리형 프로그래밍의 사상적 배경입니다. 선언형은 '논리' 부분에 집중하고 '제어'는 처리계에 맡기려는 시도로 읽을 수 있습니다."
    },
    {
      "type": "ox",
      "prompt": "선언형 언어를 쓰면 컴파일러나 런타임이 항상 최적의 실행 계획을 찾아 준다.",
      "answer": false,
      "explanation": "옵티마이저는 통계와 휴리스틱에 기대므로 나쁜 계획을 고르기도 합니다. 그래서 실무에서는 실행 계획을 확인하고 질의를 고치는 작업이 필요합니다."
    },
    {
      "type": "text",
      "prompt": "Prolog에서 두 항이 같아지도록 변수에 값을 맞춰 넣어 매칭하는 핵심 연산을 무엇이라 하는가?",
      "answers": [
        "단일화",
        "통일",
        "유니피케이션",
        "unification",
        "unify"
      ],
      "explanation": "단일화(unification)입니다. 목표와 규칙 머리를 맞춰 보며 변수 결속을 만들고, 실패하면 백트래킹합니다."
    },
    {
      "type": "ox",
      "prompt": "순수 함수(pure function)는 같은 입력에 대해 항상 같은 결과를 내고 외부 상태를 바꾸지 않는 함수를 말한다.",
      "answer": true,
      "explanation": "순수 함수만으로 짠 코드는 '무엇을 계산하는가'가 곧 정의가 되어, 선언형적으로 읽히는 이유가 됩니다."
    },
    {
      "type": "choice",
      "prompt": "선언형 스타일이 주는 대표적 이점으로 가장 적절한 것은?",
      "choices": [
        "실행 절차를 감춰 코드에 의도가 드러나고 구현 교체 여지가 생긴다",
        "모든 프로그램이 자동으로 병렬화된다",
        "메모리 사용량이 항상 절반으로 줄어든다",
        "컴파일이나 해석 과정이 필요 없어진다"
      ],
      "answer": 1,
      "explanation": "실행 세부를 감추면 코드가 '무엇을 하려는가'를 드러내고, 구현을 바꿔도 코드를 고치지 않아도 되는 여지가 생깁니다. 나머지는 선언형이 보장하지 않는 것들입니다."
    },
    {
      "type": "ox",
      "prompt": "'선언형'이라는 말은 프로그래밍 언어 밖에서도 설정 파일·인프라 정의·UI처럼 '원하는 최종 상태를 기술한다'는 뜻으로 널리 쓰인다.",
      "answer": true,
      "explanation": "쿠버네티스 매니페스트나 인프라 코드가 대표적입니다. 사용자는 원하는 상태를 적고, 도구가 현재 상태와의 차이를 메웁니다."
    },
    {
      "type": "ox",
      "prompt": "선언형 언어로 쓴 프로그램에서는 무한 루프나 비종료가 발생할 수 없다.",
      "answer": false,
      "explanation": "Prolog의 좌재귀 규칙은 탐색이 끝나지 않을 수 있고, Haskell에서도 끝나지 않는 재귀를 얼마든지 쓸 수 있습니다. 종료성은 패러다임이 보장해 주지 않습니다."
    }
  ]
}
