Einführung der funktionalen Programmierung in Ihre Entwicklungsumgebung [geschlossen]


15

Dies ist eine lange Geschichte, aber ich werde versuchen, sie so gut wie möglich zusammenzufassen. Wir sind ein .NET-Shop, der Software für verschiedene Arten von Fonds schreibt. Zum Beispiel schreiben wir Software für das Management von gesundheitsbezogenen Angaben, Software für das Rentenmanagement, 401 (k) -Software und einige andere finanzielle Dinge.

Jetzt betreten wir ein neues Gebiet: Derivate und quantitative Analysen, was sehr aufregend erscheint. Dies ist etwas, das in den nächsten 8-12 Monaten herunterkommt, wie mir gesagt wurde.

Jetzt habe ich einige Funktionen selbst gelernt, hauptsächlich oberflächliche Einblicke in verschiedene Sprachen über dieses Buch , habe mich aber nie wirklich damit befasst. Nun, da wir ein .NET-Shop sind, dachte ich, dass F # eine gute Wahl sein könnte, da wir möglicherweise einige .NET-Bibliotheken und vorhandenes Wissen nutzen könnten.

Meine Frage ist, wo ich anfangen soll? Es fällt mir außerordentlich schwer, herauszufinden, ob ich mit Haskell, Erlang, Scala, F # usw. zusammenarbeiten soll. Sie scheinen alle sehr interessant und kompetent zu sein, und offen gesagt ist dies eine gute Chance, um auszubrechen, wenn ich von Microsoft abhängig bin.

Hat jemand eine ähnliche Situation gehabt? Wenn ja, welche Erfahrungen haben Sie gemacht, um den Sprung in die funktionale Welt zu schaffen, und was haben Sie gewählt und warum? Ich weiß, dass dies eine große Frage ist, aber ich kenne keine Entwickler, die derzeit funktionale Methoden verwenden. Ich kann mich also nur ununterbrochen mit Googeln beschäftigen und überall Flammenkriege in der besten funktionalen Sprache finden.


Empfohlene Lektüre: Wo soll
Mücke

Antworten:


14

Prototyp, Prototyp, Prototyp! Nehmen Sie ein Stück Business-Funktionalität, das Ihrer Meinung nach eine funktionale Programmierung erfordert, und probieren Sie die verschiedenen Sprachen aus, um zu sehen, ob sie Ihnen wirklich die gewünschten Vorteile und die gewünschte Interoperabilität bieten.


Guter Rat und ich werde es beachten, in der Tat mache ich gerade eine Erlang-Installation, um es auszuprobieren.
Nodey The Node Guy

10

Die erste Frage, die Sie wirklich beantworten müssen, ist, warum Sie überlegen, eine funktionale Sprache zu verwenden. Wenn Sie einen geschäftlichen Grund für den Wechsel nicht rechtfertigen können, sollten Sie dies nicht tun. Mit anderen Worten, es ist definitiv ein Fehler, ein neues Framework, eine neue Sprache oder eine andere neue Technologie in Ihre Arbeitsumgebung einführen zu wollen, nur weil Sie es lernen möchten oder weil es so aussieht, als wäre es das nächste "coole" Ding. Sie müssen sich also zuerst ehrlich fragen, was die Motivation ist.

Wenn Sie wirklich das Gefühl haben, eine funktionale Sprache zu benötigen, um ein bestimmtes Problem zu lösen, und davon ausgehen, dass die meisten gängigen funktionalen Sprachen Ihren Anforderungen entsprechen, würde ich mich für die ausgereifteste und diejenige mit der größten Benutzergemeinschaft entscheiden. Erlang ist eine gute Wahl und erfüllt beide Anforderungen. In einer reinen MS / .NET-Umgebung kann ich jedoch die Verwendung von F # verstehen.


2
@ennukiller - Ich kann definitiv erkennen, dass funktionale Programmierung eine gute Wahl für uns wäre und ich werde nicht lügen. Ich würde sie auch gerne nur für die bloße intellektuelle Anregung verwenden, die sie bieten wird. Wir werden eine Menge Berechnungen durchführen und ich möchte die Vorteile von Multi-Core nutzen. Außerdem ist es unerlässlich, dass jede mathematische Funktion als richtig erwiesen wird. Ich verstehe, dass dies mit funktional einfacher sein kann.
Nodey The Node Guy

2
Wenn Sie Beweise benötigen, ist reine Funktionsprogrammierung am besten. Einige Vorschläge hier sind für funktionale Add-Ons zu imperativen Sprachen gedacht - sie sind möglicherweise vertrauter, geben Ihnen jedoch keinen nachweislich korrekten Code. Bei Vorhandensein von Nebenwirkungen können Sie nicht die Tatsache verwenden, dass x = x ("referentielle Transparenz"), und Sie müssen nachweisen, dass das x später im Code immer noch den gleichen Wert wie zuvor hat. In einigen Sprachen kann es zum Beispiel vorkommen, dass x:=3; y:=10; x:=add(x,x);sich ein xWert von nicht 6 und ein yWert von nicht 10 ergibt. Es ist in diesem Zusammenhang nicht praktikabel, die Richtigkeit Ihrer Funktionen zu beweisen.
AndrewC

9

Ich würde F # für einen Shop mit einer vorhandenen .Net-Codebasis genau so zustimmen wie Scala für einen Shop mit einer vorhandenen Java-Codebasis.

Funktionale Programmierung ist ein Werkzeug wie jedes andere. Gut eingesetzt und in die Art und Weise integriert, in der Sie bereits Code entwickeln, können Sie produktiver arbeiten, indem Sie einfacher über die Funktionsweise Ihres Codes nachdenken. Das Wechseln der Sprache ist jedoch alles andere als kostenlos. Daher ist Ihre beste Wahl eine Lösung, mit der Sie so lange wie möglich Ihren vorhandenen Code für den Übergang verwenden können. Der sicherste Weg, eine neue Sprache nicht in Ihre Umgebung einzuführen, besteht schließlich darin, Ihren Mitarbeitern mitzuteilen, dass sie alles, was sie bisher haben, neu schreiben müssen, um die Vorteile einer Änderung zu erkennen, die zu diesem Zeitpunkt Sie versuchen immer noch, sie weiter zu verkaufen.


7

Ich würde empfehlen, mit der funktionalen Programmierung zu beginnen, ohne gleich eine neue Sprache zu lernen. Es macht es nur schwieriger, wenn Sie versuchen, ein neues Paradigma zu erlernen, während Sie gleichzeitig versuchen, die Syntax einer neuen Sprache in den Griff zu bekommen.

Natürlich haben Sprachen, die speziell für die funktionale Programmierung entwickelt wurden, einige Vorteile (z. B. bestimmte Konstrukte wie das Verstehen und die standardmäßige Unveränderbarkeit von Datenstrukturen). Im Allgemeinen besteht der größte Schritt jedoch darin, Ihr Denken in ein funktionales zu ändern Stil. C # ist großartig dafür.

Grundsätzlich hören Sie einfach auf, den Status Ihres Codes zu ändern. Ich habe das mit Java gemacht und mit C # ist es noch einfacher, weil Sie Lambdas haben. Sobald Sie den Dreh raus haben und ein Gefühl dafür haben, wofür es gut ist, wird es sehr einfach sein, eine funktionierende Sprache zu erlernen (unabhängig davon, ob Sie F # oder Erlang wählen) und damit immens produktiv zu sein.


1
+1: Ich stimme dir zu. Ich habe auch angefangen, in Java und C ++ in einem funktionaleren Stil zu programmieren (unter Verwendung von finalen und const-Variablen, Aufbrechen komplexer Operationen unter Verwendung von Funktionskomposition usw.). Ich denke, dies hat definitiv meinen Programmierstil in Java und C ++ verbessert. Nach einer Weile, wenn man sich bereit fühlt, weiter zu gehen, kann man eine funktionale Sprache ausprobieren (Haskell, Ocaml, SML, Lisp, Scala, F # usw.)
Giorgio

1

Wenn Sie nur die Funktionsprogrammierung erlernen und verstehen möchten, installieren Sie IronPython und konzentrieren Sie sich auf die Funktionsmerkmale in Python. Im schlimmsten Fall lernen Sie ein Tool kennen, das in C # integriert werden kann, um die Anzahl der Codezeilen in einer Anwendung zu verringern und Ihnen zu helfen, fehlerfreiere Produkte vorzeitig bereitzustellen.

Schauen Sie sich DaBeaz 'Präsentationen über Generatoren an, um zu sehen, wie funktionale Ansätze in Python komplexe Dinge vereinfachen können. Http://www.dabeaz.com/generators/

Abgesehen davon denke ich, dass Sie klug wären, etwas Zeit bei Scala zu investieren. Es läuft auf .NET im Beta-Modus, sodass Sie es installieren und heute zu Lernzwecken verwenden können. Ab Herbst wird es für .NET im Release-Modus sein. Dies bedeutet, dass Sie Code in Scala schreiben können, der in JVM und .NET portierbar ist. Und da Scala auf Actors und Message Passing basiert, ist es sehr, sehr einfach, eine Anwendung zu erstellen, die aus mehreren separaten Programmen besteht, die auf mehreren separaten Computern ausgeführt werden. Wenn Sie der Mischung die .NET / JVM-Portabilität hinzufügen, muss ein weiterer Aspekt berücksichtigt werden. Sie könnten eine Anwendung haben, die sowohl Java-Bibliotheken von Drittanbietern als auch .NET-Bibliotheken von Drittanbietern nutzt, ohne mit der Entwicklung von Protokollen herumzuspielen, damit diese kommunizieren. Beide Prozesse würden in Scala geschrieben, und würde Scala Remote Messaging (Remote Actors) verwenden, um zu kommunizieren. Schauen Sie sich die Akka-Bibliothek an, die, wie es scheint, irgendwann Teil der Standardbibliothek von Scala werden wird, gemessen an den Aktivitäten von Typesafe.com.


+1: Um Scala und seine Verfügbarkeit auf verschiedenen Plattformen zu erwähnen. Frage: wird akka die aktuelle schauspielerimplementierung in scala ersetzen? Oder werden die beiden nebeneinander existieren?
Giorgio

Ich bin nicht sicher, ob Akka bald die derzeitigen Scala-Schauspieler ersetzen wird, aber der Scala-Schöpfer Martin Odersky hat sich mit dem Akka-Schöpfer Jonas Boner der Firma Typesafe angeschlossen. Sie fördern Scala mit Akka und jetzt mit dem Play-Framework. Es ist also wahrscheinlich, dass der Schwerpunkt der Entwicklung auf Akka liegen wird. Wenn Sie mit Scala nur Schauspieler lernen, sollten Sie sich zuerst auf Akka konzentrieren.
Michael Dillon

Vielen Dank für die Informationen! Ich habe mir die Schauspieler in Scala angesehen, aber bisher nur sehr oberflächlich.
Giorgio

-1

Ich stimme mit dem Hauptgedanken der akzeptierten Antwort überein, und da Sie sich im Grunde genommen mit Erlang beschäftigen, klingt es so, als hätten Sie wahrscheinlich ein ziemlich gutes Verständnis dafür, wie Sie lernen, und brauchen nur einen kleinen Schubs in der richtigen Richtung Richtung, so klar, es war eine gute Antwort für Sie ... Aber ich denke, ich würde die Frage ein wenig anders angehen, da ich sehe, dass diese Antwort mir überhaupt nicht viel geholfen hätte; Ich codiere immer, um zu lernen! Also, hier sind meine Gedanken ...

(Übrigens neige ich dazu, detaillierter zu arbeiten, beispielsweise für Kapitel in einem Buch, und ich bin mir sicher, dass ich meine Instinkte hier nicht vollständig unterdrücken kann , aber ich werde es anders versuchen; ich bin es Ich werde hier nur meine Gedanken zusammenfassen und für den Fall, dass jemand mehr Details zu irgendetwas möchte oder meint, dass etwas, das ich sage, in diesem Format irreführend ist, werde ich mein Bestes tun, um mich daran zu erinnern, die Antworterinnerungen durchzugehen ...)

Um zu versuchen, mich auf dem Laufenden zu halten, verstehe ich die Stoßfragen, die im OP gestellt werden. Ich werde mich auf ein Minimum beschränken, um das zu erklären.

Zuerst die schnellen Antworten:

befand ich mich in einer ähnlichen situation? Zumindest war es ähnlich; Ich war in leitender Position bei vielen verschiedenen Projekten, die nichtsdestotrotz miteinander zu tun hatten ... (CRM / Web / DB / Datenintegration / etc.)

Wie / warum habe ich den Sprung zu funktional gemacht? " Ich sah einige LINQ-Beispiele und obwohl ich definitiv von einer Art integrierter, statisch typisierter Abfragesprache geträumt hatte [da ich hauptsächlich statisch typisierte Sprachen (hauptsächlich C ++ und später C #) verwendet hatte )] während meiner gesamten Karriere ... Aber es war eine ziemlich schnelle Umgebung, in der ich mich befand, und obwohl ich es oft geschafft hatte, zu sehen, was in der Vergangenheit auf mich zukam, hatte ich es nie wirklich durchdacht, so dass ich es nie vorhergesehen hatte Genauso einfach könnte / würde ich Operationen an einfachen alten Objekten zulassen (lol!). Als ich es sah, wusste ich, dass ich es haben musste. Das ist das Warum und der Beginn des Wie: Ich habe mich darauf konzentriert, LINQ zu verstehen .

Vier Gedanken ... ähm, nein, das ist nicht richtig ... Vorüberlegungen

Wenn ich Martijn Verburgs Antwort lese , fällt mir die Erwähnung der Geschäftsfunktionalität sofort ein, Code für alles, woran ich arbeite, zu implementieren Ich bin mir nicht sicher, ob ich irgendetwas direkt für die Arbeit (oder die bevorstehende Arbeit) hatte, das mir die Aufregung / Leidenschaft gegeben hätte, die Sie meiner Meinung nach für die ersten Probleme haben sollten, mit denen Sie sich befassen ...

Ich war fast ausschließlich in statisch getippten Sprachen verankert + OOP-Metaphern und -Muster + was auch immer ich versehentlich mein Gehirn umwickelte, während ich meine tatsächlichen Probleme über die Jahre hinweg löste ... Wenn du überhaupt so bist wie ich, Sie haben wahrscheinlich viel Gehirn für Dinge, die Ihnen mit LINQ / FP nicht so viel helfen.

Ich denke, es ist ein bisschen wie reine prozedurale vs. OO-Programmierung: Es gibt eine Menge prozeduraler Dinge, die Sie in OOP verwenden werden, aber diejenigen, die von C ++ zu C ++ kommen, ohne dass grok / ken / "get" OO zur Priorität gemacht wird am Ende sehr, sehr schlecht in C ++. Tatsächlich habe ich verdammt viele (15+) langjährige Firmware- und Gerätetreiberentwickler interviewt, die wirklich dachten, sie kannten C ++, aber höchstens ein schrecklich grundlegendes / lehrbuchartiges Verständnis von C ++ hatten, mit praktisch keinem Verständnis von oder Erfahrung mit OOP - weil sie OOP nie wirklich gemacht haben ... Sie haben Singleton-Mehrzweckklassen mit statischen Elementen und statischen Funktionen mit einer gewissen Anzahl von nicht-statischen / nicht-singleton-Klassen geschrieben, die als Strukturen verwendet wurden.

Und FP hat einige (für diejenigen, die sich nicht mit dem Paradigma auseinandersetzen) Konzepte und andere Dinge, die damit einhergehen, und obwohl ich festgestellt habe, dass die Hybridisierung vieler Techniken für mich ideal ist, verstehe ich mehr und Je mehr Zeit vergeht, desto begrenzter war mein Denken, bevor ich echte funktionale Fähigkeiten in mein Toolset einbaute. In der Vergangenheit war es mir gelungen, viele Dinge auf eine Art und Weise umzusetzen, die ein bisschen kreativer war als die der meisten OO-Programmierer, aber wenn ich die Konzepte verwende, war mein Denken vorrangig ... Es gibt ganze Klassen von Problemen, die gelöst werden können in ein paar Zeilen, die in C ++ / C # eine Menge Arbeit gekostet haben.

plötzlich findest du dich ...

In einem "zu langen" Beitrag

Sie befinden sich in einem Labyrinth verdrehter "nicht gelesen" s, alle gleich.

Sie sehen in naher Zukunft eine Telefonkonferenz, die sich rasch nähert.
> knapp
Uhhuh. Sicher. Okay, wir werden sagen, der "knappe" Modus ist "an".

Sie sehen in naher Zukunft eine Telefonkonferenz, die sich rasch nähert.
> was soll das heißen
Ich sag bloß'. Musstest du heute morgen nichts tun?

Sie sehen in naher Zukunft eine Telefonkonferenz, die sich rasch nähert. 
> Hey, ist das ein Greuel hinter dir?
Was!? WO?! [rennt schreiend weg]

> Entschuldigung, ich habe nicht verstanden, WAS WO, umformulieren?
[rennt weiter und schreit, Sarkasmus unbemerkt]

Also ... Was soll ich lernen, liebe PSE, liebe PSE?

Ich persönlich habe in C # mit LINQ angefangen. Es erlaubte mir, ein paar Konzepte gleichzeitig vorzustellen, und während ich ständig über FP und seine Konzepte und mehr über LINQ und die Beziehung zwischen den beiden las, gab es mir einen Weg nach vorne, während ich noch produktiv arbeitete. Ich fügte einige Dinge gleichzeitig hinzu, die Datenabfragen wurden schnell zu einem nützlichen Werkzeug für mich, ohne dass ich eine Tonne verstehen musste.

Wenn ich jetzt zurückblicke, wünschte ich mir, ich könnte mein nächstes Projekt (etwa ein Jahr später in Angriff genommen) zuerst durchführen. Ich habe mich einigermaßen mit F # vertraut gemacht (was mir übrigens einen großen Vorsprung beim Erlernen von ML (Metasprache) und anderen Derivaten (z. B. auch OCaml ) verschafft hat .)

Grundsätzlich denke ich, dass eine anständige Antwort auf das, was 'davon abhängt, ein gutes Paar von Programmierproblemen zu finden, das Sie interessiert, aber natürlich muss es mit ein bisschen FP gepaart werden, das Sie lernen möchten ... (und Sie können spülen / Wiederholen / Aufschäumen, nachdem Sie etwas von der Liste gestrichen haben ...) Und natürlich lernen Sie am Ende immer etwas mehr als die Hauptsache, die Sie sich vorgenommen haben. Zuerst machte ich ein paar kleine Schritte, aber dann machte ich größere Dinge und ließ die kleineren Dinge an ihren Platz fallen, während ich diese machte.

Was schwimmt zuerst auf Ihrem Boot? Besonders am Anfang ist es am besten, etwas Spaßiges und Aufregendes (für Sie) zu haben, und das wird Ihr Interesse so hoch halten, dass es sich für Sie lohnt. Also, IOW-Probleme, an denen gearbeitet werden muss, und Techniken, die diese Probleme angehen ... Zuerst werden LINQ- und Inline-Daten für mich abgefragt. Rekursion war eine andere für mich, einschließlich Schwanzrekursion, ich grabe das GodelEscherBach-ness davon; und ich hatte über Schwanzrekursion gelesen. Ungefähr zu dieser Zeit wurden die Dinge, an denen ich arbeitete, auf Eis gelegt und ich hatte einen großen Zeitblock, so dass ich noch eine ganze Weile dranbleiben konnte. Mit weniger Unterbrechungen war es einfacher, aber weil ich Dinge auswählte, die mir Spaß machten, war es auch bei Arbeitsunterbrechungen nicht allzu schwer. :)

Und obwohl ich nichts Cooles gefunden habe, kann ich Ihnen von einem selbstbewussten Krebs-Programm erzählen, aber ich habe es geschafft, ziemlich gut darin zu werden.

Und ... Womit soll ich es lernen, liebe PSE, liebe PSE, womit?

Zu diesem Zweck verwendete ich verschiedene Algorithmen, an denen ich mich sowieso gerade interessierte, und verschiedene Dinge, an denen ich mich fragte, ob Sie F # können, und wenn mir die Ideen ausgehen, ging ich gegen 99 Flaschen Bier und das Projekt Euler vor Probleme ...

Ich bin sicher, Sie können viele Dinge finden, die Sie interessieren, für die FP relevant ist. Es bietet alles, von Verbesserungen bis hin zu OOP, mit denen Sie die Dinge etwas prägnanter formulieren können, bis hin zu einer Form, die Sie nicht erkennen und wahrscheinlich nicht einmal das mentale Modell hatten, das Sie ausdrücken können Vor.

Aber ... da ist ein Loch in meinem Modell, liebe PSE, ein Loch ...

Und aus diesem Grund ist es wichtig, dass Sie sich vor allem zu Beginn, aber wirklich während Ihrer gesamten Lernzeit (und ist es nicht immer wahr, wenn Sie etwas lernen?) Zwischen den Problemen zumindest ein wenig Zeit lassen, um Dinge zu lesen, die nichts miteinander zu tun haben noch FP und Zeit zum Lesen des von Experten geschriebenen Quellcodes, vorzugsweise zur Lösung gleicher oder ähnlicher Probleme; sowie ihre Erklärungen der Dinge ...

Und die ganze Zeit musst du dein Gehirn anstrengen, um alles zu verstehen, nicht aus deiner alten Perspektive, sondern aus FP selbst ... Irgendwann hat es für mich geklickt und ... das, was ich am besten beschreiben kann das Niederländisch wird mehr oder weniger fließend; Irgendwann habe ich es geschafft, mich ausreichend in die Denkweise einzubringen (ich habe es durch Eintauchen gemacht, was im Grunde das ist, was ich hier beschrieben habe).

Und schließlich tat ich es; Es gelang mir, alles zu verinnerlichen und mein Gehirn herumzudrehen, bis FP / LINQ herauskam, ohne dass ich mich auch nur anstrengen musste, um es wieder in OOP zu übersetzen. (Ja, das habe ich getan. Ich musste etwas haben, an das ich meinen Rock hängen konnte. Hut. Wie auch immer.)

Abschließende Gedanken...

Meine Güte, es scheint, Sie verlieren Ihre Fähigkeit, sich Ihre Unterschrift klug vorzustellen
Abschnittsüberschriften. Schade.

Die Telefonkonferenz rückt immer noch rasch näher. Es erscheint jetzt viel größer.
> ja, ja, na ja .. kurz und bündig. Wie ich sehe, hast du es geschafft, diese Grauen zu verlieren.
 Anruf schließen, dass ... nun ja, ich bin ter ... OH NEIN ES IST ZURÜCK!
AAAAAAAHHHHHH !! [rennt schreiend davon]

Die Telefonkonferenz rückt immer noch rasch näher.
Es ähnelt irgendwie Sir Lancyjohn Cleezewiz.
Es ist fast an dir.
> Hey, beeil dich zurück! Ich habe ein Experiment mit dir zu versuchen! (und ein Po-Ta-To)

Natürlich finden Sie im Internet eine Fülle von Informationen zu FP. Hauptsache ist, grundlegende Konzepte zu verstehen und dann zu lernen, sie anzuwenden. Erfahren Sie zum Beispiel, warum Unveränderlichkeit für FP wichtig / nützlich ist. Ich empfehle dringend, ein wenig Theorie zu lernen, um zu allem beizutragen, zum Beispiel, wie reines FP für formale Beweise viel zugänglicher ist. Dies war eine treibende Kraft hinter dem Vorfahren von F #, ML. YMMV natürlich magst du jemand sein, dem die Tränen langweilen. In diesem Fall gibt es viele Beispiele, viele Versuche und Irrtümer, um genau zu sehen, warum die verwendeten Techniken so sind, wie sie sind. Moment der Glühbirne.

Also lasse ich es erstmal dabei. Hoffe, dass dies für jemanden von Nutzen ist. Ich wollte ein bisschen mehr über bestimmte Dinge lernen, aber im Moment habe ich keine Zeit mehr. Ich hoffe, dass ich bald etwas Zeit finde, um darauf zurückzukommen, obwohl es eine lange Woche für mich sein wird, also wird es wahrscheinlich zumindest das Wochenende sein.

<3 "Einführung von GRUEBOL, eine Lücke; nur bis SnozzML fertig ist. Es sollte bald sein; diesmal hat mir ein riesiges Komitee geholfen." - Grace Hopperwit Egghead, Berühmte letzte Worte , XX97 GUE <3


Was ist "Liebes SO"?
gnat

war lieber Stapelüberlauf; soll der Trittfrequenz des Liedes 'Da ist ein Loch im Eimer' entsprechen xD
shelleybutterfly

wenn Gesendete außerhalb von SO, dies scheint Ihre Punkte schwieriger zu verstehen - zu prüfen , bearbeiten für das zur Rechenschaft ing
gnat

derp! ja in der Tat getan haben. Tyvm. :)
Shelleybutterfly

Wenn jemand Vorschläge hat, wie ich meine Antwort verbessern kann, würde ich es begrüßen. War es schlechter Humor? oder schlechter rat? Es basiert auf meiner Erfahrung und ich ändere es gerne, wenn ich es nützlicher machen kann. danke;)
Shelleybutterfly
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.