NG Programmiersprache?



  • SideWinder schrieb:

    Das mit Spring musst du mir jetzt aber erklären, habe gerade ein Projekt mit Spring hinter mir und kann es bis jetzt nur empfehlen. Wobei hier auch weit nicht alle Teile des Frameworks eingesetzt wurden.

    http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12



  • Mr. N schrieb:

    Im Ernst, was ist "gute" und was ist "böse" Abstraktion? Das musst du mir erläutern, fürchte ich.

    Ich bevorzuge da Sachen, die weniger abstrakt als Rekursion sind.

    summe=0
    foreach i in xs
      summe+=i
    

    Manchmal (besonders wenn man Hochschulprofessor ist) baut man auch mal was rekursiv.

    fib 0 = 0
    fib 1 = 1
    fib n = fib (n-1) + fib (n-2)
    

    Gute Abstraktion. Jetzt steht das Zeug auch recht hübsch und übersichtlich da.

    Aber dann kommt einer, dem ist das doch nicht abstrakt genug, denn man kann ja noch fast den erzeugten Code erahnen, und er baut

    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
    

    Böse Abstraktion.





  • volkard schrieb:

    Manchmal (besonders wenn man Hochschulprofessor ist) baut man auch mal was rekursiv.

    fib 0 = 0
    fib 1 = 1
    fib n = fib (n-1) + fib (n-2)
    

    Gute Abstraktion. Jetzt steht das Zeug auch recht hübsch und übersichtlich da.

    Aber dann kommt einer, dem ist das doch nicht abstrakt genug, denn man kann ja noch fast den erzeugten Code erahnen, und er baut

    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
    

    Böse Abstraktion.

    Das zweite ist natürlich performanter, wenn man die ganze Liste will.

    Wobei ich - bitte nicht glauben, dass ich den Code hübsch fände - da noch eins draufsetzen kann:

    fix $ ([0,1] ++) . (zipWith (+) <*> tail)
    


  • Zeus schrieb:

    @SideWinder
    Ein kleiner Überblick über Nano:
    [...]

    Vielen Dank, hast du die Zusammenfassung extra für mich gemacht oder erst gestern ins Repository hochgeladen? 🙂

    Bin von einigen Dingen begeistert, aber bspw. die Begrenzung auf Rekursion als einzig iteratives Element will ich nicht wahrhaben 😃

    MfG SideWinder



  • Mr. N schrieb:

    volkard schrieb:

    Manchmal (besonders wenn man Hochschulprofessor ist) baut man auch mal was rekursiv.

    fib 0 = 0
    fib 1 = 1
    fib n = fib (n-1) + fib (n-2)
    

    Gute Abstraktion. Jetzt steht das Zeug auch recht hübsch und übersichtlich da.

    Aber dann kommt einer, dem ist das doch nicht abstrakt genug, denn man kann ja noch fast den erzeugten Code erahnen, und er baut

    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
    

    Böse Abstraktion.

    Das zweite ist natürlich performanter, wenn man die ganze Liste will.

    Warum soll das performanter sein?



  • SideWinder schrieb:

    Vielen Dank, hast du die Zusammenfassung extra für mich gemacht oder erst gestern ins Repository hochgeladen? 🙂

    Ich hab sie auf Anfrage für dich und alle Lauscher gemacht 😉

    SideWinder schrieb:

    Bin von einigen Dingen begeistert, aber bspw. die Begrenzung auf Rekursion als einzig iteratives Element will ich nicht wahrhaben 😃
    MfG SideWinder

    Yo mal sehen 🙂



  • nachfrager schrieb:

    Warum soll das performanter sein?

    Weil die Fibonacci-Zahlen nicht immer wieder berechnet werden. Wenn du fib 4 rekursiv berechnest, berechnest du fib 1, fib 2, fib 3 und fib 4 immer auch (bei der naiven Rekursion sogar teilweise mehrfach). Bei der rekursiven Liste von volkard werden die Zahlen nur einmal berechnet und wiederverwendet.



  • Wenn ich blos den "Rekursionsschritt"? bei der Version erkennen würde 😃



  • Also baue ich mir zuerst Schlösser mit 5 Stockwerken der Abstraktion und muß dann doch selber die Abstraktion bis runter auf sagen wir mal C-Niveau auflösen und mir vorstellen, wie er es innendrin macht, damit ich nicht in eine Falle tapse, und eine sehr langsame Funktion baue. Uih, das würde mich aber ein bißchen nerven. 🤡 🤡 🤡



  • Mr. N schrieb:

    nachfrager schrieb:

    Warum soll das performanter sein?

    Weil die Fibonacci-Zahlen nicht immer wieder berechnet werden. Wenn du fib 4 rekursiv berechnest, berechnest du fib 1, fib 2, fib 3 und fib 4 immer auch (bei der naiven Rekursion sogar teilweise mehrfach). Bei der rekursiven Liste von volkard werden die Zahlen nur einmal berechnet und wiederverwendet.

    Da nehme ich dann doch lieber eine for-schleife.



  • hehe schrieb:

    Da nehme ich dann doch lieber eine for-schleife.

    Dann zeig deine Künste.



  • Mr. N schrieb:

    hehe schrieb:

    Da nehme ich dann doch lieber eine for-schleife.

    Dann zeig deine Künste.

    Uninstressant, die For-Schleife für Fibonacci steht bei Stackoverflow. Hab ich gemerkt nachdem ich meine implementiert habe *gg*.



  • Zeus schrieb:

    Mr. N schrieb:

    hehe schrieb:

    Da nehme ich dann doch lieber eine for-schleife.

    Dann zeig deine Künste.

    Uninstressant, die For-Schleife für Fibonacci steht bei Stackoverflow. Hab ich gemerkt nachdem ich meine implementiert habe *gg*.

    Dann könnte man vergleichen, welche Methode komplizierter ist.



  • http://stackoverflow.com/questions/1518726/recursive-fibonacci

    int fib(int n)
    {
        int a = 1, b = 1;
        for (int i = 3; i <= n; i++) {
            int c = a + b;
            a = b;
            b = c;
        }           
        return b;
    }
    

    Auf die iterative Version bin ich nur darauf gekommen, weil ich es in Tabellenform auf Papier gebracht habe.



  • Erstmal was ganz anderes: Überleg dir doch, nano-lang auf github zu schieben.

    Zeus schrieb:

    http://stackoverflow.com/questions/1518726/recursive-fibonacci

    int fib(int n)
    {
        int a = 1, b = 1;
        for (int i = 3; i <= n; i++) {
            int c = a + b;
            a = b;
            b = c;
        }           
        return b;
    }
    

    Auf die iterative Version bin ich nur darauf gekommen, weil ich es in Tabellenform auf Papier gebracht habe.

    OK, dann vergleichen wir es mal mit der berühmten idiomatischen Haskell-Version:

    fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
    

    Mal davon abgesehen, dass diese Version eine _Liste_ _aller_ Fibonacci-Zahlen erzeugt, also [1,1,2,3,5,8,13,21...]...

    Die iterative Version von dir besitzt durchaus eine beachtliche Komplexität. Man muss schon nachdenken, was das macht. Genauso wie bei der Version mit zipWith. Natürlich ist für dich die iterative Version einfacher, weil du es seit Jahren übst, auf iterative Algorithmen zu starren, und sie zu entziffern. Bei den funktionalen Pendants fehlt dir da einfach die Übung.

    Aber das ist nichts angeborenes. Beide Algorithmen sind für einen sehr unerfahrenen Programmierer undurchdringlich.

    Ich habe mir mal die Mühe gemacht, den iterativen Algorithmus so umzubauen, dass er auch eine unendliche Liste von Fibonacci-Zahlen (modulo 264) erzeugt:

    boost::uint64_t a = 1, b = 1;
    cout << "1 1 ";
    for (int i = 3; ; i++) {
        boost::uint64_t c = a + b;
        a = b;
        b = c;
        cout << b << ' ';
    }
    


  • Also ich finde, dass rekursive Algos oft deutlich einfacher zu lesen sind als die iterativen. Auch weil sie viel kürzer sind. Weiterer Vorteil der rekursiven Variante: man hat unveränderliche Objekte.



  • @Mr.N
    Nur weil ich für hehe antworte, heisst es nicht, dass ich es leichter finde. Ich find die Version, die Volkard gepostet habe, am leichtesten 😉



  • Naja, die hier gewählte Sprache ist auch irgendwie nicht passend zum Problem.

    Vielleicht würde Paarzuweisung was retten.

    int fib(int n)
    {
        alt,neu = 1,1;
        for i=3 to n
          alt,neu = neu,alt+neu
        return neu
    }
    

    Oder yield? Nee, eher nicht.

    Vielleicht mit swap.

    int fib(int n)
    {
        int a = 1, b = 1;
        for (int i = 3; i <= n; i++)
           swap(a+=b,b);
        return b;
    }
    

    Nein, eher auch nicht.



  • Mr. N schrieb:

    Ich habe mir mal die Mühe gemacht, den iterativen Algorithmus so umzubauen, dass er auch eine unendliche Liste von Fibonacci-Zahlen (modulo 264) erzeugt:

    boost::uint64_t a = 1, b = 1;
    cout << "1 1 ";
    for (int i = 3; ; i++) {
        boost::uint64_t c = a + b;
        a = b;
        b = c;
        cout << b << ' ';
    }
    

    Ja.
    Oder

    10 a=1:b=1
    20 a=a+b:print a
    30 b=b+a:print b
    40 goto 20
    

Anmelden zum Antworten