Zoeken…


Voorwaardelijke constructen

In Common Lisp is if het eenvoudigste voorwaardelijke construct. Het heeft de vorm (if test then [else]) en wordt geëvalueerd tot then of de test waar is en else . Het overige deel kan worden weggelaten.

(if (> 3 2)
    "Three is bigger!"
    "Two is bigger!")
;;=> "Three is bigger!"

Een heel belangrijk verschil tussen if in Common Lisp en if in veel andere programmeertalen is dat CL's if een expressie is, geen statement. Als zodanig, if vormen retourwaarden, die aan variabelen kan worden toegewezen, gebruikt argumentlijsten, etc:

;; Use a different format string depending on the type of x
(format t (if (numberp x)
              "~x~%"
              "~a~%")
           x)

Gemeenschappelijke Lisp's if kunnen worden beschouwd als gelijkwaardig aan de ternaire operator?: In C # en andere "gekrulde accolades" talen.

Bijvoorbeeld de volgende C # -uitdrukking:

year == 1990 ? "Hammertime" : "Not Hammertime"

Is gelijk aan de volgende Common Lisp-code, ervan uitgaande dat dat year een geheel getal heeft:

(if (eql year 1990) "Hammertime" "Not Hammertime")

cond is een ander voorwaardelijk construct. Het lijkt enigszins op een reeks if verklaringen en heeft de vorm:

(cond (test-1 consequent-1-1 consequent-2-1 ...)
      (test-2)
      (test-3 consequent-3-1 ...)
      ... )

Meer precies, cond heeft nul of meer clausules en elke clausule heeft één test gevolgd door nul of meer consequenties. Het gehele cond construct selecteert de eerste clausule waarvan de test niet tot nil evalueert en evalueert de consequenties in volgorde. Het retourneert de waarde van de laatste vorm in de consequenties.

(cond ((> 3 4) "Three is bigger than four!")
      ((> 3 3) "Three is bigger than three!")
      ((> 3 2) "Three is bigger than two!")
      ((> 3 1) "Three is bigger than one!"))
;;=> "Three is bigger than two!"

Als u een standaardclausule wilt geven om te evalueren of er geen andere clausule naar t evalueert, kunt u een standaardclausule toevoegen met t . Dit is qua concept zeer gelijkaardig aan SQL's CASE...ELSE , maar het gebruikt een letterlijke booleaanse waarde in plaats van een trefwoord om de taak te volbrengen.

(cond
    ((= n 1) "N equals 1")
    (t "N doesn't equal 1")
)

Een if constructie kan worden geschreven als een cond constructie. (if test then else) en (cond (test then) (t else)) zijn equivalent.

Als u slechts één clausule nodig hebt, gebruik dan when of unless :

(when (> 3 4)
  "Three is bigger than four.")
;;=> NIL

(when (< 2 5)
  "Two is smaller than five.")
;;=> "Two is smaller than five."

(unless (> 3 4)
  "Three is bigger than four.")
;;=> "Three is bigger than four."

(unless (< 2 5)
  "Two is smaller than five.")
;;=> NIL

De do-lus

De meeste looping- en voorwaardelijke constructen in Common Lisp zijn eigenlijk macro's die meer basale constructies verbergen. dotimes en dolist zijn bijvoorbeeld gebaseerd op de do macro. Het formulier voor do ziet er als volgt uit:

(do (varlist)
    (endlist)
   &body)
  • varlist is samengesteld uit de variabelen die in de lus zijn gedefinieerd, hun beginwaarden en hoe deze na elke iteratie veranderen. Het gedeelte 'wijzigen' wordt geëvalueerd aan het einde van de lus.
  • endlist bevat de endlist en de waarden die aan het einde van de lus worden geretourneerd. De eindconditie wordt geëvalueerd aan het begin van de lus.

Hier is er een die begint bij 0 en gaat tot (niet inclusief) 10.

;;same as (dotimes (i 10)) 
(do (( i (+ 1 i))
    ((< i 10) i)
   (print i))

En hier is er een die door een lijst gaat:

;;same as (dolist (item given-list)
(do ((item (car given-list))
     (temp list (cdr temp))
   (print item))

Het varlist gedeelte is vergelijkbaar met dat in een let instructie. U kunt meer dan één variabele binden en deze bestaan alleen binnen de lus. Elke gedeclareerde variabele staat tussen haakjes. Hier is er een die telt hoeveel enen en enen in een lijst.

(let ((vars (list 1 2 3 2 2 1)))
  (do ((ones 0)
       (twos 0)
       (temp vars (cdr temp)))
      ((not temp) (list ones twos))
    (when (= (car temp) 1)
      (setf ones (+ 1 ones)))
    (when (= (car temp) 2)
      (setf twos (+ 1 twos)))))
-> (2 3)

En als een while-lusmacro niet is geïmplementeerd:

(do ()
    (t)
  (when task-done
    (break)))

Voor de meest voorkomende toepassingen zijn de meer specifieke dotimes en doloop macro's veel beknopter.



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