Rust: Problema de seguimiento para identificadores que no son ASCII (característica "non_ascii_idents")

Creado en 12 oct. 2015  ·  54Comentarios  ·  Fuente: rust-lang/rust

Los identificadores que no son ASCII están actualmente restringidos a funciones. Se debe arreglar el manejo de ellos y quitar la puerta principal.

B-unstable C-tracking-issue P-low T-lang

Comentario más útil

No estoy seguro de si este es el lugar correcto para publicar esto, pero es probable que aparezcan algunos problemas interesantes con la pelusa de símbolos matemáticos. Se evita fácilmente escribiendo los nombres de las variables, pero podría ser importante si el objetivo es lograr una mejor correlación con las ecuaciones reales.

Por ejemplo, Δ (mayúsculas) frente a δ (minúsculas) en la siguiente captura de pantalla. El linter no es /incorrecto/, pero tampoco tiene sentido aplicar el requisito del caso de la serpiente aquí.

screen shot 2017-06-27 at 2 28 55 pm

Todos 54 comentarios

/cc @rust-lang/lang

nominando

cc @SimonSapin

Aparentemente implementamos esto: http://www.unicode.org/reports/tr31/ o algo así.

Me gustaría ver esto estabilizado, pero tomará algo de trabajo convencernos de que estamos haciendo lo correcto.

No tengo idea de qué es lo correcto aquí. Además de las recomendaciones de Unicode, es posible que deseemos ver qué hacen realmente otros idiomas y qué informes de errores relacionados o críticas reciben. ¿O esto ya se hizo cuando se introdujo la función por primera vez?

@SimonSapin
C y C++ usan http://unicode.org/reports/tr31/#Alternative_Identifier_Syntax (con algunas restricciones menores) y no he visto ninguna queja al respecto en los foros de isocpp o listas de problemas :)
Descripción general del problema: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1518.htm
Implementación en Clang: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/UnicodeCharSets.h?view=markup
CC https://github.com/rust-lang/rust/issues/4928

También hay un problema con la normalización de los identificadores y la asignación de nombres Unicode mod a los nombres del sistema de archivos (en OS X, IIRC), pero no puedo encontrar el enlace relevante aquí: https://github.com /rust-lang/rust/issues/2253. (En el peor de los casos, mod s y extern crate s no en línea pueden ser forzados a ser ASCII)

Sí, #2253 es el gran problema que conozco que me hace preocuparme por la estabilización prematura de los identificadores que no son Unicode.

(La discusión allí es más amplia y podría decirse que podría dividirse en dos subprocesos; por ejemplo, _podríamos_ tomar una ruta de normalización para los identificadores y otra para los contenidos de cadenas literales).

es posible que deseemos migrar esta discusión al repositorio de RFCS, por ejemplo, en https://github.com/rust-lang/rfcs/issues/802

Estoy de acuerdo en que esta es una característica que merece pasar por el proceso de RFC.

He reutilizado este problema para rastrear la estabilización (o desaprobación, etc.) de la puerta de funciones non_ascii_idents .

Después de la discusión en la reunión del equipo de lang, decidimos que sí, un RFC sería el camino correcto a seguir aquí. Necesitamos algo que recopile las soluciones de otros lenguajes, analice sus ventajas y desventajas y sugiera la opción adecuada para Rust. Esto es lo suficientemente controvertido y complejo como para que se presente a la comunidad en general, especialmente porque muchos de nosotros que hackeamos Rust a diario no tenemos mucha experiencia con no ASCII de todos modos.

triaje: P-bajo

Marcado tan bajo como que no hay RFC en la actualidad y, por lo tanto, no hay contenido procesable.

En JavaScript, Perl 5 y Perl 6 esta característica está disponible.
Javascript (Firefox 50)

function Слово(стойност) {
  this.стойност = стойност;
}
var здрасти = new Слово("Здравей, свят");
console.log(здрасти.стойност) //Здравей, свят

Perl >=5.12

use utf8;
{
  package Слово;
  sub new {
    my $self = bless {}, shift;
    $self->{стойност} = shift;
    $self
  }
};
my $здрасти = Слово->new("здравей, свят");
say ucfirst($здрасти->{стойност}); #Здравей, свят

Perl6 (esta no es solo la próxima versión de Perl. Este es un nuevo lenguaje)

class Слово {
  has $.стойност;
}

my $здрасти = Слово.new(стойност => 'здравей, свят');
say $здрасти.tc; #Здравей, свят

Me encantaría verlo en Rust también.

Por si sirve de algo, los identificadores en ECMAScript 2015 se basan en la sintaxis del identificador predeterminado del anexo n.° 31 del estándar Unicode .

Perl con use utf8; usa la expresión regular a continuación, con XID_Start y XID_Continue presumiblemente también de UAX # 31.

/ (?[ ( \p{Word} & \p{XID_Start} ) + [_] ])
        (?[ ( \p{Word} & \p{XID_Continue} ) ]) *    /x

¡Sí! ¡Gracias @SimonSapin!

Para Python es <XID_Start> <XID_Continue>* .

Así que parece que muchos lenguajes de programación que permiten identificadores que no son ASCII se basan en el mismo estándar, pero en los detalles, cada uno hace algo ligeramente diferente...

Personalmente, me encantaría ver soporte para identificadores relacionados con las matemáticas. Por ejemplo, ∅ (y operadores de conjuntos, como ∩ y ∪). Traducir ecuaciones de trabajos de investigación/especificaciones a código suele ser un proceso terrible que da como resultado un código detallado y difícil de leer. Ser capaz de usar los mismos identificadores en el código que están en las ecuaciones matemáticas del artículo simplificaría la implementación y haría que el código fuera más fácil de verificar y comparar con las ecuaciones del artículo.

¿Cuál es el punto de esta característica exactamente? Además de agregar la posibilidad de crear una combinación realmente fea de diferentes idiomas en su código (el inglés es el único idioma verdaderamente internacional), no brinda beneficios en cuanto a la funcionalidad del idioma. ¿O es el soporte de Unicode por el hecho de admitir Unicode?

@DoumanAsh No todos los programas son internacionales, y la fluidez en inglés no tiene que ser un requisito para la programación.

Está bien que los mantenedores de cualquier proyecto decidan que los nombres de las variables y los comentarios en su código deben estar en inglés. Esto es lo que sucede con muchos proyectos de código abierto, incluido el propio rustc. Pero eso no significa que el lenguaje deba restringirse a eso.

El caso de uso que veo no es para escribir código de producción, sino para enseñar. Realmente apesta decirle a la gente que tienen que hablar inglés con fluidez para convertirse en programadores. La otra situación es cuando está escribiendo una interfaz de usuario en un idioma extranjero, si su interfaz de usuario tiene un cuadro de texto con la etiqueta "příjmení" pero termina poniendo el valor en una variable llamada "apellido" que es extraño. Aún más raro es si tienes un campo llamado "rodné_číslo" (número de identificación nacional checo). No hay una palabra análoga en inglés para eso. Entonces, si estuviera escribiendo una aplicación de impuestos checa o una aplicación bancaria, tendría que usar un nombre extraño sin una buena razón. De todos modos, no es como si una aplicación de este tipo fuera portátil a otros idiomas.

Otra buena razón para permitir esto es que los lingüistas a menudo necesitan usar la notación IPA en los nombres de las variables. Los nombres en inglés de los símbolos IPA pueden ser ridículamente largos. Por ejemplo, el sonido r del inglés americano en la palabra red se transcribe como un carácter ɹ̠ pero se denomina aproximante retroflexivo postalveolar. https://en.wikipedia.org/wiki/Alveolar_and_postalveolar_approximants Entonces, si estoy escribiendo un programa de texto a voz, podría razonablemente querer escribir fn say_ɹ̠() en lugar de fn say_post_alveolar_retroflexive_approximant() .

En el lado de las cosas que no son de opinión, creo que hay una discusión interesante aquí con respecto a qué puntos de código Unicode pueden ser parte de un nombre de variable. Por ejemplo: ¿Puedo nombrar una variable price€ ? Probablemente no, no creo que price$ funcione, ¿verdad? ¿Puedo crear una macro →![] para generar vectores? Sé que alguien podría querer hacerlo, pero → es un "símbolo matemático" http://www.fileformat.info/info/unicode/char/2192/index.htm . Entonces, cuando lexing, debemos tomar una decisión sobre qué puntos de código son aceptables y cuáles no, y tal vez el óxido no debería simplemente preguntar tontamente al estándar Unicode si algo es una letra o no.

@timthelion en la implementación actual, Rust no simplemente pregunta tontamente al estándar Unicode si algo es una letra o no; se basa en las propiedades Unicode XID_Start y XID_Continue que tienen un comportamiento correcto e intuitivo en todos sus ejemplos.

  • say_ɹ̠ está permitido porque tanto 'ɹ' como '̠' son XID_Continuar.
  • price€ y price$ no están permitidos porque '€' y '$' no son XID_Continuar.
  • →![] no está permitido porque '→' no es XID_Start.
  • příjmení y rodné_číslo están permitidos.

@dtolnay gracias por la explicación. Espero que no te hayas ofendido por mi uso de la palabra "tonto", tal vez esa fue una palabra mal elegida.

No, solo señalo que las grandes mentes piensan igual y la buena gente del comité técnico de Unicode tenían las mismas preocupaciones que tú.

Puedo pensar en otros casos de uso en producción.

Algunas palabras en un campo específico son difíciles de traducir al inglés, pero algunos programas (por ejemplo, juegos, servicios locales en línea y fuera de línea) pueden tener que lidiar, por ejemplo, nombres de platos chinos, nombres de héroes, nombres de lugares. Los programadores que trabajan para empresas no necesitan saber cuáles son las traducciones al inglés, pero tienen que dar sus nombres de variables y funciones. Se les ocurrirán nombres extraños si tienen que usar inglés, generalmente muy difíciles de entender para otros compañeros de trabajo.

En este punto creo que no hay duda de que hay muchos casos de nosotros. Lo que queda por hacer es averiguar los detalles:

  • Qué caracteres exactamente se deben permitir. Por ejemplo, la puntuación no ASCII probablemente debería excluirse.
  • Cuánta normalización se debe hacer: dos identificadores se pueden representar con diferentes puntos de código (diferentes bytes UTF-8 en los archivos fuente) pero aun así se pueden considerar equivalentes.

Varios otros idiomas están de acuerdo con el Anexo estándar Unicode # 31, pero tienen pequeñas diferencias en los detalles. Idealmente, averiguaríamos qué motivó estas diferencias para decidir qué es lo mejor para Rust.

https://rosettacode.org/wiki/Unicode_variable_names tiene información para muchos idiomas.

Estoy de acuerdo con @SimonSapin : nadie duda de que esto sería útil. El problema es que no existe una solución estándar y muchos de nosotros (por ejemplo, yo mismo) estamos en una mala posición para evaluar las compensaciones. Lo que nos falta es alguien que recopile las restricciones y haga una recomendación, sospecho. Sospecho que en este punto cualquier decisión sería preferible a ninguna decisión, aunque definitivamente preferiría seguir algún precedente (idealmente, una especificación o anexo Unicode, pero tal vez también otro idioma) que simplemente adoptar Otro conjunto de reglas.

@nikomatsakis Sería bueno investigar exactamente qué motivó las pequeñas diferencias entre varios idiomas, pero si nadie da un paso adelante para hacer esa investigación y queremos continuar de todos modos, entonces creo que siguiendo exactamente UAX # 31 (que creo que es lo que nuestro la implementación actual lo hace) es un buen valor predeterminado.

Todavía puede valer la pena pasar por el proceso de RFC con un diseño detallado, incluso si coincide con la implementación actual. (Qué caracteres se pueden usar, cómo se normalizan/comparan por equivalencia, cómo tratamos con futuras versiones de Unicode, etc.) Sugiero que quien escriba este RFC lea UAX 31 de arriba a abajo al menos una vez.

También es posible que deseemos considerar la creación de un nuevo perfil PRECIS [1] (o, más probablemente, utilizando un subconjunto restringido de uno de los perfiles existentes) para los identificadores. Esto nos permitiría normalizar los identificadores que deberían considerarse iguales incluso si son ligeramente diferentes (p. ej., para entornos locales que tienen teclados que generan texto que se ve igual, pero difiere ligeramente en su representación Unicode), así como proporcionar una clara y un conjunto conciso de reglas para determinar qué es un identificador de Rust válido.

No estoy al tanto de ninguna implementación Rust existente del marco PRECIS (creo que todavía falta gran parte de la infraestructura Unicode requerida para crear uno, pero esto probablemente tendría que arreglarse de alguna manera).

No me llamaría un experto, pero he ayudado a construir una implementación de PRECIS y, en general, estoy familiarizado con los RFC y algunos de los escollos y trampas, por lo que estaría feliz de ayudar (o molestar al grupo de trabajo de PRECIS para obtener ayuda) donde sea necesario

[1] [RFC 7564](https://tools.ietf.org/html/rfc7564): marco PRECIS: preparación, cumplimiento y comparación de cadenas internacionalizadas en protocolos de aplicación

Buen punto sobre los personajes que se ven iguales. aqui esta la wikipedia
articulo sobre el tema
https://en.wikipedia.org/wiki/Duplicate_characters_in_Unicode

Aquí hay un artículo que explica que los caracteres duplicados de
los guiones asiáticos están en su mayoría unificados:

https://people.w3.org/rishida/scripts/chinese/

El 11/04/2017 a las 21:01, Sam Whited escribió:
>

También podemos considerar la creación de un nuevo (o, más probablemente, el uso de un
subconjunto restringido de uno de los perfiles existentes) Perfil PRECIS [1]
para identificadores. Esto nos permitiría normalizar los identificadores que
deben considerarse iguales incluso si son ligeramente diferentes (p.
para locales que tienen teclados que generan texto que se ve igual,
pero difiere ligeramente en su representación Unicode) así como proporcionar
un conjunto claro y conciso de reglas para determinar qué es un Rust válido
identificador

No tengo conocimiento de ninguna implementación Rust existente de PRECIS
marco (mucha de la infraestructura Unicode necesaria para crear uno
todavía falta, creo, pero esto probablemente tendría que arreglarse
un poco de cualquier manera).

[1] RFC 7564 https://tools.ietf.org/html/rfc7564 : Marco PRECIS:
Preparación, Cumplimiento y Comparación de Cadenas Internacionalizadas
en Protocolos de Aplicación


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/rust-lang/rust/issues/28979#issuecomment-293367700 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ABU7-IMgXefW2yZYyM0tn8qLhpGFw0bSks5ru84GgaJpZM4GM3Lj .

@SamWhited ¿Por qué PRECIS sobre NFC o NFKC de Unicode?

¿Por qué PRECIS sobre NFC o NFKC de Unicode?

TL: DR: la normalización es solo un paso que nos gustaría hacer al determinar si algo es un identificador válido. Es posible que también sea necesario (o no) realizar otras operaciones.

@SimonSapin La normalización Unicode es solo un paso de un perfil PRECIS (por lo que, de hecho, estaríamos usando la normalización; probablemente NFC como una suposición), sin embargo, PRECIS cubre una gama más amplia de cosas. Por ejemplo, los formularios de normalización no hacen mapeo de ancho (¿no lo creo?), por lo que FullWidth no será el mismo identificador que FullWidth . Si está en un teclado que quiere escribir texto de ancho completo, esto puede ser un problema (esto es probablemente más un problema con los caracteres del este de Asia que con los caracteres latinos, pero tal vez alguien de un lugar que usa texto de ancho completo podría intervenir y decirme si estoy tergiversando el problema de alguna manera). Otras cosas que puede hacer un perfil PRECIS incluyen definir un subconjunto de propiedades de caracteres que están permitidas (por ejemplo, letras, números, guiones y comienza con una letra o algo así).

_Descargo de responsabilidad:_ No he pensado realmente si la asignación de texto de ancho completo sería deseable o no; es solo un ejemplo Es muy posible que la normalización sea todo lo que importa, o tal vez no nos interese hacer ningún mapeo en absoluto; Vaya solo a verificar si los identificadores tienen la propiedad de letra o número, creo, así que si se las arreglan solo con eso, tal vez también esté bien para nosotros. Ciertamente se necesita más reflexión.

Lectura adicional: esto es lo que hace la especificación Go (que es mucho más simple de lo que sugerí, lo que puede o no ser algo bueno): https://golang.org/ref/spec#Source_code_representation

¿Qué utiliza PRECIS? ¿Algún lenguaje de programación?

¿Qué utiliza PRECIS? ¿Algún lenguaje de programación?

No estoy seguro de qué otro lenguaje hace excepto Go .

Problema relacionado con Go 2: golang/go#16033

El martes 11 de abril de 2017 a las 02:07:49 p. m. -0700, Sam Whited escribió:

Por ejemplo, los formularios de normalización no hacen mapeo de ancho, por lo que FullWidth no será el mismo identificador que FullWidth .

NFKC hace eso:

Python 3.6.0 (default, Jan 16 2017, 12:12:55)
[GCC 6.3.1 20170109] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> FullWidth = 1
>>> FullWidth
1

--
Atentamente,
lilydjwg

@SamWhited , en tu primer enlace encuentro:

identifier = letter { letter | unicode_digit } .
letter        = unicode_letter | "_" .

Pero por lo que puedo decir, Go actualmente no realiza ninguna normalización y usar PRECIS es una propuesta. ¿Es eso correcto?

Pero por lo que puedo decir, Go actualmente no realiza ninguna normalización y usar PRECIS es una propuesta. ¿Es eso correcto?

@SimonSapin eso es correcto; bueno, ni siquiera es realmente una propuesta, solo una idea para pensar como este problema (lo siento, releí esa oración y mi enlace y estaba mal redactado; no quise sugerir que lo use en este momento, solo que yo no sé qué otra cosa que no sea Go realmente hace para manejar identificadores que no son ASCII).

@SimonSapin

Todavía puede valer la pena pasar por el proceso de RFC con un diseño detallado, incluso si coincide con la implementación actual.

👍

Estaba leyendo UAX #31 para ver lo que hicieron, y me llamó la atención otro beneficio de usar un perfil PRECIS: al igual que desaprobar stringprep y usar PRECIS en su lugar, proporciona una manera de ser compatible y ágil en el futuro en todas las versiones de Unicode ( operando sobre propiedades derivadas de puntos de código en lugar de puntos de código individuales).

Si bien TR31 tiene un concepto de " identificadores inmutables " para ayudar a abordar esto, efectivamente es una versión un poco menos restrictiva de un protocolo PRECIS derivado de la clase de forma libre, pero sin las consideraciones que PRECIS ha dado al orden en que las reglas deben ser aplicado (¿no lo creo?) Tampoco cubre casos extremos cubiertos por el marco PRECIS, como el uso de sigma final griego, o algunos de los casos extremos alrededor de Hangul Jamo (nuevamente, no soy experto en ninguno de estos , pero para eso existe PRECIS, los expertos ya han hecho el trabajo).

proporciona una manera de ser compatible y ágil en el futuro en todas las versiones de Unicode (al operar en propiedades derivadas de puntos de código en lugar de puntos de código individuales).

No entiendo este punto. XID_Start y XID_Continue son propiedades derivadas.

No entiendo este punto. XID_Start y XID_Continue son propiedades derivadas.

Podría haber entendido mal UAX 31 entonces; me pareció que requería una versión específica de Unicode. Sin embargo, releyendo no puedo ver de dónde saqué eso.

No estoy seguro de si este es el lugar correcto para publicar esto, pero es probable que aparezcan algunos problemas interesantes con la pelusa de símbolos matemáticos. Se evita fácilmente escribiendo los nombres de las variables, pero podría ser importante si el objetivo es lograr una mejor correlación con las ecuaciones reales.

Por ejemplo, Δ (mayúsculas) frente a δ (minúsculas) en la siguiente captura de pantalla. El linter no es /incorrecto/, pero tampoco tiene sentido aplicar el requisito del caso de la serpiente aquí.

screen shot 2017-06-27 at 2 28 55 pm

¿Sería posible permitir emoji en nombres de variables aunque no sean XID Start/Continue, como en Swift?

@fwrs , los emojis son mucho más complicados ahora que los personajes que no son emoji.

Gracias a algunos proveedores, ahora puede tener secuencias de unión de Emoji (ZWJ) que simplemente cambian sus colores y pequeños detalles, muchos de los cuales no son necesariamente visibles a simple vista.

Además, la definición de Emoji se está expandiendo rápidamente, cada año, lo cual no es algo que necesite un lenguaje de programación a nivel de sistema que quiera ser estable y confiable.

Entonces, aunque es lindo, no creo que encaje bien con los objetivos de Rust. Sin embargo, los lenguajes educativos/de secuencias de comandos basados ​​en óxido pueden beneficiarse al permitir emojis, según sus objetivos.

@ryankurte Hay un problema semántico en su ejemplo: está transcribiendo fórmulas matemáticas, pero usó U + 0394 LETRA MAYÚSCULA GRIEGA DELTA en lugar de U + 2206 INCREMENTO. La primera es una letra del alfabeto griego y, como tal, tiene mapeo de casos; el último es un símbolo matemático y no lo es.

Me gustaría vincular este comentario: https://github.com/rust-lang/rust/issues/4928#issuecomment -343137316

No he visto la posibilidad de habilitar ataques basados ​​en homoglifos aquí (si alguien los mencionó, ignore el ruido), pero acabo de llenar un problema recortado para solicitar una pelusa que advierte sobre un código como este:

#![feature(non_ascii_idents)]
fn main() {
    let a = 2;
    let а = 3;
    assert_eq!(a, 2);  // OK
    assert_eq!(а, 3);  // OK
}

En pocas palabras, esos dos a son caracteres Unicode diferentes, por lo que el segundo enlace let no sombrea al primero, y ambas afirmaciones pasan (aunque el patio de recreo no parece admitir identificadores Unicode, por lo que la única forma de prueba esto localmente; funciona para mí).

Esta "característica" se puede usar para introducir exploits en los programas de Rust que son más difíciles de detectar, en particular dado que los enlaces let de sombreado son considerados idiomáticos por muchos Rust, incluido yo mismo.

PD: esta "característica" podría ser útil en concursos de Rust clandestinos, aunque ese #![feature(non_ascii_idents)] debería sorprender a algunos :)

@gnzlbg Creo que ya hay algo de soporte para la detección de elementos confusos para evitar que las personas intercambien sus puntos y comas por signos de interrogación griegos y demás, pero no sé si se aplica a los identificadores. Si lo hace, entonces eso resuelve ese problema; si no es así, al menos tenemos las herramientas para hacerlo listo para funcionar.

Me preocupa un poco que este sea un candidato para ser cerrado y el código eliminado del compilador porque no ha tenido un movimiento significativo por un tiempo y requiere un RFC. Me importa bastante que Rust sea un lenguaje del siglo XXI, lo que significa Unicode, y que Rust sea amigable con los programadores que no hablan inglés. Lo que me falta es la capacidad de escribir un RFC.

@Ketsuban

Creo que ya hay algo de soporte para la detección de elementos confusos para evitar que las personas cambien los puntos y comas por signos de interrogación griegos y demás, pero no sé si se aplica a los identificadores.

sí, creo que, como sugirió @oli-obk en el problema de clippy, la implementación de Rust simplemente usaría la última lista oficial de elementos confusos:

http://www.unicode.org/Public/security/revision-06/confusables.txt

Los ataques basados ​​en homoglifos se pueden prevenir. Sin embargo, esta lista debería mantenerse sincronizada, pero eso es algo que se puede automatizar como parte del sistema de compilación.

@Ketsuban

Si le importa esto, hay otros idiomas que admiten Unicode en sus identificadores, y estos idiomas tienen procesos similares al proceso RFC. Podrías empezar comprobándolos. Quién sabe, tal vez pueda fusionarlos con los comentarios en este problema y obtener un pre-RFC en el foro interno. A partir de ese momento, solo se trata de incorporar/discutir los comentarios con los demás, y antes de que te des cuenta tendrás un RFC listo.

En cierto modo, espero que nos quedemos con los identificadores ASCII para siempre. El manejo de identificadores Unicode es un gran dolor de interoperabilidad. Algunos de los ejemplos más extraños de asignaciones de NFKC son cosas como esta que se asignan al mismo identificador:

>>> ℌ = 1
>>> H
1
>>> Ⅸ = 42
>>> IX
42
>>> ℕ = 23
>>> N
23
>>> import math
>>> ℯ = math.e
>>> e
2.718281828459045
>>> ℨ = 2
>>> Z
2

@mitsuhiko El mundo real tiene ese tipo de dolor. No podemos simplemente ignorar este problema porque es difícil de manejar e involucra una característica para la que _personalmente_ no tiene uso.

Además, el RFC actual propone explícitamente NFC sobre NFKC, después de mucha discusión sobre ejemplos muy similares a esos.

¿Fue útil esta página
0 / 5 - 0 calificaciones