Яка мова програмування генерує найменш важких помилок? [зачинено]


54

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

Особисто я вважаю, що я витрачаю дуже мало часу на пошуки дивних помилок у програмах Java та C #, тоді як код C ++ має свій чіткий набір повторюваних помилок, а Python / подібний має власний набір поширених та дурних помилок, який би виявив компілятор іншими мовами.

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

Редагувати: Повністю довільне роз'яснення важко знайти помилку: для відтворення потрібно більше 15 хвилин або більше 1 години, щоб знайти причину та виправити помилку.

Пробачте, якщо це дублікат, але я нічого не знайшов на цю конкретну тему.


10
Я хотів би побачити деякі дослідження, проведені в цій темі! Не лише "мої анекдотичні дані свідчать про те, що єдиною мовою, яку я знаю, є королем", але й кількість помилок у великих проектах тощо.
Френк Шірар

@Frank .. якщо у вас було багато (а я маю на увазі багато) часу, ви, ймовірно, могли видобути деякі статистичні дані з охлоху, за умови, що ви могли б виявити виправлення, які виправляли помилки з тисяч сховищ коду.
Тим Пост

Той, де дозволені лише коментарі. Немає інших інструкцій :)
Віктор Хурдугачі

4
Я думаю, що "важко знайти" потрібно уточнити. Ваше запитання та більшість відповідей, схоже, визначають "важко знайти" як еквівалент "не зловив компілятор". Ви згадуєте, що python має дурні помилки, які були б виявлені компілятором. Досить справедливо. Але цих дурних помилок зазвичай не так важко знайти. Звичайно, вони не входять до тієї ж категорії, що і C ++-помилки, що походять із пам'яті, яка звільняється, занадто рано.
Вінстон Еверт

@ Уінстон погоджуюся.
Магнус Вольфельт

Відповіді:


58

Чим потужніша система типу мови, тим більше помилок буде виявлено під час компіляції.

На наступному малюнку порівнюються деякі добре відомі мови програмування за потужністю, простотою та безпекою систем їх типів. [ Джерело ]

alt текст

* Факторинг у здатності використовувати небезпечні конструкції.

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

Я позначив Haskell '98 як чистий, але GHC Haskell як нечистий через небезпечну * сімейство функцій. Якщо ви відключите небезпечний *, тоді перейдіть GHC Haskell відповідно.


8
Це геніально!

7
Я не міг знайти звичайного Ліса в графіці: (let ((itbe '())) ... )...
duros

7
Що? Не залишилося місця на лівій стороні для PHP?
pestaa

7
C # дозволяє безпечні покажчики: перевіряється вся арифметика вказівника. Тому я вважаю, що це має бути з Java.
Олексій десять Брінк

11
@missingfaktor: Я думаю, що C # не дуже добре розміщений. C # дозволяє і просуває більш безпечні стилі програмування. Він не повинен вимірюватися найгіршим, що дозволяє.
back2dos

20

На мою думку, Haskell допомагає вам уникнути деяких поширених джерел помилок:

  • це суто функціонально: функції не можуть мати (ненавмисні) побічні ефекти, і це робить багатоядерне програмування простішим і менш схильним до помилок
  • вона сильно набрана: ви не можете, наприклад, випадково змішати значення bool, char, int та float
  • вона набрана статично: під час компіляції виявляється багато помилок програмування
  • nullне є частиною визначень типу цінності: цим ви уникаєте помилки в мільярд доларів
  • є багато готових функцій вищого порядку, які ви можете використовувати повторно, замість того, щоб писати власні, можливо, несправні, реалізації
  • у ньому є сміттєзбірник: помилки пам'яті майже усуваються (за винятком "протікання місця" через його лінивої стратегії оцінки)

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

5
Багато хороших моментів, але, видаляючи деякі класи помилок (ненавмисні побічні ефекти, несподівані перетворення типу), Haskell додає зовсім новий клас помилок: протікання місця. (Також, хоча немає null, є undefined, який є членом кожного типу.)
j_random_hacker

5
@Mason: Якщо ви не пишете в ньому, ви не можете мати помилки в ньому :)
Michael K

2
Напевно, немає такого поняття, як безкоштовний обід - у вас можуть бути помилки, які легко знайти, або простий у написанні код, але не те й інше :)
Benjol

6
@ Мейсон, що саме "середній програміст"? Питання починається з "яка мова програмування ...", а не "яка серед C, C ++ та java ...";)
Agos

18

Традиційно найскладніше знайти помилки - це умови перегонів у багатопотокових програмах, як вони є

  • майже неможливо відтворити
  • може бути дуже тонким

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

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


Редагувати: У Java Executorsобробляють ще більшу частину важких деталей. Потрібно, щоб окремі завдання відповідали Callableінтерфейсу.


5
++ Умови гонки. Ти можеш сказати це знову.
Майк Данлаве

Так. Майте на увазі, що паралельне обчислення в цілому є важким, навіть за допомогою мовної допомоги. (Поширені макроси Lisp важкі, незважаючи на багато мовної підтримки, тому що те, що вони роблять, є дуже потужним. Той самий головний.)
Девід Торнлі

Що з Ерланг?
Мальфіст

@Malfist, я недостатньо знаю про Ерланг, щоб відповісти на це. Можливо, вам слід відкрити питання, якщо ви дійсно хочете знати?

2
Erlang - це функціональне програмування, розроблене для того, щоб зробити багатопотокове просте та безпечне. Ви не ділитесь змінними, ви передаєте повідомлення. Прочитайте сторінку вікіпедії.
Мальфіст

13

Ада розроблена так, щоб якомога більше вловлювалася під час компіляції, а не під час виконання. Це означає, що для збирання програми в Ada часто потрібно 10 разів більше, ніж еквівалент, як це говорить Java, але коли вона компілюється, ви можете бути набагато впевненішими, що цілі класи помилок не проявляться, коли програма бігати.


7
+1 за те, що правильно помітив, що Ada вловлює речі в компіляторі, які інші мови ігнорують. -1 за твердженням, що це означає, що для компіляції програми Ada потрібно 10 разів більше. Ада винагороджує програміста, який ДИЗАЙН !!! його код, хто ДУМАЄ !!! про те, що він робить, перш ніж почне шалено набирати текст. Мій особистий досвід, займаючись виробничим програмуванням в Ада для оборонних робіт, полягав у тому, що для збирання коду Ada не потрібно було значно більше часу, ніж потрібно C / C ++ або FORTRAN, але пізніше у коду Ada виникли значно менше проблем. Pratt & Whitney помітили щось подібне.
Джон Р. Стром

1
@john r strohm, наскільки я розумію, він не говорить про час, який потрібен компілятору для складання коду, скоріше час, щоб зробити код комбінованим.
Мальфіст

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

@Ptolemy, якщо човни можуть бути названі на честь жінок (крім, мабуть, американських перевізників), то мови програмування також можуть. Замість того, щоб його назвали "Ада", ніж "USS Рональд Рейган" :)

1
Як тільки я перебрав криву навчання, я фактично досить швидко написав код Ада - після того, як витратив багато часу на роздуми над дизайном. Ада, безумовно, НЕ хакерська мова. Я зараз працюю на Яві, і деякі речі, які я бачу в своїх поточних проектах, насправді змушують мене трохи пропустити Ада (ніколи не думав, що я цього скажу).
Джеймс Адам

7

По-перше, визначення: важко знайти помилку, наскільки я розумію, це помилка, яку можна відтворити, але причину важко знайти.

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

Хороші мови в цьому відношенні підтримують модифікатори доступу та застосовують їх таким чином, що важко або неможливо обійти їх. Хороші мови заохочують вас обмежувати область ваших змінних, замість того, щоб надто просто мати глобальні змінні (наприклад, "все, що не заявлено чітко, - це глобальна змінна з типом і значенням за замовчуванням").

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

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

Враховуючи все це, я б сказав, що Java та C # та багато інших мов у світі JVM та .net підходять для уникнення важкодоступних помилок.


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

Френк: принаймні блокування досить просте, щоб кожен міг це зробити, не витрачаючи днів, з’ясовуючи, яким API використовувати і т. Д.
user281377

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

@David: Я бачу вашу думку, але в багатьох випадках просте рішення - це все, що потрібно. Наприклад, розглянемо сервлет, який використовує лише декілька користувачів, які повинні використовувати спільний ресурс (наприклад, з'єднання з базою даних). Без синхронізації час від часу трапляються умови перегонів; але це не зовсім ракетна наука, щоб розмістити всі операції з доступу до бази даних у синхронізований (підключення) {} блок.
користувач281377

+1 Для цього визначення "наскільки велика область, на яку може вплинути помилка". У мене були дуже неприємні помилки з динамічними мовами, де об’єкт неправильного типу даних потрапив дуже далеко в код (завдяки друкуванню качки), перш ніж проявити себе як помилку.
Джорджіо

7

Оскільки Excel - це найбільш широко використовуваний DSL, я піду з Excel. (за винятком курсу VBA)

Він відповідає рахунку:

  • Це завжди легко відтворити (ось таблиця - це не працює)
  • Знайти помилку досить просто, оскільки вона абсолютно "функціональна" - почніть з помилкової комірки та простежте всі її залежності.

Це може бути правдою, доки ви не додасте помилок, які легко знайти.
mouviciel

+1 Трохи зухвало, оскільки Excel - це дані, а не мова. Подаруй мені гарний сміх :)
recursion.ninja

2
@awashburn - о, я не знаю. Я думаю, що це кваліфікується як мова. Кожна комірка є "змінною". Кожна змінна декларативно задається як буквальна (наприклад, 123або ABC), так і функція ( =SUM(A2:A5)). Потім Excel оцінює всі змінні, з'ясовуючи, який порядок вирішення залежностей тощо. Це, звичайно, не лише дані.
Скотт Вітлок

2
Я відкликаю свою заяву, виявляється, що Excel Turing завершений ... Я дізнався щось абсолютно неспокійне ...
recursion.ninja

1
"... справжній майстер [Лісп] розуміє, що всі дані є кодом." Можливо, це стосується і Excel, і це досить дивно. blogs.msdn.com/b/sriram/archive/2006/01/15/lisp-is-sin.aspx
Джеймс Мішра

7

Це складне питання, оскільки більшість помилок не є виною самої мови - скоріше вони винні розробники, які роблять помилки в тому, як вони використовують мову.

Я вважаю, що є кілька аспектів мовних особливостей, які впливають на ймовірність помилок:

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

  • Експресивність - якщо код коротший і має меншу кількість шаблонів / випадкової складності, то легше бачити помилки / логічні помилки.

  • Безпека типу - чим більше перевіряє час компіляції, тим більше помилок буде зафіксовано компілятором, тому в цілому безпека типу - це добре. Однак помилок зазвичай не важко знайти - навіть у повністю динамічній мові неправильний тип у структурі даних зазвичай спричиняє дуже очевидну помилку виконання, і TDD майже завжди виявляє такі помилки.

  • Незмінюваність - багато важких помилок пояснюються складними взаємодіями змінного стану. Мови, що підкреслюють незмінність (Haskell, Clojure, Erlang), мають величезну перевагу, уникаючи незмінність

  • Функціональне програмування - функціональні підходи до написання коду, як правило, більш "доказово правильні", ніж об'єктно-орієнтований код зі складними послідовностями ефектів / взаємодій. Мій досвід полягає в тому, що FP допомагає уникнути хитрих помилок - я вважаю, що десь є якісь академічні дослідження, які я не можу знайти, що це підтримує.

  • Підтримка паралельної валюти - проблеми з паралельною валютою особливо важко виявити та налагодити, тому це так важливо. Все, що вимагає ручного блокування, в кінцевому рахунку приречене на збій (а це включає в себе майже кожен об'єктно-орієнтований підхід до одночасності). Найкращою мовою, яку я знаю в цьому плані, є Clojure - це унікальний підхід до управління паралельністю, який поєднує транзакційну пам'ять програмного забезпечення з незмінними структурами даних, щоб отримати нову, надійну та компонуючу структуру паралельних даних. Дивіться http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey для отримання більш детальної інформації


Такі люди, як я, пристрасні прихильники функціонального програмування, цінують цю відповідь. Виразність - ваш друг.
Шрідхар Сарнобат

1
Найкраща відповідь поки! Я думаю , що це спирається на наступні два аналізи частоти помилок: deliberate-software.com/safety-rank-part-2 і macbeth.cs.ucdavis.edu/lang_study.pdf . Вони обидва показують, що чим чистіша, функціональніша, виразніша і безпечніша мова, тим менше помилок у ній. Так само вони обидва показують, що Clojure та Ruby уникають правила безпеки, ймовірно, вказуючи на те, що інтерактивність має однаковий вплив, як ви вказали.
Дідьє А.

@DidierA. на жаль, посилання ucdavis розірвана (без архіву wbm) - я думаю, ви отримали його зі сторінки Према Деванбу, яка тепер вказує на оновлене посилання: Велике дослідження мов програмування та якості коду в Github
icc97

5

Чим менш потужна мова, тим менше можливостей вона дає вам стріляти власною ногою.

Мови високого рівня, такі як Java та C #, створюють менше помилок, ніж мови низького рівня, такі як C ++.

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


4
+1 для "Чим менш потужна мова, тим менше можливостей дає вам можливість стріляти власною ногою".
Майкл К

Графік відсутнього фактора, схоже, говорить про те, що C # і C ++ знаходяться на рівних "основах", наскільки це можливо, щоб стріляти в себе, це піднімає Java над цим. Не те, що я згоден з цією частиною діаграми, хоча. Ви змушені пройти обручі, щоб зробити кілька знімків C #.
Jesse C. Slicer

6
Безпека та потужність не є пропорційно пропорційними (це те, що ви, здається, думаєте ;-) Haskell, наприклад, НАЙКРАЙНО потужний і все ж має дуже мало способів стріляти себе в ногу.
зниклий фактор

3
Якщо мова слабка, вам просто потрібна більша стопа.

7
@missingfaktor, це тому, що це побічний ефект, щоб стріляти собі в ногу.

3

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

На мій погляд, Delphi. На основі Pascal мова достатньо проста та інтуїтивно зрозуміла, щоб пересічний програміст (або навіть недосвідчені кодери) легко підбирав, а його багатий інструмент та бібліотечна підтримка дозволяють знайти більшість помилок легко.

  • Сильний набір тексту та суворий компілятор, який виявляє багато поширених помилок.
  • Інтуїтивний синтаксис, який не заохочує поширених помилок. ("Остання помилка у світі" if (alert = RED) {LaunchNukes;}, наприклад, не збирається.)
  • Добре розроблена об'єктна модель, яка виключає багато поширених помилок OOP C ++.
  • Перевірка меж і перевірка діапазону, вбудована в мову, різко знижує шанси на проблеми із безпекою.
  • Напевно, найшвидший відомий людині компілятор, який збільшує вашу продуктивність і ускладнює втрату вашої думки, очікуючи на збірку.
  • Відладчик Visual Studio налагоджувач хоче бути таким, як підростає.
  • Відстеження витоків, вбудованих безпосередньо в диспетчер пам'яті, робить пошук і виправлення витоків пам'яті тривіальним.
  • Велика, зріла стандартна бібліотека, яка пропонує заздалегідь складені та попередньо перевірені способи виконання загальних завдань, не будуючи власних, можливо, помилкових реалізацій.
  • Постачайте з корисними інструментами, такими як потужна система лісозаготівлі та профілер, щоб полегшити відстеження проблем.
  • Сильна підтримка громадськістю для поширених проблем, яких немає в стандартній бібліотеці, включаючи потужну сторонніх бібліотеку одночасності .

Я - жокей Delphi зі зворотного шляху, але він відійшов від коренів Паскаля, коли він дозволив мені набрати що-небудь інше, a la C / C ++:var I: Integer; Pointer(I)^ := $00;
Jesse C. Slicer

1
@Jesse: Можливо, але я бачу це як необхідну поступку прагматизму. Керніган зробив багато хороших моментів, коли написав, чому Паскаль не є моєю улюбленою мовою програмування. Набір машинописів необхідний, щоб зробити багато важливих речей низького рівня. Але однією з сильних сторін Delphi є те, що її бібліотеки інкапсулюють деталі низького рівня та роблять більшу частину небезпечного вказівника та набирання матеріалів непотрібними.
Мейсон Уілер

Я не погоджуюся з тим, що це може знадобитися, але стверджуючи, що сильне введення тексту це дещо заперечує. Оригінальний Паскаль не дозволяв таких шенагіганів, і тому був сильно набраний. Але я б не пішов так далеко, щоб назвати Delphi слабко набраним - це щось на зразок "середнього типу".
Джессі К. Слікер

1
@Jesse: Чи не дозволяла оригінальна версія Wirth Паскаля варіантів записів? IIRC вони врешті стали настільки часто використовуватися для підриву сильного набору тексту, що Борленд та інші вирішили просто поставити машинописи, щоб зробити це простішим, тому що всі так чи інакше робили.
Мейсон Уілер

en.wikipedia.org/wiki/Pascal_(programming_language)#Division and en.wikipedia.org/wiki/Pascal_(programming_language)# Критика, а також pascal-central.com/ppl/chapter3.html, схоже, вказують на те, що вона була частиною Перший стандарт був у 1983 році. Я бачу деякі згадки Вірта, які здаються 1974 роком, тому я б сказав, що так. Я думаю, що проблемною частиною було дозволяти його перекрутити як таке (тобто поля варіантів, що займають таку саму пам'ять, як і об'єднання в C). Якби вони просто використовувались як механізм обстеження, а макет пам'яті був для суперсети, це було б сильніше набрано.
Джессі К. Слікер

2

Одне, що слід враховувати, - це поворот часу.

Протягом останніх п'яти років я розробляв в основному веб-додатки в Java (JSF, Seam тощо). Нещодавно я влаштувався на нову роботу, і ми використовуємо Perl (з Catalyst та Moose).

Я набагато продуктивніший в Perl, ніж я був на Яві.

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

Я здогадуюсь, що кількість помилок у моєму коді Perl є більш-менш такою ж, як кількість помилок у моєму Java-коді, вона може бути навіть більшою. Але я знаходжу і виправляю ці помилки і простіше, і швидше.


1

Можливо, опитування кількості інструментів, доступних для статичного та динамічного аналізу коду для кожної мови програмування, може дати уявлення. Чим більше інструментів для мови, тим скоріше мова є або дуже популярною серед користувачів, або дуже популярною у створенні важких помилок. Але я не в змозі змусити Google вказати мені на будь-яке дослідження з цього приводу. Слід також зазначити, що деякі мови, такі як C, можуть бути використані для вирішення основних апаратних помилок, а також для усунення зносу апаратури у віці.


1
"працювати над зносом обладнання, яке воно старіє" ...?
j_random_hacker

Я читав, що деякі ОС Unix, які працюють на критично важливих машинах, перевіряють стан здоров'я процесора, оперативної пам’яті та іншого обладнання. serverfault.com/questions/56192/… дещо обговорює це. Якщо деякі рядки модуля оперативної пам’яті з часом стають несправними, ці несправні модулі ОС не будуть використовуватись, і він не повідомить про них у загальній доступній фізичній пам'яті. Такі речі можна зробити і на іншому апаратному забезпеченні.
vpit3833

Це цікавий примха, але я не бачу, наскільки це тут актуально. Крім того, ніщо у вашому посиланні не згадує ці саморемонтуючі ОС Unix - воно просто говорить про способи стрес-тестування апаратних засобів ПК.
j_random_hacker

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

1

Замість того, щоб говорити про мови, що говорити про особливості мови

  • java змушує вас думати про винятки (кидки ...), і ви повинні або опублікувати або обробити ці винятки. Чи дійсно це заважає мені забути помилки ситуацій, або я використовую більше винятків, отриманих із SystemException, які не потребують цього поводження?
  • як щодо "проектування за контрактом" (http://en.wikipedia.org/wiki/Design_by_contract), що змушує мене думати про попередні та постумови. Я читав, що зараз це можливо з c # -4.0.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.