생각보다 관심있는 사람들 있는 것 같아서 느낀 것만 대충 써 볼게. 난 지금 원래 프롤로그로 짜던 프로젝트가 성능 병목이 너무 심해서 머큐리로 포팅하는 중. 프롤로그 건너뛰고 바로 머큐리 쓰는 사람은 거의 없을 테니까 프롤로그와 비교해서 차이점 중심으로 정리.


0. 훨씬 빠름. 이건 뭐 당연한 거지.


1. 타입시스템이 있음. 언어를 많이 써본게 아니라서 구체적으로 어떤 시스템으로 분류되는지는 모르겠지만 아무튼 제대로 된 타입 시스템이 있음. 느낌상으론 하스켈이나 러스트랑 비슷해. 물론 러스트처럼 메모리 관리에 편집적인게 아니라서 직접적 재귀도 허용. 일단 타입을 쓸 수 있다는 것만으로 마음의 평화가 오고 에러도 컴파일 타임에 땍땍거리면서 잘 잡아줌.


근데 즉시적 생산성이 떨어지는 것도 사실이야. 프롤로그에서는 표현 가능한 모든 항이 Herbrand universe의 원소라는 전제 덕분에 공짜로 주어지는 게 많지. "write(X)" 로 X를 출력하고 "X =.." 로 X를 분해할 수 있는게 무슨 타입 하나마다 ad hoc 으로 대응하는 코드가 있어서 그런게 아니라 무조건 100% 성공하는 거니까. 이걸 못 하게 되면 은근히 스트레스 받음.


2. 모드 분석이 있음. 프롤로그에서 제일 흔한 버그 중 하나가 (A, B) 꼴로 정의된 술어에서 A가 첫번째 unification에서는 제대로 된 값을 바인딩하는데 두번째부터 junk가 나오는 경우. 이럴 때 B에 버그가 있어서 백트래킹으로 A로 되돌아간 후 실패하면 디버거는 A에 문제가 있다고 하니까 머리를 쥐어뜯게 되는데 머큐리는 이런 일이 거의 없음. 왜냐면 주어진 술어가 결정론적(언제나 딱 한가지 값으로 성공)인지, 준결정론적(실패할 수도 있지만 성공할 경우는 결정론적)인지, 비결정론적인지를 '모드'로 미리 선언하게 되어 있거든. 그리고 서브루틴들의 모드가 주어지면 내가 선언한 루틴의 모드가 맞는지도 자동으로 분석해주고, 너무 소극적인 모드를 선언했을 때는 더 강한 모드를 사용 가능하다고 제안도 해 줌.


그런데 이 모드 시스템의 결정적 단점은 프롤로그 프로그래밍의 핵심이라고 할 수 있는 부분 구체화(partial instantiation)를 막아버린다는 것. 내가 원하는 값 X에 대한 정보가 항상 0%아니면 100%인게 아니고, "X = foo(Y) 인 건 알겠는데 Y가 뭔지는 모르겠다" 일 때도 있는 법인데 foo(Y)를 다른 술어에 인자로 넘길 수 없으니까 미치고 팔짝 뛸 노릇이지. 프롤로그에서 머큐리로 넘어오다가 포기하는 사유의 반 이상은 이거 같아.


3. 선언적 디버거가 있음. 이건 이미 언급했으니까 구체적인 설명은 패스. 산업적으로 쓸만한 툴은 아닌 것 같고 실험적 성격이 강한데 그래도 쓰는 재미는 있어. 작동하는 경우에 한해서는 절차적 디버거보다 훨씬 쓰기 편하고.