Guido van Rossum macht vorerst Feierabend

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

Anscheinend hat da jemand die Nase voll, ich habe gerade seine Mail auf der Mailingliste gelesen und war erstmal überrascht. Was sagt ihr dazu? Wird sich das spürbar auf Python auswirken, wenn ja, wie?

Hier der Artikel von Golem: https://www.golem.de/news/guido-van-ros ... 35462.html
When we say computer, we mean the electronic computer.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich habe den den dort verlinkten LWN-Artikel PEP 572 and decision-making in Python gelesen und fand das Zitat hier bezeichnend:
Langa wondered if there were other PEPs with a similar kind of response. Static typing (also known as "type hints") is one that Van Rossum remembered.
Vielleicht sollte man so etwas als Zeichen sehen das solche Kontroversen PEPs ziemlich wahrscheinlich gegen eine Form der Sprache gehen wie sie von vielen gesehen und geschätzt wird. Das war dann ja auch eine BDFL-Entscheidung und kein Konsens. Und bei dem ``:=`` würde ich ganz klar sagen, wenn eine Syntaxveränderung mit so wenig Vorteil so viel Diskussion/Ablehnung zur Folge hat, sollte man das nicht durchdrücken.

Ich finde ja bei Python 2.7 ja schon das die Sprache nicht einfach ist, wie oft behauptet wird, sondern das man damit leicht verständliche Programme schreiben kann. Das ist ein Unterschied. Ein Grund ist das relativ wenig Syntax zu lernen ist. Die Situation wird mit jeder Syntax + Bedeutung die zusätzlich eingeführt wird, nicht besser.

Und wenn schon, fand ich in den Kommentaren zum LWN-Artikel die ``if re.search(…) as match:``-Syntax deutlich besser als das ``:=``. Zum einen weil es ``as`` schon als Schlüsselwort/Token in der Grammatik gibt, und bei ``except`` und ``with`` schon so verwendet wird, und weil sich das auch für ungeübte Leser leichter verstehen lässt, im Gegensatz zu einem Operator wo man raten oder nachschlagen muss. Man könnte das dann auch auf diese Block-Konstrukte beschränken. Selbst bei ``try`` könnte ich mir das vorstellen. Also:

Code: Alles auswählen

try spam() as eggs:
    whip(eggs)
except …:
    …

# vs.

try:
    eggs = spam()
except …:
    …
else:
    whip(eggs)
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@__blackjack__: genau meine Gedanken.

Das totale Chaos entsteht dann bei Comprehensions, wo die Ausführungsreihenfolge eh schon problematisch ist und zusätzlich durch die Scope-Überschreitende Definition von Variablen lustige Dinge gebaut werden können, wie

Code: Alles auswählen

def lustig(numbers):
    def sqr():
        return y*y
    return {y:=2*x: sqr() for x in numbers}
Ob wohl Tuple-Unpacking auch möglich ist?

Code: Alles auswählen

if ((y, _) := divmod(x, 2))[1] == 0:
    print(y)
else:
    print(y+1)
Wobei ich gerade sehe, das geht ja mit if-else viel schöner:

Code: Alles auswählen

z = y if ((y, _) := divmod(x, 2))[1] == 0 else y + 1
print(z)
Hier noch ein schönes Rätsel, was in welcher Reihenfolge ausgeführt wird, was also dann in x und y steht:

Code: Alles auswählen

x = [1,2,3,4,5]
y = 0
y = x[y := y+1] = x[y := y + 1]
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

@__blackjack__: Die 'as'-Variante wurde, soweit ich das im PEP verstanden habe, nicht gewählt, weil sie wohl nur einen Teil der Fälle, die abgedeckt werden sollen, abdeckt. Jetzt kann man natürlich diskutieren, ob die anderen Fälle notwendig sind oder nicht.

Ich weiß noch nicht so genau, was ich von dem ":=" halten soll; optisch weckt es Erinnerungen an Pascal und andere Sprachen, die das als regulären Zuweisungsoperator verwenden.

(Was natürlich auch ginge, wäre -- analog zum $_ bzw $0, $1 in einer gewissen anderen Sprache mit P -- eine implizite Variable "__0__" oder _____ ;) )
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ich finde den neuen Operator sogar gut. Ich hoffe nur, dass dieser nicht exzessiv eingesetzt wird, sondern nur dort, wo es sinnvoll ist.
Aber ich muss zugeben, dass es ungewohnt ist und am Anfang schwer zu deuten. Ich habe mich an SCL erinnert, als ich den Operator gesehen habe.
Dort werden alle Zuweisungen mit := gemacht. Ich denke das kommt von Pascal.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich finde die Idee auch gut. Das direkte Auswerten einer Zuweisung nutze ich auch in C-Programmen gerne. Es macht den Code kürzer und auch lesbarer, solange man es nicht übertreibt. Einzig, dass die Wahl auf := gefallen ist, könnte anfangs für manche verwirrend sein, sofern man den Operator aus anderen Sprachen schon kennt und eine andere Erwartung an seine Bedeutung hat.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@snafu: Ich nutze das in C (und ähnlichen Sprachen) auch, habe aber in Python nur *ganz* selten den Fall gehabt, das ich so etwas vermisst hätte. Und da war es dann auch immer nur der Unterschied zwischen einer Zuweisung und einem ``if`` statt das in eine Zeile zu ziehen. Um diese eine Zeile zu sparen finde ich einen neuen Operator etwas dünn.

Die immer tiefere Verschachtelung löse ich in der Regel mit Schleifen. Und so etwas wie ``while (command := input("> ")) != "quit":`` in dem ich einen Iterator erstelle und da mit ``for`` drüber gehe: ``for command in iter(partial(input, '> '), 'quit'):``. Analog beim Beispiel mit dem blockweisen lesen aus einem Dateiobjekt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Mikro-Optimierungen sind Mist. Zeilensparen ist Mist.

Sparse is better than dense. -- PEP 20
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Syntax, interestingly, complects meaning and order often in a very unidirectional way. [...] I don't care how many you really love the syntax of your favorite language. It's inferior to data in every way. -- Rich Hickey, Simple Made Easy
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Naja, wir könnten natürlich alle noch so arbeiten:

Code: Alles auswählen

f = open(filename)
try: 
    f.write(data)
finally:
    f.close()
Dann muss man keine blöde neue Syntax lernen... ;)
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@snafu: Das with-Statement ist besser, als die dazugehörige try-except-finally-Kaskade. Noch besser wäre IMO die Error- oder Exception-Monade. Das wäre dann eine Datenstruktur.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@snafu: Man kann in so einen Kontextmanager deutlich mehr Code zur Vorbereitung und zum Aufräumen unterbringen als das bei `file` der Fall ist. Das ist keine minimale Syntaxänderung um lokal ein oder zwei Zeilen zu sparen, sondern um solchen Code der am Anfang und am Ende von einem Block passieren soll in Bibliotheken auszulagern statt das den Benutzer immer wieder schreiben zu lassen. Kontextmanager waren AFAIK auch nicht so umstritten.

Um mal vom konkreten `file`-Beispiel zum Allgemeinen zu gehen (aus dem PEP):

Code: Alles auswählen

with EXPR as mgr:
    BLOCK

# =>

mgr = (EXPR)
exit = type(mgr).__exit__  # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
    try:
        VAR = value  # Only if "as VAR" is present
        BLOCK
    except:
        # The exceptional case is handled here
        exc = False
        if not exit(mgr, *sys.exc_info()):
            raise
        # The exception is swallowed if exit() returns true
finally:
    # The normal and non-local-goto cases are handled here
    if exc:
        exit(mgr, None, None, None)
Das ist ein kleines bisschen mehr/umfangreicher als das was ``:=`` macht.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

__blackjack__ hat geschrieben: Mittwoch 18. Juli 2018, 15:23 Das ist keine minimale Syntaxänderung um lokal ein oder zwei Zeilen zu sparen, sondern um solchen Code der am Anfang und am Ende von einem Block passieren soll in Bibliotheken auszulagern statt das den Benutzer immer wieder schreiben zu lassen.
Klar, ich wollte Kontextmanager auch nicht infrage stellen. Übrigens spielt die neue Zuweisungssyntax ihre Stärken z.B. bei tief verschachtelten if-Blöcken sehr gut aus. Beispiel aus PEP 572:

Code: Alles auswählen

# Current
reductor = dispatch_table.get(cls)
if reductor:
    rv = reductor(x)
else:
    reductor = getattr(x, "__reduce_ex__", None)
    if reductor:
        rv = reductor(4)
    else:
        reductor = getattr(x, "__reduce__", None)
        if reductor:
            rv = reductor()
        else:
            raise Error(
                "un(deep)copyable object of type %s" % cls)

# Improved
if reductor := dispatch_table.get(cls):
    rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
    rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
    rv = reductor()
else:
    raise Error("un(deep)copyable object of type %s" % cls)
Bei komplexen Fallunterscheidungen werde ich die neue Syntax also mit Sicherheit einsetzen, wenn sie die Lesbarkeit fördert.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@snafu: Da hatte ich ja schon gesagt, dass ich so etwas mit Schleifen mache wenn's mich stört. Bei den drei Fällen im Beispiel würde ich noch nicht von tief verschachtelt sprechen, aber das könnte man ja auch so schreiben, gegebenfalls mit ``lambda``-Ausdrücken an Stelle der `(getter, getter_arguments)`-Tupel:

Code: Alles auswählen

for (getter, getter_arguments), reductor_arguments in [
    ((dispatch_table.get, [cls]), [x]),
    ((getattr, [x, '__reduce_ex__', None]), [4]),
    ((getattr, [x, '__reduce__', None]), [])
]:
    reductor = getter(getter_arguments)
    if reductor:
        return_value = reductor(*reductor_arguments)
        break
else:
    raise Error('un(deep)copyable object of type {}'.format(cls))
Schon ist es ”flach” und leicht erweiterbar ohne zusätzliche Ebenen hinzuzufügen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: beim vorgestellten Beispiel würde aber ein `none conditional operator` noch viel kürzeren Code produzieren und zwar in der Variante `a?()`, also rufe die Funktion nur auf, wenn `a` nicht None ist kurz für `None if a is None else a()`:

Code: Alles auswählen

rv = dispatch_table.get(cls)?(x) or getattr(x, "__reduce_ex__", None)?(4) or getattr(x, "__reduce__", None)?()
if rv is None:
    raise Error("un(deep)copyable object of type %s" % cls)
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ah ja, der „existential operator“ aus CoffeeScript: ``zip = lottery.drawWinner?().address?.zipcode``. Hm, wie schwer kann es ein ein PEP zu schreiben… :-D
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mit genug Hirnschmalz, temporären Listen und einigen Verrenkungen geht alles irgendwie. Bequemer ist es aus meiner Sicht jedoch mit der neuen Syntax. Aber wer nicht will, der muss sie ja nicht einsetzen und darf gern weiterhin bei Python 2.7 stehen bleiben. Geschmäcker und Ansichten von lesbarem und wartbarem Code sind halt manchmal sehr verschieden. ;-)
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also wie gesagt finde ich die Verschachtelung da noch gar nicht tief genug um das jetzt unbedingt anders schreiben zu müssen. Wo ich so etwas bisher eingesetzt habe und auch weiterhin einsetzen werde ist das matchen von regulären Ausdrücken und dann je nach dem welcher matcht etwas mit dem Ergebnis machen. Also Parsen von zeilenbasierten Formaten. Da würde mir die neue Syntax nicht viel bringen, weil das in der Regel mehr als drei Varianten sind und ich die dann sowieso immer in eigene Funktionen/Methoden stecken, damit das keine zu lange Funktion wird und damit man die Verarbeitung der einzelnen Zeilentypen auch separat (Unit)testen kann.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

mich stört an dem `:=`, dass beim Lesen so überhaupt nicht klar wird, was das sein soll - wenn man es nicht explizit weiß. Sonst sind IMHO alle Sachen in Python so, dass man zumindest (richtig) erahnen kann, was ein Befehl macht. Also ich das erste Mal `:=` gelesen haben, habe ich spontan an Go gedacht, wo das ja bei der normalen Variablenzuweisung genutzt wird.

Gruß, noisefloor
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Interessant, dass es in dem Thread über Guidos Feierabend genau nur einen Beitrag lang um Guido ging, und dann wieder seitenlang um PEP 572.

Dabei hat Guido explizit als Grund angeführt, dass ihm das Hickhack hier zu viel wird und er nach knapp 30 Jahren nun eine lange Pause benötigt.

Es gibt ja auch andere interessante offene Fragen. Wie soll denn nun zukünftig über PEP entschieden werden, wenn der BDFL nicht verfügbar ist?
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Antworten