Limiter la porté d'une variable en emacs lisp

Limiter la porté d'une variable en emacs lisp - Langages fonctionnels - Programmation

Marsh Posté le 02-07-2011 à 09:42:57    

Bonjour
 
en bricolant la fonction suivante:

Code :
  1. (defun load-note-file()
  2.    (setq mois (format-time-string "%m" (current-time)))
  3.    (setq annee (format-time-string "%Y" (current-time)))
  4.    (setq note-file (concat "notes-" annee mois ".org" ))
  5.    (find-file note-file)
  6. )


 
Je me suis demandé quelle était la porte des variables "mois", "annee" et "note-file" de cette fonction. Il semble qu'il soit possible de les accéder aussi en dehors de la fonction, alors comment faire pour qu'elles n'interfèrent pas avec d'autres variables de même nom définies dans d'autres fonctions ?  
 
Dans la doc de emacs lisp, l'opérateur "let" est mentionné à la place de setq, mais je n'ai pas réussi à l'utiliser.
 
D'avance merci de votre aide

Message cité 1 fois
Message édité par leonhard le 02-07-2011 à 18:40:50
Reply

Marsh Posté le 02-07-2011 à 09:42:57   

Reply

Marsh Posté le 02-07-2011 à 14:06:40    

leonhard a écrit :

Bonjour
 
en bricolant la fonction suivante:

Code :
  1. (defun load-note-file()
  2.    (setq mois (format-time-string "%m" (current-time)))
  3.    (setq annee (format-time-string "%Y" (current-time)))
  4.    (setq note-file (concat "notes-" annee mois ".org" ))
  5.    (find-file note-file)
  6. )


 
Je me suis demandé quelle était la porte des variables "mois", "annee" et "note-file" de cette fonction.


Il me semble que c'est local, sauf si elles existent déjà dans la scope globale (via un setq global). Tu peux tester en exécutant ta fonction et en regardant si mois est visible dans le scope global.

leonhard a écrit :

Dans la doc de emacs lisp, l'opérateur "let" est mentionné à la place de setq, mais je n'ai pas réussi à l'utiliser.


let est une forme plus fonctionnelle (setq est une forme très impérative puisque modifiant l'environnement d'exécution).
 
Let a la forme (let (definitions) body). La partie definitions correspond à ce que tu fais avec setq: ça assigne des valeurs à des noms, mais ces noms ne sont visibles que depuis body, pas en dehors. Ça permet donc de rester bien scopé.
 
Il faut également noter qu'il y a 2 formes pour let: let et let*. La différence est visible quand on définit plusieurs variables en même temps, avec let* une définition de variable peut utiliser les variables définies avant elle (les définitions sont exécutées l'une après l'autre), avec let elle ne peut pas.
 
Avec let, ton code devrait ressembler à ça:

Code :
  1. (defun load-note-file ()
  2.  (let* ((mois (format-time-string "%m" (current-time)))
  3.         (annee (format-time-string "%Y" (current-time)))
  4.         (note-file (concat "notes-" annee mois ".org" )))
  5.    (find-file note-file)))


 
accessoirement, normalement les globales sont définies avec defvar et defconst
 
edit: accessoirement, tu pourrais déplacer ce topic dans la sous-cat langages fonctionnels :)

Message cité 1 fois
Message édité par masklinn le 02-07-2011 à 14:43:58

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 02-07-2011 à 14:43:35    

el muchacho a écrit :

Raison de non distribution:
[  ] Destinataire absent
[  ] Boite aux lettres trop petite
[X] Je suis trop flemmard pour livrer le colis en mains propres ou même ne serait-ce que sonner à l'interphone pour prévenir de mon passage
 
Depuis que la Poste sous-traite la distribution, c'est de pire en pire.


MuchachoG [:sadnoir]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 02-07-2011 à 15:01:53    

masklinn a écrit :


Il me semble que c'est local, sauf si elles existent déjà dans la scope globale (via un setq global). Tu peux tester en exécutant ta fonction et en regardant si mois est visible dans le scope global.


 

masklinn a écrit :


let est une forme plus fonctionnelle (setq est une forme très impérative puisque modifiant l'environnement d'exécution).
 
Let a la forme (let (definitions) body). La partie definitions correspond à ce que tu fais avec setq: ça assigne des valeurs à des noms, mais ces noms ne sont visibles que depuis body, pas en dehors. Ça permet donc de rester bien scopé.
 
Il faut également noter qu'il y a 2 formes pour let: let et let*. La différence est visible quand on définit plusieurs variables en même temps, avec let* une définition de variable peut utiliser les variables définies avant elle (les définitions sont exécutées l'une après l'autre), avec let elle ne peut pas.
 
Avec let, ton code devrait ressembler à ça:

Code :
  1. (defun load-note-file ()
  2.  (let* ((mois (format-time-string "%m" (current-time)))
  3.         (annee (format-time-string "%Y" (current-time)))
  4.         (note-file (concat "notes-" annee mois ".org" )))
  5.    (find-file note-file)))


 
accessoirement, normalement les globales sont définies avec defvar et defconst
 
edit: accessoirement, tu pourrais déplacer ce topic dans la sous-cat langages fonctionnels :)


 
 
Merci de ta réponse.
 
Si tu le permets j'ai encore 2 questions (ou même trois).
 
1) Je ne connais rien à la programmation fonctionnelle. Donc ce j'ai montré ici c'était la première version de mon programme. Entre-temps, j'ai pensé qu'on pouvoir se passer de ces variables en utilisant les propriétés des listes:
 

Code :
  1. (defun func-deux()
  2.    (find-file
  3.       (concat "notes-"
  4.          (format-time-string "%Y" (current-time))
  5.          (format-time-string "%m" (current-time))
  6.          ".toto"
  7.      )
  8.   )
  9. )


 
Est-ce que d'un point de vue "fonctionnel" c'est meilleur comme version ? et d'un point de vue lisp ?
 
2) Pourquoi ton code apparaît plus beau que le mien dans les messages  :jap:  
 
3) Comment on fait pour déplacer un sujet existant ? J'avais mis la section "divers" parce que j'étais pas vraiment sur que mes bricolages sont vraiment de la programmation fonctionnelle.
 
D'avance merci de ton (enfin de votre) aide
 
 

Reply

Marsh Posté le 02-07-2011 à 15:10:08    

leonhard a écrit :


Merci de ta réponse.

 

Si tu le permets j'ai encore 2 questions (ou même trois).

 

1) Je ne connais rien à la programmation fonctionnelle. Donc ce j'ai montré ici c'était la première version de mon programme. Entre-temps, j'ai pensé qu'on pouvoir se passer de ces variables en utilisant les propriétés des listes:

 
Code :
  1. (defun func-deux()
  2.    (find-file
  3.       (concat "notes-"
  4.          (format-time-string "%Y" (current-time))
  5.          (format-time-string "%m" (current-time))
  6.          ".toto"
  7.      )
  8.   )
  9. )
 

Est-ce que d'un point de vue "fonctionnel" c'est meilleur comme version ?


Que ta version d'origine? Oui. Après ça va parce que le code n'est pas trop complexe, s'il le devient utiliser let et let* reste une bonne idée :)

leonhard a écrit :

et d'un point de vue lisp ?


D'un point de vue lips, ton formattage est tout fucké, tu formattes comme si c'était du C :)

 

Exemples:

  • defun prend 3 paramètres (nom, argslist et body), il faut un espace (ou newline) entre chaque, donc pas "(defun func-deux()" mais "(defun func-deux ()" (le "()" est la liste d'arguments, vide, et un term différent du nom de la fun)
  • Les parenthèses fermantes ne sont pas assez importantes pour être sur leur ligne (accessoirement, laisses emacs reformatter ton code normalement il fait ça bien), donc
Code :
  1. (defun func-deux()
  2.  (find-file
  3.    (concat "notes-"
  4.            (format-time-string "%Y" (current-time))
  5.            (format-time-string "%m" (current-time))
  6.            ".toto" )))


(et les arguments devraient être alignés dans tes appels de fonctions, quand ils sont sur des lignes différentes)

leonhard a écrit :

2) Pourquoi ton code apparaît plus beau que le mien dans les messages  :jap:


Le forum supporte une balise code en plus de la balise cpp. Elle utilise GeSHI pour parser et coloriser le code, donc il faut lui donner le langage utilisé (j'ai tapé code=lisp).

leonhard a écrit :

3) Comment on fait pour déplacer un sujet existant ? J'avais mis la section "divers" parce que j'étais pas vraiment sur que mes bricolages sont vraiment de la programmation fonctionnelle.


La sous cat est langages fonctionnels ;)

 

Il te suffit d'éditer ton premier post, tu dois pouvoir changer la sous-catégorie depuis là

Message cité 1 fois
Message édité par masklinn le 02-07-2011 à 15:10:50

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 02-07-2011 à 18:46:58    

masklinn a écrit :


Que ta version d'origine? Oui. Après ça va parce que le code n'est pas trop complexe, s'il le devient utiliser let et let* reste une bonne idée :)


 
ok, je note, merci !
 

masklinn a écrit :


D'un point de vue lips, ton formattage est tout fucké, tu formattes comme si c'était du C :)
 
Exemples:

  • defun prend 3 paramètres (nom, argslist et body), il faut un espace (ou newline) entre chaque, donc pas "(defun func-deux()" mais "(defun func-deux ()" (le "()" est la liste d'arguments, vide, et un term différent du nom de la fun)
  • Les parenthèses fermantes ne sont pas assez importantes pour être sur leur ligne (accessoirement, laisses emacs reformatter ton code normalement il fait ça bien), donc
Code :
  1. (defun func-deux()
  2.  (find-file
  3.    (concat "notes-"
  4.            (format-time-string "%Y" (current-time))
  5.            (format-time-string "%m" (current-time))
  6.            ".toto" )))


(et les arguments devraient être alignés dans tes appels de fonctions, quand ils sont sur des lignes différentes)


 
 
ok, merci, ça aussi je note. J'ai appris quelques rudiments de lisp il y a plus de 20 ans. A l'époque l'éditeur qu'on utilisait (VMS EDT pour les vieux qui connaissent) n'avait pas de fonction pour montrer les parenthèses correspondantes. J'avais donc pris ce genre d'habitude et comme depuis j'ai principalement utilisé des langages "c-like" j'ai pas percuté  :pt1cable: Mais il n'est jamais trop tard pour prendre des bonnes habitudes.
 

masklinn a écrit :


Le forum supporte une balise code en plus de la balise cpp. Elle utilise GeSHI pour parser et coloriser le code, donc il faut lui donner le langage utilisé (j'ai tapé code=lisp).


 
Décidément ce soir je me coucherai moins con .. bon faut dire que je pars de loin  :lol:  

masklinn a écrit :


La sous cat est langages fonctionnels ;)
 
Il te suffit d'éditer ton premier post, tu dois pouvoir changer la sous-catégorie depuis là


 
ça c'est fait
 
Merci infiniment de ton aide
 
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed