Swift



  • audacia schrieb:

    sie stupide Präprozessorexpansion sind => eskalierende Build-Zeiten, brüchige Modulkopplungen (manchmal geht was kaputt, wenn man #include -Statements umstellt), unoffensichtliche Abhängigkeiten (wenn du von einem Header abhängst, den du nicht einbindest, der aber von einem anderen Header referenziert wird). Das geht alles viel besser, wie man eigentlich an jeder anderen ernstzunehmenden Sprache sehen kann.

    Du hast schlechte makefiles.

    [quote="audacia"]es gibt zwar new , aber es ist unglaublich leicht, damit exceptionunsicheren Code zu schreiben oder delete und delete[] durcheinanderzubringen,/quote]
    Kindergarten.

    audacia schrieb:

    Ich habe mich jahrelang geärgert, daß der C++Builder kein Parameter-Tooltip anzeigen konnte, wenn ich

    *lach*, Du hast jahrelang den C++Builder benutzt. Das allein reicht schon zu wissen.

    audacia schrieb:

    []Typaugmentationen wie * , & , [] beeinflussen den Typen, gehören aber verwirrenderweise syntaktisch zur Variable:
    `int
    a, b; // WTF

    int c[];`

    Schreib eine pro Zeile, sag ich seit 15 Jahren.

    audacia schrieb:

    [*]die Funktionszeigersyntax ist einfach kaputt. Was bitte ist das hier?

    int (*foo(float))(double(*)(char));
    

    Von innen nach außen und rechts vor links und alles kein Problem.

    foo ist (rechts abbiegen) eine Funktion, 
     die nimmt float (klammer zwingt nach links) 
     und gibt zurück zeiger auf (klammer fertig, weiter rechts) 
      funktion, die nimmt 
       zeiger auf funktion 
        die nimmt char 
        und gibt zurück double (links, weil rechts nix mehr ist)
       und gibt zurück int.
    

    Aber ein typedef täte gut.

    audacia schrieb:

    Ich denke, man kann erkennen, daß das nichts mit Syntaxvorlieben zu tun hat. Wohlgemerkt treten diese Probleme in Sprachen wie Java und C#, die eine C-inspirierte Syntax verwenden, by design nicht auf. Und wie bereits erwähnt gibt es auch in modernem C++ Alternativen, die diese Probleme vermeiden (uniform initialization, aliases und alias templates, Smartpointer und std::array<,> ); aber allein dadurch gehen die Altlasten ja noch nicht weg.

    Ja, wir werden alle sterben.
    Bin mir nicht so sicher, daß uniform initialization eine Hilfe ist.



  • audacia schrieb:

    AuchMondMann schrieb:

    Makros muss niemand nutzen

    Aber sie sind da, also nutzen sie Leute wie du, anstatt einen Codegenerator zu schreiben, wenn sie einen brauchen, und ich muß dann die resultierenden Probleme bekämpfen.

    einen Codegenerator schreiben, um ein einfaches build-abhängiges Debug-Makro per #ifdef DEBUG #define ... #endif zu vermeiden?? 😮

    audacia schrieb:

    Ich denke, man kann erkennen, daß das nichts mit Syntaxvorlieben zu tun hat. Wohlgemerkt treten diese Probleme in Sprachen wie Java und C#, die eine C-inspirierte Syntax verwenden, by design nicht auf.

    die sind aber nicht zero-overhead und nicht in dem Maß abwärtskompatibel zu C wie C++. Das sind aber wesentliche Features von C++.



  • gro0ßbuchstaben schrieb:

    einen Codegenerator schreiben, um ein einfaches build-abhängiges Debug-Makro per #ifdef DEBUG #define ... #endif zu vermeiden?? 😮

    du findest

    #define DOUBLE(x) 2*x
    ...
    DOUBLE(3+2)
    

    gut?? 😮



  • @Marthog
    Ziemlich sinnfreie an den Haaren herbeigezogene Unterstellung. Wieso sollte man etwas gut finden was total beknackt falsch ist?

    Nur weil man mit Feature X Fehler bauen kann, heisst das nicht dass Feature X Mist ist.

    A: Ich finde Autos praktisch.
    B: Was, du findest es gut kleine Kinder totzufahren??? 😮

    => Sinnlos



  • volkard schrieb:

    Du hast schlechte makefiles.

    Nein, ich habe gute Makefiles und präcompilierte Headerdateien, ein nützliches Compilerfeature, dessen eine altlastenfreie Sprache gar nicht bedürfte.

    volkard schrieb:

    *lach*, Du hast jahrelang den C++Builder benutzt. Das allein reicht schon zu wissen.

    Das reicht, was zu wissen? Sprich dich aus, nur keine falsche Zurückhaltung 🙂

    gro0ßbuchstaben schrieb:

    einen Codegenerator schreiben, um ein einfaches build-abhängiges Debug-Makro per #ifdef DEBUG #define ... #endif zu vermeiden?? 😮

    Netter Versuch. Meine Aussage war: die meisten Dinge, für die Makros so benutzt werden, kann man in modernen Sprachen auch ohne lösen, und meistens auf bessere Weise.



  • Marthog schrieb:

    gro0ßbuchstaben schrieb:

    einen Codegenerator schreiben, um ein einfaches build-abhängiges Debug-Makro per #ifdef DEBUG #define ... #endif zu vermeiden?? 😮

    du findest

    #define DOUBLE(x) 2*x
    ...
    DOUBLE(3+2)
    

    gut?? 😮

    ich schreibe eigentlich fast alles auf dem Präprozessor, dann läuft die exe in null Zeit.



  • audacia schrieb:

    Netter Versuch. Meine Aussage war: die meisten Dinge, für die Makros so benutzt werden, kann man in modernen Sprachen auch ohne lösen, und meistens auf bessere Weise.

    wieso sollte man den preprozessor nicht fuer die restlichen faelle nutzen sollen?



  • audacia schrieb:

    volkard schrieb:

    Du hast schlechte makefiles.

    Nein, ich habe gute Makefiles und präcompilierte Headerdateien, ein nützliches Compilerfeature, dessen eine altlastenfreie Sprache gar nicht bedürfte.

    Offenbar können sie transitive Projektabhängigkeiten nicht verfolgen.
    Ich nehme an, Du benutzt gar kein hübsches Makesystem, sondern bloß das, was MSVC Dir hinwirft. Tja, also meinet wegen soll die Sprache diesbezüglich so bleiben und die Compilerbauer dürfen Repositories, Pragmas und dergl ausprobieren, bis was Gutes sich verbreitet hat. Dein pragma comment lib ist ja schon ein halbherziger Anfang.



  • Volkard, du bist ein begnadeter Troll, aber hier verfehlst du wirklich das Ziel. Mir ist unklar, wie du überhaupt dazu kommst, über mein Buildsystem zu räsonieren.

    Schau nochmal hier:

    audacia schrieb:

    [Headerdateien sind Mist, weil] sie stupide Präprozessorexpansion sind => eskalierende Build-Zeiten, brüchige Modulkopplungen (manchmal geht was kaputt, wenn man #include-Statements umstellt), unoffensichtliche Abhängigkeiten (wenn du von einem Header abhängst, den du nicht einbindest, der aber von einem anderen Header referenziert wird). Das geht alles viel besser, wie man eigentlich an jeder anderen ernstzunehmenden Sprache sehen kann.

    Extra für dich mache ich ein paar konkrete Beispiele, damit du siehst, worum es geht:

    • eskalierende Build-Zeiten: immer mehr Bibliotheken verlegen immer mehr Logik in ihre Headerdateien, weil es so schön generisch und effizient ist, wenn man seine Algorithmen als Funktionstemplates anbietet, statt sie ganz old-fashioned in die .cpp-Dateien zu stecken. Bereits ohne diese header-dominierten Bibliotheken wie Boost sind die Build-Zeiten von C++-Code unnötig lang, wenn man keine precompiled headers benutzt, weil eben die Headerdateien für jede Quelldatei neu geparst werden müssen. Je größer aber der Anteil an template-basierten Implementierungen, desto größer wird auch die Zahl der Funktionen, für die der Compiler mehrfach (einmal pro referenzierender Quelldatei) Code generiert, und am Ende darf der Linker fast alle davon wieder wegwerfen. Das kostet Zeit. Es gibt schon Möglichkeiten, die Mehrfachinstantiierungen zu reduzieren (GCC hat so ein Flag für Template-Repositories, mit dem ich mich nicht auskenne), aber die sind entweder nicht portabel oder sehr aufwendig oder beides.
    • brüchige Modulkopplungen: eigentlich muß ich dazu nicht mehr als "windows.h" sagen, aber hier noch ein aktuelles Beispiel:
    // Because Python likes to fiddle with some proprietary configuration macros on POSIX targets, we have to include it first.
    #include <Python.h>
    
    #include <vector>
    #include <array>
    #include <string>
    #include <cstring>
    #include <cctype>
    
        // Configure NumPy to define the PyArray_API instance in this module.
    #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
    #define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
    #include <numpy/arrayobject.h>
    

    In Sprachen wie C# sind Assembly-Referenzen orthogonal, d.h. sie sind entweder da oder nicht da, und die Reihenfolge hat keinen Einfluß, ebenso die Referenzen untereinander. Außerdem wird klar getrennt zwischen dem Referenzieren von Modulen und dem Öffnen von Namespaces. In C++ muß man stattdessen Headerdateien einbinden und dem Linker die Importbibliothek mitgeben, und weil es Fälle gibt wie Python.h, die voraussetzen, daß sie die Standardbibliothek mit irgendwelchen proprietären Makros konfigurieren können, ist bei den Headerdateien die Reihenfolge kritisch.

    Außerdem willst du Python.h vielleicht nicht im PCH haben, weil es dann in allen Modulen den globalen Namespace verschmutzt; aber dann kannst du in obigem Modul keinen PCH verwenden, weil Python.h als erstes kommen muß.

    Python.h ist zwar besonders dreist, aber wenigstens ist das Verhalten dokumentiert; in den meisten Fällen ist das ja nicht einmal beabsichtigt, oder es ist seinerseits eine Altlast (wie die min / max -Makros in windows.h).

    • unoffensichtliche Abhängigkeiten: oft benutze ich einen std::string , vergesse aber, den Header einzubinden, und es klappt trotzdem, weil ein anderer Header den schon eingebunden hat. Dann kompiliere ich den Code mit einem anderen Compiler und bekomme 793 Fehlermeldungen, weil der eine andere Standardbibliothek mit anderen impliziten Includes hat. Oder noch besser: ich benutze eine Bibliothek, deren Header einen std::string verwendet, aber vergißt, den Header einzubinden, so daß nicht mal ich schuld bin.

    Aber wahrscheinlich liegt das alles nur daran, daß ich schlechte Makefiles habe und nicht ein gescheites Buildsystem benutze, sondern das, was MSVC++ mir hinwirft, und überhaupt benutze ich ja den C++Builder, das sagt ja eh alles 🤡



  • rapso schrieb:

    audacia schrieb:

    Netter Versuch. Meine Aussage war: die meisten Dinge, für die Makros so benutzt werden, kann man in modernen Sprachen auch ohne lösen, und meistens auf bessere Weise.

    wieso sollte man den preprozessor nicht fuer die restlichen faelle nutzen sollen?

    Meinetwegen kann man den Präprozessor gerne benutzen als Workaround für fehlende Sprachfeatures in C++ und irgendwelche Sprachdefekte, was wohl zusammen die restlichen Fälle ausmacht. Aber a) wird er viel zu oft für alles andere benutzt, und b) kommen ordentlich designte Sprachen prima ohne Präprozessor aus, und wenn das heutige C++ nicht die Altlasten von C geerbt hätte und außerdem mehr designt und weniger entdeckt worden wäre, hätten wir das vielleicht auch haben können.



  • hustbaer schrieb:

    @Marthog
    Ziemlich sinnfreie an den Haaren herbeigezogene Unterstellung. Wieso sollte man etwas gut finden was total beknackt falsch ist?

    Nur weil man mit Feature X Fehler bauen kann, heisst das nicht dass Feature X Mist ist.

    A: Ich finde Autos praktisch.
    B: Was, du findest es gut kleine Kinder totzufahren??? 😮

    => Sinnlos

    Natuerlich ist es sinnlos, ein Feature an einem schlechten Anwendungsfall herunterzuziehen und das sollte es ja auch sein, denn genauso ist es sinnloss, etwas zwanglaeufig schoenreden zu wollen, nur weil es wenige sinnvolle Anwendungsfaelle gibt. Die C-Praeprozessormakros sind nunmal ziemlich dumm, machen blosse textersetzung, ueberschreiben ohne Gnade anderen woerter einschliesslich keywords, koennen nichtmal expressions als parameter verwenden. Wenn man jetzt da ankommt mit "aber auf #ifdef DEBUG mag ich nicht verzichten", dann stellt sich derjenige auch absichtlich dumm.



  • audacia|off schrieb:

    rapso schrieb:

    audacia schrieb:

    Netter Versuch. Meine Aussage war: die meisten Dinge, für die Makros so benutzt werden, kann man in modernen Sprachen auch ohne lösen, und meistens auf bessere Weise.

    wieso sollte man den preprozessor nicht fuer die restlichen faelle nutzen sollen?

    Meinetwegen kann man den Präprozessor gerne benutzen als Workaround für fehlende Sprachfeatures in C++ und irgendwelche Sprachdefekte, was wohl zusammen die restlichen Fälle ausmacht. Aber a) wird er viel zu oft für alles andere benutzt, und b) kommen ordentlich designte Sprachen prima ohne Präprozessor aus, und wenn das heutige C++ nicht die Altlasten von C geerbt hätte und außerdem mehr designt und weniger entdeckt worden wäre, hätten wir das vielleicht auch haben können.

    mit soviel Abneigung bist du eindeutig im falschen Forum 👎



  • Siwfty schrieb:

    Was haltet ihr von Swift?

    Ich finde es interessant genug, dass ich es ausprobieren würde, wenn der Kram irgendwann mal unter GNU/Linux läuft. Ich bin zwar kein Fan von dieser struct/class Dichotomie ("Referenztypen" vs "Werttypen", class impliziert ARC mit runtime type information), aber die Sprache hat ja auch noch andere Dinge zu bieten (generics, protocols, algebraic data types).

    Was mich dabei persönlich interessieren würde ist, wie sehr sich Swift's "protocols" und Rust's "traits" ähnlich sind bzw wo da genau die Unterschiede liegen. Auch in Swift scheint man über protocols sowohl runtime dispatch als auch static dispatch zu bekommen.



  • krümelkacker schrieb:

    Was mich dabei persönlich interessieren würde ist, wie sehr sich Swift's "protocols" und Rust's "traits" ähnlich sind bzw wo da genau die Unterschiede liegen. Auch in Swift scheint man über protocols sowohl runtime dispatch als auch static dispatch zu bekommen.

    bei rust muss man static und dynamic dispatch durch andere schreibweisen angeben, waehrend bei Swift der compiler anscheinend zwischen statisch und dynamisch entscheidet.
    Zudem scheint mir rusts generics auch etwas maechtiger zu sein, was in anbetracht der Einsatzbereiche aber auch noetig ist.
    Swift sieht mir in vielerlei Hinsicht so aus wie rust vor einem Jahr, als die closures noch ueber type erasure implementiert waren und es noch viel groesseren Sprachkern gab.



  • ich hab mir Swift am Wochenende anschauen wollen und mit ein wenig in Apple's Metal abgeglitten bzw in die shader sprache MetalSL. Ich wollte bei dem ganzen 'spam' mit anderen sprachen hier nicht noch ein thread starten in RudP aber das ist echt nett. Templates etc. und das auf mobile.

    "Since the Metal shading language is based on C++, developers will find it familiar and easy to use"

    ein wenig lustig dass Apple Swift, MS C#, Google Java fuer ihre mobile platformen bevorzugen, aber beim shader language sind dann doch alle C bzw C++ 🙂

    https://developer.apple.com/library/ios/documentation/Metal/Reference/MetalShadingLanguageGuide/MetalShadingLanguageGuide.pdf



  • rapso schrieb:

    ein wenig lustig dass Apple Swift, MS C#, Google Java fuer ihre mobile platformen bevorzugen, aber beim shader language sind dann doch alle C bzw C++ 🙂

    Muessen halt auch einsehen, dass sich dynamische, heap-alloziierte objekte und runtime checks mit GPUs nicht gut vertragen.



  • Marthog schrieb:

    rapso schrieb:

    ein wenig lustig dass Apple Swift, MS C#, Google Java fuer ihre mobile platformen bevorzugen, aber beim shader language sind dann doch alle C bzw C++ 🙂

    Muessen halt auch einsehen, dass sich dynamische, heap-alloziierte objekte und runtime checks mit GPUs nicht gut vertragen.

    viele behaupten ja, dass der JIT das eigentlich wegbekommt. sowas wie

    foo(new Color(0,0,0,0));

    sollte theoretisch auf dem stack liegen.

    im gegensatz zu vielen umgebungen in denen c++ laeuft, sind ja shader eigentlich wie virtual machines, es gibt references und keine echten pointer. casting etc. ist sehr limitiert. (naja, aendert sich zZ, aber bis das auf mobile ist, dauert es ein wenig).


Anmelden zum Antworten