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 :

équivalent de "goto" de Pascal en Lisp


Sujet :

Lisp

  1. #1
    Membre éclairé Avatar de solawe
    Inscrit en
    Juillet 2006
    Messages
    368
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Juillet 2006
    Messages : 368
    Par défaut équivalent de "goto" de Pascal en Lisp
    Bonjour,

    je cherche l'equivalent syntaxique de l'instruction "goto" de Pascal en Lisp.

    plus plus de clarté je vous montre un exemple que je veux traduire en Lisp:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Etiquette:
    i=i+1;
    if |f|==20 then goto Etiquette;
    merci pour votre aide.

  2. #2
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut
    Lisp a pas de goto, utilise une boucle ou de la récursivité.

  3. #3
    Membre éclairé Avatar de solawe
    Inscrit en
    Juillet 2006
    Messages
    368
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Juillet 2006
    Messages : 368
    Par défaut
    Ok,merci.

  4. #4
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par GnuVince Voir le message
    Lisp a pas de goto, utilise une boucle ou de la récursivité.
    Et j'ajouterai : quelque soit le langage, même s'il a un "goto", ne l'utilise pas !

    http://xkcd.com/292/

  5. #5
    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 alex_pi Voir le message
    Et j'ajouterai : quelque soit le langage, même s'il a un "goto", ne l'utilise pas !

    http://xkcd.com/292/
    En général... il faut rajouter « en général »
    Lorsqu'un goto est utilisé intelligemment, cela peut donner quelque chose d'excellent. Mais j'admet que c'est en général mal utilisé.

  6. #6
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    En général... il faut rajouter « en général »
    Lorsqu'un goto est utilisé intelligemment, cela peut donner quelque chose d'excellent. Mais j'admet que c'est en général mal utilisé.
    Au temps pour moi : excepté en assembleur, il ne *faut pas* utiliser de goto

    Avantage du goto : aucun

    Désaventages :
    - flot de donnée imbitable (aussi appelé "code spagetti". Bref, illisible, non maintenanble, beurk)
    - moins bonne optimisation par le compilo (il ne faut pas oublier que plus on tente de se "rapprocher de la machine", moins on laisse de flexibilité au compilo et moins il peut optimiser.)
    - risque de se faire bouffer par un raptor.

    Fuyez le comme la peste (voir même un peu plus vite encore, la peste, ça peut potentiellement se soigner :-p)

  7. #7
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679

  8. #8
    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 alex_pi Voir le message
    Au temps pour moi : excepté en assembleur, il ne *faut pas* utiliser de goto
    [...]
    Fuyez le comme la peste (voir même un peu plus vite encore, la peste, ça peut potentiellement se soigner :-p)
    N'as tu jamais utilisée un switch..case ? C'est un goto en fait, certes balisé, mais c'est un goto. Bien utilisé ça peut rendre du code très clair. Le lien de GNU_Vince montre qu'il y a certain où le goto peut se poser en solution appropriée. Mais je suis d'accord que rare sont ceux qui l'utilisent avec parcimonie et qu'en général, c'est un remède au manque de structuration de sa pensée. C'est la raison pour laquelle, à ma connaissance, c'est toujours interdit dans les cours de programmation.

  9. #9
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    N'as tu jamais utilisée un switch..case ? C'est un goto en fait, certes balisé, mais c'est un goto. Bien utilisé ça peut rendre du code très clair. Le lien de GNU_Vince montre qu'il y a certain où le goto peut se poser en solution appropriée.
    Lorsque j'utilise un swicth..case, je met un break à la fin de chaque cas, pour que ce soit sémentiquement équivalent à un filtrage, et que ça reste donc de la programmation structurée. Après, évidement, c'est compilé avec des sauts, donc équivalent à un certain nombre de goto. Mais un while aussi est compilé avec des sauts.

    Sur le fait que "dans certains rare cas, ça peut être mieux", je suis raisonnablement d'acord, mais on voit dans le lien que la personne qui dit ça affirme aussi s'être servi de deux goto dans sa vie de programmeur. Pour un hacker du noyau Linux, on peut imaginer qu'il a du programmer pas mal, et pourtant, deux gotos seulement...

    Je pense que pour un débutant, il faut lui dire "n'utilise jamais de goto", et le jour où il aura une expérience suffisante de la programmation, il pourra découvrir par lui même que dans certains cas exceptionnels, il peut être judicieux de mettre un goto. Il est toujours beaucoup plus simple de commencer à coder le plus proprement possible, quite à faire plus tard des encarts au dogme que de commencer à coder comme un porc pour ensuite tenter de perdre ses mauvaises habitudes.

    Et quand on écrit "incrémenter i tant que f vaut 20" avec un goto, c'est qu'on a de très très mauvaises habitudes de programmation (et/ou qu'on utilise un langage ignoble).

  10. #10
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut
    Il y a beaucoup de choses qui sont utilisées en programmation qui pourraient être considérée comme étant aussi maléfique que goto. Je pense notament à la modification des variables. Et pourtant, on s'en sert (des fois à tort et à travers), parce que des fois, c'est la façon la plus simple, la plus claire, la plus efficace d'effectuer une opération.

    Oui, on ne devrait pas utiliser le goto, mais quand les alternatives rendent le code moins lisible, c'est vraiment un mal?

  11. #11
    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 alex_pi Voir le message
    Lorsque j'utilise un swicth..case, je met un break à la fin de chaque cas, pour que ce soit sémentiquement équivalent à un filtrage, et que ça reste donc de la programmation structurée.
    Le « break » est aussi un « goto ». La sémantique peut être correcte ou non, ça n'a aucun rapport.

    Tu n'as jamais mis un « return » dans un « while » ?? Si tu l'as fait, te rends tu compte que ça viole les principes de la programmation structurée ? C'est un saut en dehors de la fonction. Reste que ça peut être très propre. Par exemple en code d'aucun langage ( )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    while ( !e.non_vide() )
    {
        prochain := e.next() 
        if ( prochain = 0 )
            return 0 
        resultat := resultat * prochain  
    }
    store ( DB, resultat );
    return resultat ;
    On devrait le réécrire autrement pour respecter la programmation structurée. Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    while ( !e.non_vide() && prochain != 0)
    {
        prochain := e.next() 
        resultat := resultat * prochain  
    }
    if ( prochain = 0 )
        resultat = 0 
    else
        store ( DB, resultat );
     
    return resultat ;
    Bien sûr la traduction est d'autant plus simple que l'exemple est bêbêtte.
    Mais honnêtement, lequel aurais tu fait ?
    C'est très compréhensible d'utiliser des « return » bien placés, mais c'est une forme de « goto ». En cours, dans le premier cours de programmation, nous imposons aux étudiants une seule utilisation du « return » à la fin de la fonction, jusqu'à environ la mi-session. Là, nous traitons du problème de la gestion des erreurs, et on revoit cette règle. D'une certaine façon donc, on accepte l'utilisation d'un saut dans le code.

  12. #12
    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
    Ça aussi c'est je suppose.

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2010
    Messages : 5
    Par défaut
    Bon, on est pour et contre le goto, c'est une question de goût....

    Mais n'oublions pas que LISP est écrit en LISP... Donc si vous voulez écrire l'opérateur spécial while à l'aide d'une macro, vous risquez fort d'être un peu coince-coince...

    La structure est (TAGBODY) qui fait partie des fonctions de base. cf http://www.ida.liu.se/imported/cltl/clm/node91.html

    Quand à son utilisation dans une application, libre à chacun...

  14. #14
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Common lisp permet grâce au mot clé 'labels' de définir des fonctions locales dans le corps d'une fonction.
    Ceci permet un style de programmation 'à la goto'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (defun myreverse (list)
      (labels ((myreverse-acc (list acc)
             (let ((head (car list)) (rest (cdr list)))
               (cond (head
                  (cond ((atom head)
                     (myreverse-acc rest (cons head acc)))
                    (t
                     (myreverse-acc rest (cons (myreverse-acc head nil) acc)))))
                 (t
                  acc)))))
        (myreverse-acc list nil)))
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2010
    Messages : 5
    Par défaut
    Mhhh, il y a guère de goto, c'est plutôt une bonne vieille fonction recursive et un flet aurait été plus approprié vu qu'il n'y a qu'une fonction.

    pour le goto il s'agit de (GO tag).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ;;;; while à la C
    (defmacro while (cond &rest blocks)
      `(tagbody
          loop
            (if ,cond
              (progn
                 (progn ,@blocks)
                 (go loop)))
        ))
    Attention... ne pas oublier que tagbody ne stocke pas le résultat des évaluations et retourne NIL.

    Par contre on peut sortir du bloc (evidemment pas y entrer) si le tag est lexicalement accessible.

    Ensuite petit problème GO est une forme spéciale, tag n'est donc pas évalué. Mais on peut tout faire en LISP...

+ Répondre à la discussion
Cette discussion est résolue.

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