Чи існує кореляція між масштабом проекту та суворістю мови?


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 ++ через неявні кастинги.
Стівен Бернап

5
Про життєвий цикл, напевно, можна щось сказати: програмне забезпечення, яке починається у вашій першій категорії, може перетворитися на інші, "перетягуючи" мову з собою.
Мат

11
Єдине, що елегантно у JavaScript - це він працює у більшості браузерів.
JeffO

1
@StevenBurnap: Я не міг домовитися більше про різницю між статичним і суворим. Java - ще одна точка в спектрі, але статична і занадто сувора. Розробники часто зловживають статичним типізацією, використовуючи Java як приклад, але значна частина цієї критики насправді повинна спрямовуватися на надто суворий компілятор Java , а не статичну типізацію взагалі. Подивіться на Scala того ж JVM, який є статично набраним, але має набагато менше багатослівного коду завдяки фантастичним можливостям компілятора типу.
Корнел Массон

2
"Python успішно використовується для великих систем" - яке тут визначення "успіху"? Що це здебільшого працює і дає певний результат? Чи потрібна кількість тестування та робоча сила? Що з ремонтом?
Den

Відповіді:


39

Цікаве тематичне дослідження з питань масштабування проектів, які використовують динамічну та інтерпретовану мову, можна знайти у « Початковій скалі » Девіда Поллака.

Я почав шукати спосіб виразити код у своєму мозку більш простим, прямим способом. Я знайшов Рубі та Рейки. Я почувався звільненим. Рубі дозволив мені висловити поняття в набагато меншій кількості рядків коду. Rails було набагато простіше у використанні, ніж Spring MVC, Hibernate та інші «спрощені» веб-рамки Java. За допомогою Рубі та Рейлів я міг висловити набагато більше того, що було в моїй голові за коротший проміжок часу. Це було схоже на визволення, яке я відчував, коли перейшов з C ++ на Java ...

Оскільки мій проект Ruby and Rails виріс за кілька тисяч рядків коду, і коли я додав членів команди до своїх проектів, проблеми динамічних мов стали очевидними.

Ми витратили більше половини нашого тесту на написання часу на кодування, і значна частина підвищення продуктивності, яку ми побачили, була втрачена під час написання тестів . Більшість тестів були б непотрібними на Java, оскільки більшість з них були спрямовані на те, щоб ми оновили абонентів, коли ми перевстановили код, змінивши назви методів або кількість параметрів. Крім того, я виявив, що робота над командами, де було розумове поле між двома та чотирма членами команди, у Рубі все пішло добре, але, коли ми намагалися залучити нових членів до команди, розумові зв’язки важко було передати новим членам команди .

Я пішов шукати нове середовище мови та мови. Я шукав мову, настільки виразну, як Рубі, але настільки ж безпечну та високопродуктивну, як Java ...

Як бачите, основні виклики в масштабуванні проектів для автора виявилися в розробці тесту та передачі знань.

Зокрема, автор розглядає більше деталей, пояснюючи відмінності в тестовому написанні між динамічно та статично типізованими мовами у розділі 7. У розділі "Шкірно вбиваючи зайчиків: сходи Демті" автор обговорює порт "Скала" певного прикладу Рубі:

Чому Лакі Стіфф ... вводить деякі метапрограмування Рубі в масив Демті, в якому кролик бореться з масивом істот. N8han14 оновив приклад роботи в Scala ...

Порівняно з кодом Рубі, бібліотечні частини коду Scala були складнішими. Нам довелося зробити багато роботи, щоб переконатися в правильності наших типів. Нам довелося вручну переписати властивості Creature у класах DupMonster та CreatureCons. Це більше роботи, ніж method_missing. Нам також довелося провести неабияку роботу, щоб підтримати незмінність наших істот і зброї.

З іншого боку, результат виявився набагато потужнішим, ніж версія Ruby. Якби нам довелося писати тести для нашого коду Ruby, щоб перевірити, в чому нас запевняє компілятор Scala, нам знадобиться набагато більше рядків коду. Наприклад, ми можемо бути впевнені, що наш Кролик не міг володіти Сокирою. Щоб отримати цю впевненість у Рубі, нам доведеться написати тест, який гарантує, що виклик |^на Кролика не вдається. Наша версія Scala гарантує, що для цієї істоти може використовуватися лише зброя, визначена для даної істоти, що вимагатиме багато часу відображення в Рубі ...


Читання вище може змусити задуматися, що в міру збільшення проектів ще більше, тестове написання може стати непомітно громіздким. Це міркування було б помилковим, про що свідчать приклади успішних дуже великих проектів, згаданих у цьому самому питанні ("Python успішно використовується для ... YouTube").

Річ у тому, що масштабування проектів насправді не є простим. Дуже великі, довгоживучі проекти можуть "дозволити" різні процеси розробки тестів, з тестовими наборами якості виробництва, професійними командами тестових розробників та іншим важким складом.

Тестові набори Youtube або комплект із сумісністю Java впевнені, що вони живуть іншим життям, ніж тести у невеликому навчальному проекті, наприклад , масив Демті .



24

Ваше твердження не є помилковим. Вам просто потрібно копати трохи глибше.

Простіше кажучи, великі системи використовують кілька мов, а не одну мову. Можуть бути частини, побудовані за допомогою "строгих" мов, а можуть бути частини, побудовані за допомогою динамічних мов.

Щодо вашого прикладу Google та YouTube, я чув, що вони використовують Python насамперед як "клей" між різними системами. Тільки Google знає, для чого побудовані ці системи, але я думаю, що багато критичних систем Google побудовані за допомогою суворих та "корпоративних" мов, таких як C ++ або Java, або, можливо, щось, що вони самі створили, як Go.

Справа не в тому, що ви не можете використовувати толерантні мови для широкомасштабних систем. Багато людей кажуть, що Facebook використовує PHP, але вони забувають згадати, що Facebook повинен був створити надзвичайно суворі інструкції щодо програмування, щоб ефективно використовувати його в цьому масштабі.

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


"Ви не можете просто захопити кількох випускників коледжу" ... "і очікувати, що вони напишуть програмне забезпечення, яке масштабує мільйони користувачів." напевно, було б достатньо
барвники

Тут варто зауважити, що, як і в Google і Python, використання PHP у Facebook в основному є клеєм ... Я розумію, що для більшості функцій PHP використовується в основному як відносно простий клієнт для більш складної серверної системи, яка зазвичай реалізована більш традиційною мовою «важкої ваги», такою як Java, C ++, Haskell, OCaML тощо
Jules

"Тільки Google знає, на чому побудовані ці системи". У мене навіть є деякі сумніви з цього приводу :) На моєму досвіді жоден суб'єкт (людина чи інше) не може перерахувати всі частини дуже великої системи. У багатьох випадках похований у чашах якогось сервера - це давно забутий фрагмент сценарію Perl, Fortran або KSH, який виконує "Магію".
mattnz

3

Існує два види помилок: перевірити помилки (об'єднати ціле число + список плавців) та помилки бізнес-логіки (перевести гроші на банківський рахунок, перевірити, чи є у вихідного рахунку гроші).

"Динамічна" частина динамічної мови програмування - це саме те місце, де відбувається перевірка типу. У мові програмування, що "динамічно набирається", перевірка типу виконується під час виконання кожного оператора, тоді як у "статично набраній мові" перевірка типу проводиться під час компіляції. І ви можете написати інтерпретатора для статичної мови програмування (як, наприклад, emscri September ), а також можете написати статичний компілятор для динамічної мови програмування (як, наприклад, gcc-python або shed-skin ).

Мовою динамічного програмування, на зразок Python та Javascript, потрібно писати одиничні тести не лише для бізнес-логіки програми, але й перевірити, чи не має помилок синтаксису чи типу. Наприклад, якщо ви додасте "+" ціле число до списку плавців (що не має сенсу і викличе помилку), в динамічній мові помилка буде підніматися під час виконання під час спроби виконання оператора. У статичній мові програмування, такі як C ++, Haskell та Java, компілятор потрапить у такий тип помилок типу.

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

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

У статично перевіреній мові програмування компілятор вловлює більшість помилок типу під час компіляції. Я кажу найбільше, тому що поділ на нульову помилку або помилка масиву поза межами також є помилками типу.

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


3

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

Сказавши це, на будь-яку мову, на яку ми напишемо значно менше коду , варто звернути увагу (наприклад, Python vs Java). Можливо, майбутнє - у розумних, статично типових мовах із вдосконаленим висновком типу (наприклад, у формі Scala). Або гібрид, такий як C # намагається зі своїм dynamicкласифікатором ...?

І не будемо забувати "іншу" перевагу статичного набору тексту: належне заповнення / інтелісценція коду IDE, що, на мій погляд, є важливою особливістю, а не приємною для роботи.


1
"доповнення коду / інтеліссенс" - автоматичне рефакторинг також є досить важливим.
День

@День абсолютно. Чи може бути так, що динамічні мови допомагають вам писати початкові версії дуже швидко (простіше, менше запису коду), але згортаєтесь пізніше, оскільки стає важче оцінити вплив змін або зробити рефакторинг (без автоматизованих інструментів рефакторингу)?
Корнел Массон

0

Інший розгляд - хто стоїть за написанням масштабних заявок. Я працював у багатьох місцях, які хочуть використовувати Ruby або Python в деяких великих проектах корпоративного стилю, але послідовно "збиваються" ІТ-менеджерами та колективами корпоративного захисту саме через характер проектів з відкритим кодом.

Мені сказали: "Ми не можемо використовувати Ruby on Rails, тому що він є відкритим кодом, і хтось може покласти там хаки, які крадуть критичну або захищену інформацію". Вибачте, але коли хтось має таку думку, що з відкритим кодом == зло, змінити це майже неможливо. Цей напрямок мислення є корпоративним захворюванням.

C # і Java - це довірені мови з надійними платформами. Ruby та Python - це не довірені мови.


2
Я не згоден з останнім рядком. Java - одна з найнижчих точок довіри досі. C # розглядається з усією спільнотою з відкритим кодом. Рубі розглядають як міцну, але повільну (хоча вона вже не є), а Python - це довірена дівоча гламурність у всіх галузях промисловості (кому-небудь машинне навчання та інформатика?).
CodeBeard

1
Динамічні мови погані для безпеки, але "відкритий код" не є вагомою причиною. Можливо, вони означали, що "легко вплинути на одну частину коду з абсолютно іншої частини коду". Дивіться програмісти.stackexchange.com
questions/206558/…

1
Зауважимо, що дійсно "відкритість" є одним із аспектів вибору мови. Ось, наприклад, одна з трьох причин , які Джефф Етвуд пояснив, чому дискурс використовує Рубі.
Арсеній Муренко

C # є повністю відкритим кодом зараз, але він все ще курирується, планується та розробляється професійними розробниками, що приємно, я думаю. Будемо сподіватися, що подібні речі "Python 3 vs 2" тут не відбудуться.
День

Помилки та отвори в безпеці вводяться програмістами, а не мовами, і для запису я вніс ряд виправлень безпеки для проектів з відкритим кодом. Скільки закритих проектів я допоміг ??? нуль!
Реагуючий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.