2010-09-15 6 views
17

Je pense que Scala va trop loin de la simplicité, comme sa syntaxe. Par exemple Martin Odersky a écrit la méthode dans son livre:Styles et conventions de codage Scala?

def calculate(s: String): Int = 
    if (cache.contains(s)) 
    cache(s) 
    else { 
    val acc = new ChecksumAccumulator 
    for (c <- s) 
     acc.add(c.toByte) 
    val cs = acc.checksum() 
    cache += (s -> cs) 
    cs 
    } 

Si les méthodes se développe, il devient très pénible à lire le code, je ne peux pas correspondre à des accolades, ne plier la méthode IDE. Existe-t-il des conventions de codage Scala? Je pense qu'il est trop souple pour exprimer une méthode simple:

def add(b: Byte): Unit = { 
    sum += b 
} 

def add(b: Byte): Unit = sum += b 

def add(b: Byte) { sum += b } 
+0

Que ce que ces conventions de codage tenter de le faire? – wheaties

+7

Parce qu'il y a trop de façons d'exprimer une simple ligne de code dans Scala, les conventions de codage aideraient à formaliser les codes au sein des équipes ou des communautés. – Sawyer

+0

Comment une convention dans votre deuxième exemple de code aiderait-elle votre premier exemple en termes de lisibilité? – Debilski

Répondre

35

« Si la méthode grandit, il devient très pénible à lire le code ». Je pense qu'une partie de la réponse est que les méthodes ne devraient pas croître. Le style fonctionnel de programmation est d'avoir beaucoup de petites méthodes. La méthode de calcul est déjà large.

Pour répondre aux questions plus générales sur les guides de style pour la programmation Scala: Voici un representative example.

+0

Ceci est particulièrement facile car vous pouvez définir des méthodes dans les méthodes! Un excellent moyen de casser votre code. Et beaucoup plus agréable que les méthodes compagnons privés pour les fonctions récursives comme en Java. – schmmd

4

L'exemple particulier que vous citez peut sembler complexe, car il utilise un cache pour memoize les résultats. Si vous supprimez la memoization, la méthode à réduire:

def calculate(s: String): Int = { 
    val acc = new ChecksumAccumulator 
    for (c <- s) 
     acc.add(c.toByte) 
    acc.checksum() 
} 

que je pense, n'est pas complexe du tout.

+0

Vos onglets sont foireux. – Det

24

Voici un lien vers la Scala Style Guide.


La section Accolades dit:

Curly-Accolades:

accolades doivent être omis dans cas où la structure de contrôle représente une opération fonctionnelle Pure- et toutes les branches de la structure de contrôle (correspondant à if/else) sont des expressions à ligne unique. Rappelez-vous les directives suivantes:

  • si - Omettre accolades si vous avez une clause else. Sinon, entourez le contenu avec des accolades même si le contenu ne contient qu'une seule ligne.

  • while - Ne jamais omettre d'accolades (tout en ne pouvant pas être utilisé de manière purement fonctionnelle ).

  • pour - Omettre accolades si vous avez une clause de rendement. Dans le cas contraire, entourer les contenu avec des accolades, même si le contenu ne sont qu'une seule ligne.

  • cas - Omission accolades si l'expression de cas ts sur une seule ligne. Sinon, utilisez des accolades pour clarté (même si elles ne sont pas requis par l'analyseur).

    val news = if (foo) 
        goodNews() 
    else 
        badNews() 
    
    if (foo) { 
        println("foo was true") 
    } 
    
    news match { 
        case "good" => println("Good news!") 
        case "bad" => println("Bad news!") 
    } 
    

Je souhaite que les gens ont suivi ce guide de style :(


S'il vous plaît noter que je ne suis pas d'accord avec "Omettre accolades si if a une clause else" partie.Je préférerais de beaucoup voir le code comme ceci:

def calculate(s: String): Int = { 
    if (cache.contains(s)) { 
    cache(s) 
    } else { 
    val acc = new ChecksumAccumulator 
    for (c <- s) { 
     acc.add(c.toByte) 
    } 
    val cs = acc.checksum() 
    cache += (s -> cs) 
    cs 
    } 
} 
+1

les parenthèses aide à mettre en forme les codes, j'aime aussi vos styles, peut-être que je viens juste de Java. – Sawyer

+0

Je ne sais pas pourquoi une convention exigerait une ponctuation superflue. –

+0

@Randall: Dans le monde Java c'est le cas, et pour une bonne raison: cela rend le code plus facile à refactoriser, et à lire (à mon avis). – missingfaktor

1

Voici le mot de l'homme qui a écrit scala, lui-même, et toujours l'implémenteur principal de cette langue.

Source: Principes de programmation fonctionnels à Scala par Martin Odersky

vous êtes également invités à prendre son cours maintenant ou l'offre suivante link [1]

========== =================

Scala style Guide Aide

sur cette page vous trouverez une liste de problèmes communs que nous avons détecté en regardant des soumissions.

Certains des problèmes de style peuvent être détectés par le vérificateur de style automatique que nous utilisons également pour le processus de notation. Le vérificateur de style, basé sur Scalastyle, peut être exécuté localement dans sbt en exécutant la tâche styleCheck.

Problèmes courants

1 Évitez Casts et des essais de type

Ne jamais utiliser isInstanceOf ou asInstanceOf - il y a toujours une meilleure solution, tant pour les missions, ainsi que pour tout le monde réel projet Scala. Si vous voulez utiliser des moulages, prenez du recul et réfléchissez à ce que vous essayez d'accomplir. Relisez les instructions d'affectation et jetez un coup d'œil aux vidéos de conférences correspondantes.

2 Indentation

Assurez-vous que votre code est correctement en retrait, il devient beaucoup plus facile à lire. Cela peut sembler anodin et pas très pertinent pour nos exercices, mais imaginez-vous à l'avenir faire partie d'une équipe, travaillant sur les mêmes fichiers avec d'autres codeurs: il est très important que tout le monde respecte les règles de style pour garder le code sain.

Si votre éditeur n'effectue pas l'indentation comme vous le souhaitez, vous devez savoir comment modifier ses paramètres. En Scala, la norme est de mettre en retrait en utilisant 2 espaces (pas d'onglets).

3 Longueur de la ligne et les espaces

Assurez-vous que les lignes ne sont pas trop longtemps, sinon votre code est très difficile à lire. Au lieu d'écrire de très longues lignes, introduisez des liaisons de valeurs locales. L'utilisation de blancs uniformément rend votre code plus lisible.

Exemple (ligne longue, espaces manquants):

if(p(this.head))this.tail.filter0(p, accu.incl(this.head))else this.tail.filter0(p, accu) 

Mieux:

if (p(this.head)) 
    this.tail.filter0(p, accu.incl(this.head)) 
else 
    this.tail.filter0(p, accu) 

Mieux encore (voir # 4 et # 6 ci-dessous):

val newAccu =

if (p(this.head)) accu.incl(this.head) 
    else accu 
this.tail.filter0(p, newAccu) 

4 Utilisez local Valeurs pour simplifier les expressions complexes

Lors de l'écriture de code dans un style fonctionnel, les méthodes sont souvent implémentées comme une combinaison d'appels de fonction. Si une telle expression combinée devient trop grande, le code peut devenir difficile à comprendre.

Dans de tels cas, il est préférable de stocker certains arguments dans une valeur locale avant de les transmettre à la fonction (voir n ° 3 ci-dessus). Assurez-vous que la valeur locale a un nom significatif (voir # 5 ci-dessous)!

5 Choisissez des noms significatifs pour les méthodes et valeurs

Les noms des méthodes, des champs et des valeurs doivent être soigneusement choisis afin que le code source est facile à comprendre. Un nom de méthode devrait indiquer clairement ce que fait la méthode. Non, la température est jamais un bon nom :-)

Quelques exemples améliorables:

val temp = sortFuntion0(list.head, tweet) // what does sortFunction0 do? 
def temp(first: TweetSet, second : TweetSet): TweetSet = ... 
def un(th: TweetSet,acc: TweetSet): TweetSet = ... 
val c = if (p(elem)) accu.incl(elem) else accu 
def loop(accu: Trending, current: TweetSet): Trending = ... 
def help(ch: Char, L2: List[Char], compteur: Int): (Char, Int) = ... 
def help2(L: List[(Char, Int)], L2: List[Char]): List[(Char, Int)] = ... 

6 sous-expressions communes

Vous devez éviter les invocations inutiles des méthodes de calcul intensif. Par exemple

this.remove(this.findMin).ascending(t + this.findMin) 

invoque deux fois la méthode this.findMin. Si chaque appel est cher (par exemple, doit traverser une structure de données entière) et ne dispose pas d'un effet secondaire, vous pouvez enregistrer une en introduisant une valeur locale de liaison:

val min = this.findMin 
this.remove(min).ascending(t + min) 

Cela devient encore plus important si la fonction est invoquée récursivement: dans ce cas, la méthode est invoquée non seulement plusieurs fois, mais un nombre exponentiel de fois.

7 Ne copiez pas le code!

Copier-coller le code est toujours un signe d'avertissement pour le mauvais style! Il y a de nombreux inconvénients:

Le code est plus, il faut plus de temps pour comprendre Si les deux parties ne sont pas identiques, mais très similaire, il est très difficile de repérer les différences (voir exemple ci-dessous) Le maintien de deux les copies et en s'assurant qu'elles restent synchronisées sont très sujettes aux erreurs La quantité de travail requise pour apporter des modifications au code est multipliée Vous devez factoriser les parties communes dans des méthodes séparées au lieu de copier du code.Exemple (voir aussi 3 ci-dessus pour un autre exemple):

val googleTweets: TweetSet = TweetReader.allTweets.filter(tweet => 
    google.exists(word => tweet.text.contains(word))) 
val appleTweets: TweetSet = TweetReader.allTweets.filter(tweet => 
    apple.exists(word => tweet.text.contains(word))) 
This code is better written as follows: 

def tweetsMentioning(dictionary: List[String]): TweetSet = 
    TweetReader.allTweets.filter(tweet => 
    dictionary.exists(word => tweet.text.contains(word))) 

val googleTweets = tweetsMentioning(google) 
val appleTweets = tweetsMentioning(apple) 

8 Scala ne nécessite pas points-virgules

Scala sont des points-virgules nécessaire uniquement lors de l'écriture de plusieurs instructions sur la même ligne. Il faut éviter l'écriture des points-virgules inutiles, par exemple:

def filter(p: Tweet => Boolean): TweetSet = filter0(p, new Empty); 

9 Ne soumettez pas le code avec « imprimer » Déclarations

Vous devez nettoyer votre code et supprimer tous les documents imprimés ou instructions println avant de le soumettre. La même chose s'appliquera une fois que vous travaillerez pour une entreprise et que vous créerez du code utilisé en production: le code final devrait être exempt d'instructions de débogage.

10 Évitez d'utiliser Retour

En Scala, vous n'avez pas besoin souvent d'utiliser des rendements explicites parce que les structures de contrôle telles que si sont des expressions. Par exemple, dans

def factorial(n: Int): Int = { 
    if (n <= 0) return 1 
    else return (n * factorial(n-1)) 
} 

les instructions de retour peuvent simplement être supprimées.

11 Évitez mutables Variables locales

Depuis c'est un cours sur la programmation fonctionnelle, nous voulons que vous vous habituez à écrire du code dans un style purement fonctionnel, sans utiliser les opérations à effectuer côté. Vous pouvez souvent réécrire du code qui utilise des variables locales mutables pour coder avec des fonctions auxiliaires qui prennent des accumulateurs. Au lieu de:

def fib(n: Int): Int = { 
    var a = 0 
    var b = 1 
    var i = 0 
    while (i < n) { 
    val prev_a = a 
    a = b 
    b = prev_a + b 
    i = i + 1 
    } 
    a 
} 

préfèrent:

def fib(n: Int): Int = { 
    def fibIter(i: Int, a: Int, b: Int): Int = 
    if (i == n) a else fibIter(i+1, b, a+b) 
    fibIter(0, 0, 1) 
} 

12 Éliminez redondants « Si » Expressions

au lieu de

if (cond) true else false 

vous pouvez simplement écrire

cond 

(De même pour le cas négaitve).

D'autres problèmes de style? S'il vous plaît poster sur le forum en utilisant le style ou styleChecktags et nous allons compléter ce guide de style avec des suggestions.

+2

Point # 5 est drôle, étant donné que le scaladoc est juste plein de noms d'arguments nommés 'k',' g', 'p' et' z'. – jbx

+0

Je n'ai pas remarqué quand j'ai écrit que le créateur de la langue lui-même posté ici. Vous pouvez lire ses articles sur Scala à propos des conventions syntaxiques. http://stackoverflow.com/a/3718851/1984636 – sivi