{"id":2912,"date":"2017-03-22T15:38:36","date_gmt":"2017-03-22T14:38:36","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=2912"},"modified":"2017-03-23T08:21:24","modified_gmt":"2017-03-23T07:21:24","slug":"c-guns-funktionale-anwendung-erkannt","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=2912","title":{"rendered":"C++ Guns - Funktionale Anwendung erkannt"},"content":{"rendered":"<p>Ich habe gerade eine einfache Schleife mit 5 Zeilen geschrieben und auf einmal sah ich, dass das doch ein gutes Beispiel f\u00fcr funktionales programmieren w\u00e4re.<br \/>\nGegeben ist ein Datenvector mit custom Typ und gesucht ist ein bestimmtes Datum und, falls vorhanden, davon ein bestimmter Wert. Die Schleife l\u00e4sst sich von Hand so ausdr\u00fccken:<\/p>\n<pre><code>\r\n    struct Blah {\r\n        size_t idx;\r\n        int att;\r\n    };\r\n\r\n    vector&ltBlah> data { {2, -1}, {1, -1}, {5, 50}, {3, 10}};\r\n\r\n    \/\/ skip -1\r\n    size_t start = 0;\r\n    for(size_t i=0; i < data.size(); ++i) {\r\n        int att = data[i].att;\r\n        if(att != -1) {\r\n            start = data[i].idx;\r\n            break;\r\n        }\r\n    }\r\n    cout << \"start \" << start << \"\\n\"; \/\/ print 5\r\n<\/code><\/pre>\n<p>Hier gibt es gleich eine ganze Reihe von Fehlerquellen. Von welchem Typ muss i sein, size_t oder int? Inkrement mit ++i oder i++ ? Ist der operator[] \u00fcberhaupt vorhanden, und wenn ja auch effizient? Muss der Zugriff ueber const Referenz erfolgen? Und die Schleifen koennen wir beenden beim ersten Treffer, ja sicher oder ist das \"break\" zuf\u00e4llig da. Fuer alle das, muss man den Code Zeile fuer Zeile lesen und nachvollziehen und verstehen. Wie immer ist das \"WAS und nicht WIE\" Prinzip verletzte. Denn der Code sagt nicht, WAS er macht, sondern nur WIE. Ich h\u00e4tte auch range-for nehmen k\u00f6nnen. Aber das \u00e4ndert am Prinzip nichts.<\/p>\n<p>Aus funktionaler Sicht ist die Schleife ja ein Muster fuer \"find_if_apply\" oder \"apply_if_find\" je nachdem ^^ Ob es in der funktionalen Welt so eine Funktion gibt, und wie sie genau hei\u00dft, wei\u00df ich nicht. Aber ich probier mal meine eigene Version. Ich w\u00e4le den Namen \"find_if_apply\", da es schon eine C++ Funktion std::find_if gibt, und erweitere sie um eine \"apply\" componente.<\/p>\n<pre><code>\r\ntemplate&ltclass Container, class UnaryPredicate, class UnaryFunction>\r\nvoid find_if_apply(const Container& data, UnaryPredicate p, UnaryFunction f) {\r\n    for(const auto& x : data) {\r\n        if(p(x)) {\r\n            f(x);\r\n            break;\r\n        }\r\n    }\r\n}\r\n\r\nsize_t start = 0;\r\nfind_if_apply(data,\r\n              [](const Blah& x) { return x.att != -1; },\r\n              [&start](const Blah& x) { start = x.idx; }\r\n              );\r\ncout << \"start \" << start << \"\\n\"; \/\/ print 5\r\n<\/code><\/pre>\n<p>Die Funktion find_if_apply nimmt zwei den Datensatz und zwei Funktionen. Die erste ist fuer find, und die zweite fuer apply.<br \/>\nAlso die template Funktion selbst ist wirklich \u00fcberraschend erstauling elegant einfach. Die Anwendung davon ist auch okay. Zwei einzeiler Funktionen sind noch lesbar.<\/p>\n<p>\u00dcbrigends, std::find_if alleine h\u00e4tte nichts geholfen. Da ein Iterator zurueck gegeben wird der wieder den Scope voll m\u00fcllt und manuell auf G\u00fcltigkeit gepr\u00fcft werden muss. Mit std::find_if w\u00e4re die Schleife und das if() weg gekapselt, aber gebracht h\u00e4tte es nichts.<\/p>\n<p>Noch eine Bemerkung: Die Variable idx in dem Beispiel ist explizit angegeben. \u00dcberwiegend kommt das in unseren Datenstrukturen und Algorithmen aber nicht vor. Dort ist die Position im Array der Index. Und schon funktioniert der funktionale Ansatz wieder nicht. Man k\u00f6nnte find_if_apply nat\u00fcrlich so erstellen und dokumentieren, dass das erste Argument der Lambdas der Laufindex ist. Aber nicht immer wird er auch in den Lambdas ben\u00f6tigt. Da mit Overloads und sonstige Tricks kommen macht alles wieder nur viel zu kompliziert. Noch dazu hat nicht jeder Container auch ein Laufindex. Bei Listen funktioniert es ist nicht, und da ist es dann Datenstruktur abh\u00e4ngig, wo der Index des Datums steht. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich habe gerade eine einfache Schleife mit 5 Zeilen geschrieben und auf einmal sah ich, dass das doch ein gutes Beispiel f\u00fcr funktionales programmieren w\u00e4re. Gegeben ist ein Datenvector mit custom Typ und gesucht ist ein bestimmtes Datum und, falls vorhanden, davon ein bestimmter Wert. Die Schleife l\u00e4sst sich von Hand so ausdr\u00fccken: struct Blah [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17],"class_list":["post-2912","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2912","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2912"}],"version-history":[{"count":6,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2912\/revisions"}],"predecessor-version":[{"id":2929,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2912\/revisions\/2929"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2912"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}