다른 Lisp들과의 차이점
다른 Lisp들과의 차이점 (Differences with other Lisps)
이 정보는 Common Lisp나 Scheme에 익숙한 프로그래머를 위해 제공돼요.
- Clojure는 대소문자를 구분해요 (case sensitive)
- Clojure는 Lisp-1이에요
()는 nil과 같지 않아요- 리더(reader)는 부수 효과가 없어요
- 키워드(keyword)는 심볼이 아니에요
- 심볼은 저장 위치(storage location)가 아니에요 (Var 참고)
nil은 심볼이 아니에요t는 문법이 아니에요 —true를 쓰세요- 읽기 테이블(read table)은 사용자 프로그램이 접근할 수 없어요
let은 순차적으로 바인딩해요do는 반복 구성소가 아니에요- 꼬리 호출 최적화(tail-call optimization)가 없어요 —
recur를 사용하세요. - syntax-quote는 심볼 해석(resolution)을 수행하므로
`x는'x와 같지 않아요. `(backtick)은 자동 젠심(automatic gensym)을 제공해요.~는 언쿼트(unquote)이고,는 공백(whitespace)이에요- 맵, 벡터, 집합을 위한 리더 문법(reader syntax)이 있어요
cons,first,rest는 구체적인 cons 셀(cell)이 아니라 시퀀스 추상화(sequence abstraction)를 다뤄요- 대부분의 데이터 구조는 불변(immutable)이에요
- lambda는
fn이며, 인자 수(arity)에 따른 오버로딩을 지원해요 =는 동등성(equality) 술어예요- 전역 Var는 (dynamic으로 선언되어 있다면) 어휘적(lexical) 지역 바인딩을 방해하지 않고 동적으로 다시 바인딩될 수 있어요. 동적 바인딩과 어휘적 바인딩을 구분하는 데 특별한 선언은 필요 없어요. Clojure는 Lisp-1이므로 (전역) 함수도 (dynamic으로 표시되어 있다면) 동적으로 다시 바인딩될 수 있어요.
letrec,labels,flet은 없어요 — 자기 참조에는(fn name [args]...)을, 상호 참조에는 letfn을 사용하세요.- Clojure에서
nil은 '아무것도 없음(nothing)'을 뜻해요. 어떤 타입이든 값이 없음을 나타내며, 리스트나 시퀀스에만 국한되지는 않아요. - 빈 컬렉션은
nil과 구별돼요. Clojure는nil과'()를 동일시하지 않아요. false는 두 가능한 불리언 값 중 하나를 뜻하고, 다른 하나는true예요- 컬렉션에는 리스트보다 더 많은 것이 있어요. 빈 컬렉션의 인스턴스를 가질 수 있고, 그중 일부는 리터럴 지원(
[],{},())을 가져요. 따라서 센티널(sentinel) 빈 컬렉션 값은 존재할 수 없어요. - Scheme에서 온 사람이라면,
nil이 여러분의#f관념에 가장 가깝게 매핑될 거예요. - Clojure의 큰 차이점은 시퀀스예요. 시퀀스는 특정 컬렉션이 아니며, 특히 반드시 구체적인 리스트일 필요는 없어요. 빈 컬렉션에 그 요소들의 시퀀스를 요청하면(
seq호출)nil을 반환하며 "하나를 만들어 낼 수 없어요"라고 말하는 거죠. 시퀀스의 마지막 요소에rest를 요청하면 _또 다른 논리적 시퀀스_를 반환해요. 그 시퀀스가 비었는지는 그 시퀀스에 다시seq를 호출해야만 알 수 있어요. 이 덕분에 시퀀스와 시퀀스 프로토콜이 지연(lazy) 될 수 있어요. - 일부 시퀀스 함수는 Scheme과 CL에서 '리스트'(pair/cons)만 조작하고 '빈' 리스트를 나타내는 센티널 값(
'()과nil)을 반환했던 함수들에 대응해요. Clojure의 반환 값은 구체적인 빈 컬렉션을 반환하지 않고 오히려 또 다른 논리적 시퀀스를 반환한다는 점에서 달라요. 일부 시퀀스 함수는 Scheme/CL에 대응물이 없고, Haskell/ML 류 함수에 매핑돼요. 그런 함수 중 일부는 무한하거나 계산된 시퀀스를 반환하는데, 여기서 Scheme/CL 리스트 같은 구체적 데이터 구조와의 비유는 매우 희박해져요. - 컬렉션/데이터 구조와 seq/반복을 구분하는 게 도움이 돼요. CL과 Scheme에서는 둘이 혼동되지만, Clojure에서는 별개예요.
| Clojure | Common Lisp | Scheme | Java | |
|---|---|---|---|---|
| nil이 있나? | nil - 'nothing'을 뜻함 | nil - false 또는 빈 리스트를 뜻함 | - | null |
| true가 있나? | true | - | #t | true (원시 타입) |
| false가 있나? | false | - | #f | false (원시 타입) |
| 조건식이 구분하는 것: | nil 또는 false / 그 외 전부 | nil/non-nil | #f/non-#f | false/true |
| 리스트/시퀀스 라이브러리가 구별되는 구체 타입을 조작하나? | 아니요 - 여러 컬렉션 구현을 가진 seq 추상화 | 예 - cons와 vector | 예 - pair | 아니요 - 여러 컬렉션 구현을 가진 Iterator 추상화 |
| 싱글턴 빈 리스트 값? | 아니요 - 구체 컬렉션 타입의 구별되는 빈 값을 가질 수 있음 | nil | '() | 아니요 |
| 시퀀스 끝 반환값: | seq가 nil을 반환하는 논리적 시퀀스 | nil | '() | false |
| 호스트 null: | nil | 해당 없음 | 해당 없음 | 해당 없음 |
| 호스트 true: | true (박싱됨) | 해당 없음 | 해당 없음 | 해당 없음 |
| 호스트 false: | false (박싱됨) | 해당 없음 | 해당 없음 | 해당 없음 |