Это немного субъективно, но я надеюсь получить более четкое представление о том, какие факторы делают оператор понятным для использования по сравнению с тупым и трудным. Недавно я рассматривал языковые схемы, и одна проблема, на которую я всегда обращаю внимание, это когда нужно сделать какую-то ключевую операцию в языке оператором, а когда использовать ключевое слово или функцию.
Haskell несколько печально известен этим, поскольку пользовательские операторы легко создавать, и часто новый тип данных поставляется с несколькими операторами для использования на нем. Например, библиотека Parsec содержит множество операторов для объединения парсеров, например, с самоцветами, >.
и .>
я даже не могу вспомнить, что они значат прямо сейчас, но я помню, что с ними было очень легко работать, как только я запомнил, что они на самом деле имеют в виду. leftCompose(parser1, parser2)
Был бы вызов функции такой, как было бы лучше? Конечно, более многословный, но более понятный в некоторых отношениях.
Перегрузки операторов в C-подобных языках представляют собой аналогичную проблему, но сталкиваются с дополнительной проблемой перегрузки значения знакомых операторов, таких как +
необычные новые значения.
На любом новом языке это может показаться довольно сложной задачей. Например, в F # приведение использует математически выведенный оператор приведения типов вместо синтаксиса приведения стиля C # или многословного стиля VB. C #: (int32) x
VB: CType(x, int32)
F #:x :> int32
Теоретически новый язык может иметь операторы для большинства встроенных функций. Вместо def
или dec
или var
для объявления переменной, почему нет ! name
или @ name
или что-то подобное. Это, безусловно, сокращает объявление, сопровождаемое связыванием: @x := 5
вместо declare x = 5
или let x = 5
Большинству кода потребуется много определений переменных, так почему бы и нет?
Когда оператор понятен и полезен, а когда скрыт?
+
для конкатенации строк или <<
для потоков). С другой стороны, в Haskell оператор является либо просто функцией с произвольным именем (то есть не перегруженной), либо частью класса типов, что означает, что, хотя он полиморфен, он выполняет одинаковую логическую функцию для каждого типа, и даже имеет такую же подпись типа. Так >>
это >>
для каждого типа и никогда не будет немного сдвиг.