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

Scheme Discussion :

Question de débutant (call-with-input-file)


Sujet :

Scheme

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 35
    Points : 28
    Points
    28
    Par défaut Question de débutant (call-with-input-file)
    Bonjour, je débute en scheme et suis un peu dérouté (dégouté ? ;-)) par la syntaxe... Je cherche à comprendre ce code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (call-with-input-file "test1.scm"
      (lambda (p)
        (let f 
    	    ((x (read p))
    	  )
        (if (eof-object? x)
        	'()
          (cons x (f (read p))))
        )
      )
    )
    Je vois le principe du lambda appelé directement par call-with-input-file... Qui fait un truc du genre
    open
    yield -> le code lambda
    close

    Par contre, je pige pas trop ce qui suit :
    - Que représente le f du let ? (Puisque ce que les données lues se trouvent dans x)
    - A la fin, quand on détecte un EOF on retourne une liste vide mais dans le cas contraire (la lecture continue) que fait le cons x ? Pourquoi y a-t-il encore un read ??

    J'imagine aussi que le nil ou le cons sont retourné à l'appelant, et que l'appelant procède à un boucle tant qu'on lui retourne pas nil...

    Merci de m'éclairer... Je cherche des exemples en scheme simples à comprendre, pas du tout orienté vers les maths, du coup je me tourne vers les fichiers, les sockets, etc.

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Bon alors commençons par le début : l'aide la plus complète est dans DrScheme lui même -> help dans le menu.

    Ainsi tu peux apprendre tout sur let ou sur call-with-input-file.

    Maintenant, tu as très bien compris le second en fait — enfin, du moins je le crois — mais c'est la syntaxe du premier qui te trompe. C'est une « nouvelle » syntaxe qui n'existait pas dans R5RS (la précédente norme). Une fois qu'on la connait, elle devient évidente.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (let nom-fonction ([x init-x] [y init-y] …) corps-fonction)
    revient à écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (let-rec ([nom-fonction {λ (x y …) corps-fonction}) 
        (nom-fonction init-x init-y …)
    Comprends-tu le principe ?

    Essayes de comprendre la fonction. N'oublies pas que cons permet d'ajouter un élément à une liste. Le plus compliqué ici c'est de suivre le principe impératif de lecture d'un fichier séquentiel. As-tu essayé d'appliquer la fonction pour voir le résultat ?

    Si tu as d'autres questions n'hésites pas.

    Au passage, j'ai déjà vu pire comme question de débutant. De plus cet exemple n'est pas super. Est-ce que tu connais ces liens :
    http://mitpress.mit.edu/sicp/
    http://www.htdp.org/2003-09-26/Book/
    http://www.ccs.neu.edu/home/dorai/t-...-y-scheme.html
    ftp://ftp.cs.utexas.edu/pub/garbage/...intro_toc.html
    http://gustavus.edu/+max/concrete-abstractions.html

    Ce sont tous des excellents cours et les deux premiers sont même des must read pour tout étudiant en informatique.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    Merci pour ta réponse... J'avais installé Dr Scheme mais ne m'en servais pas car je m'évertuais à faire mes premiers pas en Scheme avec l'interpréteur guile sous linux. C'est vrai que DR Scheme est quand même plus simple d'emploi, surtout pour un débutant. Et l'aide en ligne est super !

    Concernant let, je comprends la forme avec let-rec que tu donnes. Par contre je n'arrive pas à 'voir' comment cela s'applique au code initial.

    Ce serait :
    - définir une fonction f avec un paramètre x initialisé par la valeur retournée par (read)
    - si EOF retourner une liste vide
    - sinon retourner une liste constituée de la valeur lue (ici x) et d'un appel récursif à f - mais c'est quoi ce paramètre (read p), pourquoi n'a-t-on pas écrit (f) tout court puisque le lambda est ((x (read p)) et qu'il lit aussi dans le fichier ? non ?


    En tout cas c'est très surprenant et très nouveau comme manière de lire d'un fichier pour quelqu'un qui n'a jamais connu que do x=read() until eof pendant toute sa vie ;-)

    Au passage, je remarque que le read interprète les données lues. Si je veux lire un simple fichier texte, je fais comment ?

    A propos de doc pour l'instant j'utilise surtout "An Introduction to Scheme and its Implementation" (ici http://www.cena.fr/~decrock/langages...intro_toc.html) que je trouve plus facile à lire que "The Scheme Programming Language 3rd Edition".
    J'ai aussi trouvé ceci a l'avantage d'être en français : http://gdw.free.fr/index_js_fr.htm (déplier le menu linuxmag, puis scheme)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Citation Envoyé par Paganoni Voir le message
    [...]
    Ce serait :
    - définir une fonction f avec un paramètre x initialisé par la valeur retournée par (read)
    - si EOF retourner une liste vide
    - sinon retourner une liste constituée de la valeur lue (ici x) et d'un appel récursif à f - mais c'est quoi ce paramètre (read p), pourquoi n'a-t-on pas écrit (f) tout court puisque le lambda est ((x (read p)) et qu'il lit aussi dans le fichier ? non ?
    Ton premier point est exact. Ton deuxième l'est aussi. Pour le troisième, tu oublies que f prend un argument. Comme je l'ai dit ce code n'est pas super car f et x sont des noms très peu significatifs.

    Supposes que j'écrive ceci à la place de ton code
    Code scheme : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    (call-with-input-file "test1.scm"
                {lambda (p)
                  (let traiter-un-token ([token (read p)])
                    (if (eof-object? token)
                        '()
                        (cons token (traiter-un-token (read p)))))})
    Est-ce qu'ainsi tu comprends mieux le rôle de chacun. C'est normal de passer un paramètre à ta fonction f puisqu'elle a pour but de traiter un élément issu de la lecture (un token)

    N.B. remarque comment j'utilise les crochets et les accolades pour mieux pouvoir lire mon code DrScheme l'autorise.

    Citation Envoyé par Paganoni Voir le message
    [...]
    En tout cas c'est très surprenant et très nouveau comme manière de lire d'un fichier pour quelqu'un qui n'a jamais connu que do x=read() until eof pendant toute sa vie ;-)
    Non pas vraiment car la boucle ici est une forme de while ou de do. Ce qui change dans la manière d'écrire c'est d'utiliser une fonction récursive. Mais ça, c'est quelque chose que tout informaticien doit maîtriser.

    Citation Envoyé par Paganoni Voir le message
    [...]
    Au passage, je remarque que le read interprète les données lues. Si je veux lire un simple fichier texte, je fais comment ?
    Il suffit d'utiliser autre chose que read qui renvoie un datum:
    un peu de lecture sur les entrées/sorties. Tu peux lire caractère par caractère si tu veux.

    Citation Envoyé par Paganoni Voir le message
    [...]
    A propos de doc pour l'instant j'utilise surtout "An Introduction to Scheme and its Implementation" (ici http://www.cena.fr/~decrock/langages...intro_toc.html) que je trouve plus facile à lire que "The Scheme Programming Language 3rd Edition".
    J'ai aussi trouvé ceci a l'avantage d'être en français : http://gdw.free.fr/index_js_fr.htm (déplier le menu linuxmag, puis scheme)
    Ne néglige pas trop TSPL c'est un bon livre

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Ton premier point est exact. Ton deuxième l'est aussi. Pour le troisième, tu oublies que f prend un argument. Comme je l'ai dit ce code n'est pas super car f et x sont des noms très peu significatifs.
    Merci pour la clarification du code source, mais je ne comprends toujours pas pourquoi il y a deux appels à (read). Je vais formuler les choses différemment : combien de fois est exécuté le read(p) de cette ligne ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (let traiter-un-token ([token (read p)])
    Une fois ou bien à chaque itération ? Vu que c'est censé être une initialisation de la variable définie dans le let, je dirais une seule fois. Et donc si c'est bien le cas, je comprends maintenant la manière dont ce bout de code tourne...

    Citation Envoyé par Garulfo Voir le message
    Non pas vraiment car la boucle ici est une forme de while ou de do. Ce qui change dans la manière d'écrire c'est d'utiliser une fonction récursive. Mais ça, c'est quelque chose que tout informaticien doit maîtriser.
    J'ai déjà utilisé les fonctions récursives mais jamais pour lire le contenu d'un fichier. C'est ça qui me surprend et que je trouve original ! Mais franchement je crois quand j'aurai à le faire moi même je passerai par une simple boucle... Désolé pour la beauté du geste ;-)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Citation Envoyé par Paganoni Voir le message
    Merci pour la clarification du code source, mais je ne comprends toujours pas pourquoi il y a deux appels à (read). Je vais formuler les choses différemment : combien de fois est exécuté le read(p) de cette ligne ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (let traiter-un-token ([token (read p)])
    Une fois ou bien à chaque itération ? Vu que c'est censé être une initialisation de la variable définie dans le let, je dirais une seule fois. Et donc si c'est bien le cas, je comprends maintenant la manière dont ce bout de code tourne...
    Regarde la définition que je t'ai donnée pour cette forme du let. Le (read p) sert à l'initialisation de ta fonction. Il n'est donc exécuté qu'une fois. Ta fonction a un argument quand elle est rappelée, il lui fait un token a traiter. On en relit donc un.

    J'ai déjà utilisé les fonctions récursives mais jamais pour lire le contenu d'un fichier. C'est ça qui me surprend et que je trouve original ! Mais franchement je crois quand j'aurai à le faire moi même je passerai par une simple boucle... Désolé pour la beauté du geste ;-)
    Mais c'est une simple boucle. Ici pas de cas complexe de récursivité.
    Tu lis le premier élément, tu le traites en l'ajoutant à la suite des éléments que tu traites au fur et à mesure. C'est très très simple. Juste un manque de maîtrise de la récursivité.

    Finalement c'est un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    liste est une liste vide
    token prend la valeur du prochain élément du flot (p)
    tant que token n'est pas la fin du fichier
       ajouter token à liste
    retourner la liste
    c'est juste le contexte qui te trompe. Rien n'est compliqué ici. Pas de piège, pas de truc syntaxique.

    En fait il y a une toute petite différence. Mais je te laisse tester et deviner quoi. En tout cas, rien de terrible.

    Encore une fois, le code aurait pu être mieux écrit dans un contexte de cours en séparant les fonctions pour te permettre de mieux lire. Si c'est la première fois que tu vois cette forme de let c'est aussi génant pour toi.

    Mais ce code est d'une simplicité terrible crois-moi.

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/11/2010, 09h41
  2. Réponses: 2
    Dernier message: 23/02/2010, 19h45
  3. [MFC] Quelques questions de débutant...
    Par Sephi dans le forum MFC
    Réponses: 4
    Dernier message: 20/02/2004, 17h25
  4. Questions de débutant
    Par J-P-B dans le forum XMLRAD
    Réponses: 12
    Dernier message: 24/07/2003, 15h19
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 29/04/2002, 23h18

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