2010-07-12 13 views
4

J'ai une instruction let dans laquelle je voudrais déstructurer dynamiquement une liste. Ce qui suit est ma solution:Liste de Destructuring dynamique dans Clojure

symList ;; list of some Strings which will become the vector of Symbols to assign to 
valList ;; list of some values, same length as symList 

(let [(map read-string symList) valList] 
    ...) 

Une valeur exemple de symList serait ("pt1" "pt2") et une valeur d'exemple de valList serait (1 2)

Cependant, cela produit une exception que la première partie est une « forme de liaison non pris en charge ". Je soupçonne qu'il me manque quelque chose concernant la citation syntaxique, ou que ce n'est pas possible. Tout avis serait grandement apprécié.

EDIT: Je ne connaîtrai que ces valeurs lors de l'exécution, d'où cette approche. Deuxièmement, je dois être capable de passer plus tard la portée lexicale, d'où l'utilisation de let.

+1

Je suis intéressé à voir si c'est possible; cela semble douteux mais je ne suis pas un expert. – Pointy

Répondre

2

Si symList et valList ont la valeur correcte au moment de la compilation, vous pouvez alors écrire un macro pour le faire. Si elles ne sont connues qu'au moment de l'exécution, vous devrez utiliser/écrire une fonction pour effectuer la déstructuration et retourner le résultat de cette déstructuration sous forme de structure de données. Dans le second cas, pour quelque chose de simple comme ceci, vous pouvez utiliser (zipmap symList valList) pour obtenir une carte.

+0

J'ai pensé autant, et j'ai déjà écrit une fonction pour le faire, car les valeurs ne seront pas connues avant l'exécution. Le problème est que je dois alors passer la portée lexicale ailleurs (avec ces valeurs liées à leurs symboles), ce qui ne peut pas être fait avec 'def' (je crois - corrigez-moi si je me trompe). Y at-il un moyen de faire la déstructuration en utilisant zipmap et toujours l'avoir défini dans le 'let'? –

+2

Lexiquement vous ne pouvez pas faire cela (à moins que le code cible ne soit encore du code et que vous voulez construire du code que vous passez à eval). La portée dynamique est faisable, cependant. Si symList était une liste de vars et que la cible était écrite pour utiliser ces vars, vous pourriez utiliser clojure.core/with-bindings pour faire ce que vous voulez. Il y a probablement une meilleure solution au problème que vous essayez de résoudre avec cette approche. – Brian

0
(let [valList (map str symList)] 
    (somefun valList)) 

L'erreur que vous obtenez est parce que votre instruction let était en arrière (LET [val SOURCE] STUFF)

+0

Je pensais que 'let' fonctionnait de telle sorte que c'était (valeur de symbole). Donc, dans ce cas, je voudrais être en mesure de se référer au symbole pt1 et obtenir 1, pt2 et obtenir 2, etc –

+0

(let [pt1 1 pt2 2] (println pt1)) imprimerait 1 via stdout. –

0

peut-être matchure peut vous donner ce que vous voulez

+0

J'ai vérifié, mais je ne pouvais pas trouver quelque chose qui ferait cela, même si c'est une bibliothèque cool. –

0

Bien que je suis incapable de trouver un moyen de déstructurer dynamiquement une liste, pour ceux d'entre vous qui sont intéressés par la création de valeurs qui sont lexicalement au lieu de scope dynamiquement, J'ai trouvé que intern à tout espace de noms dont vous avez besoin fonctionne bien.