Schwarzer Gürtel in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Sonntag 25. November 2007, 22:02

poker hat geschrieben:
birkenfeld hat geschrieben: Ich halte first-class-Funktionen hier durchaus für ausreichend, und vor allem, mit Pythons Syntax vereinbar.
Ja, ist halt ein anderes Konzept und bietet eine andere Herangehensweise. Hat aber mit Ruby-Blöcken genau soviel am Hut wie `with`
Nein, es hat damit viel mehr "am Hut". Rubys Blöcke sind schließlich kaum was anderes als anonyme Funktionen...

Ich verstehe nun wirklich nicht, was an

Code: Alles auswählen

3.times { |i| print i }
konzeptuell anders sein soll als an

Code: Alles auswählen

times(3, lambda i: print(i))
eine entsprechende Definition von "times" vorausgesetzt.
poker hat geschrieben:Aber weshalb Blöcke in Python nicht gehen, müsstest du mir erklären. (Ja, Armin sagte schon wegen der Einrückungen, aber was genau verhindert das?)
Schlag doch mal eine Syntax für Blöcke vor, dann sehen wir schon :)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Montag 26. November 2007, 14:51

poker hat geschrieben:Du, Reinhold, [...]
Wer ist Reinhold?
poker hat geschrieben:Das first-class-functions in Ruby (wegen dem Objektsystem.) nicht möglich ist, ist klar.
Mag mir das mal jemand erklären?
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Montag 26. November 2007, 15:06

Y0Gi hat geschrieben:
poker hat geschrieben:Du, Reinhold, [...]
Wer ist Reinhold?
Ehm, Georg Brandl? :shock:
http://www.google.de/search?aq=t&oq=&hl ... uche&meta=

Ich dachte das wäre bekannt ;) Er ist ja schon ein par tage im Core Team, damals noch unter seinem richtigen Namen.

[OT]Aber sag mal Reinhold, wie bist du auf Georg Brandl gekommen?[/OT]
Y0Gi hat geschrieben:
poker hat geschrieben:Das first-class-functions in Ruby (wegen dem Objektsystem.) nicht möglich ist, ist klar.
Mag mir das mal jemand erklären?
Gerne. Zugegeben, der satz ist ein wenig schwamig von mir, aber wenn ich mal näher ausgeführt habe, kann man das darauf herleiten.

Gib mir mal ein Augenblick. Ich schreibe dazu ein par Beispiele damit man das visuell nachvollziehen kann :)
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Montag 26. November 2007, 15:51

Y0Gi hat geschrieben:
poker hat geschrieben:Das first-class-functions in Ruby (wegen dem Objektsystem.) nicht möglich ist, ist klar.
Mag mir das mal jemand erklären?
hi Yogi.

Als erstes ist wichtig zu wissen, das Ruby total OOP ist. Dann muss man begreifen das man auf Attribute (~Variabeln) nicht zugreifen kann von außen. Solche Zugriffe werden über Methoden forciert ;) Wo wir auch schon die Antwort darauf haben warum bei Ruby die Klammern optional sind.

Aber der Reihe nach:


Folgendes geht nicht

Code: Alles auswählen

class MyClass
  def initialize
    @eggs = [NIL, 1]
  end
end

c = MyClass.new
c.eggs
und wirft folgende exception:
test.rb:8: undefined method `eggs' for #<MyClass:0x29406f4 @eggs=[nil, 1]> (NoMe
thodError)
Nur die Instanz selbst hat zugriff auf seine Instanzvariablen. Außerhalb kann man nur über Methoden darauf zugreifen:

Code: Alles auswählen

class MyClass
  def initialize
    @eggs = [NIL, 1]
  end

  def eggs
    @eggs
  end
  def eggs=(value)
    @eggs = value
  end

end

c = MyClass.new
p c.eggs

c.eggs = 1
p c.eggs

c.eggs=(42)
p c.eggs()
Ergibt:
[nil, 1]
1
42
Hier kann man auch schon sehen wie Ruby Arbeitet. ein `c.eggs` oder `c.eggs()` ruft die Methode lesend auf. Ein `c.eggs = ` oder `eggs=()` währe dann eine Forcierung einer Zuweisung.

Da obere Möglichkeit zu viel Schreibkram ist, nur für Variablen die man nur lesen oder etwas zuweisen möchte, gibt es dafür auch eine Kurzform:

Code: Alles auswählen

class MyClass
  attr_accessor :eggs
  def initialize
    @eggs = [NIL, 1]
  end
end
`attr_accessor ` erzeugt selbständig `eggs()` und `eggs=()`. Darüberhinaus gibt es noch `attr_reader` das nur die `eggs()` erzeugt und ein `attr_writer` das nur `eggs=()` erzeugt.



So, aufgrund dieses OOP-Designs hat man sich dann entschieden klammern optional zu machen. Aber durch diese Entscheidung, ist es nicht möglich Funktionen "direkt" (=über ihren Namen) als Referenzen rumzureichen. Das heißt aber nicht das Ruby nicht Funktionen höherer Ordnung unterstützt ;) IN Ruby muss man halt vorhandenen Funktionen (eigentlich Methoden, den Funktionen gibt es in dem Sinne nicht) in proc-objects umwandeln um sie rum zureichen.

Auch kann man für anonyme Funktionen in ruby Blöcken verwenden (Insofern hat birkenfeld mit seiner Aussage auch irgendwie recht. Er bedenkt aber nicht das Blöcke noch weiter mehr machen können als er in seinem Trivial beispiel zeigt).

folgendes Python Beispiel

Code: Alles auswählen

def foo():
    return 42
def bar(f):
    foo()
bar(foo)
würde in Ruby z.B. so gehen:

Code: Alles auswählen

def foo()
  42
end

def bar(f)
  f.call
end

p bar(self.method(:foo))
Nicht so schön wie first-class-funktionen aber naja, es geht und IMO überwiegen die anderen Vorteile in Ruby und das Klammern optional sind ;)

/e
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Montag 26. November 2007, 17:30

poker hat geschrieben:
Y0Gi hat geschrieben:
poker hat geschrieben:Du, Reinhold, [...]
Wer ist Reinhold?
Ehm, Georg Brandl? :shock:
http://www.google.de/search?aq=t&oq=&hl ... uche&meta=

Ich dachte das wäre bekannt ;) Er ist ja schon ein par tage im Core Team, damals noch unter seinem richtigen Namen.
Huh? Ich dachte, 'birkenfeld' wäre der Nickname gewesen und er hat sich dann entschieden, Python unter seinem echten Namen weiter zu entwickeln... und einige Mailinglist-Archive bestätigen mir das offenbar auch. Nur, dass es einen imaginären Vornamen gab, war mir noch nicht bekannt.


poker: Danke für die Aufklärung.

Der Accessor-Kram ist mir bekannt gewesen.

Jetzt wo du's beschreibst, meine ich mich daran zu erinnern, mal über diesen umständlichen Weg gelesen zu haben, über den man direkt auf die Funktionen und Methoden als Objekte in Ruby zugreifen kann.

Ich persönlich schätze auch leere Klammern beim Funktionsaufruf, weil sie genau diesen kennzeichnen. Nun, das ist wohl der Preis, den man (vielleicht anfangs nichts ahnend) bei Rubys Entwicklung bezahlen musste, um (zugegeben, öfter) ein paar Zeichen weniger tippen zu können.
poker hat geschrieben: folgendes Python Beispiel

Code: Alles auswählen

def foo():
    return 42
def bar(f):
    foo()
bar(foo)
Du meinst hier nicht zufällig folgendes?

Code: Alles auswählen

def foo():
    return 42

def bar(f):
    f()  # <--

bar(foo)
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Montag 26. November 2007, 19:57

Y0Gi hat geschrieben:Huh? Ich dachte, 'birkenfeld' wäre der Nickname gewesen und er hat sich dann entschieden, Python unter seinem echten Namen weiter zu entwickeln... und einige Mailinglist-Archive bestätigen mir das offenbar auch. Nur, dass es einen imaginären Vornamen gab, war mir noch nicht bekannt.
Hmm, das kann natürlich auch sein. Ich bin darauf damals gestoßen als ich material zu nem Python Projekt von Martin v. Löwis gesucht habe. Da ist mir diese pdf unter die Arme gekommen. Wie dem auch sei, ich denke "Georg Brandl" ist birkenfelds Künstlername und nicht umgekehrt. Ich kann mich aber auch Irren. Ich würde mich aber sehr wunder in Anbetracht von welcher Region er kommt ;)

Y0Gi hat geschrieben: Nun, das ist wohl der Preis, den man (vielleicht anfangs nichts ahnend) bei Rubys Entwicklung bezahlen musste, um (zugegeben, öfter) ein paar Zeichen weniger tippen zu können.
Da ist was dran. Einerseits ist ja Ruby "direkt" von Perl inspiriert. Aber ich denke hauptsächlich ist dieses "Eigenartige" Objektsystem schon bewusst von Matz geplant gewesen und auch dessen Konsequenz. -> Wer hat schon lust dann immer Klammern anzugeben für Forcierte Attributzugriffe? IMO hat er es bewusst drauf angelegt.
Y0Gi hat geschrieben: Du meinst hier nicht zufällig folgendes?
Upsss, hab mich verschreiben :D

Was mich aber an Ruby aufregt ist das keine Closures so wie in Python möglich sind, sondern nur über lambda's. Dafür sind Rubys lambda's aber besser als Pythons :D

Code: Alles auswählen

def eggs():
    def inner():
        print "spammmm"
    return inner
print eggs()
eggs()()
<function inner at 0x00B24A30>
spammmm
In Ruby:

Code: Alles auswählen

def eggs
  lambda do
    print "spammmm"
  end
end

p eggs
eggs.call
#<Proc:0x02b796b4@test.rb:4>
spammmm
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Montag 26. November 2007, 20:39

poker hat geschrieben:Wie dem auch sei, ich denke "Georg Brandl" ist birkenfelds Künstlername und nicht umgekehrt. Ich kann mich aber auch Irren. Ich würde mich aber sehr wunder in Anbetracht von welcher Region er kommt ;)
Vielleicht hab ich aber auch beide Namen erfunden.

Armin
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Andy
User
Beiträge: 196
Registriert: Sonntag 1. Januar 2006, 20:12
Wohnort: aus dem hohen Norden....

Montag 26. November 2007, 21:26

birkenfeld hat geschrieben: Vielleicht hab ich aber auch beide Namen erfunden.
Armin
birkenfeld, ich verrate Dich jetzt mal:
"Reinhold Birkenfeld" was a pseudonym Georg Brandl first used when he was sixteen. Three years (plus change) later, he has decided to become known within the Python development community by his real name. Among the expected humourous replies, there was some discussion about whether pseudonyms should be permitted for people contributing to Python, but this (including exactly what a "contribution" is) wasn't resolved.
python dev summary
EDIT: Birkenfeld's gone
Antworten