Подтвердить что ты не робот

Использование строк вместо символов: добро или зло?

Достаточно часто я встречаюсь со списками опций функций (или более общих списков замещения) формы {foo->value,...}. Это приводит к ошибкам, когда foo уже имеет значение в $Context. Один очевидный способ предотвратить это - использовать вместо символа строку "foo": {"foo"->value,...}. Это работает, но, похоже, я нарисовал некоторые опытные LISP, которых я знаю, которые наказывают меня за объединение символов и строк и говорят мне использовать встроенные цитаты.

В то время как, безусловно, можно написать код, который позволяет избежать конфликтов без использования строк, часто кажется, что это больше проблем, чем того стоит. С другой стороны, я не видел слишком много примеров правил замены типа {"string"->value}. Итак, вопрос для вас - это приемлемый шаблон использования? Существуют ли случаи, когда это особенно уместно?.. Куда его следует избегать?..

4b9b3361

Ответ 1

По моему мнению (отказ от ответственности - это только мое мнение), лучше избегать использования строк в качестве имен опций, по крайней мере для "основных" опций в вашей функции. Строки OTOH полностью соответствуют настройкам (r.h.s. опций). Это не означает, что вы не можете использовать строки, как вы заметили. Возможно, они могут быть более подходящими для подпараметров, и они используются таким образом многими системными функциями (обычно "суперфункциями", такими как NDSolve, которые могут иметь подпараметры в опциях). Основные проблемы, которые я вижу при использовании строк, заключается в том, что они уменьшают возможности самоанализа, как для системы, так и для пользователя. Другими словами, сложнее обнаружить опцию, которая имеет имя строки, чем имя символа, - для последнего я могу просто проверить имена символов в пакете, а также имена символьных параметров имеют сообщения об использовании. Вы также можете автоматизировать некоторые вещи, например, написать утилиту, которая находит все имена опций в пакете и т.д. Это легче сделать, когда имена опций являются символами, поскольку все они принадлежат одному и тому же контексту. Также легко обнаружить, что некоторые параметры не имеют сообщений об использовании, это можно сделать автоматически, написав функцию утилиты.

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

Что касается возможных коллизий, если вы следуете некоторым соглашениям об именах, таким как имя параметра, всегда начинающееся с заглавной буквы, плюс добавьте большую часть вашего кода в пакеты и не начинайте имена переменных или функций (для функций в интерактивном сеансе), с большой буквы, то вы значительно уменьшите вероятность таких столкновений. Кроме того, вы должны Protect имена опций, когда вы их определяете, или в конце пакета. Затем столкновения будут обнаружены как случаи затенения. Избегать теневого копирования, OTOH, является общей необходимостью, поэтому случай вариантов не является более особенным в этом отношении, чем имена функций и т.д.