Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    LLB
    LLB est déconnecté
    Membre Expert
    Inscrit en
    mars 2002
    Messages
    962
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 962
    Points : 1 128
    Points
    1 128

    Par défaut CTP - Mise à jour de F#

    Une nouvelle version de F# vient de sortir et c'est une très grosse mise à jour. Il y a quelques incompatibilités avec les versions précédentes au niveau de la bibliothèque standard, mais c'est justement pour poser les bases définitives du langage. Toute la bibliothèque standard a été nettoyée, beaucoup de choses ont été recodées, un nombre impressionnant de bugs et incohérences a été corrigé... Bref, il faut mettre à jour.

    Les détails sont là :
    http://blogs.msdn.com/dsyme/archive/...p-release.aspx

    Une nouvelle fonctionnalité, qui permet de mettre des unités aux nombres, est détaillée ici :
    http://blogs.msdn.com/andrewkennedy/...ing-units.aspx

  2. #2
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 009
    Points
    1 009

    Par défaut

    Je vois que le cas particulier "assert false" a été retiré. Comme tout cas particulier, il gratte un peu, mais il est quand même bien pratique et a une signification clairement définie. Qu'est-ce que vous allez utiliser à la place ?

    En lisant le changelog j'ai aussi trouvé une phrase un peu étrange :
    The type of truncate is now 'a -> 'a (indeed for any floating point type or a type supporting a static Truncate method)
    Qu'est-ce que ça veut dire exactement ?

  3. #3
    LLB
    LLB est déconnecté
    Membre Expert
    Inscrit en
    mars 2002
    Messages
    962
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 962
    Points : 1 128
    Points
    1 128

    Par défaut

    La fonction truncate issue de Caml (float -> int) faisait double emploi avec la fonction de conversion int. En Caml aussi, on trouve une redondance truncate / int_of_float.

    La fonction truncate de .Net est de type float -> float. Il a donc été choisi de s'aligner sur .Net plutôt que sur Caml pour cette fonction. Donc, truncate 3.2 renvoie 3.0.

    En F#, cette fonction est maintenant générique et est utilisable pour tous les types flottants : float, float32, decimal, etc. On peut utiliser truncate sur tous les objets implémentant la méthode statique Truncate (par défaut, tous les types flottants de F#, mais c'est extensible aux types que l'on souhaite).

    Je vois que le cas particulier "assert false" a été retiré. Comme tout cas particulier, il gratte un peu, mais il est quand même bien pratique et a une signification clairement définie. Qu'est-ce que vous allez utiliser à la place ?
    Lancer une exception me semble bien.

  4. #4
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 009
    Points
    1 009

    Par défaut

    Mais du coup, c'est quoi son type ? Ils l'ont vraiment mise en ('a -> 'a) ?

    Lancer une exception me semble bien.
    Oui mais en général on utilise "assert false" pour dire "ce cas ne peut pas se produire" (par exemple dans les clauses qu'on sait impossibles, mais qu'on tient à rajouter pour rester exhaustif). Vous avez une exception pour dire ça ?

  5. #5
    LLB
    LLB est déconnecté
    Membre Expert
    Inscrit en
    mars 2002
    Messages
    962
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 962
    Points : 1 128
    Points
    1 128

    Par défaut

    Je ne sais pas quelle exception il faudrait utiliser. En Caml, assert fait appel à Assert_failure. Ça a été renommé AssertionFailure dans F#, mais ce n'est pas très pratique à utiliser soi-même.

    À la limite, "exception InternalError" n'est pas très long à taper.


    Citation Envoyé par bluestorm Voir le message
    Mais du coup, c'est quoi son type ? Ils l'ont vraiment mise en ('a -> 'a) ?
    Non, pas tout à fait. C'est le même principe que pour les opérateurs (+), (*), etc. Son vrai type est :

    Code :
    val truncate : ( ^a ->  ^a) when  ^a : (static member Truncate :  ^a ->  ^a)
    Mais le compilateur doit pouvoir résoudre le type concret statiquement. Pour résoudre, il regarde comment la fonction est utilisée ; si l'argument n'est pas connu, il utilise le contexte (plus loin dans le fichier) ; dans le pire des cas, il utilise le type par défaut (ici, float). Quelques exemples pour que ce soit plus clair :

    Code :
    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
    > truncate 3.2M;;
    val it : System.Decimal = 3M
    
    
    > truncate;;
    val it : (float -> float) = <fun:clo@42>
    
    
    > let foo x = truncate x
    let a = foo 3.2f;;
    
    val foo : float32 -> float32
    val a : float32
    
    
    > let bar x = truncate x
    let b = bar 3.2M;;
    
    val bar : System.Decimal -> System.Decimal
    val b : System.Decimal
    
    
    > truncate<float32>;;
    val it : (float32 -> float32) = <fun:clo@43>
    
    
    > let f x : decimal = truncate x;;
    val f : decimal -> decimal

  6. #6
    Membre Expert
    Inscrit en
    avril 2007
    Messages
    831
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 831
    Points : 1 009
    Points
    1 009

    Par défaut

    Intéressant. En gros, comme le système de typage ne veut (ou ne peut) pas s'embarrasser du type complet (qui est un peu polymorphe, mais pas vraiment), il se comporte comme un type faible, avec un défaut sur "float" plutôt que d'exposer la variable faiblement polymorphe '_a (ou ^a).

    C'est sans doute une bonne solution, parce qu'elle est plutôt simple à comprendre et remplit son rôle (qui est de simplifier la vie du développeur, pas de révolutionner le système de typage).

  7. #7
    LLB
    LLB est déconnecté
    Membre Expert
    Inscrit en
    mars 2002
    Messages
    962
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 962
    Points : 1 128
    Points
    1 128

    Par défaut

    Et pour compléter un peu, on peut propager ce polymorphisme avec le mot-clé inline :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    > let inline foo x = truncate x;;
    
    val inline foo :  ^a ->  ^a when  ^a : (static member Truncate :  ^a ->  ^a)
    
    > let inline foo x = x + truncate x;;
    
    val inline foo :
       ^a ->  ^b
        when  ^a : (static member ( + ) :  ^a *  ^a ->  ^b) and
              ^a : (static member Truncate :  ^a ->  ^a)
    Mais les fonctions marquées inline ont plusieurs restrictions (notamment, elles ne peuvent pas être récursives). Elles fonctionnent un peu comme les templates du C++, en moins puissant quand même, et sont inlinées dans le code généré.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •