Есть ли корреляция между масштабом проекта и строгостью языка?

72

Объясняя разницу между строгостью языков и парадигм моей коллеге, я кончил тем, что:

  • Толерантные языки, такие как динамические и интерпретируемые языки, лучше всего используются для прототипов и небольших проектов или веб-приложений среднего размера. При выборе элегантных динамических языков, таких как Python или JavaScript, с Node.js, преимуществами являются:

    1. Быстрое развитие,

    2. Сокращенный шаблонный код,

    3. Способность привлекать молодых креативных программистов, которые бегают от «корпоративных языков»,   таких как Java.

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

    1. Хорошо известные парадигмы и модели, разработанные на протяжении десятилетий,

    2. Простота статической проверки,

    3. Возможность найти много профессиональных разработчиков с многолетним опытом.

  • Строгие языки, такие как Haskell, Ada или методы, такие как контракты кода в C #, лучше подходят для систем, которые предпочитают безопасность, а не гибкость (даже если Haskell может быть чрезвычайно гибким), таких как жизненно важные системы и системы, которые, как ожидается, будут чрезвычайно стабильными. Преимущества:

    1. Возможность поймать как можно больше ошибок во время компиляции,

    2. Простота статической проверки,

    3. Легкость формальных доказательств.

Однако, глядя на языки и технологии, используемые крупномасштабными проектами для крупных корпораций, кажется, что мое утверждение неверно . Например, Python успешно используется для больших систем, таких как YouTube или других приложений Google, которые требуют значительного количества строгости.

Есть ли еще корреляция между масштабом проекта и строгостью языка / парадигмы, которую следует использовать?

Есть ли третий фактор, который я забыл принять во внимание?

Где я не прав?

Арсений Мурзенко
источник
12
Строгая проверка типов и статическая проверка типов не одно и то же. Python динамически типизирован, но более строг, чем C. Преимущество статической проверки типов заключается не в строгости как таковой, а в том, что типы проверяются во время сборки, а не во время выполнения. Я имел дело со многими проблемами C / C ++ в моей карьере из-за неявного приведения.
Gort the Robot
5
Вероятно, есть что сказать о жизненном цикле: программное обеспечение, которое запускается в вашей первой категории, может эволюционировать в другие, «перетягивая» язык вместе с ним.
Мат
11
Единственное, что элегантно в javascript - это то, что он работает в большинстве браузеров.
Джеффо
1
@StevenBurnap: Я не могу согласиться с разницей между статической и строгой. Ява - это еще одна точка спектра, будучи статичной и слишком строгой. Разработчики часто ругают статическую типизацию, используя в качестве примера Java, но большая часть этой критики должна быть направлена ​​на чрезмерно строгий компилятор Java , а не на статическую типизацию в целом. Просто посмотрите на Scala на той же JVM, которая статически типизирована, но содержит гораздо меньше подробного кода из-за фантастических способностей вывода типов компилятором.
Корнел Массон
2
«Python успешно используется для больших систем» - каково здесь определение «успех»? Что это в основном работает и дает какой-то результат? Включено ли количество необходимых испытаний и рабочей силы? Как насчет ремонтопригодности?
Den

Ответы:

39

Интересное тематическое исследование по вопросам масштабирования проектов, в которых используется динамический и интерпретируемый язык, можно найти в « Начальной Scala » Дэвида Поллака.

Я начал искать способ выразить код в моем мозгу более простым, более прямым способом. Я нашел Ruby и Rails. Я чувствовал себя освобожденным. Ruby позволил мне выразить концепции гораздо меньшим количеством строк кода. Rails было намного проще в использовании, чем Spring MVC, Hibernate и другие «оптимизированные» веб-фреймворки Java. С помощью Ruby и Rails я получил возможность выразить гораздо больше того, что было в моей голове за более короткий промежуток времени. Это было похоже на освобождение, которое я почувствовал, когда перешел с C ++ на Java ...

Когда мои проекты на Ruby и Rails вышли за рамки нескольких тысяч строк кода, и когда я добавил членов команды в свои проекты, проблемы динамических языков стали очевидными.

Мы потратили больше половины времени написания тестов, и значительная часть роста производительности, которую мы видели, была потеряна при написании тестов . Большинство тестов в Java были бы ненужными, потому что большинство из них были направлены на то, чтобы убедиться, что мы обновили вызывающие программы при рефакторинге кода путем изменения имен методов или количества параметров. Кроме того, я обнаружил, что работая в командах, где между двумя-четырьмя членами команды были умственные способности, дела в Ruby шли хорошо, но, поскольку мы пытались привлечь новых членов в команду, психические связи было трудно передать новым членам команды .

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

Как видите, основные проблемы в масштабировании проекта для автора оказались в разработке тестов и передаче знаний.

В частности, автор более подробно объясняет различия в написании тестов между динамически и статически типизированными языками в главе 7. В разделе «Ужасно убивая кроликов: лестницы Двемти» автор обсуждает порт Scala конкретного примера Ruby:

Почему Lucky Stiff ... представляет некоторые концепции метапрограммирования Руби в массиве Двемти, в котором кролик сражается с множеством существ. N8han14 обновил пример для работы в Scala ...

По сравнению с кодом Ruby библиотечные части кода Scala были более сложными. Нам пришлось проделать большую работу, чтобы убедиться, что наши типы были правильными. Нам пришлось вручную переписать свойства Creature в классах DupMonster и CreatureCons. Это больше работы, чем method_missing. Нам также пришлось проделать немалую работу, чтобы поддержать неизменность наших существ и оружия.

С другой стороны, результат был намного более мощным, чем версия Ruby. Если бы нам пришлось писать тесты для нашего кода на Ruby, чтобы проверить, в чем нас убеждает компилятор Scala, нам потребовалось бы намного больше строк кода. Например, мы можем быть уверены, что наш Кролик не может владеть Топором. Чтобы получить такую ​​уверенность в Ruby, нам нужно написать тест, который удостоверится, что вызов |^на Rabbit завершится неудачно. Наша версия Scala гарантирует, что этим Существом может использоваться только Оружие, определенное для данного Существа, что потребовало бы много времени отражения в Ruby ...


Чтение выше может заставить задуматься о том, что по мере роста проектов тестовая запись может стать непомерно громоздкой. Это рассуждение было бы неверным, о чем свидетельствуют примеры успешных очень крупных проектов, упомянутых в этом самом вопросе («Python успешно используется для ... YouTube»).

Дело в том, что масштабирование проектов не очень просто. Очень большие, долгоживущие проекты могут «позволить» другой процесс разработки тестов, с комплектами тестов качества продукции, профессиональными командами разработчиков тестов и другими тяжелыми вещами.

Youtube тестовые наборы или набор Java Compatibility уверен , жить другой жизнью , чем тесты в небольшой учебник проекта , как массив Dwemthy в .

комар
источник
24

Ваше утверждение не так. Вам просто нужно копать немного глубже.

Проще говоря, большие системы используют несколько языков, а не только один язык. Могут быть части, которые построены с использованием «строгих» языков, и могут быть части, которые построены с использованием динамических языков.

Что касается вашего примера с Google и YouTube, я слышал, что они используют Python в основном как «клей» между различными системами. Только Google знает, из чего строятся эти системы, но держу пари, что многие критически важные системы Google построены с использованием строгих и «корпоративных» языков, таких как C ++ или Java, или, возможно, что-то, что они сами создали, например, Go.

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

Так что да, некоторый уровень строгости требуется для крупных проектов. Это может быть связано либо со строгостью языка или структуры, либо с принципами программирования и соглашениями по коду. Вы не можете просто взять нескольких выпускников колледжа, дать им Python / Ruby / JavaScript и ожидать, что они напишут программное обеспечение, которое масштабируется на миллионы пользователей.

Euphoric
источник
«Нельзя просто захватить несколько выпускников колледжа» ... «и ожидать, что они напишут программное обеспечение, которое масштабируется на миллионы пользователей». вероятно, было бы достаточно.
красители
Стоит отметить, что, как и в случае с Google и Python, использование PHP в Facebook в основном как клей ... Насколько я понимаю, для большинства функций PHP в основном используется как относительно простой клиент для более сложной серверной системы, которая обычно реализуется в более традиционном "тяжеловеса" языка, таких как Java, C ++, Haskell, OCaml и т.д.
Жюль
«Только Google знает, из чего построены эти системы» ... У меня даже есть некоторые сомнения по этому поводу :) По моему опыту, ни одна сущность (человек или нет) не может перечислить все части очень большой системы. Во многих случаях в чашах какого-то сервера скрывается давно забытый фрагмент сценария Perl, Fortran или KSH, который выполняет «Магию».
Mattnz
3

Существует два вида ошибок для проверки: ошибки типа (объединение целых чисел + список с плавающей запятой) и ошибки бизнес-логики (перевод денег на банковский счет, проверка наличия денег на исходном счете).

«Динамическая» часть динамического языка программирования - это просто место, где происходит проверка типов. В «динамически типизированном» языке программирования проверка типов выполняется во время выполнения каждого оператора, тогда как в «статически типизированном языке» проверка типов выполняется во время компиляции. И вы можете написать интерпретатор для статического языка программирования (как это делает emscriptem ), а также вы можете написать статический компилятор для динамического языка программирования (как это делает gcc-python или shed-skin ).

В динамическом языке программирования, таком как Python и Javascript, вам нужно писать модульные тесты не только для бизнес-логики программы, но и для проверки, нет ли в вашей программе ошибок синтаксиса или типов. Например, если вы добавите целое число «+» в список чисел с плавающей запятой (что не имеет смысла и выдаст ошибку), в динамическом языке ошибка будет возникать во время выполнения при попытке выполнить инструкцию. В статическом языке программирования, таком как C ++, Haskell и Java, этот тип ошибки будет обнаружен компилятором.

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

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

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

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

vz0
источник
3

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

При этом стоит обратить внимание на любой язык, позволяющий писать значительно меньше кода (например, Python против Java). Возможно, будущее за умными, статически типизированными языками с расширенным выводом типов (например, в шаблоне Scala). Или гибрид, такой как C # пытается со своим dynamicклассификатором ...?

И давайте не будем забывать о «другом» преимуществе статической типизации: правильное завершение кода IDE / intellisense, которое, на мой взгляд, является важной функцией, а не приятным для использования.

Кизил Массон
источник
1
«завершение кода / intellisense» - автоматизированный рефакторинг также очень важен.
Den
@ Совершенно верно. Может ли быть так, что динамические языки помогают вам писать начальные версии очень быстро (проще, меньше кода для написания), но затягиваются позже, так как становится все труднее оценить влияние изменений или выполнить рефакторинг (без инструментов автоматического рефакторинга)?
Корнел Массон
0

Другое соображение - кто стоит за написанием крупномасштабных приложений. Я работал во многих местах, которые хотят использовать Ruby или Python в некоторых крупных проектах корпоративного стиля, но постоянно «сбиваются» ИТ-менеджерами и группами корпоративной безопасности именно из-за природы проектов с открытым исходным кодом.

Мне сказали: «Мы не можем использовать Ruby on Rails, потому что это открытый исходный код, и кто-то может поместить туда хаки, которые крадут критическую или защищенную информацию». Извините, но если у кого-то есть такое мышление с открытым исходным кодом == зло, его почти невозможно изменить. Такое мышление является корпоративной болезнью.

C # и Java являются доверенными языками с доверенными платформами. Ruby и Python не являются доверенными языками.

Джаррет Мейер
источник
2
Я не согласен с последней строкой. Java находится в одном из самых низких пунктов доверия. C # воспринимается осторожно всем сообществом open source. Ruby воспринимается как надежный, но медленный (хотя он уже и не тот), а Python - надежное дитя для рабочих лошадей целых отраслей (машинное обучение и наука о данных, кто-нибудь?).
CodeBeard
1
Динамические языки вредны для безопасности, но «открытый исходный код» не является веской причиной. Возможно, они имели в виду «легко влиять на одну часть кода из совершенно другой части кода». См. Programmers.stackexchange.com/questions/206558/…
Euphoric
1
Обратите внимание, что действительно «открытость» является одним из аспектов выбора языка. Это, например, одна из трех причин, приведенных Джеффом Этвудом для объяснения того, почему Discourse использует Ruby.
Арсений Мурзенко
C # теперь полностью с открытым исходным кодом, но его все еще курируют, планируют и разрабатывают профессиональные разработчики, что, я думаю, приятно. Будем надеяться, что «Python 3 vs 2» здесь не произойдет.
День
Ошибки и дыры в безопасности вносятся программистами, а не языками, и, к сведению, я внес ряд исправлений безопасности в проекты с открытым исходным кодом. Сколько закрытых проектов я помог ??? нуль!
Reactgular