S-표현식


정의

S‑표현식은 심볼리컬 식(symbolic expression)의 약어로, 주로 Lisp 계열 프로그래밍 언어에서 사용되는 자료 구조 및 표기법이다. 괄호 () 로 둘러싸인 원자(atom)리스트(list) 로 구성되며, 코드와 데이터를 동일한 형태로 기술할 수 있는 동질성(homogeneity) 을 제공한다. 이러한 특성으로 인해 S‑표현식은 프로그램 자체를 데이터로 취급할 수 있는 코드‑데이터 동등성(code‑data equivalence) 을 구현하는 데 핵심적인 역할을 한다.


역사

  • 1960년대: John McCarthy가 개발한 언어 Lisp에서 처음 도입하였다. 초창기 논문 “Recursive Functions of Symbolic Expressions and Their Computation by Machine”(1960) 에서 “S‑expression”이라는 용어가 등장한다.
  • 1970~80년대: Scheme, Common Lisp, Clojure 등 다양한 Lisp 파생 언어가 S‑표현식을 표준 구문으로 채택하였다.
  • 1990년대 이후: S‑표현식은 데이터 교환 포맷(예: EDN, Racket’s s‑expressions) 으로도 활용되며, 일부 인공 지능·형식 논리 분야에서도 메타데이터 기술에 사용된다.

구조와 문법

요소 설명 예시
원자(atom) 더 이상 분해되지 않는 기본 단위. 숫자, 문자열, 심볼 등. 42, "hello", foo
리스트(list) 원자 또는 다른 리스트들의 순서 있는 집합. 괄호로 둘러쌈. (add 1 2), (if (> x 0) x (- x))
함수 호출 리스트의 첫 번째 원소가 함수(또는 연산자)이며, 뒤따르는 원소들은 인수. (multiply 3 4) → 12
인용(quote) 평가(evaluation)를 억제하고 그대로 데이터를 반환. ' 또는 (quote ...) 사용. '(+ 1 2)(+ 1 2)
구조적 정의 리스트 내에 또 다른 리스트를 중첩할 수 있어 복합 구조 표현이 가능. (define (square x) (* x x))
  • 공백(space, newline 등)은 토큰 구분자이며, 의미를 갖지 않는다.
  • 주석은 Lisp 자체 문법에 따라 ; 로 시작해 행 끝까지 무시한다.

주요 특징

  1. 단일 구문
    • 모든 프로그램 구조가 동일한 “리스트” 형태이므로 파서(parser)가 매우 단순한다.
  2. 동적 타이핑
    • 원자는 런타임에 타입이 결정되며, 리스트 자체도 데이터와 코드 모두에 사용된다.
  3. 매크로 시스템
    • 코드 자체를 조작·생성할 수 있는 강력한 매크로가 S‑표현식 기반 언어에서 자연스럽게 구현된다.
  4. 가독성
    • 중첩된 괄호가 많아 초보자에게는 가독성이 떨어질 수 있지만, 구조가 명확해 논리적 흐름을 파악하기 쉬운 장점도 있다.

활용 분야

분야 적용 예시
프로그래밍 언어 구현 Lisp, Scheme, Clojure, Racket 등
메타프로그래밍 매크로, 코드 생성, DSL 구현
구조적 데이터 교환 EDN (Extensible Data Notation), Racket 데이터 파일
인공 지능·논리 프로그래밍 Prolog‑like 논리 표현, 규칙 기반 시스템
구성 파일·스크립트 Emacs Lisp 설정 파일(.emacs), Clojure deps.edn

대표적인 예시

;; 기본적인 덧셈 함수 정의
(defun add (a b)
  (+ a b))

;; 조건문과 재귀 호출
(defun factorial (n)
  (if (<= n 1)
      1
      (* n (factorial (- n 1)))))

;; 리스트 조작
(setq my-list '(1 2 3 4))
(push 0 my-list)   ; (0 1 2 3 4)

파싱 방식

  • 읽기(read) 단계: 문자열을 토큰(token)으로 분리하고, 괄호의 짝을 맞추어 추상 구문 트리(AST) 로 변환한다.
  • 평가(eval) 단계: AST를 순회하면서 리스트의 첫 원소를 함수로 해석하고 인자를 평가한다.
  • 대부분의 Lisp 구현은 재귀적 하향 파서(recursive‑descent parser) 혹은 스택 기반 파서 를 사용한다.

관련 용어

  • 원자(atom) – 분해되지 않는 최소 단위.
  • 리스트(list) – 원자 및 리스트의 순서 있는 집합.
  • 매크로(macro) – 코드 자체를 변형·생성하는 메커니즘.
  • 코드‑데이터 동등성(code‑data equivalence) – 프로그램 자체가 데이터와 동일한 구조를 갖는 특성.

참고문헌

  1. John McCarthy, “Recursive Functions of Symbolic Expressions and Their Computation by Machine”, Communications of the ACM, 1960.
  2. Paul Graham, On Lisp, 1993.
  3. Guy L. Steele Jr., The Common Lisp HyperSpec, 1996.
  4. Clojure Documentation, “Data Structures – Lists and Vectors”, 2023.

본 항목은 2026년 현재까지 알려진 학술·기술 자료를 토대로 작성되었습니다.

둘러보기

더 찾아볼 만한 주제