2009-09-28 2 views
5

Я всегда работал на статически типизированных языках (C/C++, Java). Я играю с Clojure, и мне это очень нравится.От статического ввода до динамического ввода

Одна вещь, о которой я беспокоюсь, говорит: скажем, что у меня есть окна, которые принимают 3 модуля в качестве аргументов и по мере изменения требований, и мне нужно передать другой модуль в функцию. Я просто меняю функцию, и компилятор жалуется везде, где я ее использовал. Но в Clojure он не будет жаловаться до тех пор, пока функция не будет вызвана. Я могу просто выполнить поиск и замену регулярных выражений, но кажется, что есть шанс пропустить вызов, и он останется незамеченным до тех пор, пока эта функция не будет вызвана. Как вы с этим справитесь?

+4

Как вы, ребята, имеете дело с этим? По моему опыту, правильный ответ был бы «Не очень хорошо». –

ответ

8

Это одна из причин, по которым автоматическое тестирование/тестирование управляемых процессов еще более важно для динамически типизированных языков. Я не использовал Clojure (я в основном использую Ruby), поэтому, к сожалению, я не могу рекомендовать конкретную среду тестирования.

+2

+1. по существу, система статического типа - это всего лишь автогенерированный набор модульных тестов (как любит один из моих друзей-динамистов-евангелистов). Вам нужно закодировать их вручную на динамическом языке, что дает вам большую гибкость, но также и большие усилия. Это зависит от вас и вашего конкретного проекта, чтобы решить, согласуется ли этот компромисс с динамическим или статическим языком. – rmeador

+1

вы замаскируете тот факт, что работа с системой статического типа требует усилий. Вопрос в том, что больше? – jshen

+2

@jshen: но сколько усилий? В * хорошо * статически типизированном языке вы можете в значительной степени забыть, что он статически типизирован. Только в барахле, как на C-языках, вы должны постоянно напоминать компилятору о всех типах. – jalf

0

Вы теряете определенный уровень рефакторинга и сохраняете безопасность при переходе на динамические языки. Чем больше информации у компилятора, тем больше он может сделать во время компиляции для вас.

+0

Извините мое невежество, но как динамическая типизация заставляет вас потерять некоторый уровень рефакторинга? – khelll

+0

Он, вероятно, означает «автоматический рефакторинг» здесь. –

+0

Я считаю, что предложение означает «рефакторинг безопасности». – DigitalRoss

0

Тим Брей обсуждает его here, критика которого от Седрика here и post об искусстве, обсуждая его подробно.

3

Первое я хотел бы упомянуть о том, что Брюс Eckel написал очень интересную статью под названием Strong Typing vs Strong Testing (ссылка вниз на данный момент, к сожалению, но, надеюсь, это будет скоро).

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

Его цель состоит в том, что если вы разрабатываете программы должным образом, то есть выполняете какие-либо тесты и регрессионные тесты, отсутствие компилятора будет заставлять вас добавлять какие-то дополнительные, несколько базовые тесты в любом случае, поэтому большие потери.

Итак, я думаю, что первый ответ, который я вам даю, сосредоточен на тестировании, что-то, что вы должны делать в любом случае, и такие изменения не должны сильно влиять на вас.

Вторая вещь Я бы хотел упомянуть, что многие динамические языки, которые я видел (например, Python), имеют гораздо лучшие возможности для изменения того, что делают методы/классы, не нарушая существующий код.

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

Я предлагаю посмотреть, какие методы Clojure позволяют делать подобные вещи и решать, применяют ли они в вашей ситуации.

1

Тестовое покрытие, безусловно, важно. Но динамически типизированный язык позволит вам работать по-другому. В строго типизированном языке (например, Java) изменение интерфейса требует изменения всех вызывающих абонентов. В Ruby вы могли бы это сделать ... но, вероятно, этого не произойдет.Вместо этого вы, вероятно, добавите гибкость методу одним из нескольких способов. А именно:

  • У вас, как правило, очень мало методов, которые занимают до трех параметров в Ruby (в отличие от Java). Поскольку у вас нет строго типизированного интерфейса Java, вы разбиваете проблему на более мелкие части и шаги. Гораздо чаще пишут методы, которые принимают только один параметр, а затем реорганизуют, когда он становится более сложным.
  • Это возможно - и обычно - оставить прежнее поведение на месте при добавлении дополнительных аргументов. Например, если вам нужно добавить третий аргумент в метод с двумя аргументами, вы установите его значение по умолчанию, чтобы сохранить прежнее поведение (и сохранить рефакторинг). Если вы знакомы с библиотеками Javascript, такими как jQuery, они используют это везде с «необязательными» аргументами.
  • Подобно дополнительным аргументам, методы могут расти, чтобы получить список гибких параметров. Обладая надежным покрытием, вы можете легко добавить новое поведение к существующему методу и безопасно знать, что вы не нарушили существующий код. В Rails такие методы, как «render», используют широкий спектр опций.
2

Вы делаете то же самое, что и вы, если этот метод является частью открытого интерфейса, которым вы не являетесь единственным пользователем.

Вы добавляете новый метод с дополнительным модулем и меняете старый, чтобы вызвать новый с подходящим значением по умолчанию.

О, и если ваша программа является то, что большой, убедитесь, что у вас есть хорошие тесты (тест-это должно сделать его проще, чем Java)

1

Вы не полностью без поддержки компилятора в Clojure. В конкретном примере, который вы даете, это изменение функции, которое было бы изменено, с помощью компиляции кода Clojure. Я все еще делаю сильный -> динамический переход на печать и нахожу это утешительным!

0

Если вам действительно нужна статическая типизация, вы можете использовать https://github.com/clojure/core.typed и модуль leiningen для проверки прохождения статической переменной.

Смежные вопросы