Действительный идентификатор символов в Scala

Одна вещь, которую я нахожу довольно запутанной, это знание, какие символы и комбинации я могу использовать в именах методов и переменных. Например

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

Насколько я понимаю, существует различие между буквенно-цифровыми идентификаторами и идентификаторами операторов. Вы можете смешивать одно или другое совпадение, но не оба одновременно, если они не разделены подчеркиванием (смешанный идентификатор).

Из раздела Программирование в Scala 6.10,

Идентификатор оператора состоит из одного или нескольких символов оператора. Символы оператора являются печатными символами ASCII, такими как +,:,?, ~ Или #.

Точнее, символ оператора принадлежит к набору математических символов Unicode (Sm) или других символов (So) или 7-разрядным символам ASCII, которые не являются буквами, цифрами, круглыми скобками, квадратными скобками, фигурными скобками, одинарными или двойными кавычка или символ подчеркивания, точка, точка с запятой, запятая или обратный тик.

Таким образом, мы исключены из использования ()[]{}'"_.;, и `

Я посмотрел математические символы Unicode в Википедии, но те, которые я нашел, не включали +, :, ? и т.д. Есть ли где-нибудь определенный список символов оператора?

Кроме того, есть идеи, почему математические операторы Unicode (а не символы) не считаются операторами?

3 ответа

Решение

Работа от синтаксиса EBNF в спецификации:

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”

Но также с учетом самого начала лексического синтаксиса, который определяет:

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

Вот что я придумаю. Работая отбором в ассортименте \u0020-007F, исключая буквы, цифры, скобки и разделители, мы имеем для opchar... (барабанная дробь):

! # % & * + - / : < = > ? @ \ ^ | ~ а также Sm а также So - за исключением скобок и периодов.

(Изменить: добавив действительные примеры здесь:). Таким образом, вот несколько действительных примеров, которые выделяют все случаи - следите за \ в REPL я должен был сбежать как \\:

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

Примечание 1:

Я нашел этот индекс категории Unicode, чтобы выяснить, Lu, Ll, Lo, Lt, Nl:

  • Лу (заглавные буквы)
  • Ll (строчные буквы)
  • Ло (другие буквы)
  • Lt (заглавие)
  • Nl (буквенные числа, такие как римские цифры)
  • Sm (символ математики)
  • Итак (символ другой)

Заметка 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

Заметка 3:

Другие операторские вещи, которые являются зарезервированными словами: _ : = => <- <: <% >: # @ а также \u21D2 ⇒ и \u2190

Спецификация языка. дает правило в главе 1, лексический синтаксис (на странице 3):

  1. Оператор персонажей. Они состоят из всех печатаемых символов ASCII. которые не входят ни в один из перечисленных выше наборов, математические символы (Sm) и другие символы (So).

Это в основном то же самое, что и ваша выдержка из "Программирование в программировании в Scala" + не является математическим символом Unicode, но это определенно печатный символ ASCII, не перечисленный выше (не буква, включая _ или $, цифра, парантез, разделитель).

В вашем списке:

  1. # недопустимо не потому, что символ не является символом оператора (#^ допустимо), а потому что это зарезервированное слово (на странице 4) для проекции типа.
  2. & 2 недопустимо, потому что вы смешиваете символ оператора & и неоператорский символ, цифра 2
  3. £ 2 допустимо, потому что £ не является символом оператора: это не семибитовый ASCII, а расширенный 8-битный ASCII. Это не приятно, как $ тоже не один (это считается буквой).

используйте обратные кавычки, чтобы избежать ограничений и использовать символы Unicode

      val `r→f` = 150
println(`r→f`)

Другие вопросы по тегам