본문으로 건너뛰기
피드

왜 아직도 Lisp를 배워볼 만한가

backend 약 11분
vote
0
댓글
북마크

Lisp는 괄호가 많은 이상한 언어처럼 보이지만, 핵심은 문법이 아니라 언어 자체를 확장할 수 있다는 점에 있음. 매크로, 코드-데이터 동일성, REPL 중심 개발이 합쳐지면 프로그램을 '작성'한다기보다 살아 있는 시스템을 계속 진화시키는 방식으로 개발하게 됨.

  • 1

    Lisp 매크로는 반복 코드 생성 수준이 아니라 언어에 새 구문을 추가하는 도구에 가까움

  • 2

    코드와 데이터가 모두 리스트로 표현되는 동형성 덕분에 프로그램이 프로그램을 다룰 수 있음

  • 3

    REPL 중심 개발은 핫 리로딩을 별도 도구가 아니라 언어의 기본 작업 방식으로 만든다는 게 포인트

  • 4

    AutoCAD의 AutoLISP와 Emacs 사례처럼 Lisp는 확장 가능한 소프트웨어를 만들 때 특히 강함

Lisp가 이상해 보이는 건 맞는데, 이상한 데 이유가 있음

  • Lisp 코드를 처음 보면 대부분 반응은 비슷함. 괄호가 너무 많고, 들여쓰기도 낯설고, format에 왜 첫 인자로 출력 대상을 넘기는지부터 머리가 멈춤

    • 글쓴이도 처음엔 똑같이 당황했고, 그 다음엔 패키지, 심볼, 프로젝트 생성, 라이브러리 import, REPL, condition, restart 같은 Lisp식 생태계를 다시 배워야 했다고 함
    • 진짜 허들은 문법보다 사고방식임. 알고리즘을 짤 때 언어가 제공하는 문법 안에서만 생각하는 게 아니라, 문제에 맞게 언어를 키워나가는 쪽으로 머리가 바뀜
  • 글의 핵심 주장은 단순함. Lisp를 배우면 다른 언어가 못 보여주는 종류의 힘을 보게 된다는 것

    • Paul Graham의 'Blub paradox'가 여기서 등장함. 덜 강력한 언어만 써본 사람은 더 강력한 언어가 제공하는 개념 자체를 못 알아볼 수 있다는 얘기
    • 그래서 Lisp의 장점은 설명만으로는 잘 안 꽂힘. 재즈를 물어보면 이미 늦었다는 Louis Armstrong식 농담처럼, 직접 써봐야 감각이 온다는 쪽

중요

> 이 글에서 말하는 Lisp의 강점은 '괄호 문법이 취향에 맞냐'가 아니라, 언어 자체를 문제에 맞게 바꿀 수 있느냐에 있음.

매크로는 보일러플레이트 제거기가 아니라 언어 확장 장치임

  • Lisp에서 가장 센 카드로 소개되는 건 매크로임. 그런데 여기서 말하는 매크로는 C, Rust, Swift의 매크로와 결이 다름

    • 다른 언어의 매크로가 주로 반복 코드 생성이나 보일러플레이트 제거에 가까운 반면, Lisp 매크로는 새 언어 구성요소를 만드는 도구에 가까움
    • 예를 들어 Common Lisp에 C 스타일 while 연산자가 없어도, 개발자가 직접 매크로로 while을 만들어 언어에 붙일 수 있음
  • 왜 함수로는 안 되고 매크로여야 하냐가 이 글의 중요한 설명 포인트임

    • 함수는 인자를 호출 전에 평가함. 그래서 fake-while 같은 함수를 만들면 조건식과 본문이 먼저 실행되어 버리고, 본문 자리에 코드 블록이 아니라 값이 들어감
    • 글의 예시에서는 (print counter)(decf counter)가 먼저 평가되어 body가 2가 되고, 결국 (funcall 2)를 실행하려다 2는 함수가 아니다라는 에러가 남
    • 반면 매크로는 인자를 미리 평가하지 않고 코드 조각 그대로 받음. 그래서 조건과 본문을 원하는 형태로 감싸서 컴파일러가 실행할 코드로 확장할 수 있음
  • Lisp에서는 매크로 확장 결과를 REPL에서 직접 확인할 수 있음

    • macroexpand로 매크로가 어떤 코드로 바뀌는지 볼 수 있고, 컴파일러가 실제로 받는 코드도 확인 가능함
    • 이게 중요한 이유는 매크로가 마법처럼 숨겨진 기능이 아니라, 코드 변환을 명시적으로 다룰 수 있는 도구라는 점 때문임

리스트가 끝까지 간다

  • Lisp의 이름 자체가 LISt Processing에서 왔고, 이 글은 그 이름이 그냥 역사적 농담이 아니라고 설명함

    • Lisp 프로그램은 symbolic expression, 줄여서 s-expression의 연속으로 구성됨
    • s-expression은 원자(atom)이거나 리스트임. 숫자, 문자열, 심볼 같은 값도 있고, 그 값들을 담은 리스트도 있음
  • Lisp의 독특한 힘은 코드와 데이터가 같은 재료로 만들어진다는 데서 나옴

    • ( + 1 2 ) 같은 리스트는 평가되면 + 심볼이 함수로 해석되어 3을 만듦
    • 그런데 앞에 quote를 붙이면 같은 리스트가 실행되지 않고 데이터로 남음
    • 이 성질을 동형성(homoiconicity)이라고 부름. 코드도 리스트고 데이터도 리스트라서, 코드를 데이터처럼 조작할 수 있음
  • 이 구조 때문에 Lisp 매크로는 단순 치환보다 훨씬 강함

    • 코드가 리스트라면 리스트를 바꾸는 방식으로 소스코드를 바꿀 수 있음
    • 결과적으로 '프로그램을 쓰는 프로그램'을 자연스럽게 만들 수 있고, 다른 언어들이 수십 년 동안 흉내 내려 한 능력이 여기서 나옴

REPL은 콘솔이 아니라 살아 있는 프로그램의 창임

  • Lisp 개발자는 보통 에디터에서 파일만 열고 시작하지 않음. 먼저 Lisp 프로세스를 띄우고, REPL에 붙이고, 그 프로세스 안으로 프로젝트를 로드함

    • REPL은 Read-Eval-Print Loop의 약자고, 코드를 읽고 평가하고 결과를 출력하는 인터랙티브 환경임
    • 중요한 건 이 REPL이 현재 실행 중인 Lisp 프로세스와 연결되어 있다는 점임
  • 일반적인 개발 흐름은 작성, 컴파일, 실행, 디버깅의 반복임. Lisp는 이 흐름이 꽤 다름

    • 실행 중인 프로세스에 함수를 평가해 넣고, 바로 결과를 보고, 필요하면 다시 정의함
    • 함수 하나만 따로 테스트할 수도 있고, 데이터베이스 쿼리, 변수 검사, 디버깅 같은 작업도 같은 환경에서 바로 할 수 있음
    • Lisp 프로세스는 며칠에서 몇 주 동안 계속 살아 있을 수 있고, 그 안에서 함수, 매크로, 변수가 계속 재정의됨
  • 글쓴이는 이걸 현대 프론트엔드의 핫 리로딩과 비교함

    • 웹 프론트엔드는 파일 저장만 해도 번들러가 변경된 모듈을 다시 컴파일하고, 웹소켓으로 페이지에 변경분을 주입함
    • 하지만 Lisp에서는 핫 리로딩이 별도 도구가 아니라 코드 평가의 기본 결과에 가까움
    • 심볼을 다시 정의하면 함수든 데이터든 매크로든 실행 중인 시스템이 새 정의를 집어듦

ℹ️참고

> 글쓴이는 Lisp 개발을 '프로그램을 건설하는 것'보다 '프로그램을 진화시키는 것'에 가깝다고 표현함. 새 프로세스에 코드가 평가되어 들어가는 순간, 그 살아 있는 시스템 자체가 프로그램이 된다는 얘기임.

확장 가능한 소프트웨어를 만들 때 Lisp가 빛남

  • 글은 Lisp의 언어 확장성과 라이브 시스템이 합쳐지면, 확장 가능한 소프트웨어를 만들기 쉬워진다고 봄

    • 보통 데스크톱 앱은 플러그인 시스템이나 스크립팅 언어로 확장성을 제공함
    • 문제는 개발자가 별도 확장 시스템을 설계하고 유지해야 하고, 사용자는 또 그 API나 스크립트 문법을 배워야 한다는 점임
  • Lisp에서는 내부 DSL을 만들고, 필요하면 그걸 사용자에게 노출하는 방식이 자연스러움

    • 글쓴이는 클라이언트 웹사이트용 CMS 서버에서 서버 사이드 웹페이지를 생성하는 매크로를 만들었다고 함
    • 이 DSL을 사용자에게 열어주면, 사용자는 별도 템플릿 언어의 {{ user_name }}{% for %} 같은 문법을 배우는 대신 Lisp 표현식 안에서 변수, 반복, 문자열 포맷을 그대로 쓸 수 있음
    • 템플릿도 Lisp 코드라서 조건문, 재귀, 고차 함수, REPL 디버깅까지 그대로 따라옴
  • 수학 소프트웨어 예시도 나옴. 사용자가 수식을 쓰면 Cartesian graph에 렌더링하는 프로그램에서, 수학과 드로잉을 위한 작은 DSL을 만들었다는 얘기

    • 사용자는 복잡한 렌더링 코드를 몰라도 짧은 코드로 곡선을 그릴 수 있음
    • Lisp이기 때문에 변수, 헬퍼 함수, 루프를 써서 여러 곡선을 생성하는 것도 가능함
  • 실제 역사적 사례로는 AutoCAD와 Emacs가 나옴

    • AutoCAD는 AutoLISP로 반복 작업 자동화와 복잡한 기하 구조 생성을 지원해왔음
    • Emacs는 자체 Lisp 방언으로 대부분이 구현되어 있고, PDF 리더, 웹 브라우저, 이메일 클라이언트, RSS 리더, 터미널 멀티플렉서, Git 클라이언트, 음악 플레이어, 채팅 클라이언트, 스프레드시트, IRC 클라이언트, 윈도 매니저까지 확장된 사례로 소개됨

그래서 Lisp의 시대는 왔냐면, 안 왔고 아마 안 올 가능성이 큼

  • 글은 Lisp 찬양으로만 끝나지 않음. 언젠가 Lisp의 시대가 와서 대학에서 널리 가르치고, 회사들이 Lisp 개발자를 쉽게 뽑고, 모두가 REPL 기반 개발을 하게 될 거라는 기대는 결국 실현되지 않았다고 선을 그음

    • Lisp는 1960년대부터 살아남았고, Fortran 다음으로 오래된 현역 언어 중 하나임
    • 수많은 언어가 Lisp에서 영감을 받았지만, Lisp의 핵심 조합을 그대로 대중화한 언어는 많지 않음
  • 결론은 'Lisp를 실무 기본 언어로 쓰자'가 아니라 'Lisp를 배우면 프로그래밍 언어의 가능 범위를 다시 보게 된다'에 가까움

    • 매크로, REPL, 인터랙티브 환경, 확장 가능한 소프트웨어 모델 중 하나만 떼어서는 Lisp를 설명하기 어렵다는 게 글의 입장임
    • 이 기능들이 한데 묶였을 때 Lisp다운 개발 경험이 만들어짐
    • 그래서 Lisp를 안 쓰게 되더라도, 한 번 배워두면 다른 언어를 볼 때 '여기엔 뭐가 빠져 있지?'라는 질문을 하게 됨

기술 맥락

  • Lisp가 매크로를 중요하게 보는 이유는 단순히 코드를 짧게 만들기 위해서가 아니에요. 함수 호출 전에 인자가 평가되는 일반 언어 모델로는 새 제어 구조를 만들기 어렵기 때문에, Lisp는 코드를 데이터로 받아 변환하는 쪽을 언어의 핵심 능력으로 둔 거예요.

  • REPL 중심 개발이 강한 이유는 피드백 루프가 파일 단위가 아니라 실행 중인 프로세스 단위로 줄어들기 때문이에요. 서버를 다시 띄우고 전체 앱을 재시작하는 대신, 함수 하나를 바꿔서 살아 있는 환경에 바로 밀어 넣을 수 있으니 탐색과 디버깅 방식이 달라져요.

  • DSL 이야기가 중요한 이유는 확장성을 플러그인 API로 따로 설계하지 않아도 된다는 점이에요. 내부에서 문제를 풀려고 만든 매크로와 표현식을 사용자에게 제한적으로 열어주면, 사용자는 별도 템플릿 언어나 스크립트 런타임을 배우지 않고도 같은 언어의 힘을 일부 가져갈 수 있어요.

  • 다만 이 선택에는 비용도 있어요. 매크로와 동형성은 강력하지만, 팀 전체가 코드 확장 방식을 이해하지 못하면 추상화가 너무 멀리 가기 쉬워요. 글이 Lisp를 '쉽다'고 말하지 않고 '가파른 학습 곡선이 있다'고 인정하는 이유도 여기 있어요.

이 글의 재미는 'Lisp가 제일 세다'는 오래된 떡밥을 문법 취향 문제가 아니라 개발 워크플로와 확장성 문제로 다시 설명한다는 데 있음. 당장 실무 언어를 갈아타자는 얘기보다는, 언어가 문제에 맞춰 변할 수 있다는 감각을 배워두면 다른 스택을 볼 때도 눈이 달라진다는 쪽에 가깝다.

댓글

댓글

댓글을 불러오는 중...

backend

EDB 포스트그레스 AI, 포레스터 멀티모델 데이터 플랫폼 리더 선정

EDB의 AI 데이터 플랫폼 EDB 포스트그레스 AI가 2026년 2분기 포레스터 웨이브 멀티모델 데이터 플랫폼 보고서에서 리더로 선정됐음. 트랜잭션, 분석, AI 워크로드를 하나의 플랫폼에서 다루는 흐름이 강해지는 가운데, EDB는 전략과 현재 제공 기능 모두에서 높은 평가를 받았다고 밝힘.

backend

Bun, Zig에서 Rust로 갈아탔다: 11일짜리 초대형 런타임 포팅 실험

Bun 팀이 53만 줄이 넘는 Zig 코드베이스를 Rust로 기계적으로 포팅했고, Bun v1.4.0부터 Rust 기반으로 전환될 예정임. 핵심 이유는 성능보다 안정성이었고, use-after-free, double-free, 메모리 누수 같은 문제를 컴파일러와 타입 시스템으로 더 빨리 잡기 위해서였음. Claude Code 워크플로 64개를 병렬로 돌려 11일 만에 전 플랫폼 테스트 통과까지 밀어붙인 사례라, LLM 기반 대규모 코드 마이그레이션의 꽤 강한 신호탄임.

backend

시카고 미술관 API에 숨어 있는 ‘조회수 낮은 작품’ 필드

시카고 미술관 API에는 웹사이트에서 거의 조회되지 않은 작품을 표시하는 불리언 필드가 있다. 기준은 2010년 1월 1일 이후 조회수 200회 미만으로, API 설계 안에 꽤 인간적인 큐레이션 포인트가 숨어 있는 셈이다.

backend

유엔넷 DB 관리 솔루션, 오라클에서 PostgreSQL로 가는 일본 시장 노린다

유엔넷이 일본 PostgreSQL 기술지원 기업 뮤텍과 독점 공급 계약을 맺고 DB 성능 분석 솔루션 타란튜너를 일본에 공급해. 오라클에서 PostgreSQL로 전환하는 기업이 늘면서 SQL 지연, 잠금 경합, 실행 계획 비교 같은 운영 관리 수요를 겨냥한 움직임이야.

backend

메타, 낡은 DDR4 메모리를 새 서버에서 재활용하려고 CXL 칩까지 만들었다

메타가 기존 서버에서 빼낸 DDR4 메모리를 새 DDR5 기반 서버에 붙이기 위해 자체 CXL ASIC ‘Vistara’를 만들었다. 수백만 대 규모 서버 플릿 중 약 40%는 메모리 증설이 어려운데, 메모리 자체의 수명은 서버보다 길다는 점을 활용한 접근이다. Vistara는 DDR4를 별도 NUMA 노드로 노출하고, 머신러닝 추론·빅데이터·DB·캐시·CI/CD 워크로드에서 메모리 부족으로 인한 실패와 재시작 부담을 줄이는 데 쓰인다.