From 0e7bfeb14201d278a51083d695e7479500fb37aa Mon Sep 17 00:00:00 2001 From: netpyoung Date: Tue, 23 Jan 2024 01:49:59 +0900 Subject: [PATCH] add: ch04/lesson_04.md --- src/ch03/lesson_04.md | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/ch03/lesson_04.md diff --git a/src/ch03/lesson_04.md b/src/ch03/lesson_04.md new file mode 100644 index 0000000..3599687 --- /dev/null +++ b/src/ch03/lesson_04.md @@ -0,0 +1,110 @@ +# 레슨 04. 조립과 분해 + +- [원문](https://dept-info.labri.fr/~strandh/Teaching/MTP/Common/David-Lamkins/chapter03-04.html) + +## CONS + + `cons`는 리스트의 가장 기본적인 구성 요소입니다. 이는 함수므로 이의 인자들을 평가합니다. 리스트를 만들때에는 `cons`의 두번째 인자로 `리스트` 혹은 `NIL`이 들어올것입니다. + +``` lisp +(cons 1 nil) +;;=> (1) + +(cons 2 (cons 1 nil)) +;;=> (2 1) + +(cons 3 (cons 2 (cons 1 nil))) +;;=> (3 2 1) +``` + + `cons`는 새로운 항목을 리스트의 시작 부분에 추가합니다. 비어있는 리스트 `( )` 는 `NIL`과 동일하며, + +``` txt +( ) == NIL +``` + +따라서 이렇게 작성할 수 있습니다: + +``` lisp +(cons 1 ()) +;;=> (1) + +(cons 2 (cons 1 ())) +;;=> (2 1) + +(cons 3 (cons 2 (cons 1 ()))) +;;=> (3 2 1) +``` + + 혼란스럽게 느껴진다면, 맞습니다, `NIL`에는 뭔가 특별한 능력이 있습니다. `NIL`은 키워드는 아니지만 자기 자신을 상수 값으로 가지는 리스프의 두개의 심볼 중 하나입니다. 또 다른 심볼은 `T`입니다. + + `( ) == NIL`이란 것과 `NIL`이 스스로 평가된다는 것을 종합해보면, 이는 `(quote ())`를 `()`로 쓸 수 있다는 것을 의미합니다. 그렇지 않았다면, 리스프는 빈 리스트를 처리하기 위해 평가 규칙에 예외를 추가해야 했을 것입니다. + + +## LIST + + 아마 여러분이 눈치챗다면, 중첩된 `cons` 폼으로도 리스트가 만들어질 수 있다는 것은 조금 지루할 수 도 있습니다. `list` 폼은 좀더 명료한 방법으로 동일한 일을 수행합니다: + +``` lisp +(list 1 2 3) +;;=> (1 2 3) +``` + + `list`는 여러 인자를 취할 수 있습니다. `list`는 함수이기에, 이는 인자를 평가합니다: + +``` lisp +(list 1 2 :hello "there" 3) +;;=> (1 2 :HELLO "there" 3) + +(let ((a :this) + (b :and) + (c :that)) + (list a 1 b c 2)) +;;=> (:THIS 1 :AND :THAT 2) +``` + +## **FIRST**와 **REST** + + 리스트가 (첫번째와 나머지) 두 부분으로 만들어졌다고 가정한다면, 여러분은 `first`와 `rest` 두 연산자를 이용하여 리스트의 개별 원소들을 얻을 수 있습니다: + +``` lisp +(setq my-list (quote (1 2 3 4 5))) +;;=> (1 2 3 4 5) + +(first my-list) +;;=> 1 + +(rest my-list) +;;=> (2 3 4 5) + +(first (rest my-list)) +;;=> 2 + +(rest (rest my-list)) +;;=> (3 4 5) + +(first (rest (rest my-list))) +;;=> 3 + +(rest (rest (rest my-list))) +;;=> (4 5) + +(first (rest (rest (rest my-list)))) +;;=> 4 +``` + + `first`와 `rest` 함수를 이리저리 엮는 것은 분명 지루한 작업일 것입니다. 또, 이러한 접근 법은 프로그램에서 특정 요소만을 선택하고자 할때나 혹은 리스트의 길이가 무한일때 잘 먹히지 않을 것입니다. 4장[p 84] 에서 재귀 함수를 정의할때 이러한 문제를 어떻게 해결하는지 살펴볼 것입니다. 나중에 13장에서 [p 150], 리스프가 제공하는 리스트 혹은 시퀀스 속 요소를 선택할 수 있는 함수들을 살펴 볼 것입니다 + + `first`와 `rest`는 꽤 최근 동안 활약해온 `car`와 `cdr` 함수의 이름을 바꾸어 리스프에 추가된 것입니다. 초기 리스프 구현체 중 하나에서 `car`와 `cdr`의 이름이 유례됬고, 이 이름에 기반한 구현체가 이미 오래전에 바뀌었음에도 불구하고 수십년간 고수되었습니다 + + +## 짚고 넘어가기 + +- `cons` +- `list` +- `first` +- `rest` +- `car` +- `cdr` +- `nil` , `( )` +- `T` \ No newline at end of file