Каковы особенности динамических языков (например, 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
, но я никогда не использую его, даже в динамических языках.
Я нахожу, что проблема гораздо важнее всего, когда речь идет о выборе языка для использования для данной задачи. Инструменты, культура, библиотеки - все это гораздо интереснее, чем печатать, когда дело доходит до решения проблемы с языком.
Изучение языка программирования, с другой стороны, совершенно иное.:)
Ответ 5
Некоторая критика Scala была выражена Стивом Йегге здесь и здесь, и Guido van Rossum, которые в основном атаковали сложность системы Scala. Они явно не являются "программистами Scala". С другой стороны, здесь похвала от Джеймса Страчана.
Ответ 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 может поймать за секунду. Кроме того, наличие всех типов во время компиляции упрощает рефакторинг.