Quels sont les exemples d'incohérence et d'incomplétude dans Unix / C?

20

Dans le célèbre essai de Richard Gabriel, The Rise of Worse is Better , il met en contraste les versions caricaturales des philosophies de conception du MIT / Stanford (Lisp) et du New Jersey (C / Unix) selon les axes de la simplicité, de l'exactitude, de la cohérence et de l'exhaustivité. Il donne l'exemple du «problème de perte de PC» ( discuté ailleurs par Josh Haberman ) pour soutenir qu'Unix donne la priorité à la simplicité de mise en œuvre plutôt qu'à la simplicité de l'interface.

Un autre exemple que j'ai trouvé est celui des différentes approches des chiffres. Lisp peut représenter des nombres arbitrairement grands (jusqu'à la taille de la mémoire), tandis que C limite les nombres à un nombre fixe de bits (généralement 32-64). Je pense que cela illustre l'axe de correction.

Quels sont quelques exemples de cohérence et d'exhaustivité? Voici toutes les descriptions de Gabriel (qu'il admet être des caricatures):

L'approche MIT / Stanford

  • Simplicité - la conception doit être simple, à la fois dans la mise en œuvre et l'interface. Il est plus important que l'interface soit simple que l'implémentation.
  • Exactitude - la conception doit être correcte dans tous les aspects observables. L'inexactitude n'est tout simplement pas autorisée.
  • Cohérence - la conception ne doit pas être incohérente. Une conception peut être légèrement moins simple et moins complète pour éviter toute incohérence. La cohérence est aussi importante que l'exactitude.
  • Complétude - la conception doit couvrir autant de situations importantes que possible. Tous les cas raisonnablement attendus doivent être couverts. La simplicité n'est pas autorisée à réduire excessivement l'exhaustivité.

L'approche du New Jersey

  • Simplicité - la conception doit être simple, à la fois dans la mise en œuvre et l'interface. Il est plus important que l'implémentation soit simple que l'interface. La simplicité est la considération la plus importante dans une conception.
  • Exactitude - la conception doit être correcte dans tous les aspects observables. Il vaut mieux être simple que correct.
  • Cohérence - la conception ne doit pas être trop incohérente. La cohérence peut être sacrifiée pour la simplicité dans certains cas, mais il est préférable de supprimer les parties de la conception qui traitent de circonstances moins courantes que d'introduire une complexité de mise en œuvre ou une incohérence.
  • Complétude - la conception doit couvrir autant de situations importantes que possible. Tous les cas raisonnablement attendus doivent être couverts. L'exhaustivité peut être sacrifiée au profit de toute autre qualité. En fait, l'exhaustivité doit être sacrifiée chaque fois que la simplicité de mise en œuvre est compromise. La cohérence peut être sacrifiée pour atteindre l'exhaustivité si la simplicité est conservée; la cohérence de l'interface est particulièrement inutile.

Veuillez noter que je ne demande pas si Gabriel a raison (ce qui n'est pas une question appropriée pour StackExchange) mais pour des exemples de ce à quoi il aurait pu faire référence.

Ellen Spertus
la source
6
Si vous êtes curieux, ce n'est pas un problème de devoirs. Je suis l'enseignant. :-) À la réflexion, peut-être que cela en fait mes devoirs.
Ellen Spertus
4
J'ai du mal à voir pourquoi cette question n'est pas sur Unix et Linux (ou peut-être l' ingénierie logicielle ?). Pouvez-vous nous expliquer en quoi vous avez besoin d'une perspective CS sur la question? Veuillez également préciser si vous souhaitez des exemples positifs ou négatifs.
Raphael
Cette question n'est-elle pas plus adaptée sur programmers.stackexchange.com ?
Basile Starynkevitch
J'ai posté ceci sur CS parce que je considère que la conception de langage est l'un des domaines profonds fondamentaux de l'informatique, couvrant la calculabilité, la complexité, l'architecture, la convivialité, etc. J'aurais pu le publier sur Unix / Linux, bien que je cherchais un vue. Quant aux programmeurs, les gens me sont presque toujours hostiles quand je poste là-bas, même quand je pense que je suis sur le sujet, alors je reste loin de là.
Ellen Spertus

Réponses:

15

Le titre de la question suggère que certaines incohérences de base de l'interface utilisateur peuvent vous intéresser:

Les commandes Unix ne suivent aucune syntaxe particulière pour spécifier les options et les drapeaux. Par exemple, la plupart des commandes utilisent des lettres simples précédées de «-» comme indicateur:, cat -n some_filemais des exceptions comme tar tf some_file.taret dd in=some_file out=some_other_file count=2existent dans les commandes couramment utilisées.

Unix et ses descendants et parents ont plusieurs syntaxes d'expression régulière légèrement différentes. Les shells utilisent "*" là où d'autres programmes (grep, egrep, vi) utilisent '. *'. egrep a '+' et '|' en tant qu'opérateurs, grep ne le fait pas.

L'interface d'appel système «tout est un fichier» de base peut être considérée comme incomplète: lecture / écriture / recherche / fermeture ne convient pas à tous les périphériques d'E / S. Les exceptions grandement nécessaires sont regroupées dans des appels «ioctl», mais des appareils comme les cartes son ne conviennent même pas très bien.

Bruce Ediger
la source
Bonne réponse. Quand j'ai vu le titre, j'ai immédiatement pensé "ioctl" (et fcntl) mais maintenant je n'ai plus à taper de réponse.
Louis
1
les motifs globaux ne sont pas des expressions régulières
jk.
8

Cohérence

Lisp a une syntaxe très cohérente, toutes les extensions de langage peuvent être intégrées naturellement via des macros et autres. C, d'autre part, a une syntaxe plutôt de code, qui permet de prendre des "raccourcis", donc dans certains cas, le code C semble en fait plus simple.

Complétude

En Lisp, si vous ne disposez pas d'une fonctionnalité linguistique spécifique dont vous avez besoin, vous pouvez l'implémenter vous-même avec des macros. C a aussi un préprocesseur, mais c'est plutôt déroutant.

Daniil
la source
8

Les chaînes de C ne peuvent pas contenir de caractère 0 et ses fonctions de bibliothèque ne conviennent pas pour traiter des données binaires.

Les noms de fichiers sur les systèmes Unix ne peuvent pas contenir le caractère 0 ou le caractère 47 (la barre oblique).

Dans l'implémentation d'origine d'Unix, les noms de fichiers étaient limités à 14 caractères. Les versions ultérieures ont seulement assoupli cette limitation; ils ne l'ont pas éliminé.

Ajouté : La E2BIGcondition d'erreur système, quand on a essayé execavec une liste d'arguments qui avait trop d'arguments, ou occupait trop de mémoire, ou un environnement trop grand.

Unix est connu pour ce type de limitation arbitraire. Jusqu'à l'avènement de Perl en 1987, la manipulation de grands ensembles de données, ou des ensembles de données avec de longs enregistrements, ou des données binaires, était extrêmement peu fiable.

Mark Dominus
la source
Ne pas autoriser /n'est pas arbitraire, il est nécessaire (?) De résoudre les ambiguïtés tout comme /le séparateur de chemin. Je viens de créer un fichier 000, apparemment cette restriction spécifique a disparu à l'époque d'un GNU / Linux moderne.
Raphael
Je ne voulais pas dire que l'interdiction de /était arbitraire, seulement que les limites de longueur de ligne et de taille de fichier étaient arbitraires.Le point, cependant, est qu'un design différent aurait pu permettre aux noms de fichiers de contenir des barres obliques, mais les concepteurs d'Unix le juger important.
Mark Dominus
Je suis sûr qu'à l'époque, ces limites ont été introduites pour des raisons de performances; des techniques non développées peuvent également jouer un rôle. Du point de vue d'aujourd'hui, ils semblent douteux, c'est sûr. En ce qui concerne /, je suis curieux: en supposant qu'un chemin doit être codé en chaîne, comment faire cela sans un caractère réservé pour la séparation des chemins?
Raphael
Je ne comprends pas votre point. La question demande des "exemples d'incohérence et d'incomplétude dans Unix / C"; il ne mentionne pas les performances.
Mark Dominus
1
@Raphael: Vous vous débarrassez des problèmes stupides de séparateur en définissant un pathtype de données abstrait, et utilisez-le dans vos interfaces au lieu d'exposer une implémentation particulière (chaînes ascii terminées par null).
Wandering Logic
4

L'IIRC, mon professeur, a déclaré que l'incapacité d'utiliser des char *variables dans les switchénoncés en C est une question d'incohérence, mais pour moi, c'était un problème de généralité (exhaustivité). Je pense qu'il vaut mieux utiliser la «cohérence» uniquement dans vos algorithmes ou dans la conception de logiciels pas dans le langage de programmation lui-même (du moins pas dans des langages comme C. peut-être qu'un langage buggy a un problème de cohérence), parce que les langages de programmation ont des normes solides qui définissent le domaine des règles et travailler en appliquant une entrée aux règles. Donc, si quelque chose n'est pas autorisé dans la langue, il est prévu de ne pas être autorisé et ce n'est pas une incohérence dans la langue, à mon humble avis.


  1. J'ai utilisé la généralité comme exhaustivité. je pense que c'est la même chose. j'ai peut-être tort.
  2. Ce n'est pas une réponse. peut-être une suggestion ou mon opinion.
intoxiqué
la source
3

Le meilleur exemple que j'ai est le pauvre utilisateur qui avait un fichier nommé .. -ret tapé rm *.

Que cette histoire soit vraie ou non, elle est devenue un classique des haineux Unix.

Voir The Unix-Haters Handbook , qui a une introduction par Dennis Ritchie lui-même, pour beaucoup de ces exemples.

J'ajouterai en outre qu'éviter ces types de problèmes a été une force majeure dans la conception du Power Shell de Microsoft.

S. Robert James
la source
J'ai lu l'essai de Richard Gabriel au dos du manuel Unix-Haters. :-)
Ellen Spertus
3
  • Certes, la multitude de significations des mêmes (courts) drapeaux pour les commandes est une incohérence.
  • Chaque programme qui utilise des expressions régulières a sa propre syntaxe
  • Les fichiers de configuration des services sont tous de syntaxe différente (cela peut être pardonné en partie, votre démon de messagerie a peu en commun avec votre serveur Web ou le démarrage du système, mais quand même)
  • Il existe différents éditeurs! Les utilisateurs utilisent des coques différentes !! Pourquoi y a-t-il autant d'environnements de bureau?!?

OTOH, le fait que la coque se dilate globes, et non le programme, élimine beaucoup d'incohérences irritantes présentes dans d'autres systèmes. Idem du fait que vous pouvez utiliser la même commande pour copier un fichier d'un endroit à l'autre dans le filessytem, ​​sur une disquette ou d'un disque Zip sur bande.

Donc, oui, Unix est incohérent. Il en va de même pour les autres systèmes, juste différemment ;-)

vonbrand
la source
2

LISP prenant en charge les nombres à précision infinie par rapport à C ne prenant en charge que les entiers machine n'est pas un exemple de «correction» du langage. Il s'agit d'une simple question découlant du fait que les langues avaient des objectifs de conception très différents.

Le but de C était d'être un langage proche de la machine pouvant être utilisé pour implémenter des systèmes d'exploitation. Les machines (pour la plupart) ne prennent pas en charge les nombres décimaux de précision infinie. Les machines (pour la plupart) ont des nombres entiers de longueurs de bits fixes.

Dave
la source