Sök…
S-Expression
Ett uttryck i Scheme är vad som kommer att bli avrättat. Ett S-uttryck, som det vanligtvis kallas, börjar med ett ( och slutar med a ) . Den första medlemmen i uttrycket är vad som kommer att bli avrättad. Följande medlem av uttrycket är parametrarna som kommer att skickas till uttrycket under utvärderingen av uttrycket.
Till exempel lägga till siffror:
(+ 1 2 3)
I detta fall är + en symbol för en tilläggsfunktion som tar flera parametrar. 1 , 2 och 3 skickas till + -funktionen.
S-Expression kan innehålla S-Expressions som parametrar som visas i följande exempel:
(if (< x y)
x
y)
Vilket kan läsas som om x är mindre än y return x annars returnerar y . I detta exempel utvärderar vi villkorsuttrycket, beroende på det upplösta värdet kommer antingen x eller y att returneras. Det kan utvärderas till detta
(if #t x y)
x
(if #f x y)
y
Ett mindre uppenbart exempel för nybörjare är att ha ett S-Expression som en del av den första medlemmen i ett S-Expression. På detta sätt kan vi ändra beteendet hos en metod genom att ändra funktionen som kommer att kallas utan att behöva skapa grenar med samma parametrar. Här är ett snabbt exempel på ett uttryck som antingen lägger till eller subtraherar nummer om x är under y.
((if (< x y) + -)
1 2 3)
Om x är under y , kommer uttrycket att utvärderas som:
(+ 1 2 3)
6
annat
(- 1 2 3)
-4
Som ni kan se tillåter Scheman att programmeraren kan bygga upp komplex kodkod och samtidigt ge programmeraren verktyg för att förhindra duplikering av kod. På andra språk kunde vi se samma exempel skrivet som sådant:
(om (<xy) (+ 1 2 3) (- 1 2 3))
Problemet med den här metoden är att vi duplicerar mycket kod medan det enda som ändras är metoden som heter. Detta exempel är ganska enkelt men med mer skick kunde vi se många liknande linjer duplicerade.
Enkel låt makro
Låtuttryck i schema är i själva verket makron. De kan uttryckas med lambdas. En enkel låt kan se ut så här:
(let ((x 1) (y 2))
(+ x y))
Det kommer att returnera 3 när värdet på det sista uttrycket för låtkroppen returneras. Som du kan se är ett låtuttryck verkligen att utföra något. Om vi översätter denna del av koden med lambdas, skulle vi få något liknande:
((lambda (x y) (+ x y)) 1 2)
Här kan vi se att vi ringer den anonyma lambdaen med 1 och 2 direkt. Så resultatet i detta fall är också 3.
Med det i åtanke förstår vi att ett låtuttryck består av två delar. Det har parametrar och en kropp som en lambda har, men skillnaden är att låta uttryck kallas efter direkt efter deras utvärdering.
För att förklara hur ett låtuttryck fungerar från en abstrakt till konkret syn, skulle det se ut så här.
(let params body ...)
(let (param1 param2 ...) body ...)
(let ((p1 val1) (p2 val2) ...) body ...)
Parametrarna är en lista över par (name value) som ska användas i kroppen av let .
Varför använda låta uttryck?
Låt uttryck är särskilt användbara för att lagra variabler på en metod precis som initialiseringar av variabel på c-liknande språk. Det är gynnsamt att använda define eftersom variablerna försvinner av låtuttrycket ... Att använda en definiera faktiskt lägger till en variabel i den aktuella exekveringsmiljön. Variabler som läggs till i den globala miljön kan inte tas bort. Låt uttrycket är säkert att använda var som helst. Det kan också användas för spökvariabler utan att beröra föräldrarnas omfattning.
Till exempel:
(let ((x 1))
(let ((x 2) (y x))
(display x)
(display y))
(display x))
Det kommer att skriva ut:
2
1
1
I detta fall definieras x med 1 och spöks sedan av x i den andra let med värdet 2 . Variabeln y initieras med värdet x för överordnad omfattning. Efter att det inre let har utförts visar det initiala värdet på x med 1. Det inre let ändrade inte värdet på överordnade omfång.
När du behöver initiera variabler bör du använda låta uttryck som detta:
(let (
(user (get-current-user session))
(db (get-current-db session))
(ids (get-active-ids session))
)
(mark-task-completed db user ids)
(change-last-logged db user)
(db-commit db))
Här i detta exempel initialiseras variablerna och används flera gånger i kodblocket. Och när låtuttrycket är klart frigörs variablerna automatiskt eftersom de inte är nödvändiga längre.
Prickad syntax för par
Det finns en viss syntax som gör att vi kan skriva cons på ett mer kompakt sätt än att använda cons .
Ett par kan skrivas som sådant:
'(1 . 2) == (cons 1 2)
Den stora skillnaden är att vi kan skapa pairs med offert. Annars skulle Scheme skapa en ordentlig lista (1 . (2 . '())) .
Punktsyntaxen tvingar uttrycket att endast ha två medlemmar. Varje medlem kan vara av valfri typ inklusive par.
'(1 . (2 . (3 . 4)))
> (1 2 3 . 4)
Observera att den felaktiga listan ska visas med en punkt i slutet för att visa att cdr för det sista paret i listan inte är den tomma listan '() .
Detta sätt att visa listor är ibland förvirrande eftersom följande uttryck skulle uttryckas inte som man skulle förvänta sig det.
'((1 . 2) . ( 3 . 4))
> ((1 . 2) 3 . 4)
Eftersom listan vanligtvis hoppar över . , det första argumentet i listan skulle vara (1 . 2) , det andra argumentet skulle vara 3 men eftersom listan är olämplig är det sista . visas för att visa att det sista elementet i listan inte är '() . Även tänkt, uppgifterna visas på ett annat sätt, de interna uppgifterna är som de skapades.