[Python] 0 in (False,) // 0 == False

Daniele Varrazzo piro a develer.com
Ven 5 Feb 2010 17:20:47 CET


On Fri, 05 Feb 2010 15:54:44 +0100, Pietro Battiston <toobaz a email.it>
wrote:
> Il giorno ven, 05/02/2010 alle 14.58 +0100, Daniele Varrazzo ha scritto:
>> On Fri, 05 Feb 2010 14:41:00 +0100, Pietro Battiston <toobaz a email.it>
>> wrote:

>> > Ripeto: in un mondo ideale, io asserterei "True + 1 == 2" _e_ "True
!=
>> > 1" senza timore...
>> 
>> A me un pò di timore fa... Se le due proprietà di sopra fossero vere:
>> 
>> True + 1 == 2 => True + 1 - 1 == 2 - 1 => True == 1
>> 
>> Quindi non puoi avere anche True != 1, a meno di non rompere il
>> funzionamento degli interi.
>> 
> 
> A me sembra tu stia assumendo che True sia un intero (dato che parli di
> "funzionamento degli interi") per concludere che deve essere un intero.

No, non sto assumendo questo. Tutte le manipolazioni di sopra le ho fatte
con gli interi, sottraendo interi da interi e assumendo proprietà sensate
sugli interi (associatività, 0 come elemento neutro).

> Io ti dico che non lo vorrei nemmeno considerato come tipo numerico, ma
> come un generico tipo che fa il casting ad intero(/float) in modo
> sensato nelle operazioni con altri int.

Quello che ho mostrato qui è che ci sono problemi in un type system che
ammetta contemporaneamente i due predicati "True + 1 == 2" e "True != 1".
Puoi volere un sistema in cui bool == int non sia fattibile del tutto e
spari un'eccezione, questo sì. Ma se implementi aritmetica mista per non
implementare gli operatori logici misti sembra un sistema deboluccio.

Guarda, per il sistema che vorresti tu, con i bool tipi a parte, penso
occorra non ammettere operatori aritmetici sui booleani né aritmetica
mista. Non puoi fare il giochino dei triangoli o [a,b][True]? Pace :) si
potrebbe sempre usare una funzione esplicita per mappare bool in int.
Questa potrebbe essere anche la __int__() stessa, non c'è problema e le
stringhe già lo fanno ("1" + 1 fallisce ma int("1") + 1 no).  Un sistema di
questo genere premia più la consistenza matematica che la
convenienza/convenzione (a differenza di python in cui a volte la praticità
batte la purezza). Boole non si è mai sognato di dire che vero e falso
siano sommabili (in algebra, non in Python) e non me lo metto certo a dire
io :)

> Ti concedo che quanto hai scritto sopra è controintuitivo per chi è
> abituato a ragionare con i bool sottoclassi di int... ma a me False == 0
> sembra controintuitivo ad un livello molto più immediato; mi rendo conto
> che è questione di gusti ma, con tutto il rispetto, non riesco a non
> pensare che i gusti qui siano un po' condizionati da quello che offre la
> casa...

Il fatto è che c'era un'altra casa prima (il C) che già l'offriva (anzi,
era l'unico piatto, visto che false non c'era e tutti i programmi avevano
un #define FALSE (0) da qualche parte). Visto che il risultato di questa
implementazione è stato che TRUE e FALSE sono sommabili, e che questa si è
rivelata una caratteristica utile, si è deciso di mantenerla come feature
quando in Python sono stati introdotti True e False.

> Per cui onestamente da quel che dici tu non riesco a convincermi della
> tua (vostra) posizione.
> 
> Per farti un esempio: ora come ora,
> 
>>>> 1 + ''
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for +: 'int' and 'str'

Già l'ho detto: int e str non sono sommabili non per qualche
impossibilità, ma proprio per le troppe possibilità: è un'operazione
ambigua (visto che sia int che str implementano + ma con semantica divesa:
non si capirebbe se con S + N intendevi S + str(N) o int(S) + N), e una
delle scelte di base fatte in Python è di evitare le ambiguità.


> OK, supponiamo che per qualsivoglia motivo a me faccia comodo che
>   numero + stringa
> restituisca
>   numero + len(stringa)
> , e quindi mi faccio le mie due classi che ereditano da int e str
> rispettivamente, in cui faccio l'override di tutte le operazioni
> aritmetiche che mi fanno comodo, rimpiazzando ogni argomento stringa con
> len(stringa).
> Bene, puoi dire che è inutile e stupido, ma non mi si "rompe" proprio
> niente: sarà perfettamente normale che, se int(a) == 0 e int(b) == 1,
>   a != []
> ma
>   [] + b = b + a
> 
> Ora, immagina che invece che subclassare io implementi direttamente la
> stessa operazione in cpython direttamente in int e str... cosa cambia?!

Non ho capito tutti i passaggi dell'esempio (parlavi di stringhe e poi hai
messo le liste). Ma penso di aver capito il senso. Se non l'ho capito,
spiega pure, ma mi sembra che stiamo finendo a discutere di una cosa ancora
diversa da quella originale.

-- 
Daniele Varrazzo - Develer S.r.l. 
http://www.develer.com


Maggiori informazioni sulla lista Python