Vorstellung der Sprache C-mol - methodenorientierte Softwareentwicklung



  • HumeSikkins schrieb:

    Wenn du meinen Beitrag genau liest, wirst du feststellen, dass ich die DP-Lösung nicht mit C-mol in Verbindung gesetzt oder verglichen habe. Ich habe lediglich darauf hingewiesen, dass es auch in "klassischen" Sprachen wie C++ eine *saubere* Möglichkeit gibt, einen Pro- und Epilog *automatisch* ausführen zu lassen.

    Ack, die Moeglichkeit existiert natuerlich. Ich hatte nur herausgehoert, dass du sie auch bevorzugen wuerdest. Das ist dann eben eine Frage der Lesbarkeit...



  • das worauf ich (und vielleicht hume) hinaus wollten: gibt es einen triftigen grund, diese erweiterung herzunehmen? von c nach c++ hab ich klassen. das ist verdammt hart in c zu emulieren. dieses methoden-dings ist ja erwiesenermasen leicht zu emulieren.
    nochwas: bei mehrfach abgeleiteten klassen, bei denen eine virtuelle methode immer wieder gleich implementiert werden muss, ist ein konstruktionsfehler, denn dann muss die funktion doch nicht virtual sein. wäre sie virtual und als solche immer anders implementiert, so ist kein gewinn gegenüber c-mol, denn da müsste man auch alle medhoden neu definieren. sind nur teile der funktion gleich, so kann man diesen auslagern, und dann in der abgeleiteten methode einfach über die super-klasse ansprechen.

    ab und zu, gerade bei ablaufprogrammen (vgl. fliesband mit verpacker), könnte soetwas schon praktisch sein. aber wie gesagt: wie steht's mit der aufwand - nutzen - relation? brauhc ich einen neuen/erweiterten c++ compiler, eine schulung für mein team auf c-mol? oder sag ich ihnen in einer kurzen teambesprechung: so jungs, die funktionen müssen in ein DP Template geklatscht werden (und alle kennen sich aus)



  • @Korbian: Du hast recht: Auch wenn die Erweiterungen in manchen (speziellen) Fällen ganz nützlich sein können, aber das wiegt wohl nicht die Probleme, Fragen ... einer neuen Programmiersprache bzw. sogar Standards auf.



  • OK, Team A schreibt ein Programm. Jenny schreibt eine Klasse "Drehtuer", Peter eine Klasse "Drehstuhl". Beide implementieren HumeSikkins "Drehbar". Nun können instanzen beider Objekte wuderbar gedreht werden und arbeiten auch mit allem zusammen, was Drehbarkeit erfordert.

    Team B hat die selbe Aufgabe. Allerdings soll es das ganze MO implementiert sein. Auch hier gab es jemand, der schonmal was drehbares geschrieben hat.

    method Drehen (int grad) {
       void prolog ()
       {
          cout << "gleich wird gedreht\n"
       }
       void epilog ()
       {
          cout << "und das war's\n"
       }
       void <Rad> ()
       {
          ...
       }
    
    };
    

    Und jetzt will Elke etwas für ihre Drehtür und Bob etwas für seinen Drehstul. Was machen sie? Leiten Sie jeweils eine Methode auf? Sie können doch wohl kaum an der Originalmethode rumpfuschen.



  • wir waren uns ja schon einig, dass irgenwie kaum sinnvolle beispiele zu finden sind 🙂 du müsstest eher von einem prozeduralem programmtyp ausgehen. also so ne art fliesbandabarbeiter.



  • Genau das ist mein Problem. ICh finde keine Beispiele in meinen Problemen, wo ich die MO einsetzen kann. Das kann aber auch daran liegen, dass ich noch nicht MO denken kann.

    Oh und das mit den Mulithandlern hatte ich total falsch verstanden.

    cih dachte ein void<Foo, Bar>() könnte ich als Methode()°(foo, bar)() aufrufen und deshalb als dispatcher missbrauchen. Aber es heißt, das der eine Handle sowohl für Foo, als auch für Bar-objekte funktioniert.



  • @Heluim:
    Sicher könnten die beiden in dem Fall beide eine Methode aufleiten, was aber keine schöne Lösung wäre. Das wäre eine Art C++ Lösung, die man in C-mol geschrieben hat. Ist das Projekt methodenorientiert geplant worden, wäre eine Person mit der Entwicklung aller Drehroutinen und damit mit der Entwicklung der Dreh-Methode beauftragt. Somit wären eben alle gleichartigen Routinen bei einer Person.

    @Korbinian:
    Ja, es mag sein, dass die C-mol-Erweiterungen wirklich mit C++ leichter nachzubilden sind, als C++ mit C. Wobei es denke ich bei intensiver Nutzung von Methodenvererbung, etc. Mit der "Staffelung" der Prologe und Epiloge auch nicht mehr so ganz einfach werden dürfte. Allerdings (hatte ich ja schon mal angesprochen) liegt die Stärke eines Entwicklungssystems ja nicht nur in den Vorteilen der technischen Realisierung sondern vor allem auch darin, dass diese Vorteile automatisch entstehen, wenn man ein solches System anwendet.
    Zum Beispiel gibt es auch Möglichkeiten funktionale Progammieransätze in einer imperativen Sprache nachzubilden. Ich kann beispielsweise explizit bei der Entwicklung mit einer imperativen Sprache darauf achten (wie auch in der Funktionalen Programmierung), das Programmieren mit Seiteneffekten zu vermeiden. Allerings entsteht dieser Vorteil implizit, wenn ich das Programm gleich in einer funktionalen Sprache (wie z.B. Scheme) entwickle und "funktional" Denke.
    Mit anderen Worten: Verwende ich C-mol muss ich bei der Entwicklung nicht explizit verhindern, dass Coderedundanzen und Codestreuungen, etc. entstehen. Es kommt automatisch nicht vor, wenn ich methodenorientiert denke!

    Was den Umstand sich in eine Erweiterung/neue Sprache einzuarbeiten angeht:
    Da ist natürlich auch was dran. Aber ich denke mit C-mol ist es schon relativ einfach, die methodenorientierten Konzepte einzusetzen: Sowohl die Syntax wie auch die "semantischen" Regeln sind alle (fast) identisch wie in C++ und daher denke ich sehr "intuitiv" für C++ Programmierer anzuwenden.
    Außerdem kann man C-mol ja (wie gasagt) auch nur sehr gezielt einsetzen. Man kann ja trotzdem alle C++ Konstrukte verwenden und nur dort, wo es sinnvoll ist, methodenorientiert arbeiten. Der C-mol Compiler verarbeitet ja auch C++ Code oder man kann auch nur die methodenorientierten Module C-mol-compilieren.

    Aber allgemein ist es natürlich richtig, dass es geeignetere und ungeeignetere Probleme für C-mol gibt.

    @Bashar:
    Nein, ich denke CLOS ist eher eine "Objektorientierung für Lisp", oder?



  • SendKey schrieb:

    Mit anderen Worten: Verwende ich C-mol muss ich bei der Entwicklung nicht explizit verhindern, dass Coderedundanzen und Codestreuungen, etc. entstehen. Es kommt automatisch nicht vor, wenn ich methodenorientiert denke!

    das ist genau der punkt: c-mol nimmt mir den denkschritt ab, den ich bei c++ machen muss, nämlich das stete aufpassen, dass ich nicht sachen öfters schreibe, indem es mich ja permanent erinnert, generische sachen in den epi- und prolog zu klatschen. wenn man aber ein weitsichtiger programmierer ist, erkennt man gleiche sachen im voraus, und kann sie gleich zusammenfassen.

    Was ist z.b., wenn ich nicht nur einen pro- und epilog brauche, sondern auch zwischendurch einen abschnitt haben, der für alle zielklassen gleich ist. wie komme ich denn in c-mol weiter? muss ich dann 2 methoden definieren?

    Und eben nochmal zum hauptproblem: (Fast) jede gängige Programmiersprache(nerweiterung) hat einen "aufwand" legitimierenden grund, z.b. Java wenn ich plattformübergreifend schnell ein programm mit grafischer oberfläche haben will, pascal/c wenn ich nur prozedural arbeiten muss, etc.
    Bei c-mol ist das ganze so speziell, dass es kaum beispiele gibt, wo man es anwenden kann. wozu also diese spracheerweiterung lernen, wenn man sie eh pauschal gesagt nicht brauchen kann, man muss bei sowas immer den zeit/nutzen aufwand sehen: wieviel zeit brauche ich, um das konzept und die spracherweiterung drin zu haben, und was fuer einen nutzen hab ich davon.
    es wäre mir sehr geholfen, wenn du 2-3 beispiele bringen könntest, wo c-mol super reinpasst, und die aber auch häufige programmierprobleme/aufgaben sind.

    ps: noch was: ich wage zu behaupten, dass in dem drehbar beispiel die c++ variante sauberer und übersichtlicher ist.

    edit:

    SendKey schrieb:

    Ist das Projekt methodenorientiert geplant worden, wäre eine Person mit der Entwicklung aller Drehroutinen und damit mit der Entwicklung der Dreh-Methode beauftragt. Somit wären eben alle gleichartigen Routinen bei einer Person.

    uff. nimm mal ein projekt mit 100 klassen. dann muss ja der methodenentwickler alle 100 klassen im kopf haben! viel sinnvoller wäre es, wenn jeder entwickler den speziellen teil zu seiner klasse selbst zur verfügung stellt, und einer die generischen teile erstellt, und die speziellen nur durchsieht. das würde sich aber in gewisser weise nicht mit mo-entwicklung decken.



  • SendKey schrieb:

    @Bashar:
    Nein, ich denke CLOS ist eher eine "Objektorientierung für Lisp", oder?

    Naja, schon, aber ich meinte eher die Idee dahinter. Im Gegensatz zu den üblichen OO-Sprachen, in denen man eine Klasse definiert und ihr einen festen Satz Methoden spendiert, sind die beiden Aspekte in CLOS getrennt.
    Genau (anscheinend jedenfalls) wie in C-mol definiere ich die Methoden als zugehörig zu einer "generischen Funktion", etwa so:

    (defgeneric area (obj))
    
    (defmethod area ((obj circle))
      (* pi (square (radius obj))))
    
    (defmethod area ((obj square))
      (square (side obj)))
    
    (area (make-instance 'square :side 5))
    ==> 25
    

    Den Prologen und Epilogen entsprechen dabei :before bzw. :after-Methoden.

    (defmethod area :before ((obj square))
      (princ "Prolog von area (square)"))
    


  • Ich hab mich mit dem Konzept noch nicht beschäftigt, sondern nur diesen Thread gelesen. Dieser allerdings birgt für mich eine ganz wichtige Erkenntnis die Bashar gemacht hat: Er erkennt parallelen zu einem Sprachmittel einer anderen Sprache... Ich finde den Punkt insofern interessant, als das man dadurch vermuten könnte, dass sich hier ein (vl. umsteiger?) die Mühe gemacht hat ein ihm bekanntes Mittel nachzubilden, weil C++ ihm das nichtmehr bietet und er sich mit den restlichen Mitteln nicht auskennt? (nur so eine Theorie)

    Wenn ich mir den Thread hier so durchlesen, dann fällt mir ebenfalls auf, dass man wirklich nur mit ach und krach irgend ein Beispiel zusammenzimmern kann.. von was sinnvollem gar nicht zu reden.

    -junix



  • Korbinian schrieb:

    das ist genau der punkt: c-mol nimmt mir den denkschritt ab, den ich bei c++ machen muss, nämlich das stete aufpassen, dass ich nicht sachen öfters schreibe, indem es mich ja permanent erinnert, generische sachen in den epi- und prolog zu klatschen. wenn man aber ein weitsichtiger programmierer ist, erkennt man gleiche sachen im voraus, und kann sie gleich zusammenfassen.

    Ja, das ist in der Theorie richtig. In der Praxis meiner Meinung nach oft nicht richtig machbar.

    Korbinian schrieb:

    Was ist z.b., wenn ich nicht nur einen pro- und epilog brauche, sondern auch zwischendurch einen abschnitt haben, der für alle zielklassen gleich ist. wie komme ich denn in c-mol weiter? muss ich dann 2 methoden definieren?

    In diesem Fall sollte man entweder Multihandlings für die entsprechenden Klassengruppen definieren, oder mit Methodenvererbung arbeiten.

    Korbinian schrieb:

    Und eben nochmal zum hauptproblem: (Fast) jede gängige Programmiersprache(nerweiterung) hat einen "aufwand" legitimierenden grund, z.b. Java wenn ich plattformübergreifend schnell ein programm mit grafischer oberfläche haben will, pascal/c wenn ich nur prozedural arbeiten muss, etc.
    Bei c-mol ist das ganze so speziell, dass es kaum beispiele gibt, wo man es anwenden kann. wozu also diese spracheerweiterung lernen, wenn man sie eh pauschal gesagt nicht brauchen kann, man muss bei sowas immer den zeit/nutzen aufwand sehen: wieviel zeit brauche ich, um das konzept und die spracherweiterung drin zu haben, und was fuer einen nutzen hab ich davon.
    es wäre mir sehr geholfen, wenn du 2-3 beispiele bringen könntest, wo c-mol super reinpasst, und die aber auch häufige programmierprobleme/aufgaben sind.

    Gut, meiner Meinung nach hab ich ja schon versucht einige solcher Beispiele zu bringen. Allerdings wurden diese dann immer in C++ umgeschrieben. 🙂 Wie gesagt, meiner Meinung nach ist es nicht "natürlich" so zu arbeiten. Ist es nicht viel geschickter nach semantischen Gesichtspunkten zu entwickeln ohne große Gedanken an die technische Umsetzung zu verschwenden und der Rest entsteht durch das System "automatisch"? Eigentlich sollte das doch einfacher sein, als sich ständig darüber Gedanken machen zu müssen, wie ich überflüssige Mehrfachimplementierungen vermeide.

    Korbinian schrieb:

    ps: noch was: ich wage zu behaupten, dass in dem drehbar beispiel die c++ variante sauberer und übersichtlicher ist.

    Ich persönlich nicht, aber für mich greift hier das gleiche Argument wie obendrüber beschrieben. Wird eine Dreh-Methode entwickelt, so ergibt sich automatisch, was sinnvollerweise in Prolog und Epilog ausgelagert werden sollte. Es muss nicht explizit daran gedacht werden. Außerdem befasst sich dann auch ein Programmierer mit dem gleichen Typ von Routinen!

    Korbinian schrieb:

    uff. nimm mal ein projekt mit 100 klassen. dann muss ja der methodenentwickler alle 100 klassen im kopf haben! viel sinnvoller wäre es, wenn jeder entwickler den speziellen teil zu seiner klasse selbst zur verfügung stellt, und einer die generischen teile erstellt, und die speziellen nur durchsieht. das würde sich aber in gewisser weise nicht mit mo-entwicklung decken.

    Nein, eigentlich nicht, er muss nur die semantisch gleichartigen Teile der Klassen im Kopf haben; und auch nur die der Klassen, die von seiner Methode verarbeitet werden. So muss ein Programmierer beispielsweise nicht wissen, welche Dateihandles eine Klassengruppe besitzt, wenn er eine Dreh-Methode für die Klassen implementiert.
    Wohingegen der objektorientierte Programmierer sehr viel mehr von einer abgleiteten Klasse verstehen muss, wenn er alle verschiedene (abstrakte) Methoden implementieren will. Man trennt in der MOP eben nach "klassenübergreifenden Gemeinsamkeiten".

    Wenn in der OOP Programmierer Klassen ableiten um ihre speziellen Klassen zu implementieren, muss jeder Programmierer Ahnung von dem haben, was er implementieren soll. Das kann unter Umständen heißen, dass sich mehrere Programmierer damit beschäftigen müssen, wie man die Klasse in eine Datei schreibt, wie man sie dreht, wie man sie visualisiert, etc.
    In der Methodenorientierung hätte man einen Programmierer für jeden dieser Funktionalitäten. Der Programmierer, der sich um die Drehalgorithmik kümmert, muss keine Einblicke in die Klassenteile haben, die für das Drehen uninteressant sind. So sind die Gebiete der einzelnen Programmier sehr von einander getrennt, was weniger Schnittstellendefinitionen, etc. erfordert.



  • Seh ich das eigentlich mit der Formulierung der folgenden Maxime richtig:

    Cmol legt einfach nochmals ein Abstraktionslevel auf mein Klassensystem welcher es mir ermöglicht, für gleiche Aktionen mit unterschiedlichen Objekten die selbe Methode aufzurufen?

    -junix



  • @Bashar:
    Interessant! Also CLOS kannte ich vorher noch gar nicht. Habs mir halt nur mal kurz angesehn. Aber es scheint tatsächlich einiges an Übereinstimmung zu C-mol zu geben. Kann man diese "generischen" Areas auch vererben (wie in C-mol), so dass man die Prolog/Epilog-Idee (bzw. Before/After) auf höheren Abstraktionsebenen weiterführen kann?

    @junix:
    Wie gesagt: Ich dachte eigentlich ich hab schon ein paar ganz gute Beispiele angeboten. Natürlich ist es so, dass sich C-mol umso mehr lohnt, je größer das Projekt ist, aber ich hab hier ja auch schon ein paar Anwendungsfälle beschreiben. Nochmal der Verweis zu einer Übersicht, die die Anwendungsgebiete meiner Meinung nach recht gut zusammen fast:

    http://www.mosd.net/files/MOP-Overview.pdf



  • @junix:
    Ich würde nicht unbedingt sagen, dass es ein Abstraktionslevel auf das Klassensystem legt. Ich würde aus Sicht eines Objektorienierers eher sagen, die MOP stellt eine Art "Querverstrebung in der Klassenhierarchie" dar!

    Ansonsten ja: Es werden sonst gleichartige Aktionen auf verschiedene (sich in einer Klassenhierarchie befindende) Klassen verteilt. Mit C-mol werden solche gleichartigen Aktionen in einer Methode zentralisiert.



  • Wenn ich mir dieses Paper so ansehe, dann bekomme ich immer mehr den Eindruck hier will sich jemand u die Design-Phase der Applikation drücken und die gute alte VHT-Programmierung (Vom Hirn ins Terminal)wieder aufleben lassen... Bei dem in dem von dir erwähnten Paper beispiel wäre für mich eigentlich der Schritt zu einer CDrawableObject-Basisklasse von Vornherein logisch...

    -junix



  • SendKey schrieb:

    Ansonsten ja: Es werden sonst gleichartige Aktionen auf verschiedene (sich in einer Klassenhierarchie befindende) Klassen verteilt. Mit C-mol werden solche gleichartigen Aktionen in einer Methode zentralisiert.

    Aber worin liegt da der Sinn? Letzendlich muss ich ebenso in meiner KLasse eine Paint-Methode bereitstellen, die von der zentralen Methode aufgerufen werden kann.

    -junix



  • Wieso wird jetzt auf einmal auch noch die imperative Programmierung eingebracht? Bis auf in der Assemblerprogrammierung ist die doch total in vergessenheit geraten.

    In der prozeduralen Programmierung konnte ich einfach Module anderer Projekte nehmen und die dort definierten Prozeduren im neuen Projekt weiterverwenden. Das war kein Problem, da es nur einen kleinen Satz fest definierter Typen gab.

    In der OOP hat man diesen Vorteil ebenfalls. Mann kann Klassen aus alten PRojekten problemlos weiterverwenden und sogar durch Ableitungen an neue, spezielle Situationen anpassen. Man baut den Vorteil also sgar weiter aus.

    Die MOP macht das ganze jetzt zu nichte. Eine Methode ist für einen festen Satz an Typen definiert und das war's. Habe ich ein ähnliches Problem in einem neuen Projekt darf ich alles neu Entwickeln. Auch wenn ich innerhalb dieser Entwicklung wenig Redundanzen habe ist die neuentwicklung an sich kaum zumutbar. Diese Erkenntnisse habe ich jeden Falls aus dem Drehbar-Beispiel gezogen.

    Gibt es einen festen Satz an Typen bzw. Klassen, der sich garantiert nicht erweitert ist die MOP ganz groß. Sollte es sich aber um eine Klassenhirachie handeln, die, sei es auch nur gelegentlich, erweitert wird, ist die MOP (um's ganz krass aus zu drücken) für'n Arsch.



  • @Heluim:
    Sicher könnten die beiden in dem Fall beide eine Methode aufleiten, was aber keine schöne Lösung wäre. Das wäre eine Art C++ Lösung, die man in C-mol geschrieben hat. Ist das Projekt methodenorientiert geplant worden, wäre eine Person mit der Entwicklung aller Drehroutinen und damit mit der Entwicklung der Dreh-Methode beauftragt. Somit wären eben alle gleichartigen Routinen bei einer Person.

    Ja, aber es gibt viel öfter Projekte, die Teile alter Projekte wiederverwenden wollen. Und genau das verhindert die MO.

    Sowohl die Syntax wie auch die "semantischen" Regeln sind alle (fast) identisch wie in C++ und daher denke ich sehr "intuitiv" für C++ Programmierer anzuwenden.

    Mich stört das Semikolon nach Methoden unheimlich. Was soll das da? Das wirkt irgendwie falsch. Ich bin es gewohnt, das Semikolons da sind, wo ich sie brauche. Hinter class steht eins, weil ich direkt Objekte instanzieren kann. Hinter Funktionen steht keins, weil es keinen Sinn machen wüde. Hinter Methoden steht eins, obwohl es keinen Sinn macht.

    Was ist z.b., wenn ich nicht nur einen pro- und epilog brauche, sondern auch zwischendurch einen abschnitt haben, der für alle zielklassen gleich ist. wie komme ich denn in c-mol weiter? muss ich dann 2 methoden definieren?

    Schon komplett die alten Ansätze verdrängt und Komplett auf MO umgestiegen? Schreib dir 'ne Funktion, die von der Methode verwendet wird. Vielleicht wäre es nett, wenn man innerhalb von Methoden Funktionen definieren könnte, die dann privat sind, und nur dazu dienen besser strukturieren zu können und Redundanzen zu vermeiden.



  • Was fehlt sind erweiterbare Methoden. Jemand definiert eine Methode mit Pro- und Epilog und den von mir im letzten Posting und von Korbinian geforderten privaten Funktionen und jeder kann für seine Klasse neu Handlings definieren.

    methode Foo () {
       Foo () 
       { ... }
       ~Foo () 
       { ... }
    
       // Klasse, von der man bereits weiß, das sie behandelt werden muss
       void <Bar> ()
       {
       }
    private:
       int helper_function ()
       { ... }
    };
    
    // Später jemand anders, der mein ein Baz sollte ebenfalls behandelt werden:
    
    handle Foo::<Baz>()
    { ... }
    

    So könnte man Redundanzen vermeiden.



  • SendKey schrieb:

    @Bashar:
    Kann man diese "generischen" Areas auch vererben (wie in C-mol), so dass man die Prolog/Epilog-Idee (bzw. Before/After) auf höheren Abstraktionsebenen weiterführen kann?

    Hm, wie genau meinst du das? Ich hab mich wie gesagt mit C-mol aus Zeitgründen noch nicht befasst ... vielleicht kann ich die Frage in ein paar Tagen beantworten.

    Helium schrieb:

    Wieso wird jetzt auf einmal auch noch die imperative Programmierung eingebracht? Bis auf in der Assemblerprogrammierung ist die doch total in vergessenheit geraten.

    C++ ist eine imperative Sprache.


Anmelden zum Antworten