On 2014-02-13 18:50, Dario Bertini wrote:
On 02/13/2014 05:03 PM, Daniele Varrazzo wrote:
- sai che a[n] non è un carattere ma è un byte. La bugia dei widechar non regge. Neanche quella di unicode in python che però si rompe al di fuori del BMP (a meno che non lo compili 4 byte per carattere blah blah)

Forse sono pignolo, ma "la bugia dei widechar non regge" non vuol dire
quasi nulla visto che:
- non specifichi cos'è un widechar (è un codeunit a 16 bit, o un
codepoint memorizzato in 32?)
- non chiarisci in che modo non regge

wchar_t è compiler dependent: potrebbe essere anche 8 bit. Tanto per essere utile.

Se fosse 16 bit, comunque ti servono 2 unità per esprimere un carattere fuori BMP (surrogate pairs)

Se fosse 32 bit, comunque ci sono i caratteri combinanti. Non ne esci.

Cosa non regge è l'idea che se hai widechar, non mi interessa quanto wide, comunque né accesso casuale né lunghezza siano operazioni genericamente utili. Anche in utf32:

    In [3]: s = u'\u0075\u0301'

    In [4]: len(s)
    Out[4]: 2

    In [5]: print s
    ú


Python da questo punto di vista non ha nessun problema, con Py3.3
l'astrazione unicode non mi sembra sia leaky e comunque mi risulta che tutte le distro linux fornissero da diversi anni solo le wide build di
python di default

Non lo sapevo. Che spreco. Nessuno usa i caratteri fuori dal BMP <grin> Non so come verificarlo ma sembra sia così:

sys.getsizeof(u'aa') - sys.getsizeof(u'a')
4


insomma: di default le cose funzionano bene da anni... anche se sono
d'accordo che il fardello cognitivo del ricordarsi di "fallire
graziosamente" sulle narrow build fosse un deal breaker

- tipicamente l'i/o non richiede encoding/decoding

Questo vuol dire che se i dati che leggi non sono codificati
correttamente te ne accorgi proprio nel mezzo dell'elaborazione

Anche in python. Tutto funziona finché non arriva un accento e le cose si rompono. Magari si rompono in I/O, mentre tutto quello che occorreva era leggere una stringa da un database e scriverla su una pagina web: per un programma scritto negli ultimi 10 anni ci sono buone chance che entrambi siano utf8 e la codifica/decodifica non era necessaria: un accento sarebbe arrivato indenne a destinazione, anche se Python non l'avrebbe visto come codepoint singolo.

Il problema sono i dati legacy. Go credo non ne voglia avere a che fare, e ne approfitta per fare pulizia. Se scrivi un programma oggi da zero sarà bene che faccia tutto con unicode/utf8. Il problema delle codifiche 8 bit è un problema che hanno i linguaggi colla, e Go ha deciso di semplificare su questo punto e guardare al presente/futuro invece che al passato. Anche ora, con tutte le interfacce che gestisco (database, web, email, file...) non uso praticamente nessun encoding che non sia utf8. Se proprio c'è un input latin1 ok, ci sarà un decoder sull'interfaccia che lo converte: non cambia rispetto a Python.


penso sarebbe stato meglio fare di len("whatever") un compile error in Go, e fornire una funzione size() allo scopo... size si presta di meno
ad essere fraintesa come "lunghezza di un testo"

se uno non sa che cosa sta facendo, a livello di usare una stringa senza sapere se sono codepoint o una codifica, non vedo la necessità di venirgli incontro. Meglio faccia un altro lavoro. Altrimenti rischia di centrare male la stringa in cinese nello schermo.

Se per questo vorrei una macchina del tempo per dare una martellata sulle dita di chi ha implementato str.encode() e unicode.decode(), perpretando sempre di più l'idea che str e unicode siano intercambiabili. Ho bestemmiato i miei santi migliori dietro alle librerie che chiamano x.decode() qualunque cosa sia x, e siccome va bene agli americani va bene a tutti. O meglio magari funziona nella shell ma si rompe in crontab perchè una variabile d'ambiente è diversa [1]. Dare ad unicode l'interfaccia non di una lista ma di un iterabile avrebbe fatto notare che len(unicode) non è un'operazione poi così utile - e se proprio ti serve fai len(list(u)). Invece che ha fatto in python3? Ha azzoppato bytes rimuovendo l'operatore %, quindi tutto *deve* essere [de]codificato. A questo punto ecco il bastone, lì ci sono i cuccioli di foca... Ok fine rant :)


È un linguaggio opinionato

Anche Python è un linguaggio opinionato: solo perchè a te non piacciono
i bytes literals (così mi sembra), non vuol dire che "paghi sempre
l'overhead necessario" :P

Perché non mi dovrebbero piacere i byte literal? :)

E sì, paghi overhead in codifica (input), elaborazione (4 volte la memoria e quindi il tempo per processarla) e decodifica (output) anche dove non sarebbe stato necessario: è un fatto che non vedo come si possa negare. Usare unicode ovunque mi va benissimo: è giusto ed è il presente e il futuro. È la scelta di rappresentarlo internamente come array di codepoint che crea delle strozzature. Go non ha queste chicane, il che lo rende più efficiente sull'I/O di qualunque magia possa fare Python. Penso gli dia più questo che il fatto di essere compilato.


-- Daniele


[1] ok, questo è un problema diverso, ma deriva dal fatto che in python tutti gli encoding hanno la stessa importanza, che è una panzana colossale visto che solo uno gestisce il dominio completo, mentre gli altri esplodono su diversi sottoinsiemi.

    piro@bagheera:~$ python -c 'print u"\u20ac"'
    €
    piro@bagheera:~$ LC_CTYPE=C python -c 'print u"\u20ac"'
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)

Cosa vorrei da un linguaggio moderno? Che se chiedo di scrivere dell'unicode in un file i dati, grazie, per favore, convertili nell'unico encoding che può gestire tutto il dominio unicode, no, non voglio fare una partita alla roulette degli encoding. Se in quel file strano e curioso voglio scriverci in LATIN15 ti passerò dei byte codificati da me. Sì esistono terminali che non gestiscono utf8. Sì, sono io il coglione se ti chiedo di stamparci sopra €, non è colpa tua: un risultato indeterminato va bene. Ma ti prego, non crashare alle 3 di mattina per un print.

_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a