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

Caml Discussion :

Un peu d'introspection ne nuit pas


Sujet :

Caml

  1. #1
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut Un peu d'introspection ne nuit pas
    introspection ... je crois que c'est le nom qui correspond à ma question.

    Je voudrais savoir s'il existe un moyen simple, à partir d'une déclaration de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let mon_exemple = `Truc ( true , `Muche [ "ahaha", 3.14159 ; "beeeh", 1.414]);;
    de récupérer une chaine correspondant à ce que renvoie le TopLevel. Par exemple ce serait une fonction "toplevel_of_value" utilisée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    (* pseudo-code *)
    let s = toplevel_of_value mon_exemple
    s serait une string et vaudrait : " `Truc (true, `Muche [("ahaha", 3.14159); ("beeeh", 1.414)])"

    je suppose que la question n'intéresse pas que moi ...

  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
    Citation Envoyé par james-mi Voir le message
    introspection ... je crois que c'est le nom qui correspond à ma question.

    Je voudrais savoir s'il existe un moyen simple, à partir d'une déclaration de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let mon_exemple = `Truc ( true , `Muche [ "ahaha", 3.14159 ; "beeeh", 1.414]);;
    de récupérer une chaine correspondant à ce que renvoie le TopLevel. Par exemple ce serait une fonction "toplevel_of_value" utilisée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    (* pseudo-code *)
    let s = toplevel_of_value mon_exemple
    s serait une string et vaudrait : " `Truc (true, `Muche [("ahaha", 3.14159); ("beeeh", 1.414)])"

    je suppose que la question n'intéresse pas que moi ...
    Si j'ai bien compris ta question, la réponse est non en ce qui concerne ocaml à proprement parler. Le choix a été fait dès le départ de Caml (et même avant) de ne pas mélanger les deux niveaux de langages : objet (dans le sens général pas spécialement OO) et type. Ça peut compliquer la vie sur certains points, mais, surtout historiquement, ça permettait d'éviter les tours de passe-passe qui poseraient des problèmes pour le type-checking.

    Je l'avais déjà dit qqpart (car la question a déjà été posé sous une autre forme) : c'est un débat ancestrale comparable à celui des réalistes et des idéalistes... en effet, existe-t-il une catégorie des catégories se demandait Aristote ?

  3. #3
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    merci de ta réponse.

    En fait je n veux pas récupérer le type, simplement la chaîne de caractère que renvoie le TopLevel...

    On peut le coder soi-même bien sûr, mais c'est très fastidieux ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let to_string = function
      | `Truc expr -> "`Truc (" ^(to_string expr) ^ ")"
      etc...
    d'où la question de trouver quelque chose de tout cuit

  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 james-mi Voir le message
    merci de ta réponse.

    En fait je n veux pas récupérer le type, simplement la chaîne de caractère que renvoie le TopLevel...

    On peut le coder soi-même bien sûr, mais c'est très fastidieux...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let to_string = function
      | `Truc expr -> "`Truc (" ^(to_string expr) ^ ")"
      etc...
    d'où la question de trouver quelque chose de tout cuit
    Moui effectivement ce n'est pas exactement la même chose. Mais je ne pense pas qu'il y ait ça dans le langage. Car ça voudrait dire que ce serait un système générique pour récupérer le type quelqu'il soit. Hors c'est une méta-information. Cependant là, IOCWT ou Bluestorm, par exemple, devraient pouvoir te le confirmer ou te l'infirmer.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Effectivement, si tu veux spécifiquement ce que renvoie le toplevel, la réponse est non : ça n'est pas possible.

    Cependant, tu as raison en décrivant la possibilité de déclarer un opérateur to_string pour chacun de tes types. C'est une opération que l'on peut d'ailleurs automatiser dans une certaine mesure, et cela a été fait à ma connaissance par trois projets :
    - sexplib, qui ajoute à la demande des fonctions de conversion vers des s-expressions (c'est comme ce que fait le toplevel mais en utilisant une représentation plus lispeuse sur la forme)
    - json-statc, qui fait en gros la même chose mais pour le format JSON
    - deriving, qui est une solution un peu plus générale, s'inspirant des type classes Haskell

    Si ça t'intéresse (en réalité, la plupart des gens ont besoin de ce genre de tout-printer pour faire du debugging uniquement, et c'est d'une utilité discutable), je te conseille de commencer par regarder du côté de sexplib, c'est probablement la plus simple à utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type foo = ...
    with sexp
    déclare deux fonctions foo_of_sexp et sexp_of_foo.

    Il faut aussi savoir que ces solutions ne sont pas "parfaites" dans le sens où tous les types OCaml ne sont pas forcément représentables. Les types fonctionnels ne sont pas gérés, mais tu pourrait aussi avoir des problèmes avec certaines d'entre elles si tu manipules des données cycliques (liste infinie...) ou ce genre de chose. À ma connaissance, sexplib implémente la plupart des choses que l'on peut raisonnablement espérer à ce niveau.

  6. #6
    alex_pi
    Invité(e)
    Par défaut
    Pour me lancer dans le débat théologico-pragmatique de Garuflo, je rappelle que OCaml est un langage très fortement et statiquement typé. Cela signifie que toute les informations de typage sont déterminées à la compilation. Mais cela signifie aussi qu'à runtime (lors de l'execution), toutes ces informations ont été effacées. Il n'y a *aucun* moyen à runtime de retrouver le type d'une donnée. Et une des raisons pour les effacer est assez pragmatique : ça va plus vite. Il n'y a pas de tests à faire à runtime, on sait que tout va bien se passer, que les arguments passés à une fonctions sont les bons, etc. Donc on peut foncer les yeux fermés ;-)

    La contrepartie (entre autre) est qu'écrire une fonction d'impression générique est bien impossible, désolé.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Ceci dit, il serait techniquement possible, tout en conservant cette philosophie, de faire connaître au compilateur des opérateurs spéciaux du langage qui ont besoin de connaître le type des valeurs, type qui serait statiquement déterminé au moment de la compilation et leur serait "envoyé" à ce moment là.

    Il me semble que cette approche avait été étudiée pour la sérialisation par exemple, mais je ne sais pas si elle a été mise en place dans certains langages. Ce que je voulais dire c'est typage fort et des valeurs non typées au runtime ne sont pas à priori pas incompatibles avec l'ajout au langage d'opérateurs utilisant le typage des valeurs.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 99
    Points : 93
    Points
    93
    Par défaut Danger d'une telle fonction
    Le problème d'une telle fonction serait la difficulté à écrire une doc. Car il faudrait pouvoir précisément décrire la sortie d'une telle fonction, et ce pour tous les cas, car l'on ne pourrait se permettre l'à peu près.

    Et on ne peut pas passer un type abstrait à une telle fonction, cela n'aurait presque aucun sens.

  9. #9
    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 NokyDaOne Voir le message
    Le problème d'une telle fonction serait la difficulté à écrire une doc. Car il faudrait pouvoir précisément décrire la sortie d'une telle fonction, et ce pour tous les cas, car l'on ne pourrait se permettre l'à peu près.[...]
    Je ne comprends pas ton « objection »... En quoi ne pas pouvoir écrire une documentation extrêmement précise empêche d'écrire une fonction ?

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 99
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Je ne comprends pas ton « objection »... En quoi ne pas pouvoir écrire une documentation extrêmement précise empêche d'écrire une fonction ?

    Une doc imprécise empèche d'utiliser une fonction, car c'est un peu comme programmer avec des undefined behavior. On ne peut avoir une garantie du truc et un jour un bug sort à cause de ça.

  11. #11
    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 NokyDaOne Voir le message
    Une doc imprécise empèche d'utiliser une fonction, car c'est un peu comme programmer avec des undefined behavior. On ne peut avoir une garantie du truc et un jour un bug sort à cause de ça.
    Une doc très mal faite... empêcherait de l'utiliser (à la limite), mais pas de l'écrire.

    Une doc légèrement imprécise ou qui n'est pas complètement détaillée dans les mécanismes d'implémentations non.

    Et rien n'empêcherait d'écrire une explication en français précise de ce que fait (fonctionnellement) la fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type_of : 'a -> type 
    L'appel [type_of x] renvoie le type de x.
    En quoi est-ce imprécis ?

    Une doc ne doit pas indiquer le cœur de l'implémentation, mais le comportement.

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Points : 32
    Points
    32
    Par défaut
    afficher une variable de manière générique comme dans le top-level, si si ça existe !!!

    http://caml.inria.fr/cgi-bin/hump.fr.cgi?contrib=510
    http://okmij.org/ftp/ML/gprint/gprint.txt

    Code text : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    For example,
     
        let pr_type et = Format.printf "\n%s@." et
     
        let () = 
          let x = Some ([|(10,true);(11,false)|]) in 
          pr_type (print .<x>.)
     
    prints the following two lines:
     
           Some [|(10, true); (11, false)|]
           (int * bool) array option

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Points : 32
    Points
    32
    Par défaut Vprint
    Il y a l'air d'y avoir ça aussi :
    http://caml.inria.fr/cgi-bin/hump.fr.cgi?contrib=590
    http://www.pps.jussieu.fr/~li/software/vprint/README

    Code ocaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # open Vprint
     
    (* Some values are easy to identify *)
    # print ("asdf", [||], 3.14, [|1.01; 2.689|], 32l, 64L, 111n);;
    <"asdf", [||], 3.14, [|1.01; 2.689|], 32l, 64L, 111n>

  14. #14
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par fgjdfgjdgj Voir le message
    afficher une variable de manière générique comme dans le top-level, si si ça existe !!!

    http://caml.inria.fr/cgi-bin/hump.fr.cgi?contrib=510
    http://okmij.org/ftp/ML/gprint/gprint.txt

    Code text : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    For example,
     
        let pr_type et = Format.printf "\n%s@." et
     
        let () = 
          let x = Some ([|(10,true);(11,false)|]) in 
          pr_type (print .<x>.)
     
    prints the following two lines:
     
           Some [|(10, true); (11, false)|]
           (int * bool) array option
    ... j'ai jeté un coup d'oeil sur la doc et ça à l'air de correspondre exactement à ce que je veux. Merci fhgdfvghfj...

    Par contre cela va-t-il marcher sous OCaml normal, je ne connais pas MetaOCaml ? ( j'ai consulté http://www.metaocaml.org/ mais c'est du chinois pour moi ...

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 99
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Une doc très mal faite... empêcherait de l'utiliser (à la limite), mais pas de l'écrire.

    Une doc légèrement imprécise ou qui n'est pas complètement détaillée dans les mécanismes d'implémentations non.

    Et rien n'empêcherait d'écrire une explication en français précise de ce que fait (fonctionnellement) la fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type_of : 'a -> type 
    L'appel [type_of x] renvoie le type de x.
    En quoi est-ce imprécis ?

    Une doc ne doit pas indiquer le cœur de l'implémentation, mais le comportement.

    Je parlais de la fonction qui affichait le contenu de la variable. Vu que son résultat serait alors sûrement utilisé ailleurs que dans juste un affichage pour un humain.

    Après pour la fonction de type il faudrait encore définir ce qu'est un type.

  16. #16
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    NokyDaOne > on peut quand même raisonnablement définir cette fonction par induction sur les constructeurs de type (on décrit son fonctionnement sur les types algébriques, les enregistrements, et les objets et variantes polymorphes), en précisant le comportement sur les types abstraits (par exemple utiliser une fonction fournie avec le type abstrait en question).

    Pour ce qui est de la représentation en tant que valeur du type, les Haskelliens ont travaillé là dessus (ils ont essayé pas mal de trucs et c'est généralement plutôt imbouffable de loin), mais encore une fois ce n'est pas insurmontable.

  17. #17
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Citation Envoyé par bluestorm Voir le message
    Pour ce qui est de la représentation en tant que valeur du type, les Haskelliens ont travaillé là dessus (ils ont essayé pas mal de trucs et c'est généralement plutôt imbouffable de loin), mais encore une fois ce n'est pas insurmontable.
    En F#, c'est pas imbouffable.

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Points : 32
    Points
    32
    Par défaut README
    Si tu lis le paragraphe descriptif :
    http://caml.inria.fr/cgi-bin/hump.fr.cgi?contrib=510
    à la fin c'est marqué :
    _fully_ compatible with the regular OCaml

    c'est marqué la même chose dans le début du README :
    http://okmij.org/ftp/ML/gprint/gprint.txt

  19. #19
    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 NokyDaOne Voir le message
    Je parlais de la fonction qui affichait le contenu de la variable. Vu que son résultat serait alors sûrement utilisé ailleurs que dans juste un affichage pour un humain.
    Mais encore une fois, la limitation n'est pas technique. Elle est philosophique.

    Citation Envoyé par NokyDaOne Voir le message
    Après pour la fonction de type il faudrait encore définir ce qu'est un type.
    Enfin, tu fais ce qu'on appelle ici « du gaussage de virgule »... Ça veut dire que tu es pointilleux sur des détails qui n'amène rien. Tout dépend du niveau auquel on est confronté... et si on peut le programmer, on peut l'expliquer. Sinon comment est-ce que ça aurait pû être conçu ? C'est tautologique.

  20. #20
    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 fgjdfgjdgj Voir le message
    Si tu lis le paragraphe descriptif :
    http://caml.inria.fr/cgi-bin/hump.fr.cgi?contrib=510
    à la fin c'est marqué :
    _fully_ compatible with the regular OCaml

    c'est marqué la même chose dans le début du README :
    http://okmij.org/ftp/ML/gprint/gprint.txt
    Enfin... ta solution utilise Obj.magic ! Et si j'ai bien compris il utilise aussi MetaOcaml... Il sort donc a priori de OCaml pour y retourner.
    C'est correct et ça marche. Mais on brise la philosophie de base de OCaml.

Discussions similaires

  1. Problème un peu bête mais j'arrive pas a comprendre.
    Par mckilleron dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 15/09/2010, 11h33
  2. Réponses: 5
    Dernier message: 11/02/2009, 09h23
  3. setTimeOut ne peu pas appeler une fonct. et appeler une var?
    Par bywazy dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 15/06/2005, 09h56
  4. Forum Dot Net un peu fourre tout.... Diviser ou pas ?
    Par Troopers dans le forum Evolutions du club
    Réponses: 21
    Dernier message: 09/07/2004, 22h05

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