Question

gens simples question: Je fais beaucoup de programmation (professionnel et personnel) dans les langages compilés comme C ++ / Java et dans les langues interprétées comme Python / Javascript. Personnellement, je trouve que mon code est presque toujours plus robuste quand je programme dans les langues statiquement typés. Cependant, presque toutes les langues que je rencontre interprété utilise un typage dynamique (PHP, Perl, Python, etc.). Je sais pourquoi les langages compilés utilisent typage statique (la plupart du temps), mais je ne peux pas comprendre l'aversion pour le typage statique dans la conception de langage interprété.

Pourquoi la déconnexion raide? Est-il partie de la nature des langues interprétées? POO?

Était-ce utile?

La solution

Question intéressante. BTW, je suis l'auteur / mainteneur de PHC (compilateur pour PHP), et je fais ma thèse sur les compilateurs pour les langages dynamiques , donc j'espère pouvoir offrir quelques idées.

Je pense qu'il ya une hypothèse erronée ici. Les auteurs de PHP, Perl, Python, Ruby, Lua, etc n'a pas conçu « langues » interprétées, ils ont conçu des langages dynamiques et les mises en œuvre à l'aide d'interprètes. Ils l'ont fait parce que les interprètes sont beaucoup plus faciles à écrire que les compilateurs.

première implémentation de Java a été interprété, et il est un langage typé statiquement. Les interprètes n'existent pour les langues statiques: Haskell et OCaml ont tous deux interprètes, et il y avait un interprète populaire pour C, mais qui était il y a longtemps. Ils sont très populaires car ils permettent un REPL , ce qui peut faciliter le développement.

Cela dit, il y a une aversion pour le typage statique dans la communauté de langage dynamique, comme on pouvait s'y attendre. Ils croient que les systèmes de type statique fournis par C, C ++ et Java sont verbeux, et ne vaut pas l'effort. Je pense que je suis d'accord avec cela dans une certaine mesure. La programmation en Python est beaucoup plus amusant que C ++.

Pour aborder les points des autres:

  • dlamblin dit : « Je ne me sentais fortement qu'il y avait quelque chose de spécial à propos de la compilation vs interprétation qui suggère dynamique sur le typage statique. » Eh bien, vous êtes très mal là-bas. La compilation des langages dynamiques est très difficile. Il est surtout la déclaration de eval à considérer, qui est largement utilisé en Javascript et Ruby. PHC compile en avance sur le temps PHP, mais nous avons encore besoin d'un interprète d'exécution pour gérer evals. eval aussi ne peut pas être analysé de manière statique dans un compilateur optimisé, mais il y a un technique fraîche si vous ne avez pas besoin solidité.

  • Pour la réponse damblin Andrew Hare réponse est fondée sur l'hypothèse erronée questionneurs, et a lui aussi des choses à l'envers. , Il soulève toutefois une question intéressante: « comment est difficile l'analyse statique des langages dynamiques? ». Très très dur. En gros, vous obtiendrez un doctorat pour décrire comment il fonctionne, ce qui est exactement ce que je fais. Voir aussi le point précédent.

  • La réponse la plus correcte est si loin de Ivo Wetzel . Cependant, les points qu'il décrit peuvent être traités lors de l'exécution dans un compilateur, et de nombreux compilateurs existent pour Lisp et Scheme qui ont ce type de liaison dynamique. Mais, oui, son délicat.

Autres conseils

langues Interprété utilisent typage dynamique parce qu'il n'y a pas d'étape de compilation pour le faire l'analyse statique. Les langages compilés font l'analyse statique au moment de la compilation ce qui signifie que toute erreur de type sont signalés au développeur comme ils travaillent.

Il est plus facile à comprendre si l'on considère qu'une langue statiquement typé a un compilateur qui applique les règles de type en dehors du cadre de l'exécution. langues ne sont jamais analysées Interprété statiquement donc des règles de type doivent être appliquées par l'interprète dans le cadre de l'exécution.

Je pense qu'il est à cause de la nature des langages interprétés, ils veulent être dynamiques, de sorte que vous pouvez changer les choses à l'exécution. En raison de ce compilateur ne sait jamais exactement ce qui est l'état du programme après la ligne de code suivante a étét exécutée.

Imaginez le scénario suivant (en Python):

import random
foo = 1

def doSomeStuffWithFoo():
    global foo
    foo = random.randint(0, 1)

def asign():
    global foo
    if foo == 1:
        return 20
    else:
        return "Test"


def toBeStaticallyAnalyzed():
    myValue = asign()

    # A "Compiler" may throw an error here because foo == 0, but at runtime foo maybe 1, so the compiler would be wrong with its assumption
    myValue += 20


doSomeStuffWithFoo() # Foo could be 1 or 0 now... or 4 ;)
toBeStaticallyAnalyzed()

Comme vous pouvez le voir, espérons, un compilateur ne serait pas de sens dans cette situation. Acutally il pourrait vous mettre en garde contre la possibilité que « maValeur » peut-être autre chose que d'un numéro. Mais en JavaScript qui ne parviendrait pas parce que si « maValeur » est une chaîne, 20 serait implictily converti en une chaîne aussi, par conséquent, aucune erreur ne se produirait. Donc, vous pourriez obtenir des milliers d'avertissements inutiles dans tous les sens, et je ne pense pas que ce soit l'intention d'un compilateur.

La flexibilité est toujours avec un prix, vous devez jeter un regard plus profond sur votre programme, ou d'un programme plus attentivement, autrement dit que vous êtes le dans des situations comme COMPILER ci-dessus.

Ainsi, votre solution comme le compilateur? - le fixer avec un "essayer: sauf":)

+ types statiques Compilateurs = Code machine efficace
+ Types dynamiques Compilateurs = code machine inefficace

Considérez le pseudo-code suivant:

function foo(a, b) {
    return a+b
}

Une langue statique sera en mesure de savoir (par déclaration ou inférence) qui a et b sont des nombres entiers, et compilera jusqu'à

%reg = addi a,b

ou quelque chose de similaire, de toute façon.

Un compilateur pour un langage dynamique devrait émettre un code à
1. Vérifiez qu'ils types a et b
2. traiter chaque cas ou une combinaison des cas

%reg1 = typeof a
beq %reg1, int, a_int_case
beq %reg1, float, a_float_case
beq %reg1, string, a_string_case

label a_int_case
%reg1 = typeof b
beq %reg1, int, a_int_b_int_case
beq %reg1, float, a_int_b_float_case
beq %reg1, string, a_int_b_string_case

label a_int_b_int_case
%out = addi a,b
goto done

label a_int_b_float_case
%tmp = mkfloat a
%out = addf %tmp,b
goto done

... Etc. I can't finish

Alors que vous pouvez générer du code machine plus intelligent que ça, vous ne seriez pas en mesure d'aider générer beaucoup de code -. Cela rend la compilation pas une victoire majeure pour un langage dynamique

Comme les interprètes sont beaucoup plus faciles à écrire, et la compilation ne vous fait pas beaucoup de bien, pourquoi ne pas écrire un interprète?

(en fait compilateurs Just-en-temps des informations de type et peuvent compiler jusqu'à la déclaration unique Ils ont en fait plus d'informations que les systèmes de type statique, et peut théoriquement faire encore mieux tous assembleur est simulé,.. Toute ressemblance avec le code réel qui pourrait fonctionner sur une machine réelle est purement fortuite.)

Peut-être qu'il est parce que l'une de mes principales langues interprétées est Perl et un de mes langages compilés est Objective-C, mais je ne fortement ressenti qu'il y avait quelque chose de spécial à propos de la compilation vs interprétation qui suggère dynamique sur le typage statique.

Je pense qu'il est clair que les deux parties cherchent à l'autre et de penser: « Il y a certains avantages à cela. » Il est plus facile dans plusieurs applications pour obtenir une certaine flexibilité de type dynamique, alors qu'il peut être plus facile de maintenir quelque chose qui est statiquement typé et appliquée.

Je suis en désaccord avec Andrew Hare explication bien. Alors qu'un langage purement interprété devrait ajouter dans une étape de pré-traitement, et donc ne pas être purement interprétées afin d'avertir le programmeur avant l'exécution d'erreurs statiques de frappe, il ne fait pas obstacle à lancer une erreur de type à l'exécution comme il se produit. Donc, manque compilation ne signifie pas aucune vérification de type statique peut se produire. Mais depuis l'obtention d'une erreur de type à l'exécution n'est pas aussi utile que d'obtenir un à la compilation, ou lors d'un contrôle prévol, je peux voir comment l ' « avantage » de typage statique dans cette situation peut sembler être plus d'une nuisance, et ainsi se jeter en faveur des avantages typage dynamique apportent.

Si vous saviez dès le départ que vous préférez garder vos types statiques parce que le code vous feriez mieux d'écrire personnellement plus maintenable en conséquence, et vous concevez votre langage interprété, rien ne vous empêche de concevoir la langue comme statiquement typé un .

Pour citer le langues interprétées article wiki « Théoriquement, toute langue peut être compilé ou interprété , cette désignation est appliquée uniquement en raison de la pratique de la mise en œuvre commune et non une propriété sous-jacente d'une langue. "
Il y a une bonne wiki de uniquement sur la saisie.

Les langages typés dynamiquement vous donnent plus interprété la liberté dans la façon dont vous programme. Il permet la programmation méta soit réalisable. Il permet des variables à créer au moment de l'exécution. Permet de hash anonymes et des réseaux anonymes à créer à tout moment au cours de l'exécution sans jamais déclarer auparavant quoi que ce soit avant la main. Il permet des informations non déterminé à une table de hachage inscription au sans jamais déclarer toutes les clés à l'avance. Vous pouvez avoir des sous-routines créées à partir indéterminée entrée aléatoire. Vous pouvez alimenter un code de programme que peut être exécuté dynamiquement. langues Interprété les chaînes de libérer ce qui limite la programmation en général. Vous êtes limité à ce que vous tapez dans le fichier source avec les langages typés statiquement. Vous pouvez faire plus avec moins dans un langage typé dynamiquement.

La plupart des robots étant fait beaucoup aujourd'hui avec les langues interprétées plus parce que l'information doit être déterminée lors de l'exécution et de nouvelles variables doivent être apportées pour stocker ces informations lors de l'exécution. l'apprentissage de la machine est basée sur des informations sont interprétées. Nous nous sommes en tant qu'êtres humains interprètes qui explique pourquoi les robots sont conçus de cette façon. L'avenir est vraiment interprété. Bien sûr, vous avez besoin langues statiquement typé pour construire des interprètes afin langues statiquement tapées ne disparaîtront jamais à moins que les interprètes sont construits dans le code assembleur à l'avenir. La plupart des interprètes sont construits sur des langues statiquement tapées ces jours-ci.

langues Interprété exceller dans un environnement dynamique. Si vous pouvez interpréter le nouveau code / informations lors de l'exécution alors pourquoi pas. Si votre vraiment bon à la programmation dynamique, vous pouvez créer un code qui peut créer des variables et hash sans jamais taper tout dehors. Vous pouvez réduire le nombre de lignes radicalement si votre travail avec d'énormes quantités de données. Vous pouvez utiliser un dumper de données pour imprimer toutes vos informations parce que les langues interprétées conservent généralement une trace du type de variables à l'exécution permettant pour que cela soit possible. Vous ne pouvez pas faire cela dans barebones c ++. La seule fois où c ++ et c sait ce qui se passe est au moment de la compilation. Après que vous êtes seul à moins que vous mettre en œuvre quelque chose de vous.

Qui veut être lié tant au fichier source ces jours surtout quand votre travail dans des environnements dynamiques. Tous vos faire est de limiter votre potentiel. Une fois que votre cou profond dans le code dynamiquement interprété et vous retournez à tout, vous trouverez le langage typé statiquement plus de mal à votre stupide code, car votre façon de penser toujours dans un état d'esprit sans limites. Votre esprit a besoin de revenir à nouveau être limité à ce qui est tapé dans le fichier source.

A la manière de styles de programmation: le code statiquement typé produit des résultats statiques. le code tapé produit des résultats Dynamiquement dynamiques ou statiques.

Si vous allez être programmer quelque chose qui ne change jamais un comportement autre que ce qui est connu, sont tapés langues statiquement grand pour cela. Si votre GÉRER comportement dynamique puis Les langages typés dynamiquement sont mieux pour ces cas. Tout dépend de la situation la plupart du temps.

Chaque langue a ses hauts et des bas. Il suffit de choisir et dois choisir à bon escient.

Je pense que le typage statique rend plus facile pour les compilateurs et qui est le principal (sinon seulement) raison pour laquelle il est présent dans les langages compilés.

Pour les langues interprétées il est plus facile de supposer que les variables ne sont de type (seules les valeurs ont) parce qu'ils sont considérés non pas comme un placers pour les données qui doivent adapter à l'intérieur, mais l'étiquette plutôt pour les données qui flotte quelque part sur le tas .

Si programmeur veut-ce qu'il peut toujours affirmer que variable contient une valeur de type donné (par exemple en mission). Il n'y a aucune raison de le construire dans la langue. Bien sûr que non le même genre de contrôle que vous avez pour les langages compilés.

Vous pourriez probablement langue dans laquelle vous devez déclarer explicitement le type de chaque variable, mais si vous ne le faites pas, il est beaucoup plus facile de faire des choses intéressantes avec le typage statique nécessiteraient de programmeur très soigneusement conçu types génériques complexes.

D'autre part. Connaissez-vous un langage typé dynamiquement compilé (statique, non JIT)?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top