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 :

Eval en caml?


Sujet :

Caml

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut Eval en caml?
    Bonjour,

    Existe en en caml une fonction de type "eval" comme on la retrouve dans des langages de scripts comme php ou python. Comme il est possible d'interpréter le caml, me suis dit que c'était possible .... après je suis en train de penser que si on compile, ca peut poser problème d'avoir des trucs interprétés en live par le programme ...

    Enfin bon, si quelqu'un peut répondre à ma question, je suis preneur :p

    Merci,
    Seb

  2. #2
    alex_pi
    Invité(e)
    Par défaut
    Non ça n'existe pas

    Bonne journée

  3. #3
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Si une telle fonction existait, elle serait certes typable, mais inutilisable en pratique. Cependant, en bidouillant un peu le compilo, je pense que l'on pourrait y arriver... mais il faudrait inclure le compilo entier en tant que bibliothèque !

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    La question avait déjà été posée par moi:
    http://www.developpez.net/forums/d57...on-eval-apply/

  5. #5
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par InOCamlWeTrust Voir le message
    Si une telle fonction existait, elle serait certes typable, mais inutilisable en pratique. Cependant, en bidouillant un peu le compilo, je pense que l'on pourrait y arriver... mais il faudrait inclure le compilo entier en tant que bibliothèque !
    Tu types ça comment ?

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Tu types ça comment ?
    "string -> string" je suppose, c'est ce que fait la REPL au final, non ? En plus sophistiqué tu pourrais rajouter l'état de l'interpréteur de façon à pouvoir interpréter plusieurs expression dans un même environnement...

    Bref c'est tout à fait faisable.

    --
    Jedaï

  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
    "string -> string" ça revient à ne pas typer du tout. On peut sûrement faire beaucoup mieux en utilisant des types plus élaborés pour représenter du code.

    Après une petite recherche dans la mailing-list MetaOCaml et consorts, j'ai trouvé un post (... de Oleg) qui décrit quelque chose ressemblant beaucoup à ça : http://caml.inria.fr/pub/ml-archives...422b1c.en.html

  8. #8
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    Par défaut
    Bonsoir Sebsheep,

    1. ça n'existe pas
    2. il y a de bonnes raisons pour lesquelles ça n'existe pas, et par conséquent ça n'est pas près d'exister un jour
    3. ça n'est pas une limitation, ça ne limite pas l'expressivité de Caml, ce que tu veux faire c'est probablement quelque chose comme un DSL (Domain Specific Language) et OCaml est un langage idéal pour ce type d'applications

  9. #9
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par SpiceGuid Voir le message
    ça n'est pas une limitation, ça ne limite pas l'expressivité de Caml, ce que tu veux faire c'est probablement quelque chose comme un DSL (Domain Specific Language) et OCaml est un langage idéal pour ce type d'applications
    je ne suis pas d'accord sur cette phrase... il y a une limite d'expressivité en raison de l'obligation de typage statique (sinon à quoi servirait de programmer des scripts )
    toutefois,il faut signaler que dans une majorité des cas, avec un peu reflexion, on trouve vite une façon equivalente de faire la meme chose (ie obtenir le même résultat, pas passer par les mêmes étapes bien sur ) avec du typage statique fort

  10. #10
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    Par défaut
    sinon à quoi servirait de programmer des scripts ?
    À faire en plus cracra ce que tu ne veux pas faire proprement ?

  11. #11
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par SpiceGuid Voir le message
    À faire en plus cracra ce que tu ne veux pas faire proprement ?
    malheureusement, c'est aussi souvent le cas

  12. #12
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Tu types ça comment ?
    eval : string -> 'a... mais comme je le disais, c'est inutilisable, et faire un type faible eval : string -> '_a, ça n'apporte rien au débat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    (* n est le résultat de la lecture d'un entier au clavier... *)
    let n = eval "read_int ()" in
    (* jusques ici pas de problèmes... *)
     
    (* mais là, il faudrait pouvoir vérifier le type au moment de l'insertion *)
    (* dans la liste, donc à l'exécution, ce que ne peut pas faire OCaml *)
    3.1416 :: 0.148065042 :: n :: []

  13. #13
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    C'est là où on voit une grande limitation du typage à la Caml (et à la Haskell).

    En réalité, le typage en Caml est presque une affaire de syntaxe. Remplacer à tour de rôle les variables de type par des types concrets, comme le fait le compilo, c'est un boulot très automatique, qui ne relève presque que de la syntaxe.

    Avec la fonction eval, on voit qu'il est possible de correctement typer une expression sans pour autant que ce typage soit en accord avec la sémantique et le sens de l'expression.

    eval : string -> 'a signifie que la fonction retourne tout type de d'expression, et qu'elle peut être, du fait du typage qui relève presque de la syntaxe, partout dans le code.

    Ce que ne dit pas le type eval : string -> 'a, c'est que la valeur de retour ne peut être utilisée dans certains cas, comme celui de mon précédent message, bien que l'expression soit utilisable dans tout contexte.

    C'est une sorte de paradoxe.

    C'est pour ça que je dis que c'est typable, mais inutilisable en pratique.

    Il y a très certainement de meilleurs mots pour expliquer celà.

  14. #14
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 681
    Points
    18 681
    Par défaut
    Citation Envoyé par InOCamlWeTrust Voir le message
    C'est pour ça que je dis que c'est typable, mais inutilisable en pratique.

    Il y a très certainement de meilleurs mots pour expliquer celà.
    ben en gros, tu joues avec un Obj.magic
    (un peu comme dans l'exemple pour faire tourner un apply en OCaml

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    Merci de vos réponses.

    Effectivement, je n'ai pas besoin d'un interpréteur "total".

    Mon idée est de faire un petit traceur de fonctions. Pour cela, l'utilisateur rentrerai la fonction mathématique qu'il veut visualiser, et l'intervalle.

    C'est pour ca que j'ai pensé à un petit eval (c'est ce que j'aurai fait en python), mais si vous avez une solution pas trop compliquée à me proposer (c'est un petit projet, pas envie de me taper de l'évaluation d'expression juste pour ca), je suis preneur

    ++
    Seb

  16. #16
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par InOCamlWeTrust Voir le message
    C'est pour ça que je dis que c'est typable, mais inutilisable en pratique.
    Pourquoi ? Il est vrai que la vérification du type doit se faire à l'exécution mais ce n'est pas un problème insurmontable : le type du eval() nécessaire est connu à la compilation et à l'exécution eval() peut déterminer le type de l'expression évaluée et vérifier qu'ils correspondent, lancer une exception si ce n'est pas le cas.

    Haskell sait faire ça (voir l'API de GHC ou hint par exemple), je ne vois pas vraiment de problème pour qu'OCaml en soit capable également.

    --
    Jedaï

  17. #17
    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
    Tappe toi l'évaluation d'expression juste pour ça. Il faut savoir qu'écrire un petit parser en OCaml c'est assez facile. Ça te permet en plus de connaître exactement le langage que tu acceptes et de travailler à un niveau bien plus abstrait sur tes données. Par exemple, avec ta solution python, quand tu entres le code d'une fonction c'est facile de l'évaluer, mais si ensuite tu veux prendre la dérivée, t'es niqué. Avec un parser à la main tu représentes ton expression mathématique de manière symbolique, et tu peux faire plein de super manipulations dessus.

    Tu ne pourras pas évidemment faire facilement un parseur formidable qui parse absolument toute formule mathématique (elles sont naturellement ambiguës et c'est très difficile), mais tu peux faire facilement un parseur pour un petit sous-ensemble qui te convient (comme tu aurais fait en acceptant seulement ce que propose python facilement). Si tu cherches un truc carrément complet, tu pourrais choisir un langage de description de maths déjà existant, et essayer de partir de là, mais c'est certainement beaucoup de travail et pas ce que tu cherches.

    Au cas où ça t'intéresse, j'ai récemment proposé à quelqu'un un code pour une petite calculatrice mathématique, basé sur son code initial. Voici ce que ça donne :
    Code ocaml : 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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    type ('a, 'b) arbre_bin = 
      | Leaf of 'b
      | Node of ('a, 'b) arbre_bin * 'a * ('a, 'b) arbre_bin
     
    let print_tree tree = 
      let indent n =
        for x = 1 to n do print_string "|    " done in
      let rec aux tree n = match tree with
      | Leaf a -> indent n; print_int a; print_newline ()
      | Node(fg, r, fd) -> 
          indent n; print_endline r;
          aux fg (n+1); aux fd (n+1)
      in aux tree 0
     
    open Genlex
     
    let lexer =
      let rec minus = parser
        | [< ''-'; s >] -> [< ''-'; '' '; minus s >]
        | [< 'a; s >] -> [< 'a; minus s >]
        | [< >] -> [< >] in
      let lexer =
        let keywords = ["("; ")"; "+"; "-"; "*"; "/"] in
        make_lexer keywords in
      fun str -> lexer (minus (Stream.of_string str))
     
    let parse =
      let op_parser op_list next_level =
        let rec loop gauche = parser
          | [< 'Kwd op when List.mem op op_list; droite = next_level; s >] ->
              loop (Node (gauche, op, droite)) s
          | [< >] -> gauche in
        parser [< acc = next_level; s >] -> loop acc s in
      let rec ope_low s = op_parser ["+"; "-"] ope_hight s
      and ope_hight s = op_parser ["*"; "/"] pth s
      and pth = parser
        | [< 'Int n >] -> Leaf n
        | [< 'Kwd "("; e = ope_low; 'Kwd ")" >] -> e
      in ope_low
     
    let rec execute tree = match tree with
    | Leaf n -> n
    | Node(fg, r, fd) ->
        let gauche, droite = execute fg, execute fd in
        match r with
        | "+" -> gauche + droite
        | "-" -> gauche - droite
        | "*" -> gauche * droite
        | "/" -> gauche / droite
        | _ -> failwith "Fonction non connue."
     
    let () =
      let chaine = read_line() in
      let tokens = lexer chaine in
      let arbre = parse tokens in
      print_tree arbre;
      print_int (execute arbre);
      print_newline ()

    Il y a des choses à améliorer (représenter les opérateurs par des chaines, c'est laid, on pourrait passer à des floats, etc.) mais c'est un code qui fonctionne, qui est court, et qui pourrait facilement être étendu pour supporter quelques opérations de plus, comme par exemple les opérations unaires log/exp/sin/cos/... .


    Enfin, il y a une dernière approche imaginable, qui est d'utiliser directement le toplevel OCaml : au lieu d'avoir un programme qui parse l'entrée de l'utilisation, tu lui demande d'utiliser le toplevel ocaml, et tu lui proposes une bibliothèque qui fait l'affiche pour lui. Ça ferait quelque chose un peu comme ça :

    Objective Caml version 3.10.2

    # load "plot.cma";;
    # let g' z t = t ** (z -. 1.) *. exp (-.t);;
    val g' : float -> float -> float = <fun>
    # Plot.draw (g' 2.);;
    Ainsi, il a à nouveau toute sa liberté pour coder des fonction (sachant que tu peux aussi proposer dans ta lib des facilités pour écrire ces fonctions plus facilement, ou des possibilités pour construire des expressions symboliques), et c'est lui qui dirige l'interaction, à travers le toplevel.


    Pour ma part, je pencherais pour la deuxième solution (petit parser fait maison), mais c'est à toi de voir selon tes besoins/envies.

  18. #18
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par Jedai Voir le message
    Pourquoi ? Il est vrai que la vérification du type doit se faire à l'exécution mais ce n'est pas un problème insurmontable : le type du eval() nécessaire est connu à la compilation et à l'exécution eval() peut déterminer le type de l'expression évaluée et vérifier qu'ils correspondent, lancer une exception si ce n'est pas le cas.

    Haskell sait faire ça (voir l'API de GHC ou hint par exemple), je ne vois pas vraiment de problème pour qu'OCaml en soit capable également.

    --
    Jedaï
    Non, il n'y a aucun moyen de connaître le type d'une expression à l'exécution.

    Les objets en Caml ne conservent aucune information sur leur types, sauf dans certains cas rares comme les fonctions, les objets dont la fonction de linéarisation est faite directement par le programmeur, etc... Mais dans les autres cas, il n'y a aucune information, mis à part la place que ça prend en mémoire.

    Je te mets ici le tableau récapitulant les rares informations disponibles sur le type que l'on peut trouver dans un objet Caml.

    http://caml.inria.fr/pub/docs/manual...manual032.html point 18.2.2 Blocks

  19. #19
    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
    MetaOcaml conserve l'information de typage, ce qui rend cette construction possible.

  20. #20
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    Merci Bluestorm, je vais voir ce que je peux faire avec un tit parseur fait maison.

    Pour ta solution d'utiliser la librairie plot ... c'est justement un "petit frere" (dire un clone serait bien prétentieux) de plot que je veux faire, donc cette solution ne m'interresse pas trop :p

    Merci encore,
    Seb

Discussions similaires

  1. Existe-t-il une fonction Eval() sous Delphi ?
    Par Hell dans le forum Langage
    Réponses: 5
    Dernier message: 20/12/2004, 17h45
  2. pb eval pour le code php dans une feuille xslt
    Par nipepsi dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 10/09/2004, 11h23
  3. [String] équivalent de la fonction eval() en javascript
    Par jeyce dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 01/09/2004, 08h42
  4. [langage] eval
    Par Quaker dans le forum Langage
    Réponses: 5
    Dernier message: 21/07/2004, 17h16
  5. algo et caml
    Par rabi dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 08/11/2002, 22h44

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