3.3. Списки, списки и ещё раз списки
| 3. Инструкция по Script-Fu |

### 3.3. Списки, списки и ещё раз списки

Теперь, когда вы знаете о переменных и функциях, обратимся к спискам в Scheme.

#### 3.3.1. Определение списка

До разговора о списках необходимо упомянуть разницу между неделимыми значениями и списками.

В предыдущем уроке вы уже видели неделимые значения, которые мы присвоили переменным. Неделимое значение — это одно-единственное значение. Так, мы можем присвоить переменной «`x`» значение 8 следующим утверждением:

    (let* ( (x 8) ) x)

(We added the expression `x` at the end to print out the value assigned to `x`—normally you won't need to do this. Notice how `let*` operates just like a function: The value of the last statement is the value returned.)

Переменная также может содержать спискок значений вместо одного значения. Чтобы присвоить переменной `x` список значений 1, 3, 5, нужно ввести:

    (let* ( (x '(1 3 5))) x)

Попробуйте ввести оба утверждения в консоль Script-Fu и посмотрите, что они выводят.

    8

При вводе второго утверждения, выводится следующее:

    (1 3 5)

Когда вывелось значение 8, это значит, что переменная `x` содержит неделимое значение 8. Однако, когда вывелось `(1 3 5)`, это значит, что переменная `x` содержит не одно значение, а список значений. Заметьте, что ни в декларации или присвоении, ни в выведенном результате нет запятых.

Синтаксис для создания списка следующий:

    '(a b c)

Где `a`, `b` и `c` — одиночные значения. Мы используем апостроф (`'`) чтобы указать, что за ним в скобках следует список одиночных значений, а не функция или выражение.

Пустой список создаётся так:

    '()

или так:

    ()

Списки могут содержать как неделимые значения, так и другие листы:

    (let*
       (
            (x
               '("GIMP" (1 2 3) ("is" ("great" () ) ) )
            )
        )
        x
    )

Заметьте, что после первого апострофа не надо больше ставить апостроф перед внутренними списками. Введите это выражение и посмотрите, что получится.

You should notice that the result returned is not a list of single, atomic values; rather, it is a list of a literal `("GIMP")`, the list `(1 2 3)`, etc.

#### 3.3.2. Как думать о списках

Полезно думать о списках, как состоящих из «головы» и «хвоста». Голова — первый элемент списка, хвост — остаток списка. Вы увидите, почему это важно, как речь пойдёт о сложении списков и о доступе к элементам списка.

#### 3.3.3. Создание списков сцеплением (Функция Cons)

One of the more common functions you'll encounter is the cons function. It takes a value and places it to its second argument, a list. From the previous section, I suggested that you think of a list as being composed of an element (the head) and the remainder of the list (the tail). This is exactly how cons functions — it adds an element to the head of a list. Thus, you could create a list as follows:

    (cons 1 '(2 3 4) )

В результате получается список `(1 2 3 4)`.

Можно также создать список с одним элементом:

    (cons 1 () )

Можно использовать ранее декларированные переменные вместо буквальных значений.

#### 3.3.4. Создание списка с помощью функции `list`

Создать список из буквальных значений и переменных можно с помощью функции `list`:

    (list 5 4 3 a b c)

Это создаст и вернёт список, содержащий значения переменных `a`, `b` и `c`. На пример:

            (let*  (
                      (a 1)
                      (b 2)
                      (c 3)
                   )

                   (list 5 4 3 a b c)
            )

Этот сценарий создаёт список `(5 4 3 1 2 3)`.

#### 3.3.5. Доступ к элементам списка

Чтобы достать значения из списка, используйте функции `car` и `cdr`, которые возвращают первый элемент списка и остаток списка, соответственно. Назначение этих функций совпадает с терминологией голова-хвост, описанной выше.

#### 3.3.6. Функция `car`

`car` returns the first element of the list (the head of the list). The list needs to be non-null (not empty). Thus, the following returns the first element of the list:

    (car '("первый" 2 "третий"))

то есть

    "первый"

#### 3.3.7. Функция `cdr`

`cdr` returns the remainder of the list after the first element (the tail of the list). If there is only one element in the list, it returns an empty list.

    (cdr '("первый" 2 "третий"))

возвращает

    (2 "третий")

тогда как

    (cdr '("один единственный"))

возвращает

    ()

#### 3.3.8. Доступ к другим элементам списка

Теперь, когда мы можем достать первый элемент списка и всё остальное, поговорим о том, как достать другие элементы (второй, третий, …) списка. Существует несколько вспомогательных функций, позволяющие достать, например, голову хвоста списка (`caadr`) или хвост хвоста списка (`cddr`), и т.д.

Номенклатура названий проста: a означает голова, d означает хвоста, поэтому

    (car (cdr (car x) ) )

можно написать как:

    (cadar x)

Для практики по доступу к спискам, попробуйте ввести следующее (всё на одной линии, если используете консоль) и, используя функции `car` и `cdr`, достать разные элементы из списка:

            (let* (
                     (x  '( (1 2 (3 4 5) 6)  7  8  (9 10) )
                     )
                  )
                  ; поместите своё выражение с car/cdr здесь
            )

Попробуйте достать число 3 из списка при помощи только двух вызовов функций. Если сможете, то вы на правильном пути стать мастером Script-Fu!

| Примечание
In Scheme, a semicolon (`;`) marks the beginning of a comment. It, and everything that follows it on the same line, are ignored by the script interpreter, so you can use this to add comments to refresh your memory when you look at the script later.

3.2. Переменные и функции |  | 3.4. Первый сценарий Script-Fu

Report a bug in GIMP Report a documentation error