IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lisp Discussion :

Variable locale en lisp


Sujet :

Lisp

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 34
    Par défaut Variable locale en lisp
    Comment peut-on mettre une variable locale dans une fonction en lisp ?


    Merci d'avance

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Par défaut
    Citation Envoyé par rodgeur62 Voir le message
    Comment peut-on mettre une variable locale dans une fonction en lisp ?


    Merci d'avance
    Avec un let : http://www.cc.gatech.edu/classes/AY2...pTutorial.html

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 34
    Par défaut
    J'avais essayé avec ca,

    mais le problème est que la variable locale créée avec un "let" est modifiée par les appels récursifs,

    en gros c'est la même variable qui est utilisé par tous les appels récursifs...

  4. #4
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Par défaut
    Citation Envoyé par rodgeur62 Voir le message
    J'avais essayé avec ca,

    mais le problème est que la variable locale créée avec un "let" est modifiée par les appels récursifs,

    en gros c'est la même variable qui est utilisé par tous les appels récursifs...
    Non... si tu déclares une variable locale elle ne sera pas partagée.

    Montres ton code, ça sera plus simple.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 34
    Par défaut
    Voilà le code...



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    (defun minmax (plateau joueur joueur_evalue profondeur opt)
    (let ((result '(0 (0 0)))
    	  (copie nil)
    	  (liste_coups (liste_coups_possibles plateau joueur))
    	  (opt_virt 0)
    	  (coup_a_jouer nil)
    	  (fils '(0 (0 0)))
    	  )
     
    	  (cond ((or (null liste_coups) (equal profondeur 0))
    				(setf (car result) (evaluation plateau joueur_evalue))
    				;(print plateau) (print joueur) (print joueur_evalue) (print profondeur) (print opt)
    				)
    			(t
    				(cond ((equal opt 1)
    						(setf (car result) -100000)
    						(dolist (coup_a_jouer liste_coups)
    							;(print plateau)
    							(setf copie '((0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)))
    							(copie_plateau plateau copie)
    							(update copie coup_a_jouer joueur);(print copie) (print plateau)(print " ")
    							(setf fils (minmax copie (- 3 joueur) joueur_evalue (- profondeur 1) (- 1 opt)))
    							(cond ((> (car fils) (car result)) (setf (car result) (car fils)) (setf (cadr result) coup_a_jouer)))
    						)
    					)
     
    				      ((equal opt 0)
    						(setf (car result) 100000)
    						(dolist (coup_a_jouer liste_coups);(print plateau)
    							(setf copie '((0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)))
    							(copie_plateau plateau copie);(print copie)(print plateau)
    							(update copie coup_a_jouer joueur);(print copie)(print plateau)(print " ")
    							(setf fils (minmax copie (- 3 joueur) joueur_evalue (- profondeur 1) (- 1 opt)))
    							(cond ((< (car fils) (car result)) (setf (car result) (car fils)) (setf (cadr result) coup_a_jouer)))
    						)
    					)
    				)
    			)
    	)
    	result
    ))



    L'appel récursif modifie la variable locale "result"...

  6. #6
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Il faut appuyer sur le bouton # de l'éditeur pour avoir les balises [CODE]
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  7. #7
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Par défaut
    Citation Envoyé par rodgeur62 Voir le message
    Voilà le code...

    [...]
    L'appel récursif modifie la variable locale "result"...
    setf... dolist...
    peut-être devrais-tu revoir ta manière d'approcher du code fonctionnel.
    Tu fais des modifications avec effet de bord en utilisant une approche impérative. Réécris un code récursif sans effet de bord (setf) et ça ira mieux je suppose.

  8. #8
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par rodgeur62 Voir le message
    Voilà le code...



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    (defun minmax (plateau joueur joueur_evalue profondeur opt)
    (let ((result '(0 (0 0)))
    	  (copie nil)
    	  (liste_coups (liste_coups_possibles plateau joueur))
    	  (opt_virt 0)
    	  (coup_a_jouer nil)
    	  (fils '(0 (0 0)))
    	  )
     
    	  (cond ((or (null liste_coups) (equal profondeur 0))
    				(setf (car result) (evaluation plateau joueur_evalue))
    				;(print plateau) (print joueur) (print joueur_evalue) (print profondeur) (print opt)
    				)
    			(t
    				(cond ((equal opt 1)
    						(setf (car result) -100000)
    						(dolist (coup_a_jouer liste_coups)
    							;(print plateau)
    							(setf copie '((0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)))
    							(copie_plateau plateau copie)
    							(update copie coup_a_jouer joueur);(print copie) (print plateau)(print " ")
    							(setf fils (minmax copie (- 3 joueur) joueur_evalue (- profondeur 1) (- 1 opt)))
    							(cond ((> (car fils) (car result)) (setf (car result) (car fils)) (setf (cadr result) coup_a_jouer)))
    						)
    					)
     
    				      ((equal opt 0)
    						(setf (car result) 100000)
    						(dolist (coup_a_jouer liste_coups);(print plateau)
    							(setf copie '((0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)))
    							(copie_plateau plateau copie);(print copie)(print plateau)
    							(update copie coup_a_jouer joueur);(print copie)(print plateau)(print " ")
    							(setf fils (minmax copie (- 3 joueur) joueur_evalue (- profondeur 1) (- 1 opt)))
    							(cond ((< (car fils) (car result)) (setf (car result) (car fils)) (setf (cadr result) coup_a_jouer)))
    						)
    					)
    				)
    			)
    	)
    	result
    ))



    L'appel récursif modifie la variable locale "result"...
    Bonjour,

    1. je ne sais pas si tu _veux_ comprendre ce que tu as fait...

    Supposons que ce soit le cas.

    Il se trouve que tu as construit (bien involontairement, je suppose) ce qu'on appelle une "closure".

    En voici un exemple très simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    (defun foo (x)
       (let ((closevar '(0)))
          (setf (car closevar) (+ (car closevar) x))
          (car closevar)))
     
    ? (foo 0)
    => 0
    ? (foo 1)
    => 1
    ? (foo 0)
    => 1
    ? (foo 1)
    => 2
    ? (foo 0)
    => 2
    Ca ressemble énormément à une variable globale (quoique pas accessible globalement) et ça ressemble encore plus à ce qu'on appelle une variable locale statique (dans d'autres langages (comme C)).

    En fait, le bout de code avec le "setf" modifie physiquement la donnée " '(0) " (qui est un cons dont le car est 0, AVANT TOUT APPEL DE LA FONCTION, et dont le cdr est NIL) qui est incluse dans le code de la fonction.

    Ce qui revient à dire que le code se modifie lui-même!

    (tu peux le vérifier en pretty-printant le code de la fonction (avec ^P en Le_Lisp))

    Si tu compiles la fonction en Le_Lisp et que tu regardes la plist du symbole foo, tu verras où la donnée encapsulée est conservée à la compilation.


    2. Pour résoudre à moindres frais ton problème, il suffit juste (mais ce n'est certainement pas la meilleure solution!!! (et j'avoue que je n'ai pas essayé de comprendre ton code (ni, bien sûr, de vérifier si ma solution marche vraiment (mais j'ai plutôt bon espoir...)))) que tu mettes un "copy" devant _toutes_ les données incluses dans ton code.

    Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun minmax (plateau joueur joueur_evalue profondeur opt)
        (let ((result (copy '(0 (0 0))))
    ...
                  (setf copie (copy '((0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0)(0 0 0 0 0 0 0 0))))
    ...
    3. Evidemment, tu peux aussi envosager d'écrire ton code différemment, comme le suggère justement Garulfo.

    4. Personnellement, je le réécrirais en objet (en CLOS ou Smeci, par exemple), en tentant d'être clair sur les objets manipulés (plateau, joueur, coup, resultat, etc.).

    HTH

    )jack(

Discussions similaires

  1. text, ntext et image sont interdits dans les variables locales
    Par Sebounet19 dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 04/07/2013, 15h44
  2. Réponses: 3
    Dernier message: 02/03/2006, 19h22
  3. [MFC] Globaliser une variable locale
    Par Philippe320 dans le forum MFC
    Réponses: 3
    Dernier message: 01/12/2005, 20h12
  4. variables locales ou globales?
    Par molesqualeux dans le forum C
    Réponses: 20
    Dernier message: 09/11/2005, 23h03
  5. variables locales ou globales ???
    Par elvivo dans le forum C
    Réponses: 13
    Dernier message: 03/07/2002, 08h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo