Ich habe ein Interview mit Herb Sutter auf Channel9 gesehen und er erwähnte am Ende des Videos, dass die Syntax von links nach rechts auf seiner Wunschliste für einen zukünftigen C ++ - Standard ganz oben stehen würde (obwohl er anerkennt, dass man C ++ auf diese Weise modifiziert würde so ziemlich ein ganz anderes Biest ergeben).
Außer, abgesondert, ausgenommen:
für Menschen verständlicher, mit bloßem Auge klarer, z
//C syntax /*pointer to function taking a pointer to function(which takes 2 integers as arguments and returns an int), and an int as arguments and returning an int*/ int (*fp)(int (*ff)(int x, int y), int b) //Go analogous syntax which is left to write f func(func(int,int) int, int) int
einfacher zu analysieren (führt zu einer besseren Werkzeugunterstützung, wie im Video erwähnt - z. B. Code-Refactoring)
Welche weiteren Vorteile bietet eine "von links nach rechts" -Syntax in einer Programmiersprache? Ich kenne nur Pascal und Go, die diese Art von Syntax verwenden (und Go geht nicht einmal den ganzen Weg, wie ich aus diesem Blog-Beitrag verstehe, aus dem ich auch die Beispiele entnommen habe). Wäre es machbar, eine Systemprogrammiersprache mit dieser Art zu haben der Syntax?
quelle
f :: (Int -> Int -> Int) -> Int -> Int
function strlen(s:String):int {...}
. Auch typisierte Lambda-Kalkül (daher Haskell).Antworten:
Der grundlegende Vorteil ist, dass das Parsen einfacher und einzigartiger ist. Beachten Sie, dass der Compiler nach dem Parsen der Zeile den genauen Typ kennt. Daher ist es von nun an unerheblich, wie der Typ definiert wurde.
Alle Funktionen, die ein Argument vom Typ Array oder Funktionszeiger zurückgeben, sind derzeit schwer zu lesen:
Und es gibt weniger Chancen für Missverständnisse (als die ärgerlichste Analyse ):
Verwenden eines ähnlichen Ansatzes zur einheitlichen Initialisierung in C ++ 0x (dh
{}
zum Identifizieren der Initialisierung). Beachten Sie, dass bei einer Annäherung von links nach rechts viel klarer ist, was wir definieren. Viele Menschen (ich bin mir sicher) wurden in der Vergangenheit (mehr als einmal) von diesem Parsing-Fehler gebissen, und das wäre bei einer Syntax von links nach rechts nicht der Fall.quelle
new
Operator zwei Semantiken fürstruct
oder gegeben werdenclass
, die für C ++ nicht zutreffen, da in C ++ keine Unterscheidung zwischen Wert- und Referenztypen besteht.Wie wir hierher gekommen sind
Die C-Syntax zum Deklarieren von Funktionspunkten sollte die Verwendung spiegeln. Betrachten Sie eine reguläre Funktionsdeklaration wie diese von
<math.h>
:Um eine Punktvariable zu haben, können Sie diese mit der Typensicherheit zuweisen
Sie müssten
fp
diese Punktvariable folgendermaßen deklariert haben :Sie müssen sich also nur ansehen, wie Sie die Funktion verwenden würden, und den Namen dieser Funktion durch eine Zeigerreferenz ersetzen, die
round
in*fp
. Sie benötigen jedoch einen zusätzlichen Satz von Parens, was einige sagen würden, macht es ein bisschen chaotischer.Im Original-C, das nicht einmal über eine Funktionssignatur verfügte, war dies früher einfacher, aber lasst uns nicht dorthin zurückkehren, ok?
Besonders unangenehm wird es, wenn man herausfindet, wie eine Funktion deklariert wird, die entweder ein Argument annimmt oder einen Zeiger auf eine Funktion zurückgibt, oder beides.
Wenn Sie eine Funktion hatten:
Sie könnten es auf folgende Weise an die Signalfunktion (3) übergeben:
oder wenn Sie den alten Handler behalten möchten, dann
Das ist ziemlich einfach. Was ziemlich einfach ist - weder hübsch noch einfach -, ist die Richtigkeit der Erklärungen.
Sie kehren einfach zu Ihrer Funktionsdeklaration zurück und tauschen den Namen gegen eine Punktreferenz aus:
Da Sie nicht deklarieren,
gotsig
fällt es Ihnen möglicherweise leichter, zu lesen, wenn Sie Folgendes weglassen:Oder vielleicht nicht. :(
Abgesehen davon, dass dies nicht gut genug ist, da das Signal (3) auch den alten Handler zurückgibt, wie in:
Also müssen Sie jetzt herausfinden, wie Sie all diese deklarieren können.
ist genug für die Variable, der Sie zuweisen werden. Beachten Sie, dass Sie
gotsig
hier nur nicht wirklich deklarierenold_handler
. Das ist also wirklich genug:Das bringt uns zu einer korrekten Definition für signal (3):
Typedefs zur Rettung
Ich denke, zu diesem Zeitpunkt sind sich alle einig, dass das ein Durcheinander ist. Manchmal ist es besser, Ihre Abstraktionen zu benennen. oft wirklich. Mit dem Recht
typedef
wird dies viel einfacher zu verstehen:Jetzt wird Ihre eigene Handlervariable
und Ihre Deklaration für Signal (3) wird gerecht
das ist plötzlich nachvollziehbar. Wenn Sie die * loswerden, werden Sie auch einige der verwirrenden Klammern los (und sie sagen, dass Parens die Dinge immer leichter verständlich machen - hah!). Ihre Nutzung ist immer noch die gleiche:
aber jetzt haben Sie Chance, die Erklärungen zu verstehen , für
old_handler
,new_handler
und selbstsignal
wenn man sie zuerst oder Notwendigkeit begegnen , sie zu schreiben.Fazit
Es stellt sich heraus, dass nur sehr wenige C-Programmierer in der Lage sind, die richtigen Deklarationen für diese Dinge selbst zu erstellen, ohne Referenzmaterialien zu konsultieren.
Ich weiß, weil wir diese Frage einmal in unseren Interviewfragen für Leute hatten, die Kernel- und Gerätetreiberarbeiten erledigen. :) Sicher, wir haben viele Kandidaten auf diese Weise verloren, als sie auf dem Whiteboard abgestürzt und verbrannt sind. Wir haben aber auch vermieden, Leute einzustellen, die behaupteten, sie hätten bereits Erfahrungen in diesem Bereich gesammelt, konnten diese Arbeit aber nicht ausführen.
Aufgrund dieser weit verbreiteten Schwierigkeit ist es jedoch wahrscheinlich nicht nur sinnvoll, sondern auch vernünftig, über all die Erklärungen zu verfügen, für die Sie nicht länger ein Triple-Alpha-Geek-Programmierer sein müssen, der drei Sigmas über dem Durchschnitt sitzt, nur um diesen zu verwenden so etwas bequem.
quelle
Ich denke, Sie haben den Punkt etwas verpasst, an dem Sie sich auf das Links-Rechts-Stück konzentriert haben.
Das Problem von C und C ++ ist die horrende Grammatik, die schwer zu lesen (Menschen) und zu analysieren (Werkzeuge) ist.
Eine konsistentere (oder regelmäßigere ) Grammatik erleichtert beides. Und einfacheres Parsen bedeutet einfacheres Tooling: Die meisten aktuellen Tools stimmen nicht mit C ++ überein, auch nicht mit dem neuesten Eclipse-Plugin, da sie das Rad neu erfinden wollten ... und fehlgeschlagen sind. Wahrscheinlich haben sie mehr Leute als das durchschnittliche OS-Projekt.
Also hast du es wahrscheinlich geschafft, wenn du dich auf das Lesen und Parsen konzentrierst ... und das ist eine große Sache :)
quelle
gcc
?