Gespräche über funktionale Programmierung in C ++ Siberia 2019

Hallo allerseits!


Vor kurzem fand in Nowosibirsk das nächste C ++ Siberia 2019 statt. Die Konferenz hatte eine gemütliche Atmosphäre und viele gute Berichte. Ich habe diese Gelegenheit genutzt, um mit zwei unserer Redner zu sprechen, die Sie bald in Moskau sehen werden.


Ivan Chukic ist einer der Entwickler von KDE, einem Lehrer und Forscher für das Design von Programmiersprachen an der Universität von Belgrad.


Alexander Granin ( graninas ) ist ein bekannter Redner und Entwickler, der sich auf FP spezialisiert hat, den Organisator der FP-Community LambdaNsk in Nowosibirsk.



Sergey: Hallo allerseits, lass uns kennenlernen. Alexander ist ein Hauptredner in diesem C ++ Sibirien, und Ivan war letztes Jahr ein Hauptredner. Lassen Sie uns über funktionale Programmierung sprechen. Soweit ich mich erinnere, war FP in C ++ das Thema Ihrer vorherigen Keynote, Ivan ...


Ivan: Nicht ganz, aber teilweise - ja.


Sergey: Und Alexanders Thema des Berichts ist die funktionale Programmierung. Deshalb habe ich ein paar Fragen vorbereitet und die erste - wie bestimmen Sie den AF?


Alexander: Ich glaube nicht, dass es eine „richtige“ Definition von FP gibt, aber wenn ich persönlich über mich spreche, ist FP etwas mit einer funktionalen Zusammensetzung und erstklassigen Funktionen.


Ivan: Ich stimme zu, aber ich würde mehr Funktionen höherer Ordnung hinzufügen - diejenigen, die andere Funktionen als Argumente verwenden und als Ergebnis zurückkehren können.


Sergey : Link zu einer Funktion in C - wird das berücksichtigt?


Ivan: Nein, C ist keine funktionierende Programmiersprache :-)


Sergey: Sag mir warum?


Ivan: Da Sie aus einer Kombination von Funktionszeigern keine neue Funktion erstellen können, können Sie nur auf vorhandene verweisen. Natürlich, wenn einige Assembler-Hacks nicht verwendet wurden.


Sergey: Großartig, jetzt habe ich eine offizielle Antwort! Die Leute stellen sich ständig die Frage, warum C keine funktionierende Programmiersprache ist, weil es dort vollwertige Funktionen gibt. Und deshalb ist C ++ eine funktionale Sprache, verständlicher ...


Alexander: Ich würde nicht sagen, dass C ++ eine wirklich funktionale Programmiersprache ist, sondern eine Reihe von Paradigmen unterstützt, die in einer Sprache zusammengefasst sind.


Sergey: Ich meine - C ++ unterstützt natürlich das Funktionsparadigma. Übrigens, warum? Unterstützt er es, weil Sie Funktionen höherer Ordnung manipulieren können?


Ivan: Nun, es scheint mir, dass er immer so war, denn selbst in C ++ 98 existieren bereits Funktionen höherer Ordnung, sogar in STL. Dies ist nicht die bequemste funktionale Sprache - es gibt Sprachen, die FP und besser implementieren. Aber für meine Bedürfnisse war es immer sehr funktional.


Sergey: Aber von diesem Ort aus genauer. Welche Bedürfnisse haben Sie?


Ivan: Es ist kompliziert. Komm schon, erzähl eine Geschichte. Als ich an der Universität war, haben wir LISP durchlaufen, und jeder hasste dieses LISP, weil es hässlich ist. Ich habe jedoch verstanden, wie C-Konstrukte direkt im LISP-Code simuliert werden können. Und dann kam eines Tages eine neue Version von Java heraus, die für Dinge wie die eingebaute foreach , und ich dachte: Wow, Sie brauchen einen neuen Compiler, eine neue Version der Sprache und alles, was neu ist, nur um etwas zu implementieren, das ich an der Universität auf LISP gemacht habe , die in der Regel nicht einmal Schleifen unterstützt. In diesem Moment wurde mir klar, dass FP eine ziemlich gute Sache ist, um Abstraktionen auf hoher Ebene zu erstellen, und deshalb verwende ich 2019 funktionales C ++.


Sergey: Tatsächlich verwenden Sie das FP für High-Level-Design.


Ivan: Genau.


Alexander: Im Moment arbeite ich nicht in C ++, aber ich würde mich nicht weigern, es zum Bearbeiten von Daten zu verwenden. Dies ist viel angenehmer als beim imperativen Ansatz. Selbst im Vergleich zu OOP sind hier im Gegensatz dazu nur Transformationen akzeptabel, und dies ist praktisch.


Sergey: Nun, Sie können FP nicht nur mit C ++ verwenden, oder? OK, dann die nächste Frage: Welchen Teil von C ++ verwenden Sie? Wenn nur Designprobleme wichtig sind, können Sie nur das Teil auswählen, das gut zum FP passt, das Sie wirklich verwenden.


Ivan: Das werden definitiv Lambda-Funktionen sein. Und noch wichtiger - Vorlagen, mit denen Sie andere Funktionen als Argumente und alles andere übergeben können, und Lambdas sind nur eine nette Syntax zum Schreiben von Funktionsobjekten.


Sergey: Ja, wir haben bereits gemerkt, dass du Lambdas wirklich magst :-)


Ivan: Es ist nicht so, dass sie sie wirklich mochten, aber dies ist eindeutig das Beste, was wir in C ++ 98 hatten. Es ist bequemer, mit ihnen zu arbeiten.


Alexander: Ja, ich mag auch Lambdas - diese Funktion ist so universell, dass man nur darauf schreiben kann. Dies ist so etwas wie ein universeller Kombinator, mit dem Sie jede Logik konstruieren können - vielleicht nicht so schön wie in anderen Sprachen, aber nicht weniger nützlich.


Sergey: Ivan, Sie haben hier bemerkt, dass es Standards vor C ++ 11 gibt, zum Beispiel C ++ 03, was sehr verbreitet ist, und dass es dort bereits funktionale Merkmale gibt. Und die neuen Standards enthalten weitere funktionale Merkmale ... Kann man sagen, dass sich C ++ in Richtung FP bewegt? Wird diese Bewegung fortgesetzt oder gestoppt? Und wozu wird es dann führen?


Ivan: Es gibt einen guten Bericht von Simon Peython Jones über Programmiersprachen im Allgemeinen, und dort hat er eine Grafik gezeichnet , die viele sichere Sprachen und die verwendeten Sprachen zeigt. Haskell begann seine Geschichte als eine völlig sichere Sprache, mit der nichts getan werden kann - weil es keine E / A und überhaupt nichts gibt. SPJ kategorisierte die C-Sprache und die Assemblersprachen als diejenigen, die sehr nützlich, aber gleichzeitig äußerst unsicher sind. Seitdem hat Haskell begonnen, sich in Richtung größerer Sicherheit zu bewegen. Auf der anderen Seite erhöhen diese Funktionen, die in C ++ angezeigt werden, hauptsächlich die Sicherheit, damit Sie korrektere Programme einfacher schreiben können. So kam es, dass die meisten dieser Dinge aus funktionalen Programmiersprachen stammen.


Sergey: Warum denkst du so? Aufgrund der Natur von AF?


Ivan: Ja, vielleicht von Natur aus ... aber ich weiß es nicht genau.


Alexander: Ich denke, dass AF jeden so fesselt, nur weil wir es satt haben, mit Vorlagen zu kämpfen, Bytes neu anzuordnen, mit einer Art Low-Level-Bodensatz - wir wollen etwas, das es wert ist, unsere eigene Intelligenz anzuwenden.


Sergey: Das heißt, für Sie ist dies eine Art intellektuelle Übung?


Alexander: Ja so.


Sergey: Ich verstehe. Wie viel interessanter ist es für einen Entwickler, über Abstraktionen auf hoher Ebene nachzudenken, als dumme Standardfunktionen zu implementieren - das ist unangenehm. Dann ist dies die Frage C: Haben Sie Erfahrung mit der praktischen Anwendung von FP in C ++? Irgendwelche Produktionsprojekte?


Ivan: Natürlich. Eines der größten Projekte der Welt, KDE, besteht aus mehreren Teilen, die den funktionalen Stil intensiv nutzen. Dies ist natürlich eine Mischung aus sozusagen traditionellem objektorientiertem C ++ mit einer Reihe von Funktionskonzepten. Ich würde niemals Purist oder so etwas sein. Ich versuche immer, das Beste aus verschiedenen Welten zu kombinieren.


Sergey: Was ist mit Haskell oder Scala? Immerhin sind sie in der Produktion weit verbreitet. Wie gefällt Ihnen die Idee, dass Haskell jetzt als Standard einer funktionalen Sprache gilt? Dies wird besonders von Puristen bemerkt.


Ivan: Ja, ich stimme zu, dass Haskell heute ein Synonym für FP ist. Tatsächlich wird jedes Merkmal von Haskell von Menschen als etwas im Zusammenhang mit FP wahrgenommen. Dies ist nicht unbedingt wahr, aber ich denke, dass Haskell wirklich die beliebteste akademische funktionale Programmiersprache geworden ist. Ich weiß, dass mehrere Banken in London und Nordeuropa Haskell in großem Umfang nutzen, aber Scala ist derzeit noch viel beliebter.


Alexander: Ich stimme zu, dass Scala populärer ist, aber Haskell scheint eine funktionalere Sprache zu sein, die meisten seiner Funktionen sind korrekter implementiert. Das heißt, wenn Sie Curry haben, das einfach zu machen ist, wenn es eine einfache Möglichkeit gibt, Kompositionen zu erstellen, wird das Programmieren einfach und unkompliziert. Es ist, als würden Sie durch den Wald gehen und die Aussicht genießen.


Ivan: Aber manchmal gibt es Bären im Wald. Wenn Sie in Russland sind.


Sergey: Glaubst du, C ++ ist hauptsächlich von Haskell inspiriert? Lohnt es sich?


Ivan: Weisen Sie auf bestimmte Ausschussmitglieder hin? :-) Jemand hat angedeutet, dass die Konzepte als Ergebnis des Verständnisses der Klassenklassen entstanden sind, aber Björn hat diese Gerüchte gestoppt und sogar ein Dokument darüber geschrieben, wie sich die Konzepte von den Klassenklassen unterscheiden. Aus meiner Sicht unterscheiden sie sich in allem, dienen aber einem Zweck. Nur verschiedene Ansätze.


Sergey: Sind Zukunft / Versprechen in irgendeiner Weise mit FI verbunden? Bartosh scheint argumentiert zu haben, dass dies schlecht implementierte Monaden sind.


Ivan: Nun ja, sie sind als Monaden implementiert und übertragen Fortsetzungen, aber ich bin mir nicht sicher, was in dieser Angelegenheit am wichtigsten ist.


Sergey: Brauchen wir eine verbesserte Monadenunterstützung in C ++?


Alexander: Natürlich ist dies das wichtigste Feature, das C ++ zu einer wirklich guten Sprache machen kann.


Ivan: Übrigens, da wir auf der Konferenz sind, möchte ich Ihnen auch eine Frage stellen, Sergey. Sie sagten, dass Konferenzen ein aufregender Job sind. Teilen Sie mit, was daran so interessant ist, und würden Sie mir oder Genosse Granin raten, unabhängig Konferenzen in anderen Teilen der Welt zu organisieren?


Sergey: Die Organisation von Konferenzen ist wirklich cool, man trifft viele interessante Leute, aber das ist nur die Spitze des Eisbergs. Und da unten - viel Arbeit, all diese Vorbereitung des Saals, Essen für die Teilnehmer, ganz zu schweigen von der Suche nach Sprechern. C ++ Russland ist immer noch nicht die berühmteste Konferenz der Welt, und die Redner müssen erklären, dass wir eine neue Konferenz sind und dass hier interessante Dinge passieren. Sie müssen den Sprecher überzeugen, insbesondere die berühmten Star-Sprecher, die nicht besonders daran interessiert sind, nach Russland zu fliegen, um ein neues Land zu sehen. Organisatorische Arbeit ist schwierig, insbesondere wenn Sie am Hauptjob arbeiten. Aber alles zahlt sich aus, wenn man mit diesen wunderbaren Menschen kommuniziert. Trotzdem habe ich jetzt den Punkt erreicht, an dem ich lieber an der Konferenz eines anderen teilnehmen werde als an meiner eigenen.


Ivan: Das heißt, Sie schlagen vor, an Konferenzen teilzunehmen, anstatt sie zu machen.


Sergey: Ja, wenn Sie die Organisation einer Konferenz vermeiden können, sollten Sie ein Risiko eingehen. Beim Organisieren fällt eine große Last auf Sie, dies ist eine weitere 8-stündige Arbeit. Persönlich beginne ich ungefähr 3 Monate vor der Konferenz weitere 8 Stunden am Tag zu arbeiten. Es macht Spaß ... aber ich hoffe, meine Familie macht genauso viel Spaß. Danke, dass Sie gefragt haben!


Und jetzt zurück zum Thema. Wir haben über funktionale Programmierung gesprochen, und Sie haben mich fast überzeugt, in dem Sinne, dass Ihre Berichte mich überzeugt haben. Es besteht der Verdacht, dass der funktionale Ansatz in C ++ mir beim Multithreading hilft, wenn ich verschiedene Dinge synchronisieren muss. Wird es wirklich helfen?


Ivan: Natürlich.


Alexander: Trotz der Tatsache, dass ich nur begrenzte Erfahrung mit funktionalem Multithreading speziell in C ++ habe, muss ich sagen, dass es in einer Welt mit reinen Funktionen viel einfacher ist, in einer Multithread-Umgebung darüber zu sprechen. Wenn Sie Logik schreiben, zum Beispiel wettbewerbsfähig, müssen Sie nicht daran denken, all diese Dinge zu synchronisieren, über Mutexe, über kritische Abschnitte, über irgendetwas. All dies verschwindet einfach, weil Sie sich den Code als regulären sequentiellen Code vorstellen und alle Multithreading- und Synchronisationsfunktionen irgendwo im Inneren versteckt sind. Es gibt viele Ansätze zur Multithread-Programmierung und zur Funktionsweise. Ich bin mir nicht sicher, ob dies bei absolut allen Ansätzen der Fall ist, aber zum Beispiel ist Software-Transaktionsspeicher ein großartiger Ansatz, um die Komplexität in wettbewerbsfähigen Anwendungen zu reduzieren. Leider geht es darum, die richtigen Kompromisse zu wählen.


Ivan: Wenn der Compiler die ganze Arbeit für Sie erledigt, müssen Sie dafür effizient bezahlen.


Alexander: Nun, es gibt verschiedene Probleme. Zuerst müssen Sie all diese Dinge wie STM verstehen und dann dieses geheime Wissen an Ihre Kollegen weitergeben. Und dann gibt es Fehler in einer bestimmten Implementierung und an Stellen, die bei Verwendung der manuellen Thread-Steuerung viel besser funktionieren können. Sie können jedoch schneller und einfacher schreiben als mit einer solchen manuellen Steuerung. Die Ausführung ist langsamer, der Code weist jedoch weniger Fehler auf. Übrigens, Ivan, was denkst du darüber, wie gut dieses Thema auf Konferenzen behandelt wird?


Ivan: Dieses Thema boomt. In den letzten Jahren alle wichtigen Konferenzen - CPPConf, C ++ Russland, Meeting C ++ usw. - Empfangene Berichte entweder direkt über FP oder über algebraische Datenstrukturen oder ähnliches. Manchmal vermuten die Redner nicht einmal, dass sie in ihrem Bericht über ein Konzept der FP sprechen. In C ++ kommen die Dinge von vielen verschiedenen Orten ... Menschen schreiben normalerweise nicht nur in einer Sprache. Stellen Sie sich vor, Ivan Ivanov arbeitet an einem Projekt in Erlang und C ++. Dann kommt Tatyana Petrovna und sie arbeitet bereits für Haskell mit sauberen Funktionen und all dem. Sie nehmen ihre Lieblingsmechanismen und portieren sie nach C ++. Infolgedessen bringen eine große Anzahl von Menschen aus verschiedenen Communities immer mehr Dinge nach C ++. All dies geschieht vor unseren Augen. Zumindest passiert dies in der C ++ - Entwicklergemeinde, aber bei C ++ - Unternehmen bin ich mir nicht so sicher. Viele Leute in der C ++ - Community arbeiten jetzt jedoch an funktionalen Konzepten.


Alexander: Ich habe richtig verstanden, dass viele Top-C ++ - Entwickler Haskell nur studieren, um zu verstehen, was mit C ++ passiert.


Ivan: Ich bin mir nicht sicher, ob sie Haskell aus diesem Grund unterrichten. Ich denke, C ++ - Entwickler sind einfach sehr egoistisch. Sie haben C ++ so gut gelernt, nur weil es komplex ist. Und wenn Sie etwas wirklich Neues lernen möchten, liegt Ihr Weg offensichtlich nicht in Java, das speziell für die Einfachheit erstellt wurde. Sie müssen im Bereich ungewöhnlicher und seltsamer Sprachen suchen, der seltsamsten, und Haskell wird automatisch zu den beliebtesten Antworten gehören. Eine Person sieht es, versteht: Oh, das ist etwas komplexer als C ++, Sie müssen lernen. Als ich Haskell studierte, war es bei mir genauso, und ich habe Freunde, die genau der gleichen Argumentation gefolgt sind.


Alexander: Als Eric Nibler bei uns in Sibirien war und seine Bibliothek für Sortimente zeigte, wurde er oft gefragt, was die Inspirationsquelle sei. Er antwortete, dass es Haskell war. Vielleicht sollten nicht alle Funktionen in einer Reihe daraus übernommen werden, aber einige werden in der Community eindeutig benötigt.


Ivan: Es ist ein bisschen Evolution. Genetisches Material. Und Haskell kann auch verbessert werden, indem man etwas aus C ++ nimmt. Die meisten Sprachen durchlaufen eine solche Entwicklung. Java hat versucht, LINQ von C # an sich selbst anzupassen, und LINQ-Ersteller von C # haben sich von Haskell usw. inspirieren lassen. Es stellt sich heraus, dass es ein wunderschönes Netzwerk gegenseitiger Beeinflussung zwischen verschiedenen Sprachen gibt.


Alexander: Ist C ++ jedoch immer noch eine einfache Sprache?


Ivan: Die meisten Leute denken so.


Sergey: Von was für einem "niedrigen Level" sprichst du?


Ivan: Kompiliert zu Low-Level-Code. Aber es funktioniert mit Abstraktionen auf hoher Ebene. Der springende Punkt und Zweck ist, dass solche Abstraktionen nicht zu unnötigem Leistungsaufwand führen. C ++ sollte aus seinen Abstraktionen Code generieren, der nicht schlechter als handgeschrieben wäre. Zumindest theoretisch.


Alexander: Was passiert, wenn jemand gegen diese Regel verstößt? Zum Beispiel Bereiche.


Ivan: Die Kompilierungsleistung leidet - ja. Alle neuen Funktionen, insbesondere die in Bibliotheken enthaltenen Funktionen, verlängern die Kompilierungszeit. Es gibt jedoch keinen Grund, warum Bereiche langsam sein sollten. Wenn sich die Bereiche verlangsamen, können Sie hier nur Compiler beschuldigen, die nicht für diesen speziellen Fall optimiert sind.


Sergey: Die Bereiche selbst bremsen nicht, sondern die Bereiche im Debug-Modus - das ist die Essenz der gesamten Diskussion. Im Release-Modus funktionieren sie einwandfrei.


Ivan: Das ist normal.


Sergey: Nicht alle sind damit einverstanden :-)


Ivan: Ja, ich weiß es in der Praxis. In einer Firma, in ihrer am häufigsten verwendeten Bibliothek ... Ich werde nicht sagen, um welche Art von Firma und Bibliothek es sich handelt ... gibt es Algorithmen, die im Debug-Modus asymptotisch signifikant langsamer sind. Und wer wird sich jetzt beschweren, dass die Bereiche dasselbe tun?


Sergey: In dem Artikel, den wir diskutieren, ging es nicht um die Frage selbst, sondern nur um ein Beispiel für einen Autor, der wütend war, dass diese Situation zu einem Trend wurde und die Produktivität im Debug-Modus gering war. In seinem Themenbereich Game Engines ist dies einfach inakzeptabel.


Alexander: Diese Leute mögen STL überhaupt nicht, weil es langsamer arbeitet als sie brauchen. Bereiche erweitern die Bibliothek nur in die gleiche Richtung, und für sie sieht es nach einer weiteren nutzlosen Funktion aus, die sie nicht verwenden können.


Sergey: Hasser werden hassen.


Ivan: Genau. Zum Beispiel verwendet jeder die Sortierung. Stellen Sie sich vor, es gibt keine Sortierung mehr in der Standardbibliothek. Wie würden Sie es implementieren?


Sergey: Normalerweise stelle ich eine solche Frage in einem Interview :-) Dies ist eine sehr häufige Frage.


Ivan: Ja, eine häufige Frage ist, wie man die Sortierung implementiert. Und dann sprechen Sie über eine Basisversion der schnellen Sortierung, die eigentlich nirgendwo auf der Welt verwendet wird, weil sie in bestimmten Fällen sehr langsam sein kann. Die Standardbibliothek erlaubt keine Verwendung, da ein garantiertes N-Protokoll N erforderlich ist und eine schnelle Sortierung nicht möglich ist. Zum größten Teil kann es, aber der Standard an dieser Stelle ist sehr streng und bedeutet nicht akkumuliertes N log N, es sollte reines N log N sein, und wie werden Sie einen solchen Algorithmus implementieren? Sie müssen recherchieren, viele verschiedene Optimierungen für die schnelle Sortierung finden und sie zu einem Algorithmus zusammenführen, der aus mindestens drei verschiedenen Algorithmen besteht, wie dies in libstdc ++ der Fall ist. Dies ist die Bedeutung von Standardbibliotheken - Sie müssen nicht alle diese Dinge wissen, um programmieren zu können. Sie müssen nicht herausfinden, wie Sie alles am effizientesten implementieren können, jemand anderes hat sich bereits um Sie gekümmert. Daher mag ich diesen Ansatz nicht, wenn Leute sagen: "STL ist sehr kompliziert, verwenden wir ihn nicht und schreiben alles manuell von Grund auf neu."


Sergey: Wir nähern uns dem Ende des Interviews, also die letzte Frage: Wie gefällt es dir in Russland?


Alexander: Es wurde kälter.


Sergey: Auch für dich? Du bist vor Ort!


Ivan: Aber für mich ist es hier viel wärmer als erwartet.


Sergey: Jetzt ist es -16 und wir haben dir gesagt, dass es -40 sein wird.


Ivan: Ja, du hast es versprochen! Ich habe mich speziell auf minus vierzig vorbereitet. Und dann schaue ich auf das Thermometer und dort ist alles wärmer und wärmer.


Sergey: Nun, jetzt werden wir uns nur auf der C ++ Russia 2019 treffen, es wird in Moskau sein und es wird eine Plus-Temperatur geben. Danke für das Interview und bis bald!


Minute der Werbung. Vom 19. bis 20. April findet eine C ++ - Russland-Konferenz statt, auf der Ivan eine Präsentation zum Thema „Nur-Bewegung-C ++ - Design“ halten und Alexander über monadische Parser sprechen wird. Darüber hinaus wird Ivan eine von drei großen Schulungen abhalten - „Angewandte funktionale Programmierung in C ++“ . Ein Monat bleibt vor der Konferenz und das Programm wird weiter verfeinert. Auf der offiziellen Website können Sie sehen, welche Berichte bereits in das Programm aufgenommen wurden, und Tickets kaufen . Bitte beachten Sie, dass es verschiedene Arten von Tickets gibt und die Auswahl der richtigen viel sparen kann.

Source: https://habr.com/ru/post/de444212/


All Articles