Der paradoxe R Performance Pfad

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Der paradoxe R Performance Pfad

Beitrag von bigben »

bigben hat geschrieben: Fr Apr 28, 2017 3:45 pm
consuli hat geschrieben:Ich hoffe, Günther hat inzwischen angefangen Backups zu machen. Weil ich habe nämlich versehentlich Dein Posting gelöscht, bigben! Ich hatte Dich zitiert und dann wollte ich meine Antwort nochmal ändern und naja, es ist dann irgendwie in Deinem Posting Kästle gelandet. Kann es mir immer noch nicht so recht erklären. Tut mir wirklich sehr sehr leid. Ich hatte ja schon mal eine separate Moderatoren Rolle beantragt, aber bisher ... Nun ist es passiert. :oops: :cry:
Pah,

Backups werden nichts daran ändern, dass ich Dir das ein Leben lang nachtragen werde :lol:

Viele liebe Grüße,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
consuli
Beiträge: 479
Registriert: Mo Okt 10, 2016 8:18 pm

Re: Der paradoxe R Performance Pfad

Beitrag von consuli »

Ich verstehe nicht, was Du meinst. Lange Zeit dachte ich, dass das was ich ganz früher mal in der Schule mit Turbo Pascal gelernt habe (Hamster im Labyrinth usw.) wäre funktionale Programmierung, weil Turbo Pascal ja Funktionen verwendet. Aber scheinbar heisst dieser Programmierstil prozedural. Die genauen Unterschiede zu funktional habe ich nie richtig verstanden, ausser das in Rezensionen zu funktionalen Programmierbüchern immer steht, dass es wohl eine Art Top-Down Ansatz ermöglichen soll (während die Programmlogik bei prozedural bottom-up definiert wird, richtig?). Und bei Top-Down im Zusammenhang mit Datenanalyse steh ich dann komplett aufm Schlauch.
Irmgard.
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Der paradoxe R Performance Pfad

Beitrag von bigben »

Hallo consuli,

ja, die Nomenklatur ist da etwas verwirrend - nicht alles, was auf Funktionen aufbaut ist auch funktional. Vielleicht hilft das Folgende bei der Einordnung: Da wir in R viele Werkzeuge einer funktionalen Sprache haben, alle Werkzeuge einer prozeduralen und viele einer objektorientierten haben, geht es in R eher um die Frage, welchen Stil man wählt.

In der objektorientierten Sichtweise, versucht man die Gegenstände der Welt durch Objekte abzubilden und deren Schnittstellen sehr genau zu definieren, so dass bei einem großen Software-Hersteller 100 Programmierer an 100 verschiedenen Objekten arbeiten können, ohne den Code des anderen zu kennen - jede Änderung an einem Objekt erfolgt mit einem Code, der diesem Objekt eigen ist und von ihm verantwortet wird.

Im Mittelpunkt der funktionalen Programmierung steht nicht das Objekt, sondern die Funktion. Funktionen sind dabei möglichst einer mathematischen Funktion ähnlich. Wenn ich eine Funktion zehn mal mit denselben Argumenten aufrufe, muss zehn mal das gleiche herauskommen. Dazu führt vor allem das von jogo immer mal wieder zitierte Prinzip: "Daten gehen als Argumente in die Funktion und sie gehen als Rückgabewert aus der Funktion". Sie gehen eben nicht als globale Variable in die Funktion oder per '<<-' aus der Funktion heraus.

In C:

Code: Alles auswählen

int i=0;
i++;
die '++' Anweisung nimmt die vor ihr stehende Variable und weist ihr auch gleich einen anderen Wert zu. i wird also ein Wert zugewiesen, ohne dass irgendwo expliziert 'i = ...' steht. Aber zurück zu R:

Code: Alles auswählen

# nicht 'funktional'
kundenliste <- c("Frank", "Stefan", "Gitti")  
zaehleKunden <- function() length(kundenliste)
zaehleKunden()

# 'funktional'
zaehleKunden2 <- length
zaehleKunden2(kundenliste)
Eine Funktion, die nicht von globalen Variablen abhängt und deren Auswirkungen auf das Programmumfeld auf Argumente und Rückgabewert begrenzt sind, kann ich losgelöst vom sonstigen Programm betrachten, bedenken und testen und irgendwann für fehlerfrei erklären. Komischerweise stößt die funktionale Programmierung bei den einfachsten Aufgaben an Probleme: sin(x) soll für gleiche x immer denselben Wert liefern. rnorm(1) soll aber nicht jedes mal denselben Wert liefern und muss daher als Ausnahme betrachtet werden.

Ein weiteres Prinzip der funktionalen Programmierung ist das, dass Variablen möglichst nie ihren Wert ändern sollten (daher wohl die Begeisterung mancher Leute für den pipe-Operator in {magrittr}) und dass man mit Metafunktionen oft besser als mit Schleifen ausdrücken kann, was eigentlich gemeint ist.

Code: Alles auswählen

for(i in 1:100) print("R kann viele Paradigmen")
# versus
replicate(100, print("R kann viele Paradigmen"))
Die erste Zeile verwirrt mit der Erstellung eines Zahlen-Vektors und der Zuweisung zu einer Variablen i, die im Code gar nicht mehr gebraucht wird. Die zweite Zeile sagt einfach nur, was der Programmierer will.
das in Rezensionen zu funktionalen Programmierbüchern immer steht, dass es wohl eine Art Top-Down Ansatz ermöglichen soll (während die Programmlogik bei prozedural bottom-up definiert wird, richtig?).
Kann man so eine Formulierung gut oder schlecht finden. Gemeint ist wohl folgendes:

Code: Alles auswählen

replicate(100, print("R kann viele Paradigmen"))
das drückt aus, dass ich etwas 100 Mal wiederholen will. Das C-Pendant dazu:

Code: Alles auswählen

int i;
for(i=0; i<100; i++) { printf("R kann viele Paradigmen"); };
Das beschreibt sehr kleinteilig, wie etwas gemacht werden soll (es soll eine Speicherzelle i geben in die ein Integer passt, diese soll auf 0 gesetzt werden, bei jedem Schleifendurchlauf um 1 erhöht werden und zwar solange i kleiner als 100 ist).

`replicate` drückt also den Gedanken des Progammierers ("Top") aus, das C-'for' geht von Speicherplätzen und deren Wertzuweisungen aus ("Bottom"). Von meinem übergeordneter Wunsch, etwas zu wiederholen, ("Top") wird bei `replicate` nicht durch Implementierungsdetails ("Bottom") abgelenkt, wie etwa der Frage, ob da intern eine Zählvariable von 0 bis 99 oder von 1 bis 100 läuft.

In R käme niemand mehr auf die Idee, C wie folgt nachzuprogrammieren. R würde es aber möglich machen:

Code: Alles auswählen

i <- 0
repeat{
  print("R kann viele Paradigmen.")
  i <- i + 1
  if(!i<100) break
}
Das tun uns R'lern die Augen weh. Das ist so nah an der Maschine ("Bottom"), dass wir es für richtig schlechten Stil halten, auch wenn es valides R ist.

Ich weiß, das war jetzt alles schon wieder viel zu viel Text, und sollte ja eigentlich nur einen Deiner Punkte illustrieren: R ermöglicht die (unvollständige) Umsetzung vieler Programmierparadigmen und vieler Progammierstile, und wenn man sich andere Sprachen so weit anschaut, dass man versteht, welche Ideen dort wie eingesetzt werden, kann einem das zum besseren Programmierer in R machen.
Ein besserer Programmierer zu sein kann auch helfen, ein besserer Datenanalyst zu sein, auch wenn das vielleicht weder eine notwendige noch eine hinreichende Voraussetzung ist.
Ob da jetzt andere "Mainstreamsprachen" oder "akademische Sprachen" in Einzelfall nützlicher sind, kann man bestimmt nicht allgemeingültig beantworten.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
consuli
Beiträge: 479
Registriert: Mo Okt 10, 2016 8:18 pm

Re: Der paradoxe R Performance Pfad

Beitrag von consuli »

jogo hat geschrieben: Mo Mai 08, 2017 2:03 pm https://de.wikipedia.org/wiki/Funktiona ... rammierung
Ist
Dabei ist insbesondere der gleichzeitige Gebrauch dieser Funktionen als reguläre Datenobjekte von Bedeutung. Programmiersprachen, die funktionale Programmierung ermöglichen, heißen funktional.
des Pudels Kern?
Irmgard.
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Der paradoxe R Performance Pfad

Beitrag von bigben »

Schwer zu sagen, wer festlegt, was des Pudels Kern ist. Ich denke nicht, dass das der Kern ist. Wenn ich mal die Einleitung der englischsprachigen Wikipedia anführen darf:
In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions[1] or declarations[2] instead of statements. In functional code, the output value of a function depends only on the arguments that are passed to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time; this is in contrast to procedures depending on local or global state, which may produce different results at different times when called with the same arguments but different program state. Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming.
https://en.wikipedia.org/wiki/Functional_programming

Im ersten Absatz wird dort die Verwendbarkeit von Funktionen als Datenobjekte gar nicht erwähnt. (Im zweiten und dritten und vierten auch nicht.) Diese ist sicher auch ein Feature, aber für mein Sprachgefühl oder mein inneres Bild des Begriffs ist der Satz des obenstehenden Zitats genau richtig, der es als Paradigma und als Style beschreibt und damit deutlich umfassender, als jedes einzelne Feature es könnte.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Der paradoxe R Performance Pfad

Beitrag von bigben »

Habe gerade mal versucht, den deutschen Wikipedia-Artikel zu lesen - da lebt sich ein Akademiker aus, aber ich würde da nichts verstehen!

Warum steht da
Die funktionale Programmierung kommt also ohne Schleifen und Zuweisungen aus, benötigt dafür aber Rekursion.
Funktionale Programmiersprachen kommen ohne Zuweisung aus? Und wofür steht dann das "="? Und das mit den Schleifen mag akademisch richtig sein, aber wenn ich mir die for-Funktionen in Racket anschaue, dann muss man schon etwas ausführlicher erklären, warum das keine Schleife ist:

Code: Alles auswählen

> (for/vector ([i '(1 2 3)]) (number->string i)) 
'#("1" "2" "3")
Und warum wird die Diskussion über statische und dynamische Typisierung in diesem Kontext aufgegriffen? Warum benutzt man in einer Enzyklopädie das Wort `"Uniqueness"-Typen`, ohne es zu erklären oder zu verlinken?? Naja, egal. Mir scheint der Eintrag nicht besonders gelungen.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Der paradoxe R Performance Pfad

Beitrag von jogo »

Wenn man mal nur die Universal-0815-Programmiersprachen nimmt von Algol und FORTRAN bis C und Pascal, dann ist es wohl für eine Vielzahl von Problemen nicht notwendig, dass man Funktionen als ganz normale Objekte verwalten kann.
Wenn jedoch genau diese Eigenschaft (Funktionen als ganz normale Objekte) einer Programmiersprache erst eine elegante Programmierung ermöglicht, dann wird man diesen Unterschied in der Konzeption verschiedener Programmiersprachen als gravierend empfinden.

Gruß, Jörg
consuli hat geschrieben: Mi Mai 10, 2017 1:39 pm
jogo hat geschrieben: Mo Mai 08, 2017 2:03 pm https://de.wikipedia.org/wiki/Funktiona ... rammierung
Ist
Dabei ist insbesondere der gleichzeitige Gebrauch dieser Funktionen als reguläre Datenobjekte von Bedeutung. Programmiersprachen, die funktionale Programmierung ermöglichen, heißen funktional.
des Pudels Kern?
consuli
Beiträge: 479
Registriert: Mo Okt 10, 2016 8:18 pm

Re: Der paradoxe R Performance Pfad

Beitrag von consuli »

jogo hat geschrieben: Do Mai 11, 2017 3:28 pm Wenn man mal nur die Universal-0815-Programmiersprachen nimmt von Algol und FORTRAN bis C und Pascal, dann ist es wohl für eine Vielzahl von Problemen nicht notwendig, dass man Funktionen als ganz normale Objekte verwalten kann.
Wenn jedoch genau diese Eigenschaft (Funktionen als ganz normale Objekte) einer Programmiersprache erst eine elegante Programmierung ermöglicht, dann wird man diesen Unterschied in der Konzeption verschiedener Programmiersprachen als gravierend empfinden.
Ok, im Gegensatz zu dem was bigben schreibt, kann ich diese Aussage verstehen. Selbstverständlich liegt das nur an meinem Unwissen. :)

Aber für die Datenanalyse in R hat das Feature "Funktionen als normale (Daten)Objekte ansprechen zu können" doch gar keine Relevanz, oder doch?

Oder kann das nur das apply von bigben? ;)

Bereinigung des Threads für die Nachwelt vorbehalten. ;-)
Irmgard.
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Der paradoxe R Performance Pfad

Beitrag von bigben »

consuli hat geschrieben: Fr Mai 12, 2017 10:15 pmOk, im Gegensatz zu dem was bigben schreibt, kann ich diese Aussage verstehen.
Sorry! Fiel mir in dem Moment nicht verständlicher ein.
Aber für die Datenanalyse in R hat das Feature "Funktionen als normale (Daten)Objekte ansprechen zu können" doch gar keine Relevanz, oder doch?

Oder kann das nur das apply von bigben? ;)
apply und seine Verwandten sind schon recht prägend für R. Als weniger häufig genutztes aber doch wesentliches Beispiel baut z. B. optim darauf, dass man ihm eine zu optimierende Funktion übergeben kann.
Ich will nicht schon wieder von der Pipe anfangen. Man wird bei weiterem Suchen sicher noch mehr finden, wo die Übergabe einer Funktion als Argument nachhaltig nützlich ist.

(Dann wiederum konnte man schon im alten C den Zeiger auf eine Funktion einer Funktion als Argument übergeben, was zwar nicht das gleiche ist, aber eben doch gegen diese Eigenschaft als Begriffsdefinition für funktionale Programmiersprachen spricht.)

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Antworten