We hebben u getraind in variabelen en functies en leiden u nu naar de modderige moerassen van lijsten in Scheme.
Voordat we meer over lijsten gaan praten, is het noodzakelijk dat u het verschil weet tussen atomic-waarden en lijsten.
U hebt al enkele atomic-waarden gezien toen we variabelen initialiseerden in de vorige les. Een atomic-waarde is een enkele waarde. Dus, bijvoorbeeld, we kunnen de variabele “x
” toewijzen aan de enkele waarde 8 in het volgende argument:
(let* ( (x 8) ) x)
(We hebben de uitdrukking x
aan het einde toegevoegd om de waarde af te drukken die werd toegewezen aan x
— normaal gesproken zou u dat niet hoeven te doen. Merk op hoe let*
net als een functie werkt: De waarde van het laatste argument is de teruggegeven waarde.)
Een variabele mag ook verwijzen naar een lijst met waarden, in plaats van naar een enkele waarde. We zouden, om de variabele x
toe te wijzen aan de lijst met waarden 1, 3, 5, typen:
(let* ( (x '(1 3 5))) x)
Probeer beide argumenten in de Script-Fu Console en merk op hoe het antwoord geeft. Wanneer u het eerste argument intypt, antwoordt het eenvoudigweg met het resultaat:
8
Echter, wanneer u het andere argument intypt, antwoordt het met het volgende resultaat:
(1 3 5)
Wanneer het antwoord met de waarde 8, informeert het u dat x
de atomic-waarde 8 bevat. Echter, wanneer het antwoord met (1 3 5)
, dan informeert het u dat x
niet een enkele waarde bevat, maar een lijst met waarden. Merk op dat er geen komma's in onze declaratie of toewijzing van de lijst staan, noch in het afgedrukte resultaat.
De syntaxis voor het definiëren van een lijst is:
'(a b c)
waar a
, b
en c
letterlijk zijn. We gebruiken de apostrof ('
) om aan te geven dat wat volgt in de haakjes een lijst is met letterlijke waarden, in plaats van een functie of uitdrukking.
Een lege lijst kan ook als zodanig worden gedefinieerd:
'()
of nog eenvoudiger:
()
Lijsten mogen atomic-waarden bevatten, maar ook andere lijsten:
(let* ( (x '("GIMP" (1 2 3) ("is" ("fantastisch" () ) ) ) ) ) x )
Merk op dat, na de eerste apostrof, u niet langer een apostrof hoeft te gebruiken bij het definiëren van de binnenste lijsten. Ga door en kopieer het argument in de Script-Fu Console en kijk wat het teruggeeft.
Het zou u moeten opvallen dat het teruggegeven resultaat niet een lijst is met enkele, atomic-waarden; in plaats daarvan is het een lijst met letterlijk ("GIMP")
, de lijst (1 2 3)
, etc.
Het is nuttig om aan lijsten te denken als dat ze zijn samengesteld uit een “kop” en een “staart”. De kop is het eerste element van de lijst, de staart is de rest van de lijst. U zult zien waarom dit belangrijk is als we bespreken hoe lijsten toe te voegen en hoe toegang te krijgen tot elementen in de lijst.
Een van de meer veel gebruikte functies die u zult tegenkomen is de functie cons. Het neemt een waarde en plaatst die als zijn tweede argument, een lijst. In het vorige gedeelte stelde ik voor dat u aan een lijst denkt als te zijn samengesteld uit een element (de kop) en de rest van de lijst (de staart). Dat is precies hoe cons functioneert — het voegt een element toe aan de kop van een lijst. Dus, u zou als volgt een lijst kunnen maken:
(cons 1 '(2 3 4) )
Het resultaat is de lijst (1 2 3 4)
.
U zou ook een lijst met een element kunnen maken:
(cons 1 () )
U mag eerder gedeclareerde variabelen gebruiken in plaats van elke letterlijke, zoals u al zou verwachten.
Definiëren van een lijst die is samengesteld uit letterlijken of eerder gedeclareerde variabelen, gebruik de functie list
:
(list 5 4 3 a b c)
Dat zal een lijst samenstellen en teruggeven die de waarden bevat van de variabelen a
, b
en c
. Bijvoorbeeld:
(let* ( (a 1) (b 2) (c 3) ) (list 5 4 3 a b c) )
Deze code maakt de lijst (5 4 3 1 2 3)
.
Gebruik, voor toegang tot de waarden in een lijst, de functies car
en cdr
, die respectievelijk het eerste element van de lijst teruggeven en de rest van de lijst. Deze functies verdelen de lijst in de constructie kop::staart, die ik eerder vermeldde.
car
geeft het eerste element terug uit de lijst (de kop van de lijst). De lijst moet niet null zijn (niet leeg). Dus, het volgende geeft het eerste element van de lijst terug:
(car '("eerste" 2 "derde"))
wat is:
"eerste"
cdr
geeft de rest van de lijst terug, na het eerste element (de staart van de lijst). Als er slechts een element in de lijst staat, geeft het een lege lijst terug.
(cdr '("eerste" 2 "derde"))
geeft terug:
(2 "derde")
terwijl het volgende:
(cdr '("de enige echte"))
geeft terug:
()
OK, fantastisch, we kunnen het eerste element in een lijst ophalen, en ook de rest van de lijst, maar hoe krijgen we toegang tot het tweede, derde of andere elementen van een list? Er bestaan verscheidene "handige" functies voor toegang tot, bijvoorbeeld, de kop van de kop van de staart van een lijst (caadr
), de staart van de staart van een lijst (cddr
), etc.
De basis conventie voor de naam is gemakkelijk: De a's en d's geven de koppen en staarten van de lijsten aan, dus
(car (cdr (car x) ) )
zou kunnen worden geschreven als:
(cadar x)
Om wat te oefenen met functies voor toegang tot lijsten, probeer het volgende in te typen (behalve dat alles op een regel moet als u de console gebruikt); gebruik verschillende variaties van car
en cdr
om toegang te krijgen tot de verschillende elementen in de lijst:
(let* ( (x '( (1 2 (3 4 5) 6) 7 8 (9 10) ) ) ) ; plaats uw code voor car/cdr hier )
Probeer toegang te krijgen tot het getal 3 in de lijst door slechts twee functie-aanroepen te gebruiken. Als u dat kunt doen, bent u op weg om een Script-Fu Master te worden!
Opmerking | |
---|---|
In Scheme markeert een puntkomma ( |