Zoeken…


S-Expressie

Een uitdrukking in Schema wordt uitgevoerd. Een S-expressie, zoals deze meestal wordt genoemd, begint met een ( en eindigt met een ) . Het eerste lid van de uitdrukking is wat er uitgevoerd gaat worden. Het volgende lid van de expressie zijn de parameters die tijdens de evaluatie van de expressie naar de expressie worden verzonden.

Bijvoorbeeld nummers toevoegen:

(+ 1 2 3)

In dit geval is + een symbool voor een toevoegfunctie waarvoor meerdere parameters nodig zijn. 1 , 2 en 3 worden naar de + -functie verzonden.

S-expressie kan S-expressies bevatten als parameters zoals getoond in het volgende voorbeeld:

(if (< x y)
  x
  y)

Die gelezen kan worden alsof x kleiner is dan y retourneer x anders retourneer y . In dit voorbeeld evalueren we de voorwaarde-expressie, afhankelijk van de opgeloste waarde, wordt x of y geretourneerd. Het zou hierop kunnen worden geëvalueerd

(if #t x y)
x
(if #f x y)
y

Een minder voor de hand liggend voorbeeld voor beginners is een S-expressie als onderdeel van het eerste lid van een S-expressie. Op deze manier kunnen we het gedrag van een methode wijzigen door de functie te wijzigen die wordt aangeroepen zonder takken met dezelfde parameters te hoeven maken. Hier is een snel voorbeeld van een uitdrukking die getallen optelt of aftrekt als x onder y ligt.

((if (< x y) + -) 
  1 2 3)

Als x lager is dan y , wordt de uitdrukking geëvalueerd als:

(+ 1 2 3)
6

anders-

(- 1 2 3)
-4

Zoals u kunt zien, laat Scheme de programmeur toe om een complex stuk code op te bouwen, terwijl de programmeur de tools krijgt om dubbele code te voorkomen. In andere talen zien we hetzelfde voorbeeld als volgt geschreven:

(if (<xy) (+ 1 2 3) (- 1 2 3))

Het probleem met deze methode is dat we veel code dupliceren, terwijl het enige dat verandert de methode wordt genoemd. Dit voorbeeld is vrij eenvoudig, maar met meer voorwaarden zien we veel vergelijkbare regels gedupliceerd.

Eenvoudig laten macro

De let-uitdrukkingen in schema zijn in feite macro's. Ze kunnen worden uitgedrukt met lambdas. Een simpele let kan er zo uitzien:

(let ((x 1) (y 2))
  (+ x y))

Het zal 3 teruggeven als de waarde van de laatste uitdrukking van het let-lichaam wordt geretourneerd. Zoals u kunt zien, voert een let-expressie daadwerkelijk iets uit. Als we dit deel van de code vertalen met lambdas, zouden we zoiets krijgen:

((lambda (x y) (+ x y)) 1 2)

Hier kunnen we zien dat we de anonieme lambda met 1 en 2 direct bellen. Het resultaat is in dit geval dus ook 3.

Met dat in gedachten begrijpen we dat een let-expressie bestaat uit 2 delen. Het heeft parameters en een lichaam zoals een lambda heeft, maar het verschil is dat expressie direct na hun evaluatie wordt genoemd.

Om uit te leggen hoe een laat-uitdrukking van een abstracte naar een concrete weergave werkt, zou het er zo uitzien.

(let params body ...)
(let (param1 param2 ...) body ...)
(let ((p1 val1) (p2 val2) ...) body ...)

De parameters zijn een lijst met een paar (name value) die in de body van de let moet worden gebruikt.

Waarom zou je expressie gebruiken?

Laat uitdrukkingen vooral nuttig zijn om variabelen op te slaan in een methode, net als initialisaties van variabele in c-achtige talen. Het is gunstig voor het gebruik van define want uit de let-expressie zijn de variabelen verdwenen ... Het gebruik van een define is eigenlijk een variabele toevoegen aan de huidige uitvoeringsomgeving. Variabelen die zijn toegevoegd aan de globale omgeving kunnen niet worden verwijderd. Laat expressie veilig zijn om overal te gebruiken. Het kan ook worden gebruikt om variabelen te ghosten zonder de bovenliggende scopes aan te raken.

Bijvoorbeeld:

(let ((x 1))
  (let ((x 2) (y x))
    (display x)
    (display y))
  (display x))

Het zal afdrukken:

2
1
1

In dit geval wordt x gedefinieerd met 1 en vervolgens ghosted door de x in de tweede let met de waarde 2 . De variabele y wordt geïnitieerd met de waarde x van het bovenliggende bereik. Nadat de inner let expressie is uitgevoerd, wordt de initiële waarde van x met 1. De inner let expressie heeft de waarde van het bovenliggende bereik niet gewijzigd.

Wanneer u variabelen moet initialiseren, moet u let-uitdrukkingen als deze gebruiken:

(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))

Hier in dit voorbeeld worden de variabelen geïnitialiseerd en meerdere keren in het codeblok gebruikt. En wanneer de let-expressie is voltooid, worden de variabelen automatisch vrijgegeven omdat ze niet meer nodig zijn.

Gestippelde syntaxis voor paren

Er is een bepaalde syntaxis waarmee we de cons cel op een compactere manier kunnen schrijven dan met de cons constructor.

Een paar kan als volgt worden geschreven:

'(1 . 2) == (cons 1 2)

Het grote verschil is dat we pairs kunnen maken met behulp van citaat. Anders maakt Scheme een juiste lijst (1 . (2 . '())) .

De puntsyntaxis dwingt de uitdrukking slechts 2 leden te hebben. Elk lid kan van elk type zijn, inclusief paren.

'(1 . (2 . (3 . 4)))
> (1 2 3 . 4)

Merk op dat de onjuiste lijst moet worden weergegeven met een punt aan het einde om aan te geven dat de cdr van het laatste paar van de lijst niet de lege lijst is '() .

Deze manier om lijsten weer te geven is soms verwarrend omdat de volgende uitdrukking zou worden uitgedrukt niet zoals men zou verwachten.

'((1 . 2) . ( 3 . 4))
> ((1 . 2) 3 . 4)

Sinds lijst meestal overslaan . , het eerste argument van de lijst zou zijn (1 . 2) , het tweede argument zou 3 maar omdat de lijst onjuist is, is het laatste . wordt getoond om aan te geven dat het laatste element van de lijst niet '() . Zelfs gedacht, de gegevens worden op een andere manier weergegeven, de interne gegevens zijn zoals ze zijn gemaakt.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow