레슨 01. 필수 - 신택스(Essential Syntax)

리스트는 괄호로 감싸져있다

리스프에 대해 우선적으로 알아할 것입니다: 괄호로 둘러싸인 모든것은 리스트(list)이다.

여기 예가 있습니다:

(1 2 3 4 5)

(a b c)

(cat 77 dog 89)

앞서 말씀드린대로, 괄호로 둘러싸인 것은 리스트입니다.

이와 같은 말을 들으면, 아마 다음과 같은 의문이 생길 것입니다:

  1. 괄호로 아무것도 없는것을 둘러싼다면?
  2. 괄호로 다른 리스트를 둘러싼다면?

두 경우 모두 대답은 같습니다. 여전히 리스트입니다.

따라서 다음 나오는 것들 또한 리스트입니다:

()

(())

((()))

((a b c))

((1 2) 3 4)

(mouse (monitor 512 342) (keyboard US))

(defun factorial (x) (if (eql x 0) 1 (* x (factorial (- x 1)))))

리스트가 아닌 유일한 경우는 다음 4개의 예제에 나온 것처럼, 좌/우측 괄호가 짝을 이루지 못하는 경우입니다:

(a b c(                   ; (: 2개 // ): 0개

((25 g) 34                ; (: 2개 // ): 1개

((())                     ; (: 3개 // ): 2개

(()))                     ; (: 2개 // ): 3개

크게 신경쓸 부분은 아닙니다: 리스프는 괄호가 일치하지 않으면 않다고 여러분에게 알려 줄 것입니다. 또, 리스프 프로그램을 작성하기 위해 사용하는 편집기 대부분은 자동적으로 일치하는 괄호를 찾는 방법을 제공해 줄 것입니다. 27장에서 편집기에 대해 살펴볼 수 있습니다 [p 227].

리스프에서 리스트는 여러가지가 될 수 있습니다. 가장 일반적인 경우, 리스트는 프로그램이나 데이터가 될 수 있습니다. 그리고 리스트가 스스로 다른 리스트를 만들 수 있기에, 여러분은 복잡한 데이터의 조합과 여러 단계의 리스트 구조로 된 프로그램을 가질 수 있습니다. 이를 잘 이해하는 자에게는 리스프는 엄청난 유연성을 부여해 줄 것이며, 그렇지 않은 자에게는 많은 혼란을 줄 것입니다. 이번장을 계속해서 나아가면서 이러한 혼란을 없애도록 노력해 봅시다.

아톰(Atom)은 공백이나 괄호로 분리된 것이다

이제 여러분은 리스트를 구분할 수 있으며, 괄호 사이에 나타나지만 (리스트가 아닌)단어나 숫자인 것들에 대한 것들을 뭐라고 부르는지 알고 싶을 것입니다. 이러한 것들을 아톰(atom)이라 부릅니다.

그러므로, 다음 단어와 숫자들은 모두 아톰입니다:

1

25

342

mouse

factorial

x

리스프에서는 거의 모든 문자를 이용하여 아톰을 구성할 수 있습니다. 이제부터 문자, 숫자, 구두점 문자들이 있는데 이들 앞뒤에 공백(줄의 시작 또는 끝 포함) 또는 괄호가 있으면 이를 모두 아톰이라고 부르겠습니다. 다음 나오는 것들은 모두 아톰입니다:

-

*

@comport

funny%stuff

9^

case-2

만일 다른 프로그래밍에 대한 경험이 있다면, 한가지 주의해야 할 점은 보통 다른 언어에서 연산자로 예약된 문자들이 리스프에서 아톰으로써 쓰였다면 별다른 의미를 갖지 않는다는 것입니다. 예를들어, case-2는 수학적(arithmetic) 표현식 뺄샘이 들어간게 아니라 여기서는 그져 아톰 그 자체입니다.

공백이나 괄호로 무엇이 아톰인지 구분할 수 있으므로, 아톰과 괄호 혹은 괄호들 사이에 있는 공백을 없앨 수 있습니다. 그러므로, 다음 두 예제는 동일합니다:

(defun factorial (x) (if (eql x 0) 1 (* x (factorial (- x 1)))))

(defun factorial(x)(if(eql x 0)1(* x(factorial(- x 1)))))

사실, 여러분은 절대로 두번째에 나타난것처럼 리스트를 작성해서는 안됩니다. 여러분은 가독성을 향상시키기 위해 리스트를 여러 라인으로 분리시키며 각 라인을 적절히 들여써야 합니다. 이 리스트는 사실 작은 프로그램이며, 다음과 같이 들여쓰면 리스퍼 프로그래머가 읽기 수월해 집니다:

(defun factorial (x)
  (if (eql x 0)
      1
      (* x (factorial (- x 1)))))

지금, 여러분은 이것이 무얼 의미하는지, 이러한 종류의 들여쓰기(indentation)가 무엇인지 대해 걱정할 필요가 없습니다. 이번장을 통해, 여러분은 들여쓰기가 들어간 많은 예제를 접하게 될 것입니다.

계속해서 보여드리는 예제와 함께, 가독성을 향상시키는 들여쓰는 방법에 대해 알려드릴 것입니다. 28장 [p 230]에서 적절한 들여쓰는 법을 포함하여, 리스프의 코딩 스타일에 대해 다룰 것입니다.

짚고 넘어가기

  • 리스트(list)
  • 아톰(atom)