Als ich einem Kollegen den Unterschied zwischen der Strenge von Sprachen und Paradigmen erklärte, stellte ich fest, dass:
Tolerante Sprachen wie dynamische und interpretierte Sprachen werden am besten für Prototypen und kleine Projekte oder mittelgroße Webanwendungen verwendet. Bei der Auswahl eleganter dynamischer Sprachen wie Python oder JavaScript mit Node.js ergeben sich folgende Vorteile:
Schnelle Entwicklung,
Reduzierter Kesselschildcode,
Die Fähigkeit, junge, kreative Programmierer anzuziehen, die aus Unternehmenssprachen wie Java fliehen .
Statisch typisierte / kompilierte Sprachen eignen sich am besten für Anwendungen, die eine höhere Genauigkeit erfordern, z. B. geschäftskritische Apps oder Apps für mittlere bis große Apps.
Bekannte Paradigmen und Muster, die sich über Jahrzehnte entwickelt haben,
Einfache statische Überprüfung
Fähigkeit, viele professionelle Entwickler mit jahrzehntelanger Erfahrung zu finden.
Strenge Sprachen wie Haskell, Ada oder Techniken wie Codeverträge in C # sind besser für Systeme, die Sicherheit gegenüber Flexibilität bevorzugen (auch wenn Haskell extrem flexibel sein kann), wie lebenswichtige Systeme und Systeme, die voraussichtlich extrem stabil sind. Die Vorteile sind:
Möglichkeit, zur Kompilierungszeit so viele Bugs wie möglich zu finden,
Einfache statische Überprüfung
Einfache formale Beweise.
Wenn ich mir jedoch die Sprachen und Technologien anschaue, die von großen Unternehmen für Großprojekte verwendet werden, scheint meine Behauptung falsch zu sein . Beispielsweise wird Python erfolgreich für große Systeme wie YouTube oder andere Google-Anwendungen verwendet, die ein hohes Maß an Strenge erfordern.
Gibt es immer noch einen Zusammenhang zwischen dem Umfang des Projekts und der Strenge der Sprache / des Paradigmas, das verwendet werden sollte?
Gibt es einen dritten Faktor, den ich vergessen habe zu berücksichtigen?
Wo irre ich mich
quelle
Antworten:
Eine interessante Fallstudie zum Thema Skalierung von Projekten, die dynamische und interpretierte Sprache verwenden, finden Sie in Beginning Scala von David Pollak.
Wie Sie sehen, waren die größten Herausforderungen bei der Projektskalierung für den Autor die Testentwicklung und der Wissenstransfer.
Insbesondere geht der Autor ausführlicher auf die Unterschiede beim Schreiben von Tests zwischen dynamisch und statisch getippten Sprachen in Kapitel 7 ein.
Das Lesen oben kann den Eindruck erwecken, dass das Schreiben von Tests mit zunehmender Größe der Projekte möglicherweise unhandlich wird. Diese Argumentation wäre falsch, wie Beispiele für erfolgreiche sehr große Projekte belegen, die in dieser Frage erwähnt wurden ("Python wird erfolgreich für ... YouTube verwendet").
Die Skalierung der Projekte ist nicht ganz einfach. Sehr große, langlebige Projekte können sich unterschiedliche Testentwicklungsprozesse "leisten", mit Test-Suiten in Produktionsqualität, professionellen Test-Entwicklerteams und anderem Schwergewicht.
Youtube-Testsuiten oder das Java-Kompatibilitätskit führen ein anderes Leben als Tests in einem kleinen Tutorial-Projekt wie Dwemthy's Array .
quelle
Ihre Behauptung ist nicht falsch. Sie müssen nur etwas tiefer graben.
Einfach gesagt, verwenden große Systeme mehrere Sprachen, nicht nur eine Sprache. Es kann Teile geben, die mit "strengen" Sprachen erstellt wurden, und es kann Teile geben, die mit dynamischen Sprachen erstellt wurden.
In Bezug auf Ihr Google- und YouTube-Beispiel habe ich gehört, dass sie Python hauptsächlich als "Klebstoff" zwischen verschiedenen Systemen verwenden. Nur Google weiß, woraus diese Systeme bestehen, aber ich wette, dass viele der kritischen Systeme von Google unter Verwendung strenger und "korporativer" Sprachen wie C ++ oder Java oder etwas, das sie selbst erstellt haben, wie Go, erstellt wurden.
Es ist nicht so, dass Sie keine toleranten Sprachen für große Systeme verwenden können. Viele Leute sagen, Facebook benutze PHP, aber sie vergessen zu erwähnen, dass Facebook extrem strenge Programmierrichtlinien erstellen musste, um es in dieser Größenordnung effizient zu nutzen.
Ja, für Großprojekte ist ein gewisses Maß an Strenge erforderlich. Dies kann entweder aus der Strenge der Sprache oder des Frameworks oder aus Programmierrichtlinien und Code-Konventionen herrühren. Sie können nicht nur ein paar Hochschulabsolventen schnappen, ihnen Python / Ruby / JavaScript geben und von ihnen erwarten, dass sie Software schreiben, die sich über Millionen von Benutzern erstreckt.
quelle
Es gibt zwei Arten von Fehlern, auf die geprüft werden muss: Typfehler (Verketten einer Ganzzahl + Liste von Gleitkommazahlen) und Geschäftslogikfehler (Überweisen von Geld auf ein Bankkonto, Überprüfen, ob das Quellkonto über Geld verfügt).
Der "dynamische" Teil einer dynamischen Programmiersprache ist genau der Ort, an dem die Typprüfung stattfindet. In einer "dynamisch typisierten" Programmiersprache wird die Typprüfung während der Ausführung jeder Anweisung durchgeführt, während in einer "statisch typisierten Sprache" die Typprüfung zur Kompilierungszeit durchgeführt wird. Und Sie können einen Interpreter für eine statische Programmiersprache schreiben (wie es emscriptem tut), und Sie können auch einen statischen Compiler für eine dynamische Programmiersprache schreiben (wie es gcc-python oder shed-skin tut).
In einer dynamischen Programmiersprache wie Python und Javascript müssen Sie Komponententests nicht nur für die Geschäftslogik des Programms schreiben, sondern auch prüfen, ob Ihr Programm keine Syntax- oder Typfehler enthält. Wenn Sie beispielsweise einer Float-Liste "+" eine Ganzzahl hinzufügen (was nicht sinnvoll ist und einen Fehler ausgibt), wird der Fehler in einer dynamischen Sprache zur Laufzeit ausgelöst, während Sie versuchen, die Anweisung auszuführen. In einer statischen Programmiersprache wie C ++, Haskell und Java wird diese Art von Typfehler vom Compiler abgefangen.
Eine kleine Codebasis in einer dynamisch überprüften Programmiersprache ist einfacher, nach Typfehlern zu suchen, da der Quellcode leichter zu 100% abgedeckt wird . Das war's, Sie führen den Code einige Male mit unterschiedlichen Werten von Hand aus und sind fertig. Eine 100% ige Abdeckung des Quellcodes gibt Ihnen einen guten Hinweis darauf, dass Ihr Programm möglicherweise keine Tippfehler enthält .
Mit einer großen Codebasis in einer dynamisch überprüften Programmiersprache ist es schwieriger, jede Anweisung mit jeder möglichen Typkombination zu testen, insbesondere wenn Sie nachlässig sind und eine Funktion schreiben, die abhängig von ihren Argumenten möglicherweise einen String, eine Liste oder ein benutzerdefiniertes Objekt zurückgibt.
In einer statisch überprüften Programmiersprache erkennt der Compiler die meisten Typfehler beim Kompilieren. Ich sage die meisten, weil ein Fehler bei der Division durch Null oder ein Fehler bei einem Array außerhalb der Grenzen auch Typfehler sind.
Meist geht es bei der eigentlichen Diskussion nicht um Programmiersprachen, sondern um die Menschen, die diese Sprachen verwenden. Dies ist der Fall, weil die Assemblersprache beispielsweise genauso leistungsfähig ist wie jede andere Programmiersprache, wir jedoch Code in JavaScript schreiben. Warum? Weil wir Menschen sind. Erstens machen wir alle Fehler und es ist einfacher und weniger fehleranfällig, ein spezielles Tool für eine bestimmte Aufgabe zu verwenden. Zweitens gibt es eine Ressourcenbeschränkung. Wir haben nur eine begrenzte Zeit, und es würde ewig dauern, bis Webseiten für die Montage fertiggestellt sind.
quelle
Meine Erfahrung mit großen Systemen ist, dass sie nicht nach der Wahl der Sprache stehen oder fallen, sondern nach Design- / Architektur- oder Testaspekten . Ich hätte lieber ein talentiertes Python-Team für mein großes Unternehmensprojekt als ein mittelmäßiges Java-Team.
Allerdings muss jede Sprache, mit der Sie deutlich weniger Code schreiben können, einen Blick wert sein (z. B. Python vs Java). Vielleicht liegt die Zukunft in cleveren, statisch typisierten Sprachen mit fortgeschrittener Typinferenz (z. B. in der Scala-Form). Oder Hybrid wie C # versucht es mit seinem
dynamic
Qualifier ...?Und vergessen wir nicht den "anderen" Vorteil der statischen Typisierung: die ordnungsgemäße IDE-Code-Vervollständigung / Intellisense, die meiner Ansicht nach ein wesentliches Merkmal ist und nicht gut zu haben ist.
quelle
Eine weitere Überlegung ist, wer hinter dem Schreiben von Großanträgen steht. Ich habe an vielen Orten gearbeitet, die Ruby oder Python für einige große Projekte im Enterprise-Stil verwenden möchten, aber von IT-Managern und Unternehmenssicherheitsteams aufgrund der Open-Source-Natur der Projekte konsequent "abgeschossen" werden.
Mir wurde gesagt: "Wir können Ruby on Rails nicht verwenden, weil es Open Source ist und jemand dort Hacks einsetzen könnte, die kritische oder geschützte Informationen stehlen." Es tut mir leid, aber wenn jemand diese Einstellung zu Open Source == böse hat, ist es fast unmöglich, dies zu ändern. Diese Denkweise ist eine korporative Krankheit.
C # und Java sind vertrauenswürdige Sprachen mit vertrauenswürdigen Plattformen. Ruby und Python sind keine vertrauenswürdigen Sprachen.
quelle