[Python] 0 in (False,) // 0 == False (era: Re: Qu)

Pietro Battiston toobaz a email.it
Dom 14 Feb 2010 13:15:33 CET


Il giorno dom, 14/02/2010 alle 12.26 +0100, Enrico Franchi ha scritto:
> On Feb 14, 2010, at 11:38 AM, Pietro Battiston wrote:
> 
> >> Eh... poi ci troviamo con questo. Indichiamo con b un booleano, con n,m,...
> >> un intero e con a qualcosa che puo' essere indifferentemente un booleano
> >> o un intero. Il nostro obiettivo e' definire le operazioni su Bool U Int, rispettivamente
> >> l'insieme dei booleani e degli interi. 
> > 
> > ... con Bool ⊂ Int ?
> 
> Dipende. Nel python attuale si, nel "tuo" python ovviamente no.
> 
> >> Normalmente ci aspettiamo che:
> >> 
> >> n + m - m == n
> >> siamo d'accordo?
> >> False + m - m != False
> > No, è qui il punto, io mi rendo perfettamente conto che questo si
> > perderebbe, ma non mi interessa, perché ... 
> > ... perché una cosa così non la userei mai e poi mai
> 
> Questo poco importa. Mi spiego, il fatto che tu od io pensiamo che usare
> una data feature del linguaggio (esplicitamente) non sia una buona idea,
> e' irrilevante.
> 
> Di fatto quello che otteniamo e' che la nuova struttura algebrica, che abbiamo
> voluto per togliere una piccola bruttura, e' un orrido. Permettermi ma trovarci
> con una cosa che non e' manco un gruppo per togliere identita' fra False e 
> 0 mi sembra una cura peggiore del male.
> 
> Il fatto che tu consideri o meno quel codice sensato non toglie che sia
> perfettamente valido e di conseguenza tutto il codice scritto assumendo
> proprieta' ragionevoli come quelle la sopra diventa automaticamente *sbagliato*.
> 
> 
> > : anche ammesso che
> > dei valori di verità si possano _contare_ (sempre perché torna comodo),
> > non li conto certamente con un booleano: prima che completamente
> > antipythonico, è estremamente controintuitivo. A parlare in generale si
> > rischia sempre, ma mi sento comunque di dire che _nessuno_ "conterebbe"
> > davvero con un booleano: tutt'al più, quel che facciamo è contare _i_
> > booleani - cosa che si fa benissimo semplicemente con la conversione al
> > volo di False in 0 e True in 1.
> 
> Quando progetti un linguaggio non puoi dire... si, questa feature del linguaggio
> e' sbagliata e porta ad assurdi, ma tanto nessuno vuole veramente usarla.
> Perche' qualcuno che la usera' ci sara'. 
> 
> E ne verrebbero fuori thread ben peggiori di questo. Per togliere un "fastidio"
> (avere due oggetti diversi con lo stesso comportamento) ci troviamo con tutta
> la struttura matematica dei tipi interi a mare.
> 
> 
> > Questo è un motivo per cui quanto scrivi sopra è ben lontano dallo
> > scandalizzarmi. L'altro è che se veramente tu ritieni che
> >   n + m - m == n
> > sia una regola sacrosanta che anche i booleani dovrebbero rispettare,
> > allora
> > 
> >   In [1]: a = 5
> > 
> >   In [2]: False + a - a
> >   Out[2]: 0
> > 
> > per me è scandaloso. Io vorrei leggere "False". Poi tu mi dici che è la
> > stessa cosa, ma io sono convinto sia questione di abitudine e non si
> > finisce più...
> 
> Non ho parlato di "regole sacrosante". Tuttavia mi sembra ragionevole, no?
> E' talmente poco sacrosanto che in C non me lo aspetto e non vale. Ma non
> e' che sia una buona cosa, voglio dire. Non me lo aspetto nemmeno con i 
> float. 
> 
> Ma visto che in Python abbiamo interi illimitati (essenzialmente), quella cosa
> li posso aspettarmela. Il fatto di perderla mi infastidisce molto piu' di 0 == False.
> 
> Questa cosa poi non e' questione di "abitudine". Tu insisti su quello che stampa.
> A me quello che stampa interessa veramente poco: mi interessa la semantica
> della computazione. Da un lato ho una cosa stampata che mi piace poco,
> dall'altra ho codice rotto. Per me non sono due cose sullo stesso piano.
> 
> > Pensa che per me invece è assurdo (anche se formalmente impeccabile) che
> > tu continui a chiamare
> >   (Bool U Int, +)
> > una cosa che, finché parliamo matematicamente, è semplicemente
> >   (Int, +)
> > dato che per come la vedi tu Bool ⊂ Int...
> 
> Non e' per come la vedo io, e' per come la vede Python. Per inciso, ho tenuto
> le cose distinte, perche' stiamo parlando di questo ipotetico nuovo Python con
> le tue regole. E in questo Python quello che stiamo andando a fare e' definire
> le operazioni in Bool U Int.
> 
> > Tu mi dici "ma non è giusto, i bool sono numeri come gli altri!".
> > Io dico di no.
> 
> No. Qui la faccenda e' andata oltre. Se non vuoi che i booleani siano interi,
> posso accettarlo. Allora ci saranno eccezioni esattamente come se sommi
> stringhe ed interi. Come fa Ruby. Questo e' un comportamento coerente.
> IMHO e' meno comodo, ma e' completamente sound e robusto.
> 
> Nel momento in cui decidiamo di dare semantica di somma ai booleani
> (che tu vuoi) tiriamo fuori i problemi di cui sopra.
> 
> > E questa è una differenza di opinione che non ha giustificazioni
> > formali: a seconda di come sei abituato a concepire il concetto di
> > booleano, alcune cose ti sembrano più controintuitive di altre.
> 
> Io ti sto dicendo: ci sono due mondi. Uno assolutamente inattaccabile
> (quello di Ruby) e uno piu' pragmatico che e' come fa Python. Nota,
> se anche i bool in Python non *fossero* numeri, ma si comportassero
> come numeri, 0 == False dovrebbe dare comunque True. 
> 
> Il mondo che tu proponi, e' quello in cui perdi praticamente tutte le 
> proprieta' algebriche utili.
> 
> > Infatti, il "problema" a cui pensavo è proprio questo, per cui per
> > tenere le cose pulite sarebbe più semplice che l'ordinamento tra Int e
> > Bool come li penso io rimanesse un ordinamento dei tipi.
> > 
> > Ciò detto, se posti i bool come li vorrei io ed un tale ordinamento
> > "stupido" poi qualcuno mi dicesse "il fatto che
> >   False > -1
> >   False < 1
> > ma
> >   False != 0
> > sembri controintuitivo è un sacrificio che vale la pena fare per poter
> > confrontare Int con Bool in modo interessante", io gli darei ragione.
> 
> Io temo che a questo punto sia proprio una tua fisima. Permetti, ma 
> mi stai dicendo che sei addirittura disposto a sacrificare il principio
> del terzo escluso, probabilmente a giocarti l'induzione ben fondata...
> 
> Tutto questo per non avere 0 == False. Ora io capisco che ti dia fastidio,
> ma non voglio credere che non ti dia un fastidio pazzesco il fatto che in
> nome di questo principio hai praticamente buttato a mare qualunque 
> possibile intuizione matematica.
> 
> > Tecnicamente, == è certamente un'uguaglianza semantica, ma io sono
> > convinto - il discorso sarebbe lungo e forse inutile - che lo scopo
> > prefissato è sempre l'aderenza all'== sintattica che un programmatore ha
> > in mente.
> 
> In un linguaggio ad oggetti, e' tutto semantico e non sintattico. Penso inevitabilmente.
> Ma davvero, non possiamo parlare di cose "intuitive" quando accettiamo che
> 
> a < b, a > b ma non a == b.
> 
> Tra l'altro, sebbene in disuso abbiamo ancora la funzione cmp. Che ritornerebbe
> -1 nel primo caso, 1 nel secondo e 0 nel terzo. Non so... cmp a sto punto dovrebbe
> lanciare un'eccezione.
> 
> 
> 
> Io credo di avere detto tutto quello che ho da dire sull'argomento.  Riassumendo,
> tu all'altare del False != 0 + aritmetica mista sei disposto a sacrificare:
> 
> 1. strutture algebriche
> 2. proprieta' abbastanza intuitive
> 3. principio del terzo escluso
> 4. cmp e simili
> 
> Io ti dico che IMHO tutto questo e' il famoso assurdo completo di cui parlavo.
> Se mi avessi detto che bandivi aritmetica mista, sarei stato assolutamente d'accordo.
> Non mi sarebbe piaciuto, ma avresti sacrificato pragmatismo per purezza.
> Si sarebbe solo potuto aprire un dibattito filosofico su quando il pragmatismo
> deve battere la purezza, al di la dello zen di Python.
> 
> Credo che invece avere aritmetica mista "castrata" che rompe praticamente
> tutte le altre proprieta' matematiche intuitive che non siano 0 != False sia una
> cura davvero peggiore del male.
> 

Il fatto è proprio che nell'implementare dei non-numeri, sono
prontissimo a sacrificare alcune proprietà che riconosco importantissime
nei numeri.

Tantopiù se comunque nei casi in cui torna utile - e lì necessariamente
si pensa in termini di ciò che torna comodo, anche se "non potrai mai
vedere tutto il codice che uno vorrebbe poter scrivere" - ho
implementate alcune operazioni comode tra bool e numeri.

Tantopiù se poi tutto ciò che ho perso lo recupero facendo un semplice
int(valore_anche_solo_potenzialmente_booleano).

Comunque anche secondo quel che dovevamo dircelo ce lo siamo detto;
chiarisco solo che non mi attribuisco del tutto l'omicidio del principio
del terzo escluso: l'ho buttato lì come possibilità, ma in effetti
sarebbe forse più coerente che l'ordinamento si comporti come un
generico ordinamento tra tipi diversi. E questa in effetti è la tua
obiezione che ritengo più azzeccata (anche se di nuovo i casi in cui
questo ordinamento torna utile mi sembrano più inesistenti che rari,
potrei sbagliarmi).

ciao

Pietro

P.S: mi scuso per il temporaneo subject surrealista che mi era sfuggito
qualche mail fa

P.P.S: Haskell... quello sì che è un (bel) linguaggio puro. Ma io
preferisco programmare in Python!



Maggiori informazioni sulla lista Python