Bien que ma question puisse être totalement hors de propos, mais j'ai senti un schéma entre la plupart des langages de programmation et leurs implémentations officielles.
Les langages interprétés ( interprétés en octets?) Comme Python, Lua etc. ont généralement une syntaxe extrêmement clémente et facile et sont généralement sans type ou ne nécessitent pas que le développeur écrive explicitement les types de variables dans le code source;
Les langages compilés comme C, C ++, Pascal, etc. ont généralement une syntaxe stricte, ont généralement des types et nécessitent généralement plus de temps de code / développement
Les langages dont les implémentations officielles sont compilées en JIT comme Java / C # sont généralement un compromis unique entre les deux ci-dessus avec certaines des meilleures fonctionnalités des deux.
Certains des langages de programmation compilés les plus modernes comme D et Vala (et l'implémentation GNU GJC de Java) sont peut-être une exception à cette règle et ressemblent à la syntaxe et aux fonctionnalités des langages compilés JIT comme Java et C #.
Ma première question est la suivante: est-ce vraiment pertinent? Ou est-ce juste une coïncidence si la plupart des langages interprétés ont une syntaxe facile, ceux compilés en JIT ont une syntaxe et des fonctionnalités modérées, etc.
Deuxièmement, si ce n'est pas une coïncidence, pourquoi en est-il ainsi? Comme, par exemple, certaines fonctionnalités ne peuvent-elles être implémentées dans un langage de programmation que si, par exemple, vous le compilez en JIT?
la source
Réponses:
Il n'y a aucun lien entre la sémantique et la syntaxe. Les langages compilés homoiconiques comme Scheme sont livrés avec une syntaxe assez minimaliste. Les méta-langages compilés de bas niveau comme Forth sont encore plus simples que cela. Certains langages compilés très strictement typés sont construits sur une syntaxe triviale (pensez ML, Haskell). OTOH, la syntaxe Python est très lourde, en termes d'un certain nombre de règles de syntaxe.
Et oui, la frappe n'a rien à voir avec la syntaxe, c'est du côté sémantique d'un langage, à moins que ce soit quelque chose d'aussi pervers que C ++, où vous ne pouvez même pas analyser sans avoir toutes les informations de frappe disponibles.
Une tendance générale est que les langages qui ont évolué trop longtemps et qui ne contenaient aucune garantie de conception contre les écarts de syntaxe évolueraient tôt ou tard en abominations syntaxiques.
la source
type checking
" est extrêmement contre-productif et ne doit pas être utilisé, il est très trompeur, il ne reflète pas la nature des systèmes de types.C'est surtout une coïncidence.
Les langages de programmation ont évolué au fil du temps et la technologie des compilateurs et des interprètes s'est améliorée. L'efficacité du traitement sous-jacent (c'est-à-dire le temps de compilation, le temps d'interprétation, le temps d'exécution, etc.) est également moins importante car les plates-formes informatiques traditionnelles ont gagné en puissance.
La syntaxe du langage n'avoir un impact - par exemple, Pascal a été très soigneusement conçu de sorte qu'il pourrait utiliser un seul compilateur passe - à savoir une passe sur la source et vous avez le code machine excutable. Ada, d'autre part, n'y a pas prêté attention, et les compilateurs Ada sont notoirement difficiles à écrire - la plupart nécessitent plus d'un passage. (Un très bon compilateur Ada que j'ai utilisé il y a de nombreuses années était un compilateur à 8 passes. Comme vous pouvez l'imaginer, il était très lent.)
Si vous regardez des langues anciennes comme Fortran (compilées) et BASIC (interprétées ou compilées), elles ont / avaient une syntaxe et des règles sémantiques très strictes. [Dans le cas de BASIC, ce ne sont pas des anciens factures de BASIC, vous devez revenir avant cela à l'original.]
D'un autre côté, en regardant d'autres choses plus anciennes comme APL (un tas d'amusement), cela avait une sorte de typage dynamique. Il a également été généralement interprété, mais pourrait également être compilé.
La syntaxe indulgente est difficile - si cela signifie que vous avez des choses facultatives ou que vous pouvez en déduire, cela signifie que le langage a une richesse suffisante pour pouvoir être éliminé. Là encore, BASIC a eu cela il y a de nombreuses années lorsque l'instruction "LET" est devenue facultative!
Bon nombre des idées que vous voyez maintenant (par exemple, la frappe sans type ou dynamique) sont en fait très anciennes - apparues pour la première fois dans les années 1970 ou au début des années 1980. La façon dont elles sont utilisées et les langues dans lesquelles ces idées sont utilisées ont changé et se sont développées. Mais fondamentalement, une grande partie de ce qui est nouveau est en fait de vieilles choses habillées de nouveaux vêtements.
Voici quelques exemples du haut de ma tête:
Je pourrais continuer.
Mise à jour: parce que je n'étais pas assez clair.
La saisie peut varier considérablement.
Le typage statique fixe à la compilation est courant (par exemple, C, Ada, C ++, Fortan, etc.). C'est là que vous déclarez une CHOSE d'un TYPE et c'est ainsi pour toujours.
Il est également possible d'avoir une frappe dynamique, où la chose récupère le type qui lui est assigné. Par exemple, PHP et certains premiers BASIC, et APL, où vous assigneriez un entier à une variable et à partir de ce moment-là c'était un type entier. Si vous lui avez ensuite attribué une chaîne, il s'agissait d'un type de chaîne. Etc.
Et puis il y a un typage lâche, par exemple PHP où vous pouvez faire des choses vraiment bizarres comme assigner un entier numérique (entre guillemets, donc c'est une chaîne) à une variable et ensuite y ajouter un nombre. (par exemple, «5» + 5 donnerait 10). C'est le pays du bizarre, mais aussi parfois du très très utile.
CEPENDANT, ce sont des fonctionnalités conçues dans une langue. L'implémentation rend cela possible.
la source
Je pense que c'est l'inverse: la mise en œuvre dépend de la syntaxe. Par exemple, si votre syntaxe permet la réflexion, l'implémentation doit fournir un runtime qui prend en charge cela.
la source
Je suis généralement d'accord avec quick_now en ce que votre observation est principalement le résultat de l'histoire. Cela dit, le raisonnement sous-jacent se résume à quelque chose comme ceci:
(Pas vraiment une citation, juste ma propre formulation.) Quand j'écris
comfortable
ici, je me réfère à ce que vous avez appelébest features of both
. Plus précisément, je ne veux pas parler pour ou contre le typage statique / dynamique ou la syntaxe stricte / indulgente. Au lieu de cela, il est important de voir l'accent mis sur les développeurs et d'augmenter leur niveau de confort lors de l'utilisation du langage.Voici quelques raisons, qui n'ont pas été mentionnées dans les réponses précédentes, qui peuvent vous donner quelques idées pour lesquelles vous observez ces choses (et qui sont toutes basées sur l'histoire du développement de la programmation de la langue):
Nous avons des centaines de langages de programmation de nos jours. Lorsqu'un nouveau arrive, comment peut-il trouver un large public? C'est la raison principale pour laquelle les nouveaux langages essaient toujours d'augmenter le niveau de confort des développeurs. Si la langue peut faire la même chose qu'une ancienne, mais peut le faire beaucoup plus facilement / plus simplement / plus élégamment / etc. vous voudrez peut-être envisager de changer réellement.
La courbe d'apprentissage va de pair avec cela. Dans le passé, nous avions peu de langues et investir du temps pour en apprendre une en valait la peine. Même si cela signifiait investir beaucoup de temps. Le confort est encore augmenté, si vous venez avec un langage que les développeurs peuvent apprendre très rapidement. La complexité de toute sorte (par exemple, syntaxe complexe impliquée) est préjudiciable à cela et, par conséquent, est de plus en plus réduite dans les langues plus récentes.
Les progrès technologiques (une raison historique directe ici) sont responsables du fait que les constructeurs de compilateurs peuvent désormais se concentrer davantage sur le confort des développeurs. Au début, nous étions heureux de pouvoir construire un compilateur. Cependant, cela impliquait souvent de lourdes restrictions. À mesure que le savoir-faire technologique augmentait, nous avons pu à nouveau lever ces restrictions.
Ainsi, en général, les langages de programmation et les compilateurs ont connu un développement similaire à celui des applications d'utilisateur final typiques:
la source
(Not a quote really, just my own formulation.)
Eh bien, vous l'avez formaté en code, pas en bloc, donc je ne pense pas que quiconque ait pensé que c'était une citation :)Un langage de programmation donné peut ou non exposer ou contraindre suffisamment d'informations sémantiques pour qu'un compilateur puisse déduire comment le réduire en code exécutable sans décisions d'exécution supplémentaires ("de quel type est cette variable?", Etc.) Certains langages sont explicitement conçus pour faire cette contrainte est obligatoire ou facile à déterminer.
Au fur et à mesure que les compilateurs deviennent plus intelligents, ils pourraient être en mesure de deviner ou de profiler suffisamment d'informations pour générer du code exécutable pour les chemins les plus probables, même pour les langages qui n'ont pas été explicitement conçus pour exposer ou limiter ces décisions.
Cependant, les langages dans lesquels le code (evalString ()) peut être créé ou entré au moment de l'exécution (et d'autres choses que le compilateur ne peut pas déduire ou deviner) peuvent nécessiter qu'un interprète ou un compilateur JIT soit disponible au moment de l'exécution, même avec des tentatives de pré- compilez-les.
Dans le passé, un langage de programmation et son implémentation pouvaient avoir évolué de manière à s'adapter à certaines contraintes matérielles, par exemple si l'interpréteur pouvait tenir en 4k ou 16k, ou si le compilateur pouvait terminer en moins d'une minute de temps CPU. Au fur et à mesure que les machines s'accélèrent, il est devenu possible de (re) compiler certains programmes précédemment interprétés aussi vite que le programmeur peut appuyer sur la touche de retour, ou d'interpréter le code source du programme précédemment compilé plus rapidement qu'un matériel légèrement plus ancien ne pouvait exécuter des exécutables compilés optimisés.
la source