Le principe KISS appliqué à la conception du langage de programmation?

14

KISS ("garder les choses simples, stupides" ou "garder les choses simples stupides", voir par exemple ici ) est un principe important dans le développement de logiciels, même s'il semble provenir de l'ingénierie. Citant de l'article de wikipedia:

Le principe est mieux illustré par l'histoire de Johnson remettant à une équipe d'ingénieurs concepteurs une poignée d'outils, avec le défi que l'avion à réaction qu'ils concevaient doit être réparable par un mécanicien moyen sur le terrain dans des conditions de combat avec uniquement ces outils. Par conséquent, le «stupide» fait référence à la relation entre la façon dont les choses se brisent et la sophistication disponible pour les réparer.

Si je voulais l'appliquer au domaine du développement logiciel, je remplacerais "avion à réaction" par "logiciel", "mécanicien moyen" par "développeur moyen" et "dans des conditions de combat" par "dans le cadre du développement / de la maintenance logicielle attendue". conditions "(délais, contraintes de temps, réunions / interruptions, outils disponibles, etc.).

C'est donc une idée communément acceptée que l'on devrait essayer de garder un logiciel simple (ou simplement stupide , au cas où vous omettez la virgule) afin qu'il soit facile de travailler dessus plus tard.

Mais le principe KISS peut-il s'appliquer également à la conception d'un langage de programmation? Connaissez-vous des langages de programmation spécialement conçus avec ce principe à l'esprit, c'est-à-dire "permettre à un programmeur moyen dans des conditions de travail moyennes d'écrire et de maintenir autant de code que possible avec le moins d'effort cognitif"?

Si vous citez une langue spécifique, ce serait bien si vous pouviez ajouter un lien vers un document dans lequel cette intention est clairement exprimée par les concepteurs de la langue. Dans tous les cas, je serais intéressé à en savoir plus sur les intentions (documentées) des concepteurs plutôt que sur votre opinion personnelle sur un langage de programmation particulier.

Giorgio
la source
4
Avez-vous exploré la famille des langues de base (ou du moins, l'intention originale derrière elles)?
4
BASIC et Pascal ... tous deux conçus comme des langages pédagogiques.
Michael Brown
1
Qu'entendez-vous par simple? La plupart des langues sont assez simples, car elles ne sont pas très nombreuses. Rien de moins complexe que l'assembleur. Les cadres sont souvent compliqués, mais ils sont conçus pour permettre «d'écrire et de maintenir autant de code que possible avec le moins d'effort cognitif».
pdr
7
Le schéma (r) a été utilisé comme langue d'enseignement pendant des années (décennies?) Et a été développé en simplifiant LISP et Algol (et peut-être plus). Le livre SICP prend beaucoup moins de temps pour enseigner la langue elle-même. De plus, les DSL viennent à l'esprit.
vpit3833
3
@Giorgio jetez un œil à Haskell. Il a très et je veux dire très peu de bits intégrés. La plupart des opérateurs sont des fonctions qui se trouvent dans la bibliothèque principale, mais qui ne sont pas nécessaires au langage lui-même, il a fait de grands efforts pour supprimer toutes les pièces inutiles
Jimmy Hoffa

Réponses:

15

Quand je pense au minimalisme, je pense à Lisp and Go . Avec Lisp, vous n'avez que des fonctions et des listes, ce qui est à peu près aussi simple que possible (enfin, il y en a un peu plus, mais peu importe). Cependant, je pense que l'affaire Go est plus intéressante.

Go a été conçu pour être simple (c'est une lecture décente). Le terme qu'ils utilisent est «orthogonalité des entités», ce qui signifie que toute entité ne doit être ajoutée que si elle fournit quelque chose de vraiment unique. Cela semble découler de l' implication des auteurs ( Russ Cox et Rob Pike ) dans Plan9 , qui était une réimagination d'UNIX avec la simplicité à l'esprit. (Si vous êtes intéressé par un design minimal, le document de Rob Pike sur un système de fenêtrage simple est une bonne lecture.)

Voici quelques exemples simples de la syntaxe:

Une seule construction en boucle

Une boucle peut ressembler à l'un des éléments suivants:

Boucle infinie

for {
}

Boucle while

for <conditional> {
}

Boucle traditionnelle

for i := 0; i < 10; i++ {
}

Boucle Foreach

// works for maps or arrays
for k, v := range arr {
}

Interrupteur polyvalent

switch {
    // cases must be evaluate to a boolean
}

switch <value> {
}

switch t := <value>; t {
    // can use t inside
}

Retour multiple

return val1, val2, ...
  • Supprime le besoin de lancer (transmettre l'erreur comme dernière valeur de retour)
  • Supprime le besoin de paramètres out
  • Supprime le besoin de tuples

Interfaces

type X interface {
    DoSomething()
    String() string
}
  • Résout des problèmes similaires aux génériques
  • Permet l'abstraction

Incorporation

type A struct {
    Thing string
}

type B struct {
    A // embeds A in B, so B.Thing refers to A.Thing
}
  • Résout le même problème que l'héritage
  • Élimine le besoin de cours

Chaînes

Peut être utilisé pour implémenter des sémaphores

var c = make(chan bool, 1)
c<-true // semaphore lock
<-c // semaphore free

Utilisé pour le message passant entre les threads

func produce(c chan<- bool) {
    for {
        c <- true
    }
}
func consume(c <-chan bool) {
    for {
        <-c
    }
}

var c = make(chan bool)
go produce(c)
go consume(c)

Peut être utilisé pour gérer des événements asynchrones

func async() chan bool {
    var c = make(chan bool)
    go doSomethingAsync(c)
    return c
}

// wait for long async process to finish
c := async()
select {
    case _ = <-c:
}

Conclusion

Je ne vais pas entrer dans toutes les parties de la syntaxe, mais j'espère que vous pourrez voir ce que le minimalisme peut faire. Le langage intrigue non pas parce qu'il ajoute une tonne de nouvelles fonctionnalités, mais parce qu'il utilise les meilleures fonctionnalités d'autres langues sans rien de plus.

Il existe généralement une «meilleure» façon de résoudre un problème. Par exemple, sur la liste de diffusion, de nombreux utilisateurs se plaignent de ne pas avoir de génériques. Après discussion, ils se rendent compte que tout ce qu'ils veulent faire peut se faire avec des interfaces. Lisez sur go efficace pour des exemples sur la syntaxe idiomatique.

L'avantage des langues KISS est qu'il est possible d'écrire du code idiomatique, car le style de code est limité par la langue. Par exemple, dans Go, vous ne pouvez pas écrire quelque chose comme ceci:

if <condition>
    statement;

Vous devez utiliser des accolades:

if <condition> {
    statement;
}

Il existe de nombreux autres exemples de cela dans la syntaxe, ce qui facilite la lecture du code d'autres personnes.

Avantages du langage KISS par rapport aux langages riches en fonctionnalités:

  • plus facile à comprendre le code des autres
  • plus facile à maîtriser l'ensemble du langage (C ++ est connu pour être difficile à comprendre)
  • se concentrer sur l'algorithme, pas sur la syntaxe
beatgammit
la source
5
À mon humble avis, la syntaxe de la boucle for traditionnelle n'est pas si géniale. Bien sûr, il est familier à tous les programmeurs de type C, mais je me souviens de la première fois que j'ai appris cela: j'étais très confus. BASIC c'est plus KISS for i=1 to 10for item in group
:,
3
@mouviciel - Je n'utilise presque jamais la boucle for traditionnelle. Le problème for i = 1 to 10est de savoir si isera jamais 10. Cela peut dépendre de la langue (bash inclut 10, python non). La boucle for traditionnelle est universelle.
beatgammit
+1, en particulier pour le résumé des avantages du minimalisme.
Giorgio
1
Aller car une étude de cas est intéressante car elle n'est pas considérée comme une langue KISS par ses détracteurs. En fait, l'argument est le suivant: un langage "simple" ne conduit pas à un code "simple" ou à une compréhension plus facile. Parfois, il doit y avoir plus de complexité (par exemple, une bonne prise en charge des génériques) pour que le code soit plus facile à comprendre.
Andres F.
14

Je pense que le Zen de Python expliquera pourquoi Python est un langage simple beaucoup mieux que moi:

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Modifier en réponse à @Giorgio

Comme l'indique votre question,

"Connaissez-vous des langages de programmation qui ont été conçus spécifiquement avec ce principe à l'esprit, c'est-à-dire pour" permettre à un programmeur moyen dans des conditions de travail moyennes d'écrire et de maintenir autant de code que possible avec le moins d'effort cognitif ""

Le python est, pour moi, ce qui me vient immédiatement à l'esprit. Le design de Python est en réponse directe à la méthodologie de Perl, le fameux "Il y a plus d'une façon de le faire". Bien que ce soit génial, permettant aux programmeurs d'écrire très facilement du code, cela n'aide pas à la maintenance. Ayant auparavant géré un programme (très mal écrit, je l'admets) écrit en Perl, j'apprécie Python forçant à la fois de bonnes pratiques de codage et un langage concis.

Python ne vous oblige pas non plus à suivre une méthodologie particulière lors de l'écriture de programmes. Je peux choisir de suivre un style de programmation orienté objet strict, ou je peux écrire un script simple à exécuter séquentiellement. Ne pas avoir à initialiser une classe, puis appeler la main()méthode comme vous êtes obligé de le faire en Java est très agréable. (De plus, l'impression sur stdout en Python est merveilleuse, mais c'est un point plutôt nul).

Enfin, la méthodologie "Batteries incluses" consistant à inclure une bibliothèque standard étendue avec le langage est merveilleuse. Au lieu de parcourir un référentiel externe pour les packages, la plupart de ce dont j'ai besoin est déjà inclus dans la langue. C'est aussi bien d'avoir ce dépôt externe, mais ne pas avoir à creuser pour effectuer une opération de base est vraiment pratique.

Zach Dziura
la source
3
Merci pour la citation utile. Est-ce l'intention officielle du ou des concepteurs de Python? Notez également que tous les lecteurs pourraient ne pas être d'accord avec votre opinion sur Python, il est donc peut-être un peu trop fort d'affirmer que «Python est un langage simple» comme un fait bien connu et accepté. Serait-il possible de le formuler comme "Python a été conçu avec la simplicité à l'esprit"?
Giorgio
@Giorgio - C'est l'expérience de nombreux développeurs d'ici que le python est en fait un langage simple. Simple à apprendre, simple à écrire et simple à lire. À propos de la citation, car python est "piles incluses", vous pouvez l'obtenir directement à partir du langage avec la import thiscommande.
mouviciel
1
TCL est également une bonne réponse à cela et l'IIRC a également été une réponse à la complexité de PERL.
jk.
@mouviciel Après avoir rencontré du code spaghetti Python incroyablement alambiqué à plusieurs endroits, je ne pense plus que Python réussisse dans ses objectifs ici. Python n'est pas meilleur que la plupart des langages en termes de simplicité - il peut être très bon pour l'obscurcissement accidentel.
Izkata
1
Python est simple tant que les gens restent éloignés de la plupart des __magic_functions __ () et @decorators.
weberc2
3

Une clé majeure pour maintenir la "simplicité" est de reconnaître quand la complexité sera nécessaire, et de faire en sorte que les parties du système qui puissent le mieux y faire face. Le fait d'avoir un seul type de référence d'objet qui ne fait aucune distinction entre les valeurs immuables, les valeurs mutables et les entités, rend Java "simple", n'élimine pas la nécessité de faire la distinction entre les valeurs et les entités; il prive simplement les programmeurs d'outils pour les aider à le faire.

Plus généralement, si l'on essaie de faire en sorte qu'un langage de programmation ou une fonctionnalité de structure prennent en charge plusieurs cas d'utilisation, il faut s'assurer qu'il n'y aura pas de situations où des comportements différents seraient appropriés dans différents cas d'utilisation, mais le compilateur serait incapable de dire les séparer. Ajouter plus de types à un langage ou à un framework peut sembler une complication, mais dans de nombreux cas, cela peut en fait faciliter les choses.

Considérez, par exemple, le désordre des règles entourant les types signés et non signés en C. La complexité de ces règles provient du fait que certains codes utilisent des types entiers non signés pour représenter les nombres, tandis que d'autres codes les utilisent pour représenter les membres d'un anneau algébrique enveloppant (spécifiquement, l'ensemble des entiers congruents mod 2ⁿ). Les règles de conversion de type se comportent de manières qui sont parfois appropriées à une utilisation, et parfois de manière appropriée à l'autre. Le fait d'avoir des types d'habillage et de non-habillage séparés doublerait le nombre de types entiers, mais pourrait simplifier les règles qui leur sont associées:

  • Tout type entier non-anneau de n'importe quelle taille peut être affecté à un anneau de n'importe quelle taille; un anneau ne peut être attribué qu'à un anneau de taille égale ou inférieure .

  • Les opérations autres que les opérateurs relationnels impliquant un entier non-anneau et un anneau convertiront implicitement l'entier en type d'anneau.

  • Les anneaux peuvent être explicitement convertis en nombres ou en anneaux plus grands; la valeur d'un anneau non signé est le plus petit entier non négatif qui, ajouté au zéro de l'anneau, donnerait la valeur de l'anneau. La valeur d'un anneau signé est le plus petit nombre entier qui, ajouté au zéro de l'anneau, donnerait la valeur de l'anneau, la valeur négative étant préférée en cas d'égalité.

  • Sauf comme mentionné ci-dessus, les anneaux sont limités aux opérations avec des anneaux de même taille ou plus petits.

  • Les opérations sur des entiers non-ring de différents types doivent transposer les nombres en un type qui peut prendre en charge toutes les valeurs de l'un ou l'autre opérande, ou doivent être rejetées par le compilateur si aucun type approprié n'existe

La définition des types d'anneaux semblerait doubler le nombre de types entiers, mais simplifierait grandement l'écriture de code portable. L'utilisation des mêmes types non signés pour les nombres et les sonneries réduit le nombre de types, mais conduit à des règles compliquées qui rendent presque impossible l'écriture de code portable efficace.

supercat
la source
+1 Entièrement d'accord. Un langage "simple" (simple dans le sens d'avoir une petite spécification) ne conduit pas nécessairement à un code simple, ni à une facilité de raisonnement pour le programmeur.
Andres F.
Grand commentaire. L'ajout de complexité doit être considéré en termes de coûts et d'avantages.
user1071847
2

On peut dire que Tcl a été développé dans ce sens. La langue entière peut être décrite en seulement 12 règles sur une seule page de manuel . C'est remarquablement simple et cohérent.

Le créateur de Tcl a déclaré que les objectifs suivants étaient les suivants:

  • La langue doit être extensible: il doit être très facile pour chaque application d'ajouter ses propres fonctionnalités aux fonctionnalités de base de la langue, et les fonctionnalités spécifiques à l'application doivent apparaître naturelles, comme si elles avaient été conçues dans la langue depuis le début.
  • Le langage doit être très simple et générique, afin qu'il puisse fonctionner facilement avec de nombreuses applications différentes et qu'il ne restreigne pas les fonctionnalités que les applications peuvent fournir.
  • Étant donné que la plupart des fonctionnalités intéressantes proviendront de l'application, l'objectif principal du langage est d'intégrer ou de «coller ensemble» les extensions. La langue doit donc disposer de bonnes facilités d'intégration.

Extrait de " History of Tcl " - http://www.tcl.tk/about/history.html

Bryan Oakley
la source
2

Si une langue est fixée dans sa conception à cause de KISS, elle ne peut pas grandir. Une langue qui ne peut pas grandir mourra.

Dans la vidéo suivante, Guy Steele explique intelligemment qu'un langage de programmation doit se développer et pourquoi. Si vous appliquez KISS, alors comment une langue peut-elle grandir car une fois publiée, son ensemble d'outils est fixe et ne peut jamais changer.

Le discours de Guy Steele lors de la conférence ACM OOPSLA de 1998 sur le thème "Cultiver un langage" discute de l'importance et des problèmes associés à la conception d'un langage de programmation qui peut être développé par ses utilisateurs.

C'est une vidéo d'une heure mais qui mérite d'être regardée. Si vous ne savez pas qui est Guy Steele, vous devriez vraiment le faire lorsque vous parlez de conception de langage.

J'ai choisi cette vidéo comme réponse parce que je pense qu'appliquer KISS à la conception de langage en général est une erreur, et j'espère que voir un discours d'une personne réputée de la conception de langage vous aidera à élargir votre compréhension de l'avenir de la conception de langage.

Depuis que vous êtes venu ici pour en savoir plus sur la conception de langage et que je vous ai donné une raison de ne pas utiliser KISS, il est juste que je souligne quelque chose que je trouve utile dans la conception de langage. Dimensions cognitives des notations

ÉDITER

Quand j'ai écrit la réponse ci-dessus, elle était basée sur le raisonnement suivant: si un moteur ne peut être maintenu qu'avec un ensemble d'outils fixe, ma reformulation de ce sens en ce qui concerne la conception du langage est qu'un langage ne peut pas changer une fois publié. Les commentaires indiquent que ce n'était pas ce que l'on voulait dire. Permettez-moi donc de présenter cette réponse modifiée qui sera plus conforme à la nouvelle entente.

Si l'on jette un œil aux dimensions cognitives des notations, on apprend qu'il existe de nombreuses dimensions concurrentes associées à la conception du langage que la simple simplicité et si vous vous concentrez trop sur l'une, vous en souffrirez dans d'autres. Avec la question de se concentrer fortement sur la simplicité (KISS), et soutenu par des personnes remarquables du design linguistique, j'ai soumis le discours de Guy Steele pour montrer qu'essayer de garder un design uniquement simple aura un impact sur d'autres dimensions. Plus important encore, j'essaie de faire comprendre que vous devez examiner de nombreuses dimensions et peser le pour et le contre, pas seulement la simplicité.

Guy Coder
la source
3
Alors, que se passe-t-il si la vidéo devient indisponible? Ou s'il n'est pas accessible dans certains pays? Votre réponse doit être complète et autonome, veuillez la mettre à jour pour au moins nous donner un bref résumé de la vidéo, les réponses en lien uniquement ne sont pas vraiment utiles et peuvent être supprimées à tout moment.
yannis
3
@AndreasScheinert Le guide de réponse indique clairement que les liens doivent toujours être accompagnés de résumés et / ou de citations pertinentes.
Thomas Owens
3
Je ne suis pas sûr de pouvoir souscrire à votre évaluation. Tcl, par exemple, est remarquablement simple. Il a duré des années avec seulement 11 règles régissant son utilisation. Pourtant, aussi simple soit-il, il a considérablement augmenté au cours des 20+ années de son existence. Il a maintenant 12 règles, ce qui prouve que non seulement sa bibliothèque a grandi, mais sa nature fondamentale a également été autorisée à croître tout en conservant toute sa simplicité.
Bryan Oakley
1
"Si vous appliquez KISS, alors comment une langue peut-elle se développer car une fois publiée, son ensemble d'outils est fixe et ne peut jamais changer.": Cela dépend de ce que vous entendez par simple et en grandissant. Voulez-vous dire ajouter de nouvelles bibliothèques (en anglais, ajouter de nouveaux mots au vocabulaire) ou ajouter de nouvelles constructions linguistiques (en anglais, cela signifierait ajouter, par exemple de nouveaux temps de verbe, de nouvelles prépositions, etc.). Les langues naturelles cessent finalement d'ajouter de nouvelles règles de grammaire tout en continuant à ajouter de nouveaux mots. Donc, dans mon intuition, simple fait référence au nombre de règles de grammaire, plutôt qu'au nombre de bibliothèques / mots.
Giorgio
3
@Guy Coder: D'un autre côté, la vidéo à laquelle vous avez posté un lien semble dire quelque chose de différent par rapport à ce que vous dites au début de votre réponse, à savoir qu'un langage devrait fournir certaines fonctionnalités de base qui permettent à ses utilisateurs (programmeurs) de étendre la langue (ajouter de nouvelles bibliothèques). Il ne dit pas que le langage de base devrait croître indéfiniment.
Giorgio
1

Voici une grande citation du Hardcore Visual Basic de Bruce McKinney , qui à son tour met les mots dans la bouche des concepteurs de BASIC, Kemeny et Kurtz . Souligne le mien.

Chaque langage informatique a sa propre sensation, sa propre atmosphère, son propre esprit. Vous ne pouvez pas vraiment définir cet esprit, mais vous savez ce que c'est quand vous le voyez. Je pense que Basic est l'antithèse d'une déclaration attribuée à Albert Einstein:

Rendez les choses aussi simples que possible, mais pas plus simples.

Si cette citation avait été écrite par les concepteurs originaux de Basic, John Kemeny et Thomas Kurtz, elle aurait été encore simplifiée:

Rendez les choses plus simples que possible.

C'est la contradiction avec laquelle les programmeurs Visual Basic inconditionnels vivent. Nous voulons que les choses soient simples, élégantes et intuitives, mais elles ne le sont pas. Nous voulons que nos programmes modélisent la réalité, mais ils ne le font pas. Nous voulons que notre langage fonctionne comme nous pensons, pas comme les ordinateurs ou les systèmes d'exploitation veulent que nous pensions, mais nous ne sommes pas prêts à en payer le prix .

AakashM
la source
Sur une note connexe, le fait qu'une construction de langage "puisse" être faite pour servir à plusieurs fins ne signifie pas qu'une telle conception est préférable à des constructions différentes pour ces différentes fins. Par exemple, C utilise des types non signés à la fois pour représenter des quantités numériques et pour représenter des membres d'un anneau algébrique enveloppant. L'ajout d'un nombre de n'importe quelle taille ou signature à un anneau devrait produire un membre du même anneau, tandis que l'ajout de deux nombres de n'importe quelle taille et signature devrait donner un résultat suffisamment grand pour gérer n'importe quelle valeur de l'un ou l'autre opérande. Utilisation de types non signés dans les deux cas ...
supercat
... signifie que les règles de C doivent parfois les considérer comme des nombres et parfois comme des membres de l'anneau, d'une manière qui rend presque impossible l'écriture de code propre et portable.
supercat
1

Mais le principe KISS peut-il s'appliquer également à la conception d'un langage de programmation? Connaissez-vous des langages de programmation spécialement conçus avec ce principe à l'esprit, c'est-à-dire "permettre à un programmeur moyen dans des conditions de travail moyennes d'écrire et de maintenir autant de code que possible avec le moins d'effort cognitif"?

C'est une bonne chose que vous ayez clarifié ce que vous entendez par "simple", car dans mon esprit, un langage de programmation simple est un langage avec une syntaxe minimale et peu de fonctionnalités (Scheme, Forth, ML), qui ne se traduit pas directement dans votre définition. Je pense que vous cherchez vraiment la conception de langages avec RAD (développement rapide d'applications) à l'esprit, et il y en a pas mal. Voir ce fil StackOverflow, par exemple: /programming/66227/what-is-the-best-multi-platform-rad-language

Nemanja Trifunovic
la source
"parce que dans mon esprit un langage de programmation simple est un langage avec une syntaxe minimale et peu de fonctionnalités (Scheme, Forth, ML)": Eh bien, en fait j'ai copié la définition de wikipedia mais j'ai tendance à identifier les deux choses. Par exemple, le schéma peut être appris très rapidement et après cela, je peux me concentrer sur le problème à résoudre. D'autres langages (comme C ++, que j'utilise au travail) continuent de croître et vous devez apprendre de nouvelles choses tout le temps. En outre, le code devient moins facile à gérer car différents programmeurs ont tendance à utiliser différents sous-ensembles du langage. Donc, je considérerais SML et Scheme "simple".
Giorgio
1

Je suis surpris que personne n'ait encore mentionné C, même s'il met la simplicité au premier plan de plusieurs façons importantes, souvent d'une manière si radicale que les programmeurs ne parviennent pas à apprécier la simplicité:

  • Il n'y a pas de magie cachée. Si vous écrivez a + ben C, vous avez la garantie qu'il sera compilé en une seule instruction assembleur au maximum.

    Même dans des langages relativement simples comme Java, une simple instruction comme a + bpeut prendre plusieurs microsecondes (si les variables sont des chaînes). D'autres langages ajoutent beaucoup, beaucoup plus à cela avec l'exemple extrême de C ++ où a + bpeut être surchargé pour faire apparaître les éléphants roses. Ce n'est pas le cas en C: s'il ne s'agit pas d'un appel de fonction, cela ne prendra pas plus de quelques nanosecondes. Cette prévisibilité des performances est l'une des principales caractéristiques de C, et c'est certainement une forme de simplicité.

  • Les types de données sont aussi simples que possible tout en décrivant toutes les structures de données intéressantes que vous pourriez vouloir créer en mémoire: il n'y a que les types fondamentaux qu'un processeur peut gérer + agrégation ( struct) + répétition (tableaux) + références (pointeurs) ).

    Il est vrai que les différents langages basés sur lisp sont beaucoup plus simples que C à cet égard. Cependant, ils n'essaient pas de permettre au programmeur de manipuler librement la mémoire comme le fait C.

  • Orthogonalité des fonctionnalités: vous pouvez combiner librement les fonctionnalités et elles fonctionneront ensemble comme prévu. De nombreux langages échouent en permettant à certaines constructions d'apparaître uniquement dans des contextes définis.

    Prenons par exemple les tableaux de longueur variable en C et C ++: C autorise les longueurs d'exécution partout tandis que les demandes les plus libérales pour étendre la norme C ++ ne les autorisent que dans certains contextes comme les tableaux automatiques et même là seulement dans la première dimension. Cela permet à C de gérer de véritables tableaux multidimensionnels avec des tailles connues uniquement au moment de l'exécution, tandis que les programmeurs C ++ sont réduits à écrire data[k + (j + i*lineLength)*lineCount]encore et encore.

    Un autre exemple de ceci est le pointeur: un pointeur de données en C ce n'est rien de plus ou moins qu'une simple variable contenant une adresse mémoire d'une autre variable. Puisque le pointeur est lui-même une variable, le double pointeur est une chose bien définie. C'est-à-dire, étant donné ce qui est intet ce int*qu'il est, il est clair ce qui int**doit être. Comparez cela aux références C ++ où vous n'avez absolument aucune idée de ce qui int&&est donné le sens de intet int&!)

Il est vrai que c'est précisément cette simplicité qui a valu à C tant de haine: la simplicité du langage permet aux programmeurs plus de liberté que bon pour eux, conduisant à beaucoup de problèmes avec un comportement indéfini et des pointeurs mal gérés. Surtout la simplicité de l'orthogonalité qui permet à un programmeur de définir une variable telle qu'elle int (*array[m])(struct foo* (*arg)[n])est du type qui tend à donner des maux de tête aux lecteurs car des choses vraiment complexes peuvent être exprimées sous une forme très concise par une combinaison libérale de quelques fonctionnalités simples . C'est le type de simplicité auquel C excelle, et qui lui donne la réputation d'être un langage difficile à utiliser.

De plus, la simplicité du langage oblige le programmeur à écrire beaucoup plus de code que les langages plus riches en fonctionnalités, fournissant un terrain plus fertile pour que les bogues prospèrent. Néanmoins, il reste le langage de haut niveau le plus simple possible si votre objectif principal est de programmer un vrai ordinateur et non une machine virtuelle.

cmaster - réintégrer monica
la source
L'électeur peut-il laisser un message expliquant la raison de son vote?
Giorgio
C est un gâchis. Essayez de déterminer ce que vous obtiendrez si vous ajoutez un court signé à un long non signé et stockez le résultat dans un entier. Même sans "long long", il a huit types d'entiers différents. Ce n'est pas simple.
Simon B
@SimonB Vous n'avez clairement pas compris de quoi parle mon message. La simplicité des types entiers est la suivante: un type entier a une taille (en octets et bits) et peut être signé ou non. Vous pouvez utiliser n'importe quelle combinaison de ces deux fonctions orthogonales. C'est cette orthogonalité dont je parle. C possède toutes les fonctionnalités nécessaires pour exploiter pleinement le matériel réel, ce qui implique une certaine complexité. Cependant, la façon dont C gère cette complexité consiste à combiner des concepts simples de façon orthogonale pour permettre au programmeur de faire des choses complexes.
cmaster - réintègre monica
0

Java Wikipedia - bien que cela ne soit pas explicitement indiqué dans Wikipedia, la simplification est mentionnée à plusieurs reprises et était un objectif de conception original, car le seul langage sérieux capable OO (terme utilisé de manière lâche) à cette époque était le C ++, qui, comme nous le savons tous, est puissant mais a plus de quelques pièges pour les imprudents.

La machine virtuelle Java était conçue comme un moyen de simplifier le développement multiplateforme et «Écrire une fois, exécuter n'importe où» est devenu un mantra Java pendant quelques années - encore une fois, l'intention était que le cadre était simple à déployer.

Je crois que C # tombe dans cette catégorie de simplification du langage.

mattnz
la source
Voulez-vous dire que C # a également été initialement conçu comme une simplification de C ++?
Giorgio
2
C ++ et OO? Alan Kay ne le pense pas. C # Sinplyfication ???? Je ne sais pas ce que tu veux dire par simple. Je pense qu'il vaut mieux que vous déclariez cela avant de déclarer les choses en tant que telles. LISP est simple car il a très peu de syntaxe. C # au contraire a des TONNES de syntaxe et de mots-clés.
AndreasScheinert
La possibilité de simplifier le développement multiplateforme ne signifie pas que le langage lui-même est simple. Quelque chose peut être multiplateforme mais pas toujours simple en soi.
Bryan Oakley
@Bryan Agreed - la conception de Java tenait compte du fait que les programmes multiplateformes n'étaient pas (à l'époque) simples, et pour créer des programmes simples, vous aviez besoin d'un langage simple et vous deviez éliminer la complexité de la gestion du code spécifique à la plate-forme dans le programme lui-même.
mattnz
2
@Giorgio C # était une réinvention de Java. Java était censé être à la fois moins complexe que C ++ (par exemple, pas d'héritage multiple) et quelque chose de bien plus grand (par exemple, vaste bibliothèque standard, collecte de déchets).
Sean McSomething
-2

Hm ... c'est en fait une question difficile à répondre "positivement", parce que quand je pense à la simplicité dans la conception du langage de programmation (et ce qui est "plus facile" à travailler), je pense immédiatement à:

  1. "Lisibilité" du code - dans quelle mesure le langage encapsule les objets, les méthodes, etc.
  2. La cohérence des API et interfaces linguistiques.

Il y a un certain nombre de langues qui font bien ces choses - mais ce qui me vient à l'esprit est une langue qui ne fait pas bien les choses «en tant que langage de programmation»: PHP.

[Avertissement - J'ai écrit PHP et PHP est toujours mon «go to language» pour les projets Web simples. Ceci est une critique de l'amour ...]

Premièrement, PHP fonctionne bien pour l'environnement qu'il exécute généralement sur les serveurs Web. Il est facile à installer, à entretenir, etc.

Là où j'ai du mal avec PHP: lorsque vous voulez faire quelque chose d '"inhabituel" - quelque chose que vous ne faites généralement pas régulièrement (dans le cas où je pense qu'il consomme un service Web SOAP - pas quelque chose que j'ai beaucoup fait avec PHP), vous êtes confronté à deux options:

1) Diverses extensions open source de PHP. Le modèle d'objet PHP est suffisamment lâche lorsque la conception de l'interface n'est pas non plus très cohérente d'une bibliothèque à l'autre, d'un développeur à l'autre. Lorsque vous êtes confronté à un ensemble de codes où quelqu'un a utilisé une bibliothèque dont vous n'avez jamais entendu parler, vous passez beaucoup de temps à comprendre `` ce que ça peut faire '' car le langage permet une création d'API / bibliothèque lâche.

2) Les fonctions "intégrées" - dont il y en a beaucoup . Je suis passé par quelques trous de lapin de trouver une autre bibliothèque ou d'implémenter un peu de fonctionnalité pour tomber plus tard surimpossiblyfound_basefunction()

À mon avis, la simplicité est la cohérence.

Chad Thompson
la source
-3

Maintenant, l'approche KISS des langages de programmation est une notion amusante, du moins si vous considérez les langages de programmation comme une couche d'abstraction du jeu d'instructions d'un processeur, etc. Si vous ne définissez pas "KISS" de plus près. Je dis juste ici, qu'un char à bœufs est KISS appliqué à une voiture à son maximum.

Maintenant, une autre interprétation de KISS pourrait être quelque chose comme "intelligemment fait sans ornements inutiles et pas trop compliqué". En particulier, on pourrait dire qu'il ne devrait pas y avoir trop de cas spécifiques pour des choses similaires, etc. .

Pour la programmation, il existe 2 modèles abstraits assez connus:

  • L'un est la machine de turing qui définit une machine et un modèle pédagogique simple qui est capable de calculer tout ce qu'un ordinateur pourrait faire.
  • L'autre est le Lambda-Calculus de Church et. Al. qui est équivalent en puissance

Ce qui est amusant, c'est que si la machine de turing est assez simple dans sa configuration, ce n'est pas un système facile à manipuler et je ne pense pas qu'elle soit qualifiée de "smart KISS". Mais Lambda Calculus a plus à voir avec les langages de programmation que nous connaissons - et avec les fonctionnalités pionnières de Lisp et Scheme du calcul lambda, il a fait son chemin dans de nombreux langages.

Lisp et Scheme sont VRAIMENT simples, au moins en termes de syntaxe. La syntaxe est un problème majeur avec les langages de programmation (c'est probablement pourquoi ils sont réinventés tout le temps). Dans le cas de C ++, il est presque impossible pour le cerveau humain de prédire comment certaines lignes source sont interprétées par le compilateur.)

Les lisps réduisent complètement la complexité syntaxique en introduisant une forme commune pour les commandes:

(command param1 param2 ...)

Cela peut être un appel de méthode, tel que

(max 1 2 3 4)

ainsi qu'une branche if, une boucle, etc.

(if (< 1 2) 
    (write 4)
    (write 5))

(tout le code ici est agnostique pseudo-lisp / dialecte)

La forme

(command param1 param2 ...)

peut également être interprété comme une liste

(item1 item2 item3)

Et c'est la base de la simplicité et de la beauté de Lisps. Parce que les listes imbriquées (comme dans l' ifexemple de déclaration) constituent des arbres et ceux-ci peuvent être facilement compris à la fois par la machine et par l'homme devant la machine.

Une autre caractéristique de Lisps sont les macros, je n'entrerai pas dans les moindres détails ici, mais puisqu'il n'y a pas de différence syntaxique entre les appels de fonction normaux et "Syntaxe (œuf pour les boucles, déclaration de variable, etc., tout ce que l'analyseur doit gérer dans d'autres langages de programmation) vous pouvez créer votre propre syntaxe. Les macros sont essentiellement des manipulations de l’ arbre qui constitue votre programme.

Je pense que Lisp a un BAISER à la programmation. Le fait que vous puissiez manipuler la syntaxe à l'aide de macros a conduit à un phénomène que Lisp a évolué de manière assez dynamique. Besoin d'une nouvelle fonctionnalité de langue comme - disons l'orientation de l'objet - il suffit d'écrire un système OOP avec des macros!

Alors que C a été prolongé 2 fois du rond-point avec des fonctionnalités OOP (C ++, Obj. C) Lisp a été prolongé plusieurs fois, il y a finalement eu un gagnant.

C'est une autre bizarrerie à propos de Lisp, il évolue (voir Clojure et Clojurescript pour une nouvelle Mutation intéressante de lisp).

Pour ses propriétés KISS, Lisps est privilégié comme langue d'enseignement par certains. Comme Fogus décrit dans son plan d'une langue éducative ( http://blog.fogus.me/2013/01/21/enfield-a-programming-language-designed-for-pedagogy/ )

Pour commencer, je suis convaincu que lors de l'apprentissage de sujets nouveaux et parfois complexes, il est tout à fait préjudiciable de surcharger les élèves avec des règles de syntaxe frivoles. Par conséquent, Enfield est conçu avec des règles de syntaxe minimales et ce qui est plus minimal qu'une syntaxe de type Lisp.
wirrbel
la source
2
OP définit KISS pour le contexte de cette question assez clairement, "permettre à un programmeur moyen dans des conditions de travail moyennes d'écrire et de maintenir autant de code que possible avec le moins d'effort cognitif" . OP mentionne également "intéressé à connaître les intentions (documentées) des concepteurs plutôt que votre opinion personnelle sur un langage de programmation particulier"
gnat