Caracteres de identificación válidos en Scala

Una cosa que me resulta bastante confusa es saber qué caracteres y combinaciones puedo usar en los nombres de métodos y variables. Por ejemplo

val #^ = 1 // legal val # = 1 // illegal val + = 1 // legal val &+ = 1 // legal val &2 = 1 // illegal val £2 = 1 // legal val ¬ = 1 // legal 

Según lo entiendo, hay una distinción entre identificadores alfanuméricos e identificadores de operador . Puede mezclar una coincidencia uno con otro, pero no ambos, a menos que esté separado por un guión bajo (un identificador mixto ).

De la progtwigción en Scala sección 6.10,

Un identificador de operador consiste en uno o más caracteres de operador. Los caracteres de operador son caracteres ASCII imprimibles como +,:,?, ~ O #.

Más precisamente, un carácter de operador pertenece al conjunto Unicode de símbolos matemáticos (Sm) u otros símbolos (So), oa los caracteres ASCII de 7 bits que no son letras, dígitos, paréntesis, corchetes, llaves, simples o dobles cita, o un carácter de subrayado, punto, punto y coma, o marca de retroceso.

Entonces estamos excluidos de usar ()[]{}'"_.;, Y`

Busqué símbolos matemáticos Unicode en Wikipedia , pero los que encontré no incluían + , : , ? etc. ¿Existe una lista definitiva en algún lugar de cuáles son los caracteres del operador?

Además, ¿alguna idea de por qué los operadores matemáticos Unicode (en lugar de símbolos) no cuentan como operadores?

Trabajando desde la syntax EBNF en la especificación:

 upper ::= 'A' | ... | 'Z' | '$' | '_' and Unicode category Lu lower ::= 'a' | ... | 'z' and Unicode category Ll letter ::= upper | lower and Unicode categories Lo, Lt, Nl digit ::= '0' | ... | '9' opchar ::= “all other characters in \u0020-007F and Unicode categories Sm, So except parentheses ([]) and periods” 

Pero también teniendo en cuenta el principio de la syntax léxica que define:

 Parentheses '(' | ')' | '[' | ']' | '{' | '}'. Delimiter characters ''' | ''' | '"' | '.' | ';' | ',' 

Aquí es lo que se me ocurrió. Trabajando por eliminación en el rango \u0020-007F , eliminando letras, dígitos, paréntesis y delimitadores, tenemos para opchar … (drumroll):

! # % & * + - / : < = > ? @ \ ^ | ~ ! # % & * + - / : < = > ? @ \ ^ | ~ y también Sm y So – excepto paréntesis y puntos.

(Editar: agregando ejemplos válidos aquí :). En resumen, aquí hay algunos ejemplos válidos que resaltan todos los casos: cuidado con \ en el REPL, tuve que escapar como \\ :

 val !#%&*+-/:<=>?@\^|~ = 1 // all simple opchars val simpleName = 1 val withDigitsAndUnderscores_ab_12_ab12 = 1 val wordEndingInOpChars_!#%&*+-/:<=>?@\^|~ = 1 val !^©® = 1 // opchars ans symbols val abcαβγ_!^©® = 1 // mixing unicode letters and symbols 

Nota 1:

Encontré este índice de categoría Unicode para descubrir Lu, Ll, Lo, Lt, Nl :

  • Lu (letras mayúsculas)
  • Ll (letras minúsculas)
  • Lo (otras letras)
  • Lt (titlecase)
  • Nl (números de letras como números romanos)
  • Sm (símbolo de matemáticas)
  • Entonces (símbolo otro)

Nota 2:

 val #^ = 1 // legal - two opchars val # = 1 // illegal - reserved word like class or => or @ val + = 1 // legal - opchar val &+ = 1 // legal - two opchars val &2 = 1 // illegal - opchar and letter do not mix arbitrarily val £2 = 1 // working - £ is part of Sc (Symbol currency) - undefined by spec val ¬ = 1 // legal - part of Sm 

Nota 3:

Otras cosas que parecen operadores que son palabras reservadas: _ : = => <- <: <%>: # @ y también \u21D2 ⇒ y \u2190

La especificación del idioma da la regla en el Capítulo 1, syntax léxica (en la página 3):

  1. Caracteres del operador Estos consisten en todos los caracteres ASCII imprimibles \ u0020- \ u007F. que no están en ninguno de los conjuntos anteriores, símbolos matemáticos (Sm) y otros símbolos (So).

Esto es básicamente lo mismo que su extracto de Progtwigción en Progtwigción en Scala. + no es un símbolo matemático Unicode, pero definitivamente es un carácter imprimible ASCII que no se encuentra en la lista anterior (no una letra, incluyendo _ o $, un dígito, una parátesis, un delimitador).

En tu lista:

  1. # es ilegal no porque el personaje no sea un carácter de operador (# ^ es legal), sino porque es una palabra reservada (en la página 4), para la proyección de tipo.
  2. & 2 es ilegal porque mezcla un carácter de operador & y un carácter no operador, dígito 2
  3. £ 2 es legal porque £ no es un carácter de operador: no es un ASCII de siete bits, sino un ASCII extendido de 8 bits. No es agradable, ya que $ tampoco es uno (se considera una letra).