Теперь, когда вы знаете о переменных и функциях, обратимся к спискам в Scheme.
До разговора о списках необходимо упомянуть разницу между неделимыми значениями и списками.
В предыдущем уроке вы уже видели неделимые значения, которые мы присвоили переменным. Неделимое значение — это одно-единственное значение. Так, мы можем присвоить переменной «x» значение 8 следующим утверждением:
(let* ( (x 8) ) x)
(We added the expression x at the end to print out
the value assigned to xnormally 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
)
Заметьте, что после первого апострофа не надо больше ставить апостроф перед внутренними списками. Введите это выражение и посмотрите, что получится.
Вы заметите, что возвращённый результат — не список одиночных неделимых значений, а список, содержащий буквальное значение ("GIMP"), список (1 2 3) и т. д.
Полезно думать о списках, как состоящих из «головы» и «хвоста». Голова — первый элемент списка, хвост — остаток списка. Вы увидите, почему это важно, как речь пойдёт о сложении списков и о доступе к элементам списка.
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 () )
Можно использовать ранее декларированные переменные вместо буквальных значений.
Создать список из буквальных значений и переменных можно с помощью функции 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).
Чтобы достать значения из списка, используйте функции car и cdr, которые возвращают первый элемент списка и остаток списка, соответственно. Назначение этих функций совпадает с терминологией голова-хвост, описанной выше.
car возвращает первый элемент списка (голова списка). Список не может быть пустым. Следующее выражение вернёт первое значение:
(car '("первый" 2 "третий"))
то есть
"первый"
cdr возвращает остаток списка после первого элемента (хвост списка). Если в списке только один элемент, то возвращается пустой список.
(cdr '("первый" 2 "третий"))
возвращает
(2 "третий")
тогда как
(cdr '("один единственный"))
возвращает
()
Теперь, когда мы можем достать первый элемент списка и всё остальное, поговорим о том, как достать другие элементы (второй, третий, …) списка. Существует несколько вспомогательных функций, позволяющие достать, например, голову хвоста списка (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!
|
Примечание |
|---|---|
|
В Scheme точка с запятой ( |