존 매카시의 기호 기반 접근과 리습의 설계(리스트, 재귀, 가비지 컬렉션)가 어떻게 AI와 현대 프로그래밍에 영향을 미쳤는지 살펴봅니다.

이 글은 ‘구식 AI’의 박물관 투어가 아닙니다. 프로그래머, 테크 리드, 제품 담당자 등 소프트웨어를 만드는 누구에게든 실용적인 역사 수업입니다. 존 매카시의 아이디어는 우리가 프로그래밍 언어의 목적을 어떻게 생각하는지에 큰 영향을 미쳤기 때문입니다.
리습은 단순히 새로운 문법이 아니었습니다. 소프트웨어가 아이디어(숫자뿐 아니라)를 조작할 수 있다는 데 베팅했고, 언어 설계 선택이 연구, 제품 반복, 그리고 전체 툴링 생태계를 가속화할 수 있다는 가정이었습니다.
매카시의 유산을 읽는 유용한 방법은 오늘날에도 중요한 질문으로 보는 것입니다: 우리는 의도를 보일러플레이트, 마찰, 또는 우발적 복잡성에 빠지지 않고 얼마나 직접적으로 실행 가능한 시스템으로 바꿀 수 있는가? 이 질문은 Lisp의 REPL에서부터 현대의 ‘챗-투-앱’ 워크플로우까지 울려 퍼집니다.
존 매카시는 AI라는 연구 분야를 시작하는 데 기여한 것으로 기억되지만, 그가 강조한 것은 특정한 종류의 AI였습니다: 단순히 답을 계산하는 것뿐 아니라 아이디어를 조작할 수 있는 시스템. 1950년대 중반 그는 다트머스 여름 연구 프로젝트를 조직했고(그곳에서 ‘인공지능’이라는 용어가 제안됨) 이후 MIT와 스탠퍼드에서 AI 작업을 형성했습니다. 그러나 그의 가장 지속적인 기여는 그가 계속해서 던진 질문일지도 모릅니다: 추론 자체를 프로그램으로 표현할 수 있다면 어떨까?
초기의 많은 컴퓨팅 성공은 숫자 중심이었습니다: 탄도표, 공학 시뮬레이션, 최적화, 통계. 이런 문제들은 산술에 깔끔하게 맞았습니다.
매카시는 다른 것을 겨냥했습니다. 인간의 추론은 종종 ‘만약’, ‘때문에’, ‘속한다’, ‘종류다’, ‘이 조건을 만족하는 모든 것’ 같은 개념으로 작동합니다. 이런 것들은 부동소수점 값으로 자연스럽게 표현되지 않습니다.
매카시의 접근은 지식을 기호(이름, 관계, 분류)로 보고, 사고를 그 기호들에 대한 규칙 기반 변환으로 다루는 것이었습니다.
고수준으로 보면: 숫자 기반 접근은 “얼마나?”를 묻고, 기호 기반 접근은 “이것은 무엇인가?”와 “우리가 아는 것으로부터 무엇이 도출되는가?”를 묻습니다.
추론을 프로그래밍할 수 있다고 믿는다면, 규칙, 논리 문장, 중첩된 관계 같은 표현을 편하게 다루고 처리할 수 있는 언어가 필요합니다.
리습은 그 목표를 위해 만들어졌습니다. 아이디어를 엄격하고 미리 정해진 데이터 구조에 억지로 맞추는 대신, 리습은 코드와 지식을 비슷한 모양으로 표현하는 것을 자연스럽게 했습니다. 이 선택은 학문적 스타일이 아니라 실용적 다리였습니다: 생각을 기술하는 것과 절차를 실행하는 것 사이의 다리로, 매카시가 AI가 건너야 한다고 본 바로 그것입니다.
매카시와 초기 AI 연구자들이 ‘기호적(symbolic)’이라고 했을 때, 그들은 신비한 수학을 의미한 것이 아닙니다. 기호는 단순히 의미 있는 레이블입니다: customer 같은 이름, hungry라는 단어, IF와 THEN 같은 태그. 기호는 프로그램이 아이디어(분류, 관계, 규칙)를 숫자만으로가 아니라 직접 다루게 해 줍니다.
간단한 비유: 스프레드시트는 열과 산술이 중심인 세계에 강합니다. 기호적 시스템은 규칙, 분류, 예외, 구조가 중심인 세계에 강합니다.
많은 프로그램에서 42와 "age"의 차이는 데이터 타입 그 자체보다 그 값이 무엇을 나타내는지입니다. 기호는 의미를 잃지 않고 비교하고 저장하고 결합할 수 있는 무언가를 제공합니다.
그래서 “파리는 도시다” 또는 “배터리가 낮다면 충전기를 찾아라” 같은 것을 표현하기 자연스럽습니다.
기호로 쓸모 있는 일을 하려면 구조가 필요합니다. 리습은 아주 단순한 구조인 리스트를 대중화했습니다. 리스트는 단지 항목들의 순서 있는 묶음이고, 그 항목들 자체가 다시 리스트일 수 있습니다. 이 한 가지 아이디어로 문장, 폼, 트리 형태의 지식을 표현할 수 있습니다.
작은 개념 예시(리습 스타일):
(sentence (subject robot) (verb needs) (object power))
거의 영어처럼 읽힙니다: 주어, 동사, 목적어로 이루어진 문장. 구조화되어 있으므로 프로그램은 (subject robot)을 골라내거나 (object power)를 다른 것으로 바꿀 수 있습니다.
정보가 기호적 구조로 들어가면 고전적 AI 과제들이 접근 가능해집니다:
IF) 새로운 것을 결론짓는다(THEN).핵심 변화는 프로그램이 단순히 계산하는 것이 아니라 의미 있는 지식 조각들을 검사하고 변형할 수 있다는 점입니다.
리습의 설계 결정은 학계에만 머무르지 않았습니다. 그것들은 사람들이 도구를 만드는 방식과 아이디어를 얼마나 빨리 탐색할 수 있는지에 영향을 주었습니다:
이 특성들은 실험 비용을 낮추고 프로토타입이 제품으로 더 빨리 전환되며 팀이 요구사항 변화에 적응하기 쉬운 생태계를 만듭니다.
리습은 매우 실용적인 설계 문제에서 출발했습니다: 기호를 숫자처럼 자연스럽게 다루는 프로그램을 어떻게 쓸 것인가?
매카시는 ‘더 나은 계산기’를 만들려던 것이 아니었습니다. 그는 (is (parent Alice Bob)) 같은 표현을 (+ 2 3)만큼 쉽게 저장하고 검사하고 변형하고 논리적으로 다루기를 원했습니다.
우선순위는 기호 정보를 표현하고 조작하기 쉽게 만드는 것이었습니다. 그래서 리스트와 트리 같은 구조에 초점이 맞춰졌습니다. 이는 인간이 의미를 표현할 때 이미 사용하는 형태: 문장, 논리 규칙, 중첩된 분류와 관계에 잘 맞습니다.
또 다른 목표는 언어의 핵심을 작게 그리고 일관되게 유지하는 것이었습니다. 핵심에 특수 사례가 적을수록 규칙을 외우는 시간이 줄고 아이디어를 합성하는 데 더 많은 시간을 쓸 수 있습니다. 리습은 더 큰 추상화를 만들 수 있는 작은 빌딩 블록 집합에 기대었습니다.
핵심 통찰은 프로그램과 데이터가 같은 구조를 공유할 수 있다는 것입니다. 간단히 말해: 데이터가 중첩된 리스트라면 프로그램도 중첩된 리스트일 수 있습니다.
그 결과 당신은:
리습은 또한 언어가 모두에게 하나의 정답일 필요는 없다는 사고방식을 대중화했습니다. 언어는 추론, 탐색, 지식 표현 같은 문제 영역을 중심으로 설계될 수 있고, 그럼에도 불구하고 수십 년 동안 범용 프로그래밍에 영향을 미칠 수 있다는 것입니다.
S-표현식(기호 표현식)은 리습의 대표 아이디어입니다: 코드와 데이터를 중첩된 리스트로 표현하는 단일 일관된 방식.
한눈에 보면 S-표현식은 항목들을 감싸는 괄호입니다—어떤 항목은 원자(이름과 숫자 같은)이고 어떤 항목은 다시 리스트입니다. ‘리스트 안의 리스트’ 규칙이 핵심입니다.
구조가 균일하기 때문에 리습 프로그램은 바닥부터 동일한 빌딩 블록으로 구성됩니다. 함수 호출, 설정 같은 데이터 조각, 프로그램 구조의 일부가 모두 리스트로 표현될 수 있습니다.
이 일관성의 장점:
리습을 직접 쓰지 않더라도 한 가지 교훈은 분명합니다: 시스템이 하나 또는 두 가지 예측 가능한 형태로 구성되면 엣지 케이스와 싸우는 시간이 줄고 실제로 쌓는 시간이 늘어납니다.
S-표현식은 작은 읽기 쉬운 조각들이 자연스럽게 더 큰 것으로 결합되게 장려합니다. 프로그램이 ‘그저 중첩된 리스트’라면 아이디어를 결합하는 것은 종종 한 표현을 다른 표현 안에 중첩하거나 재사용 가능한 부분으로 리스트를 조립하는 것을 의미합니다.
이것은 모듈식 스타일로 유도합니다: 하나의 일을 하는 작은 연산을 작성하고 그것들을 쌓아 더 큰 의도를 표현합니다.
눈에 띄는 단점은 낯설다는 것입니다. 많은 신입에게 괄호가 많은 문법은 이상하게 보입니다.
하지만 장점은 예측 가능성입니다: 중첩 규칙을 이해하면 프로그램 구조를 신뢰성 있게 파악할 수 있고, 도구들도 마찬가지입니다. 이 명료함은 S-표현식이 리습을 넘어선 결과를 낳은 큰 이유입니다.
재귀는 일상적인 비유로 이해하기 쉽습니다: 어지러운 방을 더 작은 ‘방’들로 나누면서 정리하는 것. 한 번에 모든 것을 해결하려 하지 않습니다. 물건 하나를 집어 제자리에 놓고 남은 부분에 같은 동작을 반복합니다. 단계는 단순하지만, 남은 것이 없을 때까지 반복하는 힘이 있습니다.
리습은 데이터의 많은 부분이 자연스럽게 리스트로 구성되기 때문에 이 아이디어에 기대었습니다: 리스트는 ‘첫 번째 항목’과 ‘나머지’라는 형태를 가지므로 재귀적 사고에 완벽히 맞습니다.
리스트를 처리하려면 첫 요소를 처리한 다음 나머지에 같은 로직을 적용합니다. 리스트가 비어 있으면 멈춥니다—이것이 재귀가 신비로워 보이지 않고 잘 정의된 이유입니다.
숫자들의 리스트 합을 구한다고 가정합시다.
정의가 영어처럼 읽히고 프로그램 구조가 그 아이디어를 반영합니다.
기호적 AI는 표현을 트리 구조(연산자와 하위 표현)로 나타내는 경우가 많습니다. 재귀는 그 트리를 ‘걷는’ 자연스러운 방법입니다: 왼쪽 부분을 평가하는 방식을 오른쪽 부분에도 적용하고, 단순 값에 도달할 때까지 계속합니다.
이 패턴들은 이후의 함수형 프로그래밍을 형성하는 데 기여했습니다: 작은 함수들, 명확한 기본 사례, 그리고 추론하기 쉬운 데이터 변환들. 리습 밖에서도 ‘한 단계 수행하고 남은 것에 반복’하는 습관은 더 깨끗한 코드와 숨겨진 부작용의 감소로 이어집니다.
초기 프로그래머들은 종종 메모리를 수동으로 관리해야 했습니다: 공간을 할당하고 누가 그것을 소유하는지 추적하며 적절한 순간에 해제하는 것을 기억해야 했습니다. 그 작업은 개발 속도를 늦출 뿐만 아니라 특정 유형의 재현하기 어려운 버그를 만듭니다: 성능을 서서히 저하시킨 누수와 원래 실수 이후에 프로그램을 충돌시키는 댕글링 포인터.
존 매카시는 리습을 위해 가비지 컬렉션을 도입하여 프로그래머들이 장부 정리보다 의미에 집중하게 만들고자 했습니다.
높은 수준에서 가비지 컬렉션(GC)은 실행 중인 프로그램에서 더 이상 도달할 수 없는 메모리 조각들—아무도 다시 사용할 수 없는 값들—을 찾아 그 공간을 회수합니다.
“모든 객체를 정확히 한 번 해제했는가?”를 묻는 대신, GC는 “이 객체에 아직 접근할 수 있는가?”를 묻습니다. 프로그램이 접근할 수 없다면 그것은 쓰레기로 간주됩니다.
기호적 AI 작업에서 리습 프로그램은 자주 많은 단명 리스트, 트리, 중간 결과를 만들어냅니다. 수동 메모리 관리는 실험을 자원 정리에 대한 지속적인 전투로 바꿔 놓습니다.
GC는 일상 경험을 변화시킵니다:
핵심 아이디어는 언어 기능이 팀 배가기가 될 수 있다는 점입니다: 원인 불명의 손상 디버깅에 쓰는 시간이 줄어들면 실제 로직 개선에 더 많은 시간을 쓸 수 있습니다.
매카시의 선택은 리습 안에만 머무르지 않았습니다. 많은 이후 시스템이 GC(그 변형들)를 채택했습니다: Java, C#, Python, JavaScript 런타임, Go 등이 모두 대규모 개발을 더 안전하고 빠르게 만들기 위해 가비지 컬렉션에 의존합니다—성능이 중요한 경우에도 마찬가지입니다.
리습에서 표현식은 일관된 형태(종종 리스트)로 작성된 코드 조각입니다. 평가는 그 표현식이 무엇을 의미하는지 그리고 무엇을 생산하는지 결정하는 과정입니다.
예를 들어 “이 숫자들을 더해라” 또는 “이 입력으로 이 함수를 호출하라”고 쓸 때, 평가기는 그 표현식을 결과로 바꾸기 위해 작은 규칙 집합을 따릅니다. 심판관처럼 어떤 것을 언제 수행하고 언제 멈출지를 결정합니다.
매카시의 핵심적인 움직임은 단순히 새 문법을 발명한 것이 아니라 ‘의미 엔진’을 작고 규칙적이게 유지한 것입니다. 평가기가 몇 가지 명확한 규칙으로 구성되면 좋은 일이 두 가지 일어납니다:
이 일관성은 리습이 기호적 AI 실험의 놀이터가 된 이유 중 하나입니다: 연구자들은 컴파일러 팀이 언어를 재설계할 때까지 기다리지 않고도 새로운 표현과 제어 구조를 빠르게 시도할 수 있었습니다.
매크로는 반복되는 코드 형태를 자동화하는 리습의 방법입니다. 함수가 계산을 반복하지 않게 도와주듯, 매크로는 구조적 반복을 제거합니다—예: “X를 수행하되 동시에 로깅도 하라” 또는 “규칙을 위한 미니 DSL을 정의하라”.
실용적 효과는 리습 안에서 새로운 편의 기능을 성장시킬 수 있다는 점입니다. 많은 현대 도구들이 이 아이디어를 반향합니다—템플릿 시스템, 코드 생성기, 메타프로그래밍 기능 등—이들은 같은 목표를 지원합니다: 더 빠른 실험과 더 명확한 의도.
관심이 있다면 이 사고방식이 일상 개발 워크플로에 어떻게 영향을 주었는지 /blog/the-repl-and-fast-feedback-loops를 보세요.
리습의 매력은 단순히 언어 자체가 아니라 그것으로 작업하는 방식에도 있었습니다. 리습은 REPL을 대중화했습니다: 읽기–평가–출력 루프(Read–Eval–Print Loop). 일상적으로 말하자면, 컴퓨터와 대화하는 것과 같습니다. 표현식을 입력하면 시스템이 즉시 실행하고 결과를 출력한 뒤 다음 입력을 기다립니다.
전체 프로그램을 쓰고 컴파일하고 실행한 뒤 무엇이 잘못됐는지 찾는 대신, 작은 단계로 아이디어를 시도할 수 있습니다. 함수를 정의하고, 몇 가지 입력으로 테스트하고, 수정하고, 다시 테스트—모두 몇 초 내에 가능합니다.
그 리듬은 실험을 장려합니다. 초기 AI 작업에서는 올바른 접근법을 모르는 경우가 많았기 때문에 특히 중요했습니다.
빠른 피드백은 ‘큰 베팅’을 ‘작은 확인’으로 바꿉니다. 연구에선 가설을 탐색하고 중간 결과를 검사하기 쉬워집니다.
제품 프로토타이핑에서는 반복 비용을 줄입니다: 실제 데이터로 동작을 검증하고, 엣지 케이스를 빨리 발견하며, 긴 빌드 사이클을 기다리지 않고 기능을 다듬을 수 있습니다.
이것이 현대의 바이브 코딩 도구들이 매력적인 이유이기도 합니다: 이들은 본질적으로 피드백 루프를 강하게 압축한 것입니다. 예를 들어 Koder.ai는 채팅 인터페이스(에이전트 기반 아키텍처 사용)를 통해 제품 의도를 빠르게 웹/백엔드/모바일 코드로 바꾸어 ‘시도 → 조정 → 재시도’ 루프를 REPL에 더 가깝게 느껴지게 합니다.
REPL 아이디어는 오늘날 다음과 같은 곳에서 나타납니다:
도구는 다르지만 원칙은 같습니다: 생각과 결과 사이의 거리를 줄이세요.
요구사항이 불확실하고, 데이터 중심 기능을 탐색하거나, API를 설계하거나, 까다로운 로직을 디버깅하는 팀은 REPL류 워크플로의 혜택을 가장 크게 봅니다. 작업이 학습 중심이라면(interacting with users, data, or edge cases), 대화형 피드백은 사치가 아니라 배가기입니다.
리습이 ‘모두의 일상 문법’이 되지는 않았지만, 아이디어를 뿌려 놓아 많은 생태계에서 통상적인 것으로 자리 잡게 했습니다.
리습이 기본으로 삼았던 개념들—값으로서의 함수, 고차 연산의 광범위한 사용, 작은 조각을 합성해 프로그램을 만드는 선호—이제 널리 보입니다. 리습과 전혀 닮지 않은 언어도 map/filter 스타일 변환, 불변 데이터 습관, 반복자나 폴드로 표현되는 재귀적 사고를 장려합니다.
핵심 변화는 사고 방식입니다: 데이터 변환을 파이프라인으로 처리하고 행동을 전달 가능한 것으로 취급하세요.
리습은 프로그램을 데이터로 표현하기 쉽게 만들었습니다. 이 사고방식은 오늘날 컴파일러, 포매터, 린터, 코드 생성기가 AST(추상 구문 트리)를 다루는 방식에 나타납니다. AST를 다뤄본 적이 있다면, 그것은 ‘코드를 데이터로’ 다루는 근사한 활동입니다—구조가 JSON 객체든 타입화된 노드든 바이트코드 그래프든.
같은 기호적 접근은 구성 자동화: 설정 형식, 템플릿 시스템, 빌드 파이프라인 모두 도구가 검사하고 변형하고 검증할 수 있는 구조화된 표현에 의존합니다.
현대의 리습 계열 언어들(넓은 의미에서)은 내부 DSL을 설계하는 방식에 계속 영향을 줍니다—테스트, 배포, 데이터 정리, UI용 소규모 맞춤 언어 등.
리습 밖에서도 매크로 시스템, 메타프로그래밍 라이브러리, 코드 생성 프레임워크는 동일한 목표를 지향합니다: 문제에 맞게 언어를 확장하되 전체를 다시 쓰지 않기.
실용적 결론: 문법 선호는 변하지만 지속적인 아이디어들—기호적 구조, 합성 가능한 함수, 확장성—은 수십 년과 코드베이스를 넘어 계속 가치가 있습니다.
리습은 ‘명석하다’와 ‘읽기 어렵다’ 사이를 오가는 평판이 있습니다. 종종 간접 경험에 기반한 인상입니다. 진실은 평범합니다: 리습은 적절한 상황에서 강력하고 다른 상황에서는 불편한 선택을 합니다.
초보자에게 리습의 균일한 문법은 프로그램의 ‘내부’를 보는 것처럼 느껴질 수 있습니다. 이 불편함은 현실입니다, 특히 구문이 다른 언어에 익숙하다면 더욱 그렇습니다.
역사적으로 보면 리습의 구조는 요점이기도 했습니다: 코드와 데이터가 같은 모양을 공유하므로 프로그램을 변형하고 생성하고 분석하기 쉬웠습니다. 편집기 지원(들여쓰기, 구조적 탐색)이 있으면 리습 코드는 종종 괄호를 세는 대신 형태로 읽힙니다.
리습이 본질적으로 느리다는 고정관념이 있습니다. 역사적으로 일부 구현은 저수준 언어에 비해 고전적 어려움을 겪었고 동적 특성은 오버헤드를 더했습니다.
하지만 ‘리습’ 전체를 하나의 성능 프로필로 취급하는 것은 정확하지 않습니다. 많은 리습 시스템은 오랫동안 컴파일, 타입 선언, 진지한 최적화를 지원해 왔습니다. 더 유용한 관점은: 메모리 레이아웃, 예측 가능한 지연 시간, 원시 처리량에 대해 얼마나 많은 제어가 필요한가이며 당신의 리습 구현이 그 요구를 충족하는가입니다.
공정한 비판 중 하나는 생태계 적합성입니다. 리습 방언과 도메인에 따라 라이브러리, 툴링, 인력 풀이 주류 스택보다 작을 수 있습니다. 빠르게 광범위한 팀으로 출하해야 한다면 이것이 언어의 우아함보다 더 중요한 문제가 될 수 있습니다.
고정관념으로 리습을 판단하지 말고 그 기본 아이디어들—균일한 구조, 대화형 개발, 도메인 특화 추상화를 위한 매크로—을 독립적으로 평가하세요. 리습을 쓰지 않더라도 이 개념들은 언어 설계와 코드 작성 방식에 날카로움을 더합니다.
매카시는 단지 역사적 언어를 남긴 것이 아니라, 소프트웨어를 더 쉽게 바꾸고 설명하고 확장하게 만드는 습관을 남겼습니다.
교묘한 표면보다 단순한 핵심을 선호하라. 직교적인 작은 빌딩 블록은 배우기 쉽고 깨뜨리기 어렵습니다.
데이터 형태를 균일하게 유지하라. 많은 것이 같은 표현을 공유하면 프린터, 디버거, 직렬화기, 변환기를 재사용할 수 있어 도구가 단순해집니다.
필요할 때 프로그램을 데이터로(데이터를 프로그램처럼) 다뤄라. 구조를 검사하고 변형할 수 있다면 안전한 리팩터링, 마이그레이션, 코드 생성기를 만들 수 있습니다.
지루한 일을 자동화하라. 가비지 컬렉션이 고전적 예이지만 넓은 관점은 실수를 예방하는 자동화에 투자하라는 것입니다.
피드백 루프를 최적화하라. 대화형 평가(REPL 스타일)는 작은 실험, 빠른 검증, 행동에 대한 더 나은 직관을 장려합니다.
확장을 1등 시민으로 설계하라. 리습 매크로는 한 가지 해법일 뿐입니다; 다른 생태계에서는 플러그인, 템플릿, DSL, 컴파일타임 변환이 같은 역할을 합니다.
라이브러리나 아키텍처를 선택하기 전에 실제 기능—예: “할인 규칙” 또는 “지원 티켓 라우팅”—을 하나 골라 트리로 그려보세요. 그런 다음 그 트리를 중첩된 리스트(또는 JSON)로 다시 작성하세요. 노드와 리프는 무엇인지, 어떤 변환이 필요한지 적어보세요.
리습이 아니더라도 다음 사고방식을 채택할 수 있습니다: AST 같은 표현을 만들고, 반복적인 글루 코드에 대해 코드 생성을 사용하며, 데이터 우선 파이프라인(파싱 → 변환 → 평가)을 표준으로 삼으세요. 많은 팀이 중간 표현을 명시적으로 만드는 것만으로도 이점을 얻습니다.
REPL 원칙이 좋지만 주류 스택에서 제품 기능을 출시한다면 도구에서 그 정신을 빌려올 수 있습니다: 빠른 반복 루프, 스냅샷/롤백, 그리고 실행 전에 명시적 계획을 도입하세요. 예를 들어 Koder.ai는 계획 모드와 스냅샷/롤백을 포함해 빠른 반복을 더 안전하게 만드는 운영적 반향을 제공합니다.
매카시의 지속적 영향은 이렇습니다: 우리가 추론 자체를 프로그래밍 가능하게 만들고 아이디어에서 실행 가능한 시스템으로 가는 경로를 최대한 직접적으로 유지할수록 프로그래밍은 더 강력해집니다.
기호적 사고는 개념과 관계를 직접적으로 표현하고(예: “고객”, “is-a(상속)”, “depends-on(의존)”, “if…then…”), 그런 표현들에 규칙과 변환을 적용합니다.
숫자 연산이 핵심인 문제가 아니라 구조, 예외, 의미가 많은 문제(규칙 엔진, 플래닝, 컴파일러, 설정, 워크플로우 로직)에 가장 유용합니다.
맥카시는 '추론을 프로그램으로 표현할 수 있다'는 관점을 강하게 밀어붙였습니다 — 단순한 계산이 아니라 추론 자체를 프로그램화하자는 생각입니다.
그 관점은 다음을 형성했습니다:
리스트는 ‘부분들로 이루어진 것’을 표현하는 최소한의 유연한 방법입니다. 리스트의 요소가 다시 리스트가 될 수 있기 때문에 자연스럽게 트리 구조가 만들어집니다.
이를 통해 다음이 쉬워집니다:
S-표현식은 코드와 데이터를 하나의 일관된 형태로 표현합니다: 중첩된 리스트.
그 일관성 덕분에 시스템은 단순해집니다:
매크로는 반복되는 코드 구조를 자동화합니다. 단순한 계산을 재사용하는 함수와 달리, 매크로는 호출 지점의 구조를 생성하거나 변형합니다.
매크로를 쓸 때의 예:
재사용 가능한 로직만 필요하면 함수가 더 적절합니다.
가비지 컬렉션(GC)은 더 이상 접근할 수 없는 메모리를 자동으로 회수합니다. 그 결과 다음과 같은 장점이 있습니다:
즉, 생산성 향상을 위한 언어 기능으로 볼 수 있습니다: 리팩터링과 프로토타이핑에 드는 비용을 줄여줍니다.
REPL은 ‘읽기-평가-출력 루프(Read–Eval–Print Loop)’로, 컴퓨터와 대화하듯 짧은 사이클로 코드를 실행하고 결과를 확인하는 환경입니다.
비 Lisp 스택에서 같은 이점을 얻으려면:
관련 읽기: /blog/the-repl-and-fast-feedback-loops
현대 워크플로우에 널리 퍼진 개념들:
map/filter, 합성)직접 Lisp를 사용하지 않더라도 이 아이디어들은 일상적으로 쓰일 가능성이 큽니다.
타협과 오해들:
실무적 접근은 명성에 의존하지 말고 도메인과 제약 조건에 맞춰 평가하는 것입니다.
간단한 연습:
이 과정은 ‘코드-같은-데이터’ 패턴이나 규칙 엔진, DSL 같은 해결책이 어디에 도움이 되는지 드러내 줄 것입니다.