Чтобы сделать этот вопрос ответственным, давайте предположим, что цена неоднозначности в уме программиста намного дороже, чем несколько дополнительных нажатий клавиш.
Учитывая , что, почему бы я , чтобы мои товарищи по команде , чтобы уйти с не аннотирования их параметры функции? Возьмем следующий код в качестве примера того, что может быть гораздо более сложным фрагментом кода:
let foo x y = x + y
Теперь быстрая проверка подсказки покажет вам, что F # определил, что вы хотите, чтобы x и y были целыми числами. Если это то, что вы намеревались, то все хорошо. Но я не знаю, хотел ли ты этого. Что если бы вы создали этот код для объединения двух строк вместе? Или что, если я думаю, что вы, вероятно, хотели добавить двойки? Или что, если мне просто не нужно наводить указатель мыши на каждый параметр функции, чтобы определить его тип?
Теперь возьмем это в качестве примера:
let foo x y = "result: " + x + y
F # теперь предполагает, что вы, вероятно, намеревались объединить строки, поэтому x и y определены как строки. Однако, как бедняга, который поддерживает ваш код, я мог бы взглянуть на это и подумать, возможно, вы намеревались добавить x и y (целые числа) вместе, а затем добавить результат в строку для целей пользовательского интерфейса.
Конечно, для таких простых примеров можно было бы отпустить, но почему бы не применить политику явной аннотации типов?
let foo (x:string) (y:string) = "result: " + x + y
Какой вред в том, чтобы быть однозначным? Конечно, программист мог выбрать неправильные типы для того, что он пытается сделать, но, по крайней мере, я знаю, что они этого хотели, что это был не просто недосмотр.
Это серьезный вопрос ... Я все еще очень плохо знаком с F # и прокладываю путь для моей компании. Стандарты, которые я принимаю, вероятно, станут основой для всего будущего кодирования F #, встроенного в бесконечное копирование, которое, я уверен, будет проникать в культуру на долгие годы.
Итак ... есть ли в выводе F # что-то особенное, что делает его ценной функцией, позволяющей комментировать только при необходимости? Или опытные F # -еры имеют привычку аннотировать свои параметры для нетривиальных приложений?
источник
Ответы:
Я не использую F #, но в Haskell считается хорошей формой для аннотирования (по крайней мере) определений верхнего уровня, а иногда и локальных определений, даже несмотря на то, что язык имеет всеобъемлющий вывод типов. Это по нескольким причинам:
Чтение
Когда вы хотите знать, как использовать функцию, невероятно полезно иметь доступную сигнатуру типа. Вы можете просто прочитать его, вместо того, чтобы пытаться сделать это самостоятельно или полагаться на инструменты, которые сделают это за вас.
Рефакторинг
Когда вы хотите изменить функцию, наличие явной подписи дает вам некоторую гарантию того, что ваши преобразования сохраняют намерения исходного кода. В языке с выводом типа вы можете обнаружить, что высокополиморфный код будет проверять тип, но не будет выполнять то, что вы хотели. Сигнатура типа является «барьером», который конкретизирует информацию о типе в интерфейсе.
Производительность
В Haskell предполагаемый тип функции может быть перегружен (с помощью классов типов), что может подразумевать диспетчеризацию во время выполнения. Для числовых типов типом по умолчанию является целое число произвольной точности. Если вам не нужна полная универсальность этих функций, то вы можете улучшить производительность, специализируя функцию для нужного вам типа.
Для локальных определений,
let
-связанных переменных и формальных параметров для лямбды, я считаю , что сигнатуры типов , как правило , стоят дороже , в коде , чем значение , они бы добавить. Поэтому в обзоре кода я бы предложил вам настаивать на подписи для определений верхнего уровня и просто запрашивать разумные аннотации в других местах.источник
.mli
файле interface ( ) (если вы пишете таковые, что настоятельно рекомендуется. Аннотации типов, как правило, исключаются из определений, поскольку они будут избыточными с интерфейсом..fsi
файлах F # signature ( ), с одной оговоркой: F # не использует файлы сигнатур для вывода типов, поэтому, если что-то в реализации является неоднозначным, вам все равно придется аннотировать его снова. books.google.ca/…Джон дал разумный ответ, который я не буду повторять здесь. Однако я покажу вам вариант, который может удовлетворить ваши потребности, и в процессе вы увидите другой тип ответа, отличный от да / нет.
В последнее время я работаю с синтаксическим анализом с использованием комбинаторов синтаксического анализа. Если вы знаете синтаксический анализ, то знаете, что обычно вы используете лексер на первом этапе и анализатор на втором этапе. Лексер преобразует текст в токены, а анализатор преобразует токены в AST. Теперь, когда F # является функциональным языком, а комбинаторы предназначены для объединения, комбинаторы синтаксического анализатора предназначены для использования одних и тех же функций как в лексере, так и в синтаксическом анализаторе, но если вы задаете тип для функций комбинатора синтаксического анализатора, их можно использовать только для lex или разобрать а не оба.
Например:
или
Так как код защищен авторским правом, я не буду его здесь включать, но он доступен на Github . Не копируйте это здесь.
Чтобы функции работали, их нужно оставить с общими параметрами, но я включаю комментарии, которые показывают предполагаемые типы в зависимости от использования функций. Это облегчает понимание функции обслуживания, оставляя функцию общей для использования.
источник
Количество ошибок прямо пропорционально количеству символов в программе!
Обычно это указывается как количество ошибок, пропорциональных строкам кода. Но меньшее количество строк с одинаковым количеством кода дает одинаковое количество ошибок.
Поэтому, хотя приятно быть явным, любые дополнительные параметры, которые вы вводите, могут привести к ошибкам.
источник