2010-07-16 6 views
4

J'ai un problème simple de syntaxe clojure (bc je suis nouveau dans la langue). pour les deux exemples i ai une lst liste de (1 2 3 4):Problème clojure unqoute

en Lisp i peut écrire:

=> `(premier de la liste est, (première lst))
(première de la liste est 1)

dans Clojure, si j'écris la même chose (avec la traduction de langue, à ~ que je pensais que je lis quelque part) je reçois:

=> '(première de liste est ~ (premier lst))
(première de la liste est (clojure.core/unquote (première LST)))

j'espérais que je peux faire ce que je veux dans Clojure aussi bien, et que je viens de la syntaxe erronée. tous les exemples que je trouve ont cependant des fonctions en premier et utilisent un `(backtick). Je ne veux pas appeler une fonction comme:

`(ma fonction ~ (première LST))

je veux juste revenir « (une liste avec, (premier LST) remplacé dans ce

Puis-je faire une telle chose dans Clojure?

EDIT: j'ai donné un mauvais exemple vu que mon problème réel traitait des chaînes. permettez-moi d'essayer un autre exemple ...

=> (définition couleur LST « (rouge vert bleu))

ce que je voulais retourner était:

=>` (La couleur que je veux est ~ (première couleur-lst))

ce yeilded tous les étranges retours que j'ai vu. l'autre façon de le faire est

=> (format "la couleur que je veux est% s" (première couleur LST))

c'est comment je résolu mon problème.

+0

Alors que d'autres vous déjà aidé à résoudre votre problème, sachez que ce n'est pas la façon Clojure. par exemple. Au lieu de symboles, clojure utilise des mots-clés. Si vous voulez des chaînes (comme dans votre exemple), utilisez-les. Tout le '~' est moche. Et vous rencontrerez un bug difficile à trouver tôt ou tard. – kotarak

+0

tout ce '' et ~ est généralement utilisé avec des macros. évitez-les autant que possible, sauf si nécessaire. –

Répondre

4

Même si votre problème est résolu, il y a des différences fondamentales de mentionner entre CL et Clojure:

La principale différence en ce qui concerne les symboles dans backquotes entre CL et Clojure est, que Clojure résout les symboles quasiquoted; ce qui donne un symbole qualifié d'espace de noms (jetez un oeil à la reader section des Clojure docs):

user> `foo 
user/foo 

Ainsi, CL:

CL-USER> (let ((list '(foo bar baz))) 
      `(first is ,(first list))) 
(FIRST IS FOO) 

Mais dans Clojure:

user> (let [lst '(foo bar baz)] 
     `(first is ~(first lst))) 
(clojure.core/first user/is foo) 

Pour pour obtenir un symbole non-qualifié dans Clojure (dans les citations de retour), vous devez utiliser quelque chose comme ceci:

user> `~'foo 
foo 

Donc, pour obtenir le même résultat que la version CL (sans tenir compte readtable cas), vous auriez à utiliser:

user> (let [lst '(foo bar baz)] 
     `(~'first ~'is ~(first lst))) 
(first is foo) 
+0

hey, c'est exactement ça! ive est passé à un autre problème depuis lors, mais je pense que je vais revenir maintenant et remplacer avec cela. C'est exactement ce que je cherchais, je ne pouvais pas raisonner sur la bonne citation/backtick/tilde combinaison. Je vous remercie. – trh178

+0

De rien. Puisque les symboles ne sont pas des citoyens de première classe dans la plupart des langages de programmation appris/utilisés de nos jours, ils sont un concept auquel il faut s'habituer. – danlei

2

Il est peu clair pour moi ce que vous entendez par « premier de la liste est » dans votre code:

'(first of list is ,(first lst)) 

Mais si vous vouliez dire par là juste un espace réservé pour le début de la liste, ce qui suit devrait beau travail (assurez-vous d'utiliser backtick!):

`(1 2 3 ~(first [1 2])) 
=> (1 2 3 1) 

Alternativement, en utilisant devis sera le résultat suivant (ce qui semble être votre problème):

'(1 2 3 ~(first [1 2])) 
=> (1 2 3 (clojure.core/unquote (first [1 2]))) 
+0

ok, maintenant j'arrive quelque part. Cela fonctionne (juste essayé). "first of list is" est juste une phrase dans mon code ci-dessus. alors peut-être que je vais à ce sujet dans le mauvais sens? lorsque la liste de backtick contient des nombres, cela fonctionne, mais pas quand il contient des mots. Je pense que le problème peut être que '(ceci est une liste) et' (ceci est une liste) évalue à la même chose dans Lisp ... mais PAS dans Clojure. cela pourrait-il être cela? – trh178

+0

Il semble que le problème que vous rencontrez est d'utiliser quote (') plutôt que backtick ('). Backtick devrait fonctionner de la même manière avec une liste de chaînes. – unignorant

+0

évaluation '(ceci est une liste) yeilds (ceci est une liste) comme ID s'attendre. évaluer '(c'est une liste) yeilds (utilisateur/cet utilisateur/est utilisateur/un clojure.core/liste) qui n'est pas ce que je m'attendais, mais c'est bc im pas utiliser le lang correctement :( – trh178

0

trouvé une autre façon.peut-être que tout le temps je ne faisais pas les choses de manière 'Clojure'?

(formate "premier de liste est% d" (premier lst)) yeilds ce que je cherchais.

Je pense que c'était en partie ma faute dans la description du problème, j'ai donné un mauvais exemple. il semble que le problème est survenu bc j'utilisais des cordes (probablement incorrectement?) dans la liste. et 'first' est aussi un appel de fonction acceptable. tout cela a embrouillé la question je crois.

+0

je pense que la confusion était en fait que vous étiez * pas * en utilisant des chaînes dans la liste d'exemple originale ;-) – unignorant