2010-07-13 28 views
10

Dans Common Lisp, vous utilisez la fonction (null x) pour vérifier les listes vides et les valeurs nulles.Chemin idiomatique pour remplacer (null x) la fonction du Lisp commun dans clojure

plus logiquement cette cartes pour

(or (nil? x) (= '() x)) 

En clojure. Quelqu'un peut-il suggérer une façon plus idiomatique de le faire à Clojure?

+1

En Lisp, 'NIL' et'() '(la liste vide) sont une seule et même chose. Votre extrait de code est un pléonasme. – Svante

+4

Pas dans Clojure: '(= '() nil) => false'. Dans d'autres langues, c'est vrai. – Isaac

+6

Svante: Votre déclaration peut ne pas être vraie dans Clojure mais j'ai un nouveau mot favori. – Ken

Répondre

16

Pour obtenir le même résultat pour une liste vide dans Clojure comme vous le faites dans Common Lisp, utilisez la fonction empty?. Cette fonction est dans la bibliothèque principale: aucune importation n'est nécessaire.

Il est également un prédicat, et suffixé par un ?, ce qui rend un peu plus clair exactement ce que vous faites dans le code.

=> (empty? '()) 
true 
=> (empty? '(1 2)) 
false 
=> (empty? nil) 
true 

Comme j-g faustus déjà noté, seq peut être utilisé pour un effet similaire.

+0

Votre réponse est meilleure, car elle fonctionne également avec des vecteurs, des cartes, des chaînes etc. sans les convertir en seqs. Je suppose que l'approche seq est appropriée si vous avez un argument de type inconnu et que vous voulez opérer sur un seq. –

+3

j-g-faustus: Je souhaite. Le defn est '(defn empty? [Coll] (not (seq coll)))'. – naiad

+0

Hah, wow, je ne peux pas croire que nous ayons raté ça. Deux ans plus tard, mais certainement bon à savoir et à avoir ici. – Isaac

10

suivants sert également de test pour fin, déjà idiomatiques

(when (seq coll) 
    ...) 

De clojure.org lazy

Cela fonctionne parce que (seq nil) et (seq()) à la fois nulle de retour. Et comme nil signifie false, vous n'avez pas besoin d'un test nul explicite.