if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Xin » Mo Aug 01, 2011 2:59 pm

Was mir gerade mal durch den Kopf ging...

Lambda-Funktionen dienen doch dazu, eine (Call-Back-)Funktion direkt als Parameter zu übergeben, so dass man nicht erst eine neue Funktion schreiben muss und den Namen der Funktion übergeben muss.
Praktisch. :-)

Anders formuliert baut man die zu übergebende Funktion in den Algorithmus ein, der den Funktionsaufruf auf eine Funktion enthält, die eine Call-Back-Funktion als Parameter benötigt.

Damit vermüllt man doch prinzipiell den Algorithmus, in dem dann mittendrin eine vollkommen andere Funktion steht, die für diesen Algorithmus als Call-Back-Funktion benötigt wird.
...okay...

Das steht doch im krassen Widerspruch zur Argumentation von Exceptions, die ihren Wert daraus ziehen, dass sie die Fehlerbehandlung aus dem Algorithmus herausziehen, so dass der Algorithmus leicht zu lesen sei.

Laufen da nicht irgendwie zwei Hypes mit ihren Philosophien frontal gegeneinander?

Wie kann es gut sein, Algorithmen von Call-Back-Funktionen mitten in den Haupt-Algorithmus zu schrieben, während man gleichzeitig die Fehlerbehandlung des Haupt-Algorithmus aus dem Haupt-Algorithmus herauszieht.
Denken wir das zu Ende: Steht jetzt nicht die Exceptionbehandlung einer Callback-Funktion zusammen mit der Definition der Call-Back-Funktion inmitten des Hauptalgorithmus', welcher zuvor mühevoll von eigenen Fehlerbehandlung befreit wurde?
Beides ist State of the Art in der Programmierung?

Sehe ich hier etwas falsch oder feiert die Informatikwelt ein Konzept, dass Code aus Algorithmen herauszieht, wie gleichzeitig ein Konzept, dass anderen Code in den Algorithmus hineinpackt?

Und wenn ich richtig liege... welches der beiden Konzept liegt falsch?
Ich bin an Meinungen interessiert - an prinzipiellen Meinungen, nicht an Meinungen mit Fallunterscheidungen, wie "Lambda toll, wenn maximal drei Zeilen" oder "Exeptions toll, wenn kein Catch-All...", das giben Programmiersprachen nämlich soweit mir bekannt ist nicht her. Was nicht unterbunden wird, wird auch gemacht.
Wer daran Zweifel hat, kann sich neuerdings einen (lebenden) Hund kaufen, der im Dunkeln leuchtet.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von cloidnerux » Mo Aug 01, 2011 4:07 pm

Laufen da nicht irgendwie zwei Hypes mit ihren Philosophien frontal gegeneinander?
Hier muss man sich auch Fragen, ab wann es Sinn macht Exceptions zu nutzen und ab wann es sich nicht mehr lohnt Lamba Funktionen zu nutzen.
Wenn du umbedingt 200 Zeilen Lambdafunktion haben willst, bitte, aber so ganz sinnvoll ist es nicht.
Andererseits wozu sollte ich eine Exception schmeißen, wenn ich nur mit Variablen und nicht mit Pointer arbeite? Vlt weil man irgendwo mal nen Divison by Zero haben könnte, gut, aber das ist mir bisher noch nie aktiv vorgekommen.

Also würde ich das Konzept so sehen, das Lambdafunktionen das leben einfacher machen sollen, wenn die Aufgaben nicht so komplex sind, z.B wenn du einen Funktion zur Selektion von Daten brauchst, die sich in 3 Zeilen implementieren lassen.
Wird die Funktion größer würde ich alleine schon wegen der Übersichtlichkeit das ganze Auslagern.

Soweit ich weiß sind Lambdafunktionen ja auch Funktionen, nur hast du keinen expliziten Namen vergeben sodass der Compiler einfach nur die Adresse der Funktion übergibt, weil du sonst ja gar nicht über den Funktionspointer die Funktion aufrufen kannst.
Damit kannst du natürlich auch Exceptions einbauen die der Aufrufer der Funktion zu handhaben hat, wie es mit einer normalen Funktion auch ist.

Es stimmt schon, das C++ 2 gegenläufige Prinzipien verfolgt, zum einen natürlich Code auszulagern, auf der anderen Seite aber Code zu integrieren. Aber hier ist es wie immer im Leben, sobald es Extrem wird, wird es schlecht. Man muss natürlich immer die Mitte zwischen beiden Finden.

P.S: Dir fehlt ein "}"
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von fat-lobyte » Mo Aug 01, 2011 4:23 pm

Xin hat geschrieben:Was mir gerade mal durch den Kopf ging...
Aus deinem Speicher für ruhige Zeiten im Forum? ;-)
Lambda-Funktionen dienen doch dazu, eine (Call-Back-)Funktion direkt als Parameter zu übergeben, so dass man nicht erst eine neue Funktion schreiben muss und den Namen der Funktion übergeben muss.

Anders formuliert baut man die zu übergebende Funktion in den Algorithmus ein, der den Funktionsaufruf auf eine Funktion enthält, die eine Call-Back-Funktion als Parameter benötigt.

Damit vermüllt man doch prinzipiell den Algorithmus, in dem dann mittendrin eine vollkommen andere Funktion steht, die für diesen Algorithmus als Call-Back-Funktion benötigt wird.
Ich glaube du benutzt den Begriff "Callback"-Funktion etwas zu traditionell. Es stimmt schon, es kann dafür verwendet werden klassische "Callbacks" zu implementieren mit Funktionszeigern für Datenauswertung ("so, hier haste deine Daten") oder Statusmeldungen ("Ich wär dann fertig.").
Wenn du dir aber die tatsächlichen ausdrücke in denen Lambdas vorkommen ansehe, z.B. in dem von dieser Webseite schamlos geklauten Code:

Code: Alles auswählen

#include <algorithm>
#include <deque>
#include <iostream>
#include <iterator>
#include <ostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v;

    for (int i = 0; i < 10; ++i) {
        v.push_back(i);
    }

    deque<int> d;
    transform(v.begin(), v.end(), front_inserter(d), [](int n) { return n * n * n; }); 

    for_each(d.begin(), d.end(), [](int n) { cout << n << " "; });
    cout << endl;

}
Dann ist das Lambda nicht einfach irgendein zufälliger Callback, den man in den Algorithmus reingezwungen hat, sonder er _ist_ der Algorithmus. Das Lambda ist hier eben kein Callback mehr, sondern teil des Codes. Auch auf Maschinenebene: Wenn ich das gleiche in C machen will, brauche ich einen Funktionszeiger. Um einen Funktionszeiger zu erhalten muss die Funktion tatsächlich existieren, und jedes mal wenn der Code gebraucht wird, muss tatsächlich der Maschinencode den aufruf machen (push argument1, push argument2, call XXX, push ebp, mov eax, [esp-8], blabla..., pop ebp, ret).
DAS ist ein echter Callback. Ich bin mir ziemlich sicher, ein Lambda mit vernünftig eingestelltem Compiler kompiliert wird sofort ge-inlined, und der Code steht auch _im_ algorithmus, und gehört dann auch dazu.

Das steht doch im krassen Widerspruch zur Argumentation von Exceptions, die ihren Wert daraus ziehen, dass sie die Fehlerbehandlung aus dem Algorithmus herausziehen, so dass der Algorithmus leicht zu lesen sei.
Versteh ich nicht. Wieso steht das im Widerspruch?
Laufen da nicht irgendwie zwei Hypes mit ihren Philosophien frontal gegeneinander?
Hypes hin oder her, es ist ein Sprachfeature, und dazu ein verdammt nützliches. Früher musste man der STL ganze Funktionsobjekte füttern mit class {} und public operator() (). Das ist eine verkürzte Syntax, und die kann von mir aus gehypt sein oder nicht, ich werde sie verwenden. Um ehrlich zu sein, wer genau hypt denn Sprachfeatures?
Wie kann es gut sein, Algorithmen von Call-Back-Funktionen mitten in den Haupt-Algorithmus zu schrieben, während man gleichzeitig die Fehlerbehandlung des Haupt-Algorithmus aus dem Haupt-Algorithmus herauszieht.
Wie gesagt, ich glaube du siehst hier den Begriff "Callback" zu eng.
Denken wir das zu Ende: Steht jetzt nicht die Exceptionbehandlung einer Callback-Funktion zusammen mit der Definition der Call-Back-Funktion inmitten des Hauptalgorithmus', welcher zuvor mühevoll von eigenen Fehlerbehandlung befreit wurde?
Beides ist State of the Art in der Programmierung?
Wer sagt denn, dass ich meine Exceptions innerhalb des Algorithmus abfangen will? Ich kann meinen catch-block genauso um den ganzen Funktionsaufruf legen.

Was mich interessieren würde, was genau verstehst du unter Fehlerbehandlung? Was stellst du dir da vor? Welche Fehler werden behandelt? Wie reagierst du darauf? Willst du z.B. std::bad_cast's auffangen? Oder std::bad_alloc's?

Was mir gerade auffällt: wie sähe denn das ohne Exceptions aus? Hier kommt die Fehlerbehandlung genauso in den Code. Da wird der Algorithmus ja noch dicker! Wenn ich in jeder Iteration abfragen muss ob eh noch alles grün ist, dann ist das auch nicht viel besser.
Ich bin an Meinungen interessiert - an prinzipiellen Meinungen, nicht an Meinungen mit Fallunterscheidungen, wie "Lambda toll, wenn maximal drei Zeilen" oder "Exeptions toll, wenn kein Catch-All..."
Wieso denn kein Fallunterscheidungen? Das ist ja die Realität - man kann sich mit ziemlich vielemen ins Bein schießen. Muss man aber nicht. Zu sagen "Lambdas sind generell Falsch" weils Leute gibt die dort ganze Funktionen reinpacken empfinde ich als hirnrissig.
Es gibt einfach keine "prinzipielle" Antwort auf jede Frage, und die Antwort wird immer vom betrachteten Fall abhängig sein. Alles andere ist akademische Informatik und gehört in den Hörsaal, aber nicht in Code.
, das giben Programmiersprachen nämlich soweit mir bekannt ist nicht her. Was nicht unterbunden wird, wird auch gemacht.
Dann sag ich: von mir aus, dann macht doch einfach! Schreibt euren queeren Code, wenn ihr meint dass es richtig ist. Ich halte mich an die Regeln der vernunft, und bewege auch meine Mitarbeiter oder mitprogrammierer dazu sich an die Regeln der Vernunft zu halten.


Was ich generell noch zu C++ sagen will: es macht Code einfach lesbarer. Es macht Code lebendiger, es macht (meistens) weniger Syntax und mehr Semantik. Man kann schreiben was man im Kopf hat, und da sind Lambdas ein klassisches Beispiel dafür: Wenn ich std::accumulate() sagen will, wie es seine elemente zu Addieren hat, will ich nciht extra eine neue Klasse anlegen müssen. Ich will IN DIESER ZEILE sagen können was ich will.

Ich hatte letzte Woche das Vergnügen Java programmieren zu dürfen. Da sind dann ausdrücke herausgekommen wie:
CommandRunner cr = IntegrationPointFactory.getInstance().createIntegrationPoint().createSession().createCommandRunner();


Super. Glatte 1 für das Verständnis des Begriffes "Objektorientierte Programmierung". Und wieso der ganze Spaß? Weil die netten Java leute gemeint haben, Operatorüberladung ist zu kompliziert für den Programmierer, den Code versteht man ja nicht. Und Mehrfachvererbung ist auch zu kompliziert, da kann man ja auch was falsch machen. Und Templates streichen wir auch, da kann man sich ja richtig ins Bein schießen. Geht ja gar nicht.
Und was ist rausgekommen? Eine Syntaktische wüste. Monokultur, die den Code unglaublich Zäh und langweilig und furchtbar "Verbose" (kein passendes deutsches Wort im Kopf) machen. Und so wie ich das sehe genau aus der Argumentation heraus, dass manche Programmierer es falsch verwenden könnten.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Xin » Mo Aug 01, 2011 7:42 pm

Faszinierend zu sehen, dass jeder meint, ich wettere gegen Lambda-Funktionen, als ob ihr mich nicht besser kennt... ^^

Und hier noch das fehlende "}" ^^
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von fat-lobyte » Mo Aug 01, 2011 8:04 pm

Xin hat geschrieben:Faszinierend zu sehen, dass jeder meint, ich wettere gegen Lambda-Funktionen, als ob ihr mich nicht besser kennt... ^^
War auch ein bisschen Wunschdenken, dass du auch mal gegen was anderes Wetterst ;-)
Xin hat geschrieben:Und hier noch das fehlende "}" ^^
Das ist ja von Quotes umgeben, das Zählt nicht. Kann dir jeder Parser bestätigen. ;-)
Haters gonna hate, potatoes gonna potate.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Panke » Di Aug 02, 2011 3:24 pm

Der Vorteil von Exceptions ist meiner Meinung nicht, dass Code zur Fehlerbehandlung aus dem Algorithmus herausgezogen wird, auch wenn das viele immer so behaupten.

Aber selbst wenn das so wäre, ist da kein Widerspruch. Einmal wird "unnötiger" Code aus dem Alogrithmus entfernt, und
einmal äußerst wichtiger Code in den Algorithmus gepackt. Anstatt ihn irgendwo anders abzuladen, wo man ihn nicht findet.

Also hätte man zwei Mal das gleiche: Ich will sehen, was mein Code macht, ohne suchen zu müssen und ohne
dass mir Boilerplate die Sicht versperrt. Structs für Funktionsobjekte, die ich nur einmal nutze, sind mMn Boilerplate.

Edit: Kann ich bitte eine Option haben, die meine eigenen \n verschluckt bei der Ausgabe, es sei denn ich schreibe gleich 2?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Xin » Di Aug 02, 2011 3:32 pm

Panke hat geschrieben:Der Vorteil von Exceptions ist meiner Meinung nicht, dass Code zur Fehlerbehandlung aus dem Algorithmus herausgezogen wird, auch wenn das viele immer so behaupten.
Ich bin für alternative Erklärungen offen :-)
Was ist Deine Meinung zu Exceptions?
Panke hat geschrieben:Aber selbst wenn das so wäre, ist da kein Widerspruch. Einmal wird "unnötiger" Code aus dem Alogrithmus entfernt, und einmal äußerst wichtiger Code in den Algorithmus gepackt. Anstatt ihn irgendwo anders abzuladen, wo man ihn nicht findet.
Schlussendlich wird alles durcheinander gewürfelt.

fat-lobytes Argumentation zieht nur, wenn die Lambda-Funktion inline in ein template eingeführt wird. Das wage ich zu bezweifeln.
Panke hat geschrieben:Edit: Kann ich bitte eine Option haben, die meine eigenen \n verschluckt bei der Ausgabe, es sei denn ich schreibe gleich 2?
Nicht in dieser Foren-Software. Einfach immer geradeausweiterschreiben :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Panke » Di Aug 02, 2011 4:49 pm

fat-lobytes Argumentation zieht nur, wenn die Lambda-Funktion inline in ein template eingeführt wird. Das wage ich zu bezweifeln.
Wie genau man da optimieren kann, lasse ich mal außen vor. Ich kann mir aber gut vorstellen, dass das nicht nur bei Templates gut funktioniert. Seine Argumentation war aber nicht rein technischer Natur. Beispielsweise bei einem Aufruf von std::sort das Sortierkriterium direkt hinschreiben zu können ist ein Vorteil. Und dann gehört der Code genau an die Stelle im Algorithmus. Idealerweise als lambd-Funktion, da diese am wenigsten boilerplate liefert. Wenn das nicht geht, mit einem Struct, dass genau an der Stelle definiert wird -- das macht C++0x auch möglich.

Ich würd' anonyme Funktionen auch nicht als Hype bezeichnen. Dafür gibt es die schon zu lange. Sind ja auch schlicht nützlich.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Xin » Di Aug 02, 2011 4:56 pm

Es ist durchaus ein Hype. Es gibt sie zwar schon lange, aber eben nicht in den populären Programmiersprachen.
Java kam soweit ich weiß recht spät damit und bei C# bin ich mir gerade nichtmals im Klaren, ob sie existieren - vermutlich aber wohl schon. Bei Java erinnere ich mich nur, dass ich die Syntax grausam fand.

In Genesys - meiner Programmiersprache - sind sie von grundauf eingeplant, da werden sie überhaupt nicht auffallen. Soll heißen, ich mag sie. Bei Exceptions bin ich noch am überlegen, ob ich sie überhaupt aufnehme.

Die Frage war aber eigentlich nach den Exceptions. Heißt Deine vorherige Antwort, dass sie einen anderen Vorteil haben oder dass sie überhaupt keinen Vorteil haben!?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: if( Konzept && !Konzept ) { printf( "Lehrmeinung?" );

Beitrag von Panke » Mi Aug 03, 2011 12:07 am

Der Vorteil von Exceptions ist meiner Meinung nach, dass man Fehler einfacher nach oben weiterreichen kann. Vor allem bei Fehler der Art: "Tritt der Fehler auf, wird das hier eh nix mehr". Auch kann man dabei direkt
Infos mitliefern, was ich besser finde als errno + Konsorten. Bei Fehlern die man direkt behandeln will,
bringen sie in der Ausprägung Python / C++ / Java in der Regel wenig. Der Punkt ist, an diesen Stellen keine
Exceptions zu nutzen.

Nur Exceptions sind ein Sprachmittel wie jedes andere auch: Es muss zum Rest der Sprache passen. Bei C++
sind sie mehr als unausgegoren und passen hier und vorne nicht: Stichwort: Exception Specification; Exception aus dem Destruktor raus bzw. throw während des Stack Unwindings; Exception + generische Programmierung; Exception und manuelle Speicherverwaltung machen es einem auch nicht einfacher, trotz RAII. Man muss sich halt vieles Angewöhnen um damit keinen Schaden anzurichten. Allerdings ist das meiste davon eh guter Stil in C++.

Edit: Zum Thema Hype: Ich würde unterscheiden zwischen "Das ist neu und keiner weiß, ob es überhaupt funktioniert, aber alle brauchen das jetzt um cool zu sein Hype" wie Cloud Computing und SaaS und "Bewährte Technologie, die jetzt der Mehrheit der Menschen zugänglich wird". Die Mainstream-Sprachen ändern sich eben relativ langsam. Und noch ein Unterschied: Niemand behauptet anonyme Funktionen wären eine Silver Bullet, wie bei Hypes normalerweise üblich.

Kann deine Sprache eigentlich Co-Routinen / Continuations?

Antworten