Již umíte pracovat s proměnnými a funkcemi, je na čase vydat se za tajemstvím seznamů (anglicky lists, které tvoří důležitou součást Scheme.
Dříve, než si o seznamech povíme více, musíte pochopit rozdíl mezi atomickými hodnotami a seznamy.
You've already seen atomic values when we initialized
variables in the previous lesson. An atomic value is a single
value. So, for example, we can assign the variable
„x
“ the
single value of 8 in the following statement:
(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.)
Proměnná může také odkazovat na seznam hodnot, ne na hodnotu jedinou. Přiřadit proměnné x
seznam hodnot 1, 3, 5 lze takto:
(let* ( (x '(1 3 5))) x)
Zkuste oba výroky ve Script-Fu konzoli a sledujte reakci. První výrok vrátí výsledek:
8
Druhý výrok však vrátí následující výsledek:
(1 3 5)
When it replies with the value 8 it is informing you that
x
contains the atomic value 8. However,
when it replies with (1 3 5)
, it is
then informing you that
x
contains not a single value, but a list
of values. Notice that there are no commas in our declaration
or assignment of the list, nor in the printed result.
Syntaxe definice seznamu je následující:
'(a b c)
where a
, b
, and
c
are literals. We use the apostrophe
('
)
to indicate that what follows in the parentheses is a list of
literal values, rather than a function or expression.
Prázdný seznam lze definovat následujícím způsobem:
'()
nebo jednodušeji:
()
Seznamy mohou obsahovat atomické hodnoty i další seznamy:
(let* ( (x '("GIMP" (1 2 3) ("is" ("great" () ) ) ) ) ) x )
Všimněte si, že za prvním apostrofem již není, pro vnitřní seznamy, apostrofy používat. Přepiště výrok do jedné řádky, vložte do Script-Fu konzole, vyzkoušejte a prohlédněte si výsledek.
Vrácený výsledek není seznam jednotlivých atomických hodnot, ale obsahuje literál ("GIMP")
, seznam (1 2 3)
atd.
O seznamech je často užitečné přemýšlet jako o útvarech složených z hlavičky a ocásku (anglicky head a tail). Hlavička je první položka seznamu, zbývající položky tvoří ocásek. Bude to užitečné, až budeme mluvit o spojování seznamů a přístupu k jednotlivým prvkům seznamu.
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) )
Výsledkem je seznam (1 2 3 4)
.
Lze takto vytvořit i seznam s jedním prvkem:
(cons 1 () )
Místo kteréhokoliv literálu můžete samozřejmě použít dříve deklarovanou proměnnou.
To define a list composed of literals or previously declared
variables, use the list
function:
(list 5 4 3 a b c)
Tak se vytvoří a vrátí seznam obsahující hodnoty proměnných a
, b
a c
. Například:
(let* ( (a 1) (b 2) (c 3) ) (list 5 4 3 a b c) )
Tento kód vytvoří seznam (5 4 3 1 2 3)
.
To access the values in a list, use the functions
car
and cdr
,
which return the first element of the list and the rest of the list,
respectively. These functions break the list down into the head::tail
construct I mentioned earlier.
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 '("first" 2 "third"))
vrátí:
"first"
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 '("first" 2 "third"))
vrací:
(2 "third")
zatímco následující:
(cdr '("one and only"))
vrací:
()
Výborně, již umíme získat první prvek ze seznamu i zbytek seznamu. Jak ale přistupovat ke druhému, třetímu nebo jinému prvku seznamu? K tomuto účelu existuje řada praktických funkcí, např. hlavička hlavičky ocásku seznamu (caadr
), ocásek ocásku seznamu (cddr
) atd.
Konvence pro pojemnovávání takových to funkcí je velmi jednoduchá. Písmena a
představují hlavičky, písmena d
představují ocásky. Například:
(car (cdr (car x) ) )
lze jednodušeji zapsat jako:
(cadar x)
To get some practice with list-accessing functions, try typing in the
following (except all on one line if you're using the console); use
different variations of car
and
cdr
to access the different elements of the list:
(let* ( (x '( (1 2 (3 4 5) 6) 7 8 (9 10) ) ) ) ; place your car/cdr code here )
Pokuste se získat číslo tři pouze dvěma voláními funkce. Pokud se vám to podaří, možná se z vás stane Mistr Script-Fu!
Poznámka | |
---|---|
In Scheme, a semicolon ( |