Was ist besser für das Prototyping: eine statisch typisierte oder eine dynamisch typisierte Sprache? [geschlossen]

8

Wenn Sie das Design für ein neues System ausarbeiten, ist es besser, mit einer statisch typisierten Sprache (wie Haskell) oder einer dynamisch typisierten Sprache (wie Ruby) zu beginnen?

Argumente, an die ich denken kann:

  • Mit einer statischen Sprache können Sie schnell eine Spezifikation und einen Bereich für die Funktionsweise des Programms erstellen. Mit einer dynamischen Sprache können Sie schnell eine funktionierende Demo erstellen, die dem Kunden zur Überprüfung vorgelegt wird.

  • Mit einer dynamischen Sprache vermeiden Sie häufig, dass Sie Datenstrukturen neu ordnen und Code umgestalten müssen, wenn Sie Ihr Design ändern. Mit einer statischen Sprache können Sie Typen vor der Implementierung definieren, wobei der Code sehr klein bleibt.

  • Bei einer statischen Sprache müssen Sie im Voraus herausfinden, was Ihr Programm tun wird. Mit einer dynamischen Sprache können Sie mit dem Schreiben von Code beginnen und das Design organisch wachsen lassen. Wie Paul Graham in Hackers and Painters sagt :

    Eine Programmiersprache dient zum Nachdenken über Programme, nicht zum Ausdrücken von Programmen, an die Sie bereits gedacht haben.

  • Mit einer statischen Sprache kann der Compiler dabei helfen, viele Arten von Fehlern zu identifizieren. Mit einer dynamischen Sprache können Sie früher mit dem Testen und Auffinden von Fehlern beginnen.

Statische und dynamische Typisierung haben sowohl Vor- als auch Nachteile beim Prototyping. Beide scheinen mir jedoch gleichermaßen gültige Ansätze zu sein. Welches ist aufgrund Ihrer Erfahrungen letztendlich besser?


Anmerkungen

Prototyping in natürlicher Sprache

Eine dritte Art von Sprache zu berücksichtigen: natürliche Sprache. Anstatt Prototypen in Code zu erstellen, kann man Prototypen schriftlich erstellen. Der Kunde kann dann Ihre Dokumentation lesen und Ihr Design frühzeitig kritisieren, aber nicht mit einer funktionierenden Demo herumspielen. Wenn die Dokumentation gut geschrieben ist, kann sie problemlos in jeder Sprache implementiert werden. Vorsichtsmaßnahmen:

  • Die Dokumentation ist möglicherweise mühsam zu lesen und schwer zu verdauen, ohne sie sehen zu können. Ich spekuliere, dass ein Kunde lieber mit etwas experimentieren möchte, das funktioniert, als eine Wand aus Text (und Bildern) zu lesen.

  • Das Prototyping einer Anwendung in Englisch und nicht in Typdefinitionen ist ausführlicher und weniger konkret.

Haskell-Typen sind beschreibend

Beachten Sie, dass Typen in Haskell besonders aussagekräftig sind, mehr als in vielen statischen Sprachen wie C ++ und Java. Angenommen, ich habe eine Funktion mit dieser Typensignatur in Haskell:

foo :: forall a. [a] -> a

Eine Funktion, die für jeden Typ aeine Liste von Typelementen verwendet aund einen Wert vom Typ zurückgibt a.

Auch ohne den Namen der Funktion zu kennen, weiß ich, dass:

  • Es führt keine Eingabe / Ausgabe durch oder ändert keine Werte ( naja , es sei denn, es verwendet unsafePerformIO falsch), da Haskell rein funktional ist.

  • Es kann die Elemente nicht als Ganzzahlen behandeln, da es jeden Typ unterstützen muss.

  • Es muss die Eingabeliste verwenden (das, oder eine Ausnahme auslösen oder in eine Endlosschleife gehen). Woher würde es sonst einen Wert vom Typ bekommen a?

Daher kann diese Funktion möglicherweise nur ein Element aus der Eingabeliste extrahieren und zurückgeben. Obwohl ich immer noch nicht weiß, welchen Gegenstand es verwenden wird, [a] -> asagt es mir fast alles andere.

Joey Adams
quelle
4
Mit welchem ​​auch immer Sie ausdrucksvoller sind.
Dietbuddha
1
Sie haben natürliche Sprachen erwähnt, aber die Programmierung mit Powerpoint (oder Photoshop) vergessen. Viele Leute finden das auch sehr nützlich.
Sylvanaar
Ich denke, eine Reihe von Argumenten über dynamische Sprachen im Vergleich zu statischen Sprachen sind falsch. Zum Beispiel glaube ich nicht, dass es überhaupt wahr ist, dass Sie vermeiden müssen, Datenstrukturen neu zu ordnen und Code umzugestalten, wenn Sie Ihr Design in einer dynamischen Sprache ändern. Dynamische Sprachen sparen Zeit, da sie keine Variablendeklarationen abgeben müssen. Sie müssen aber auch mehr Typfehler debuggen. In ähnlicher Weise wachsen Programme mit statischen Sprachen auch organisch. Sie können konkrete Typen für eine Datenstruktur angeben, dies entspricht jedoch nicht der sofortigen Angabe des Entwurfs für das Programm ....
Cervo

Antworten:

8

Ich werde mich in diesem Punkt auf die Seite von Paul Graham stellen: Dynamisches Tippen ist am nützlichsten, um Programme organisch zu erstellen. Genau das sollte Prototyping sein. Es geht darum, schnell etwas zu erledigen, das die Funktionalität des Endprodukts und nicht des Endprodukts selbst demonstriert . Bei der statischen Typisierung geht es um formale Korrektheit - angeblich; Zumindest sollte es so sein (wie in Haskell oder Agda) - aber beim dynamischen Tippen geht es um praktische Korrektheit, was beim Prototyping wichtiger ist.

In der richtigen Sprache können statische Typhinweise nachträglich als Optimierung bereitgestellt werden (und um zusätzliche Sicherheit für zukünftige Änderungen zu bieten), oder der Prototyp kann in einer statisch typisierten Sprache umgeschrieben werden, sobald die Anforderungen vom Prototyp erläutert und verfestigt wurden .

Jon Purdy
quelle
2
In einer dynamischen Sprache werden Typinformationen weggelassen. das macht es sehr knapp. Sie können problemlos alle Strukturen überprüfen, die Sie haben, da der Compiler nie versucht hat, sie stark zu optimieren. Wenn ich einen algorithmisch komplexen Code schreiben muss, beginne ich mit Python. Es ist viel einfacher, eine langsame, aber korrekte Implementierung zu erhalten. Dann portiere ich es nach Java, benutze optimale Datenstrukturen usw. Mit Haskell würde ich Clojure wahrscheinlich als Paar verwenden.
9000
6

Ich denke, das Problem mit statischen und dynamischen Typen ist nicht so wichtig, wie es sich viele Leute vorstellen.

  1. Ich benutze beide. Manchmal ist einer in einer bestimmten Situation einfach nützlicher als der andere. Dies wird meistens dadurch verursacht, dass ein bestimmtes Tool / eine bestimmte Bibliothek / Technologie verwendet werden muss. Also habe ich ausgewählt, was mit den anderen Komponenten, die ich habe, gut funktioniert.

  2. Ich denke, eines der Dinge, die Menschen an dynamischen Sprachen mögen, ist, dass viele interpretiert werden. Sie können sie über eine REPL- Konsole ändern, während sie interaktiv ausgeführt werden . Jede Sprache mit einer Bewertungsfunktion oder etwas Äquivalentem kann dies tun. Zumindest für diesen einen Aspekt ist das Typensystem also tatsächlich irrelevant.

  3. Sie können Prototypen mit Dingen erstellen, die überhaupt kein formales Typsystem haben, wie z. B. Shell-Skripte. (Sie haben aber REPL ...)

Sylvanaar
quelle
+1 für Bibliotheken verwende ich Python nicht, weil es dynamisch ist, sondern weil es Batterien enthält .
Matthieu M.
4

Tun Sie, was für Sie und für das, was Sie versuchen, am besten funktioniert. Ich finde, dass ich derzeit am besten in einer statischen Sprache prototypisiere. Mit Prototyping mit einem ausdrucksstarken Typsystem können Sie einige coole Dinge tun:

  • Schreiben Sie Funktionssignaturen ohne entsprechende Implementierungen. Mein Haskell-Code im Frühstadium enthält häufig Aussagen wie:

    foo :: Foo -> Bar
    foo _ = Fehler "nicht definiert"

Dies liegt daran, dass ich eine Vorstellung davon haben möchte, was foopassiert, wenn ich Code schreibe, der ihn verwendet, ohne dass ich tatsächlich eine Arbeitskopie davon haben muss foo. In anderen Sprachen wird dies mit so etwas erreicht throw new Exception(), was Sie in echtem Code niemals tun würden, aber in frühen Stadien einer Menge helfen.

  • Schreiben Sie Code, ohne zuerst die Typen zu schreiben, und verwenden Sie die Typinferenz, um mehr über Ihren Code zu erfahren. Ich rufe häufig :tdas GHCi (Haskell REPL) an, um herauszufinden, was ich gerade geschrieben habe. Auf diese Weise können Sie beispielsweise feststellen, wie allgemein ein Codeteil ist, und so die Anforderungen verschiedener Codeteile und die entsprechende Struktur aufzeigen.

Conal Elliot beschrieb seine Sicht auf Haskell, um bei der iPhone-Entwicklung folgendermaßen zu helfen:

"Als ich Haskell schrieb, verschwand die imperative Maschinerie aus dem Blickfeld und ich konnte nicht anders, als wesentliche Muster zu erkennen. Das Basteln mit diesen Mustern führte mich zu neuen Einsichten ... Ich bin dankbar, diese faule Sprache höherer Ordnung mit reichem zu haben statisches Tippen als Gedankenwerkzeug, um mir zu helfen, Einblicke zu gewinnen und meine Fehler auszumerzen. Es ist ein Bonus für mich, dass die Sprache auch ausführbar ist. " Quelle

Das stimmt. Einer der Götter der funktionalen Programmierung glaubt, dass Haskells Hauptwert eher eine Modellierungssprache als eine Implementierungssprache ist. Andere Guru denken ähnlich: Erik Meijer verwendet Haskell, um die zugrunde liegende Algebra und Muster zu klären, die schließlich in objektorientierte Frameworks übergehen.

Der wichtigste Grund für das Prototyping in einer strengen Sprache ist jedoch, dass die Dinge, die man "prototypisieren" möchte, meistens nicht die raffinierten Web-Apps im Frühstadium sind, die Paul Graham finanzieren möchte. Oft müssen Sie Prototypen erstellen:

  1. Erweiterungen der aktuellen Infrastruktur
  2. APIs für eine bestimmte Sprache
  3. Architektur, nicht nur neue Funktionen

In jedem dieser Fälle möchten Sie wirklich eine Sprache verwenden, die der endgültigen Implementierungssprache auf sinnvolle Weise nahe kommt.

Ein Trottel

 foo :: forall a. [a] -> a

hat keine "korrekten" (wird immer ohne Fehler oder undefinedInstanzen beendet ) Instanzen. Das ist, weil

[] :: forall a. [a]

Aber es könnte keine Funktion von []bis aexistieren, für adie es keine Instanzen gibt.

Philip JF
quelle
4

Meinen Sie Feature- oder Design- Prototypen?

Bei Feature- Prototypen geht es darum, dem Client ein Feature anzuzeigen, bevor mit der Entwicklung dieses Features von Grund auf in der endgültigen Implementierungssprache begonnen wird. Daher geht es darum, dieses Feature so schnell wie möglich zu schreiben, ohne auf Fehler oder Wartbarkeit zu achten. Dynamische Sprachen ermöglichen einen Kompromiss zwischen Korrektheit und Produktivität, indem sie hässliche Hacks zulassen, die keine statisch typisierte Sprache akzeptieren würde, wodurch sie theoretisch besser für das Schreiben von Prototypen zum schnellen Wegwerfen geeignet sind. In der Praxis ist natürlich die Fähigkeit des Entwicklers wichtiger als die Sprache, aber ein Codierer, der sowohl in Haskell als auch in Ruby gleichermaßen erfahren ist, würde in Ruby wahrscheinlich schneller einen Prototyp erstellen, und der resultierende Code wäre ein Chaos.

Bei Design- Prototypen geht es darum, durch Ausprobieren ein geeignetes Programmdesign zu finden. Hässliche Hacks sind nutzlos - nur die Fähigkeit, Designs schnell umzugestalten, ist wichtig. Eine Grundvoraussetzung für ein massives Refactoring ist eine Reihe automatisierter Tests. In dynamischen Sprachen ist dies normalerweise eine Reihe von von Entwicklern geschriebenen Komponententests, deren Schreiben ziemlich viel Zeit in Anspruch nimmt. In statisch typisierten Sprachen dienen die Typensignaturen als automatisierte Tests und ermöglichen es dem Compiler, Inkonsistenzen zu erkennen, die durch Codeänderungen verursacht werden. Statisch typisierte Sprachen glänzen beim Refactoring auf eine Weise, die keine dynamisch typisierte Sprache erreichen kann.

Victor Nicollet
quelle
0

Dynamisch, insbesondere wenn Sie wissen, dass das eigentliche Produkt in einer von mehreren gängigen statischen Sprachen vorliegen muss, um schnell genug zu sein, um das eigentliche Problem in freier Wildbahn zu lösen. Auf diese Weise werden Sie automatisch vor dem Fehler geschützt, den Prototyp als Endprodukt zu verwenden.

anon
quelle
0

Welche Sprache auch immer Sie am besten kennen.

Dynamisch gegen statisch spielt wirklich keine Rolle. Functional vs OO spielt wirklich keine Rolle. Beste Passform, Funktionen oder was auch immer sie normalerweise alle bedeutungslos sind.

Der einzige Punkt beim Prototyping ist die Geschwindigkeit der Implementierung (Code-Schreiben), da Sie das Programm häufig ändern müssen. Und Sie sollten mit Ihrer besten Sprache am schnellsten sein.

Wenn Sie zwei beste Sprachen haben, sowohl dynamisch als auch statisch, würde ich auf eine statische wetten. Weil statische normalerweise mit Komplexität umgehen können, während dynamische irgendwann versagen. Und niemand weiß wirklich, wie groß der Prototyp werden wird.

Eonil
quelle