Каковы особенности динамических языков (например, Ruby или Clojure), которые вам не хватает в Scala?

Что вы теряете на практике, когда выбираете статически типизированный язык, например Scala (или F #, Haskell, С#) вместо динамически типизированных, таких как Ruby, Python, Clojure, Groovy (который есть макросы или возможности метапрограммирования времени выполнения)? Пожалуйста, рассмотрите лучшие статически типизированные языки и лучшие (на ваш взгляд) динамически типизированные языки, а не худшие.

Резюме ответов:

Ключевые преимущества динамических языков, таких как Ruby, над статически типизированным языком, например, Scala IMHO:

  • Быстрый цикл редактирования (позволяет ли JavaRebel сократить пробел?)
  • В настоящее время сообщество Scala/Lift намного меньше, чем Ruby/Rails или Python/Django
  • Возможно изменение типов определений (хотя мотивация или необходимость в этом не очень понятна)

Ответы

Ответ 1

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

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

На практике, с Scala, вы отказываетесь от всего остального - и ничего, что меня особенно волнует. Вы не можете вводить новые методы, но вы можете скомпилировать и запустить новый код. Вам нужно указать типы в аргументах функции (и тип возвращаемого значения с рекурсивными функциями), что немного раздражает, если вы никогда не делаете ошибки типа самостоятельно. Поскольку он компилирует каждую команду, Scala REPL не так быстро, как, например, оболочки Python. И поскольку в нем используются механизмы отражения Java, у вас нет достаточной простоты онлайн-проверки, которую вы делаете с помощью, например, Python (в любом случае, не создавая собственную библиотеку проверок).

Ответ 2

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

Ответ 3

  • Динамические языки имеют гораздо более гибкие системы типов. Например, Python позволяет вводить новый метод в существующие классы или даже в один объект.
  • Многие (не все) статические языки не имеют возможности создавать сложные литералы. Например, такие языки, как С# и Java, не могут легко имитировать следующий JavaScript { 'request':{'type':'GET', 'path':mypath}, 'oncomplete':function(response) { alert(response.result) } }.
  • Динамические языки имеют очень флюидную семантику. Python позволяет операторам импорта, определениям функций и определениям классов появляться внутри функций и if.
  • eval является основным продуктом большинства динамических языков и нескольких статических языков.
  • Программирование более высокого порядка проще (по моему субъективному мнению) в динамических языках, чем статические языки, из-за неловкости необходимости полностью определять типы параметров функции.
    • Это особенно характерно для рекурсивных конструкций HOP, где система типов действительно может мешать.
  • Пользователи динамического языка не должны иметь дело с ковариацией и контравариантностью.
  • Общее динамическое программирование практически бесплатное.

Ответ 4

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

Я полагаю, вы обычно также теряете eval, но я никогда не использую его, даже в динамических языках.

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

Изучение языка программирования, с другой стороны, совершенно иное.:)

Ответ 6

Мои 2 цента...

ИМО (сильные) статически типизированные языки могут уменьшить количество необходимого кода тестирования, потому что часть этой работы будет выполнена компилятором. С другой стороны, если шаг компиляции относительно длинный, это затрудняет выполнение "инкрементного" программирования, которое в реальной жизни может привести к подверженному ошибкам коду, который был протестирован только для передачи компилятора.

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

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

Я думаю, что Scala находится где-то посередине (например, вам не нужно явно указывать типы переменных, что может облегчить обслуживание кода по сравнению, например, с С++, но если вы закончите неверное предположение о типах, компилятор будет напоминать об этом, в отличие от PHP, где вы можете писать что угодно, и если у вас нет хороших тестов, охватывающих функциональность, вы обречены на то, чтобы узнать, когда все живое и кровоточит). Возможно, это будет ужасно неправильно:)

Ответ 7

По моему мнению, разница между статическим и динамическим типированием сводится к стилю кодирования. Хотя в Scala существуют структурные типы, большую часть времени программист думает с точки зрения типа объекта, включая классные гаджеты, такие как черта. С другой стороны, я думаю, что программисты Python/Javascript/Ruby думают о прототипе объекта (список методов и свойств), который немного отличается от типов.

Например, предположим, что существует семейство классов с именем Vehicle, подклассы которого включают Plane, Train и Automobile; и другое семейство классов под названием Animal, подклассы которого включают Cat, Dog и Horse. Программист Scala, вероятно, создал бы признак Transportation или что-то, что имеет

def ride: SomeResult
def ride(rider: Someone): SomeResult

в качестве члена, поэтому она может обрабатывать как Train, так и Horse как средство транспортировки. Программист Python просто передаст объект поезда без дополнительного кода. Во время выполнения язык указывает, что объект поддерживает ride.

Тот факт, что вызовы метода разрешены во время выполнения, позволяет языкам, таким как Python и Ruby, иметь библиотеки, которые переопределяют значение свойств или методов. Хорошим примером этого является сопоставление O/R или привязка данных XML, в котором имя свойства undefined интерпретируется как имя поля в типе таблицы /XML. Я думаю, что это то, что люди подразумевают под "гибкостью".

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