Какие символы допускаются в идентификаторах F#, модулях, типах и именах членов?

Этот вопрос касается символов в идентификаторах, а не ключевых слов в качестве идентификаторов.

Я нашел этот вопрос на именах C#, но не смог найти то же самое на F#. Обычно это вряд ли актуально, но в моих тестах именования я часто использую точку . и был удивлен, что он не поддерживается в имени модуля, но поддерживается в привязке let:

// fails:
module ``Run Test.Me functions`` = 
    [<Test>]
    let ``X.Add should add``() = test <@ X.Add 2 2 = 4 @>

// Succeeds
module ``Run Test-Me functions`` 
    [<Test>]
    let ``X.Add should add``() = test <@ X.Add 2 2 = 4 @>

Вне тестов именования я не вижу большой пользы для этого, но это заставило меня задуматься: какие символы поддерживаются именами типов и модулей, и какие символы для имен членов и привязок let?

Некоторые тесты:

module ``Weird.name`` = ()  // fails
module ``Weird-name`` = ()  // succeeds
module ``Weird()name`` = () // succeeds (?)
module ``Weird*name`` = ()  // fails
module ``Weird+name`` = ()  // fails
module ``Weird%name`` = ()  // succeeds (?)
module ``Weird/name`` = ()  // fails
module ``Weird\\name`` = () // fails

Все эти имена следуют в привязке let или имени члена, но не в качестве имени типа или имени модуля. По крайней мере, это соответствует. Но я не могу найти какую-либо строку или логику в том, что разрешено, а что нет

Возможно, ограничение накладывается CLR / MSIL, а не самим F#?

1 ответ

Решение

Взгляните на спецификацию языка F# 4.0 - в разделе 3.4 Identifiers and Keywords,

Обратите внимание, что когда идентификатор используется для имени типа, регистра объединения типа, модуля или пространства имен, следующие символы недопустимы даже внутри двойных обратных кавычек:
., +, $, &, [, ], /, \\, *, \", `

В дополнение к этому списку, @ (at-sign) допускается под любым именем, но выдает предупреждение:

предупреждение FS1104: идентификаторы, содержащие '@', зарезервированы для использования при генерации кода F#

Насколько я могу найти:

Список символов можно найти в компиляторе F# с именем IllegalCharactersInTypeAndNamespaceNames.

Поскольку это используется для генерации IL, это приводит к разделу I-VI ECMA-335 - Common Language Infrastructure (CLI), который гласит:

II.5.3 Идентификаторы - Идентификаторы используются для именования объектов. Простые идентификаторы эквивалентны идентификатору. Однако синтаксис ILAsm позволяет использовать любой идентификатор, который может быть сформирован с использованием набора символов Unicode (см. Раздел I). Для этого идентификатор должен быть заключен в одинарные кавычки.

ID представляет собой непрерывную строку символов, которая начинается либо с
буквенный символ (A–Z, a–z)
или один из _, $, @, ` (серьезный акцент) или ?,
и сопровождается любым числом
буквенно-цифровые символы (A–Z, a–z, 0–9)
или персонажи _, $, @, ` (серьезный акцент) и ?

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