Почему "делать" разрешено внутри функции?

Я заметил, что следующий код компилируется и работает в VS 2013:

let f() =
    do Console.WriteLine(41)
    42

Но при рассмотрении спецификации F # 3.0 я не могу найти упоминания о do, используемом таким образом. Насколько я могу судить, do может иметь следующие применения:

  • Как часть цикла (например, while expr do expr done), это не так.
  • Внутренние выражения вычисления, например:

    seq {
        for i in 1..2 do
        do Console.WriteLine(i)
        yield i * 2
    }
    

    В этом случае не так, f не содержит выражений вычисления.

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

  • Заявление внутри модуля или класса. Это также не так, do находится внутри функции, а не внутри модуля или класса.

Я также заметил, что с #light "off" код не компилируется ( "Неожиданное ключевое слово" делает "в привязке" ), но я не нашел ничего, что объясняло бы это в разделе о легком синтаксисе.

Исходя из всего этого, я бы предположил, что использование do внутри функции таким образом не должно компилироваться, но это так. Я что-то пропустил в спецификации? Или это на самом деле ошибка в компиляторе или в спецификации?

Ответ 1

Из документации на MSDN:

A do привязка используется для выполнения кода без определения функции или значения.

Несмотря на то, что спецификация не содержит исчерпывающий список мест, которые разрешены, это просто выражение, утверждаемое как тип unit. Некоторые примеры:

if ((do ()); true) then ()
let x: unit = do ()

Обычно он опускается. Каждый из предыдущих примеров действителен без do. Поэтому do служит только для утверждения, что выражение имеет тип unit.

Ответ 2

Просматривая спецификацию F # 3.0, синтаксис выражения имеет do expr как выбор class-function-or-value-defn (типы) [Ch 8, A. 2.5] и module-function-or-value-defn (модули) [Ch 10, A.2.1.1].

Я действительно не вижу в спецификации, где function-defn может иметь более одного выражения, так что все, кроме последнего, оцениваются как unit - или что все, кроме последнего выражения, игнорируются при определении функций возвращаемое значение.

Итак, похоже, что это надзор в документации.