Cavolo, il necroposting ti ha preso la mano eh?
Guarda, con molta franchezza: ci sono punti in cui non ci arrivo proprio a discutere con te, quindi non fingerò che mi sono chiare le cose che non mi sono chiare. Quindi poi ti chiedo.
Cominciamo a metterci d'accordo sul fatto che esistono vari livelli di esperienza e/o necessità a cui corrispondono diversi problemi che si scoprono. E magari si risolvono. Se quando sviluppi sistemi complessi in team grandi vien fuori che i named arguments sono una rogna (e non stento a crederlo da quel poco che ho visto/capito), allora a quel livello non userai i named arguments. Ma non me la sento di dare la colpa a Python perché ha i named arguments.
Poi certo, è anche una questione che le cattive abitudini acquisite "da piccoli" poi è più difficile perderle... ma insomma, questa è una questione didattica.
Ora, prendiamo il caso dei dizionari ordinati. Ti dici che OrderedDict mi sta simpatico, ma in realtà... boh, direi di no. Se voglio qualcosa che conservi l'ordine di inserimento uso una lista di tuple. Se voglio un dizionario ordinato... eh, non uso niente visto che python non ha treemap. Ma se uso un dizionario non mi interessa l'ordine. Ora, posso capire che un principiante non sappia quale struttura-dati usare. Ma se un principiante vuole usare OrderedDict, tutto sommato non mi disturba terribilmente. Più che altro sospetto che la *ragione* per cui lo usa sia sbagliata, e provo a investigare.
Io ho mai usato OrderdDict? Mah, sì, qualche volta. Per qualche aspetto secondario nel lavoro con le GUI, tipo produrre menu a partire da strutture-dati che li descrivono. In casi del genere un dizionario (eventualmente annidato per i sottomenu) va bene: peccato solo che *inoltre* le voci di un menu devono essere presentate con un ordine arbitrario, e il dizionario questo non lo supporta. E quindi, OrderedDict. E' un pattern sbagliato? Mah, onestamente non direi. Cioè sì, l'ordinamento è logica-di-presentazione, tutto il resto che metto nel dizionario è logica-di-business. Cioè sì, *potrei* fare un ulteriore layer solo per astrarre questa necessità. Ma andiamo, dai: un OrderedDict va benone per questo. Tutto il resto mi sembrerebbe una inutile complicazione.
E poi prendiamo il caso dei named arguments ordinati. Certo, *io* non ne ho mai sentito la necessità. E però non sono d'accordo con te:
> il punto e' che quando si parla di named argument
> quello che vuoi fare e' proprio "ignorare" l'ordine.
Già, a meno che io non sia l'autore di un'estensione per un editor come questa
https://packagecontrol.io/packages/AutoDocstring che ispeziona i parametri della funzione e produce automaticamente uno stub per la docstring, ecco ALLORA forse mi piacerebbe presentare anche i kwargs nell'ordine giusto, no? Eh. (Questa è anche una risposta alla tua domanda "ma ci fate qualcosa con python?, il problema è stampare gli argomenti?": di tanto in tanto...)
Oppure, se scrivessi metaclassi che costruiscono classi con named arguments: allora mi piacerebbe *un sacco* che la classe costruita avesse gli argomenti nell'ordine che dico io e non buttati a casaccio (e in modo diverso a ogni esecuzione)... o sbaglio?
https://stackoverflow.com/questions/4459531/how-to-read-class-attributes-in-the-same-order-as-declared Nota che questo è proprio un esempio di "cosa che si rompe" (e si è sempre allegramente rotta, dall'alba dei tempi delle mataclassi) se *non* usi OrderedDict (cioè, se non ci sbatti il muso e poi impari a usare OrderedDict).
Dopo di che però iniziano le cose che non capisco più. Quando dici
> Un problemino dei named parameters?
> se qualcuno cambia copy(a, b) in copy(src=a, dst=b)
> il mock si rompe potenzialemente
Uh, che cosa vuol dire? Che se cambi la signature di una funzione potrebbe rompersi il suo mock? Beh sì, credo che sia vero *in generale*. Stai cambiano la signature di una funzione, caspita. Che tutto il resto intorno si rompa, beh un po' me lo aspetto.
Poi certo, se intendi dire: "non sembra che sto cambiando la signature, ma in python è così e questo causa confusione e fa perdere tempo", allora sì certo. La soluzione è non usare named arguments, hai ragione.
E poi aggiungi
> sono curioso di sapere cosa succede adesso che abbiamo gli ordered dict
> spero che non abbiano fatto sta cazzata
Non so proprio... penso che il mock che si rompeva prima si rompe anche ora (in particolare, se hai cambiato la signature non solo usando kwargs al posto di args, ma anche *cambiando* l'ordine degli argomenti), e quello che non si rompeva prima non si rompe neanche adesso... mi perdo qualcosa?
Semmai il contrario... se stavi già usando named arguments con i mock, è possibile che adesso le cose migliorino un pochino:
https://mail.python.org/pipermail/python-ideas/2009-April/004165.htmlPoi ci sono volte che non riesco a capire se esageri o se mi perdo qualcosa:
>> la serializzazione, tutte le volte che hai bisogno di ottenere
>> risultati riproducibili evitando diff spuri.
> Si, tipo la serializzazione *se* uno non ha capito come
> organizzare un layer di persistenza
Maddai... davvero io non ne capisco molto, ma ultimamente vedo (per esempio) tutta questa ansia di produrre build deterministiche... Ora, il punto è che tutto quello che origina da un dizionario e finisce in qualche modo in un... file di testo (per dire... un output serializzato), non è deterministico. Non è bello, in certi casi, avere un dizionario ordinato? E non ci pensi più.
Oppure più banalmente (e in un altro campo), se faccio i test con doctest, che per forza di cose non può far altro che confrontare stringhe, mi piacerebbe eccome avere dei dizionari order-preserving, o no? E occhei, dopo "non usare json" anche "non usare doctest"... ma insomma, ce ne sono di cose implementate male in giro, tutte perché invece 'sti benedetti dizionari sono implementati bene, eh?
E poi ci sono delle volte in cui proprio non ho capito se sono io scemo o cosa:
> Io trovo il discorso: ho implementato gli argomenti
> delle funzioni con un dizionario, ma il dizionario
> non va bene, quindi modifico tutti i dizionari
> completamente delirante. Se per te questa linea di
> ragionamento e' sensata, non c'e' spazio per discutere.
> Abbiamo una visione di software engineering drammaticamente diversa
Ma no, dai. (Ok, qui potrei dirti che se i core devs di python - Guido compreso - hanno preso questa decisione, proprio deliranti magari non sono... ma sarebbe un falso argomento, si capisce). A parte che non hanno modificato i dizionari *per* ordinare i named arguments... diciamo che è stato un concorso di ragioni... ma anche se fosse così: non c'è qualcosa di sbagliato in quello che scrivi? Non è "modifico tutti i dizionari"... ma è "estendo" i dizionari, o no? Stiamo violando il principio di sostituzione qui? Tutto quel che potevi fare con i vecchi dizionari puoi farlo anche con i nuovi, o no? C'è un problema che non vedo?
> Adesso siamo arrivati a ficcare vincoli implementativi
> nelle strutture dati core perche' la gente non sa usare
> OrderedDict. Dal mio punto di vista non mi stupirei se
> fra qualche anno ci saranno __builtin__._COOKIE e __builtin__._POST.
Beh, no. Ci sono due aspetti separati qui: primo, i named arguments. Su questi, il vincolo implementativo non è stato introdotto adesso, ma proprio dall'inizio. Se li implementi con un dizionario, ti porti dietro i difettucci dei dizionari, e sei destinato a cambiare la loro semantica tutte le volte che cambi i dizionari. E' un peccato, certo, ma un peccato antico non recente. E da un punto di vista di design, ci sono pochi dubbi che i named arguments *dovrebbero* essere ordinati: a parte le applicazioni pratiche (metaclassi, etc), averli non-ordinati è un attrito cognitivo inutilmente crudele (e già il sistema dei parametri delle funzioni in Python non è proprio una perla di chiarezza, diciamolo). Quindi ben venga la patch tardiva.
Secondo, i dizionari. Certo, adesso è stato introdotto un vincolo implementativo: se in futuro, per dire, qualcuno dovesse fare un dizionario ancora più performante *ma* non order-preserving, non potrebbe più inserirlo dentro python. Occhei, sono d'accordo. Ma d'altra parte, l'evoluzione verso un dizionario order-preserving è nella natura delle cose, e sostanzialmente i core-devs di python sono sempre stati piuttosto d'accordo su questo, da Guido a Raymond stesso.
Ora so che adesso ti metti a smattare, ma a un certo punto un linguaggio vale anche perché è usato, e se la gente si aspetta i dizionari order-preserving, vuol dire che è una soluzione comoda in un certo numero di casi d'uso. Guarda javascript (ecco, adesso smatti: te l'avevo detto). Per anni la gente ha ciclato su Object aspettandosi che fosse order-preserving. Adesso finalmente hanno Map: il risultato è che tutti usano Map nello stesso modo in cui (speravano di) usare Object. Per anni quelli di Chrome sono andati avanti a litigare con gli sviluppatori su questo (
https://bugs.chromium.org/p/v8/issues/detail?id=164#c83 ma tutto il thread...), mentre mettevano patch per sistemare piccoli bachetti, cose da nulla capisci... tipo che *il feed di Facebook* su Chrome non veniva ordinato giusto... Ma se alla fine pure i devs di Facebook sono dei niubbi che non sanno usare le strutture-dati corrette, non so, qualcosa di sbagliato ci sarà. Alla fine, devi leggere l'ultimo commento del thread: "Previously, our customized JSON parser generated a separated array of the properties on the insertion order on a Object. Now, we switched to Map everywhere". Ecco fatto, tanto ci voleva, problema risolto, passiamo ad altro.
Ora, anche se in linea di principio vedo le tue obiezioni (non tutte, e non tutte sono in grado di capirle), a lato pratico non credo che i core devs di Python in questo pasticcio se la siano cavata malissimo tenute conto delle condizioni al contorno. Non hai poi tutte quelle collections nella libreria standard; se i dizionari sono l'unico mapping che hai, la gente li usa e si aspetta che siano order-preserving; che i dizionari siano order-preserving, del resto, è probabilmente una buona cosa nel 2018; oltre tutto li hai usati per anni per implementare i named arguments in modo bizzarro bordeggiante nel fallato. Dato questo, la soluzione proposta non mi sembra che rompa codice preesistente, è più performante... e sì: hai cambiato sottilmente la semantica di un builtin. Per un linguaggio che ha vissuto il dramma di py2/py3 forse non è la cosa più grave.
Poi certo, quando vedrò __builtins__.COOKIE mi verrà il sospetto che avevi ragione tu fin dal principio.