Які п’ять речей ви ненавидите улюбленою мовою? [зачинено]


403

Останнім часом спостерігається скупчення Perl-ненависті на Stack Overflow, тому я подумав, що я поставлю питання " П’ять речей, які ви ненавидите про свою улюблену мову " до Stack Overflow. Візьміть свою улюблену мову і скажіть мені п’ять речей, яких ви ненавидите. Це можуть бути речі, які вас просто дратують, допущені вади дизайну, визнані проблеми в роботі або будь-яка інша категорія. Ви просто повинні ненавидіти це, і це має бути вашою улюбленою мовою.

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

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

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


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

Ненависть - не єдиний вимір з'ясувати, скільки людей знає, але я вважаю, що це дуже добре. Те, що вони ненавидять, також дає мені зрозуміти, наскільки добре вони думають про цю тему.


11
Це справді приємний спін на старе питання "улюбленої мови". Хороше виправдання.
Том Лейс

14
Мені здається цікавим, що, незважаючи на те, що SO має велику аудиторію .NET, на момент написання цього запису є 24 відповіді, лише одна з яких (моя) стосується .NET або мови .NET. Я поняття не маю, що це говорить про SO чи .NET, але це цікаво ...
Джон Скіт

22
Перші 15 років програмування на C / C ++ я ненавидів (в алфавітному порядку): 1. Покажчики 2. Покажчики 3. Покажчики 4. Покажчики 5. Покажчики
ілеон

4
Цікаво, скільки зауважень люди зробили з приводу ненависті своєї мови вибору, тому що вони не розуміли, як програмувати на своїй
обраній

3
Це фантастичне питання. Якщо вам цікаво, що таке мова, читати 3 різні відповіді про неї на цій сторінці було б легко найкращою корисною інформацією за час, який ви могли знайти. Також чудовий спосіб оцінити рівень досвіду (і смирення) програміста, якщо ви вже знаєте мову.
j_random_hacker

Відповіді:


182

П’ять речей, які я ненавиджу щодо Java:

  • Ніяких першокласних функцій.
  • Немає висновку про тип.
  • Відсутність розумних стандартних параметрів, наприклад, у графіці.
  • NullPointerException не містить більше інформації про те, що є null.
  • Поширення безглуздо «настроюваних» фреймворків / інтерфейсів постачальника послуг / заводські класи / системи впорскування залежностей. Конфігурація майже ніколи не використовується, DRY порушується грубо, а коди вчетверо в розмірах і половини в розбірливості.

Я знаю, я повинен перевірити Скалу.


7
@both: NPE відображається в першому рядку трансу стека. Він містить (більшу частину часу) клас, ім'я файлу java та номер рядка на зразок: "at your.faulty.code.Instance (Intance.java:1234)" Потім ви просто відкриєте цей файл, перейдіть до цього рядка і там - це змінна, яка їй нічого не призначена.
OscarRyz

35
@Oscar Reyes - Ер, ми це знаємо. Але в цьому рядку може бути кілька змінних, і повідомлення про виключення не говорить про те, яка з них є нульовою.
Зарконнен

10
У Scala теж є свої бородавки. Однак це чудово краще, ніж Java.
пшениці

10
+1 за розповсюдження рамок тощо
Еріх Кітцмуеллер

6
@Valentin, просто уявіть собі задоволення від того, що NullPointerException знаходиться в гігантському логфілі з нічного запуску, і вам потрібно розібратися, що сталося ... Налагодження - це не варіант.
Thorbjørn Ravn Andersen

216

Нічого собі, я здивований, що SQL ще цього не зробив. Здогадайтесь, це означає, що його ніхто не любить :)

  • Невідповідний синтаксис у різних реалізаціях
  • Тонкі відмінності в коді можуть мати значні наслідки для продуктивності з, здавалося б, незрозумілих причин
  • Погана підтримка маніпуляції текстом
  • Проста вартість вступу, але крута крива навчання до оволодіння мовою
  • Мінімальна стандартизація у спільноті для найкращих практик, сюди входить стиль синтаксису.

... І кілька причин бонусу ненавидіти це без додаткових витрат

  • пункт WHERE діє останньою, що спрощує передчасне виконання UPDATE або DELETE, знищуючи всю таблицю. Натомість, ГДЕ повинно йти кудись попереду.
  • Важко здійснити реляційний поділ.
  • Я можу встановити значення NULL, але я не можу перевірити його на рівність з NULL. Я можу перевірити, чи НУЛЬНИЙ, але це просто ускладнює код - без потреби, на мій погляд.
  • Чому нам потрібно повністю дотримуватися формули для стовпця GROUPED, а не встановлювати псевдонім на стовпчик, а потім GROUP BY псевдонім (або індекс стовпця, як у SORT)?

7
Можливо, ніхто не може навчитися любити це, поки не перестане думати про це як про мову. :)
Алан Мур

4
+1 для всього. І все ж люди задаються питанням, чому я змирився з головними болями ОРМ ...
Джеймс Шек

2
@Alan M ... чи не те, що означає L? :)
Кев

29
Я не можу зрозуміти, чому синтаксис для INSERT настільки відрізняється від UPDATE. І МЕРЕ незрозуміло.
LaJmOn

3
Необхідність IS NULL повинна бути зрозумілою, якщо ви вважаєте, що NULL є третім можливим результатом, одразу після ПРАВИЛЬНОГО та ЛАЖНОГО. Оскільки це значення "невідомо", ви не можете сказати, чи відповідає щось невідоме іншому, що також невідомо. Інший приклад: якщо NULL дорівнює NULL, це означатиме, що вся концепція створення JOIN буде неможливою, оскільки будь-яке значення NULL може бути узгоджене з іншим значенням NULL. Якщо ви розумієте це (що також називається потрійною логікою), ви можете зрозуміти причину введення оператора "IS" для тестування на NULL.
Олексій

159

JavaScript :

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

  2. '+' - це абсурдний вибір оператора конкатенації слабко набраною мовою. Чи намагалися вони відлякати нобу?

  3. Це мінне поле сумісності між браузерами (неважливо, він навіть увімкнено чи ні)

  4. Це, як правило, ненадійність - пов’язана з негідниками, такими як блокування кнопки "назад", спливаючі вікна, які ніколи не вмирають тощо.

  5. Налагодити це майже неможливо, оскільки є лише кілька різних повідомлень про помилки та кілька різних типів (число, рядок, об’єкт тощо)

Якби не jQuery, я, мабуть, все одно ненавиджу його так, як раніше :)


15
Я згоден з маушем. Сценарій ECMA сам по собі є красивою і потужною мовою. Саме набридливі браузери (: кашель: IE) заплутують його назву.
TJ L

32
@Mausch: де живе JavaScript у переважній більшості випадків? Ви кажете, що еквівалент "машини не сприяють глобальному потеплінню, це водіння автомобілів робить це", - звичайно, правда, але пропускаєш пункт - що ще ти робиш з машиною?
jTresidder

20
@Chris: Так, "+" - це хороший оператор для конкатенації сильно набраною мовою (наприклад, Python). У слабко набраній мові (як Javascript або C) це жахливо; він вирішує (мовчки!), що "сума:" + 2 + 3 не є "сума: 5", а "сума: 23". Хтось із більшим досвідом Javascript може надати кращі приклади.
ShreevatsaR

5
Так, C слабо набраний, порівняно з, скажімо, Python (наприклад, ви можете призначити цілі числа chars, передавати що завгодно будь-що за допомогою void * покажчиків тощо). Він статично набирається замість динамічно набраного тексту , а також вимагає явного введення тексту замість тип виводу, але вони не пов'язані з сильним типізацією v / s. [Випадкові приклади: у Python є неявна динамічна сильна типізація, Haskell має (необов'язково явний) статичний сильний набір тексту, Java має явне (переважно статичне) сильне введення тексту, C має явне статичне (відносно слабке) введення тексту.] "Сильно набране" та "слабо набране" "насправді недостатньо чітко визначені.
ShreevatsaR

5
@ShreevatsaR Класичним прикладом є: '3'+'2'='32', '3'-'2'=1.
Томас Ейл

148

PHP:

1) Змушує мене робити зайві змінні:

$parts = explode('|', $string);
$first = $parts[0];

2) Реалізація лямбдасів настільки кульгава, що приблизно еквівалентна використанню eval()і настільки жахливо неправильна, що я ніколи її не використовував (див. Http://www.php.net/create_function ).

3) Система спробу / лову, яка може зафіксувати лише близько 80% помилок, які можуть виникнути.

4) Підтримка Regex настільки ж кульгава, як і лямбда-підтримка, тому що її потрібно писати всередині звичайних рядків, що робить один з найбільш важких для засвоєння інструментів програмування приблизно втричі складніше. І PHP повинен бути "легкою" мовою?!?!?

5) Ні в якому разі не можна безпечно витягувати речі з $ _POST, не записуючи їх двічі, не будуючи власну функцію або використовуючи оператор "@":

$x = isset($_POST['foo']['bar']) ? $_POST['foo']['bar'] : null;

6) Бонусна відповідь: "@". Якщо ви не можете заперечувати правильно писати свій код, просто додайте "@" і занадто погано для тих, кому доведеться налагоджувати ваш код пізніше.


44
як щодо списку ($ first) = explode ('|', $ string); ?
mlarsen

44
В ідеалі я хотів би використати some_function (explode ('|', $ string) [0]);
занадто багато php

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

24
ви забули про функції з порядковим зміною порядку параметрів
dusoft

39
Ви забули про verbNoun, verb_noun, noun_verb, nounverb, verbnoun, nounVerb тощо. _>
Warty

135

C ++

  • Надто просто, щоб випадковим чином пошкодити пам'ять і створити майже неможливо знайти помилки (хоча, Вальгринд проходить довгий шлях до виправлення цього).
  • Повідомлення про помилки шаблону.
  • Під час використання шаблонів легко в кінцевому підсумку потрібно включити все в один файл, а потім отримати дурні рази компіляції.
  • Стандартна бібліотека - це жарт у сучасну епоху (досі немає потоків чи мережі за замовчуванням?)
  • Багато неприємних маленьких шматочків C пробиваються (зокрема, всі перетворення між короткими / int / неподписаними / тощо)

13
Я згоден з STL, але я скажу , що це є дуже добре.
Бернард

22
unicode. Я поважаю простоту Ascii, але заради блага, ми зараз в XXI столітті.
wilhelmtell

29
Коректність @Kieveli - це одна з речей, які мені найбільше не вистачає при програмуванні іншими мовами. особливо динамічно типізовані. Раї - це велика особливість, яку я часто теж сумую.
wilhelmtell

6
Більшість проблем C ++ пов'язані з тим, що вони є стандартом ISO і блокуються на 10 років.
graham.reeds

7
+1 "Повідомлення про помилки шаблону."
Жоао Портела

129

C # / .NET:

  • Класи за замовчуванням повинні бути запечатані
  • Не повинно бути lockзаяв - натомість у вас повинні бути конкретні блокуючі об'єкти, і повинні бути такі методи, як Acquireповернення одноразових жетонів блокування. Висновок: не повинно бути монітора для кожного об’єкта.
  • GetHashCode()і Equals()не повинно бути System.Object- не все підходить для хешування. Замість цього, мати IdentityComparerякий робить те ж саме, і тримати IComparer<T>, IComparable<T>, IEqualityComparer<T>і IEquatable<T>інтерфейси для призначених для користувача порівнянь.
  • Погана підтримка непорушності
  • Поганий спосіб виявлення методів розширення - це має бути набагато більш свідомим рішенням, ніж просто те, що я використовую простір імен.

Ці були з моєї голови - запитайте мене завтра, і я придумаю різні 5 :)


22
Запечатано за замовчуванням: успадкування має бути або перетворено на клас (що вимагає часу та обмежує майбутні варіанти), або заборонено. hashCode / equals: він також смокче в Java. Одного разу я напишу довгий пост про це в блозі. Прочитайте Ефективна Java для детальної інформації про те, чому дорівнює складність в ланцюгах спадкування.
Джон Скіт

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

69
У такому випадку я недостатньо розумний для вас, щоб виходити з мого коду: тому що я не можу передбачити, які майбутні зміни я можу внести, які можуть порушити ваш код. Це дуже суттєва проблема, ІМО. Запечатування коду є більш обмежуючим, але призводить до більшої свободи в реалізації та надійності.
Джон Скіт

11
Я не можу повірити, що ніхто не згадував синтаксис "goto case", я ненавиджу цього!
Аїстіна

20
Добре, що Джон Скіт не спроектував C #, або мій список виглядав би так: "1. класи за замовчуванням запечатані; 2. блокування занадто складне; 3. більшість об'єктів не підлягають доступності"!
Гейб

113

С

  • струнні маніпуляції.

Доводиться працювати вручну з буферними рядками, це схильність до помилок. Оскільки стільки обчислень дійсно рухаються та змінюють рядки (комп’ютери використовуються не так багато для великого скорочення чисел, як люди думали, що повернуться назад), дуже приємно користуватися керованими мовами або рядком C ++ об'єкти для вирішення цих питань. Коли мені доводиться це робити на прямій С, це відчувається, як плавати в пісні.


50
Домовились. Рядок маніпуляцій - це пункт 1 до 5 речей, які я ненавиджу щодо C.
BoltBait

1
Просто використовуйте безпечну бібліотеку струн DJB або щось подібне. Маніпуляція з XML є складною для більшості мов, і багато програм проводять маніпуляцію XML, але ви не бачите багатьох повідомлень, що "Perl повністю порушений, тому що він не підтримує DOM-вузли як примітивний тип даних". Вони використовують бібліотеку.
Стів Джессоп

5
C-маніпуляція з струнами справді смокче, але що стосується мовних проблем, це не найгірше.
Кріс Лутц

3
strcat для об'єднання, але зачекайте ... чи має місце призначення достатньо місця ... Ок, потрібно вставити, якщо оператор перевірити ... але зачекайте, що робити, якщо мій рядок знаходиться на купі? Гаразд, треба тримати змінну навколо, щоб відстежувати розмір ... І це може тривати і далі, і далі ...
blwy10

4
Нам потрібна нитка для п’яти речей, які ми не ненавидимо щодо C ...
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

94

Як щодо п’яти речей, які я ненавиджу, у списках "Що я ненавиджу про якусь мову"? : D

5- Фарбування помаранчевим червоним не робить це яблуком.

Коли мова розроблена, дизайнери зазвичай мають на увазі, для чого вона корисна. Використовувати його для чогось зовсім іншого може спрацювати, але скаржитися, коли це не просто глупо. Візьміть Python. Я впевнений, що або хтось має, або хтось колись зробить утиліту для створення exe з Python-коду. Чому на землі Божій ти хотів би це зробити? Було б акуратно - не зрозумійте мене неправильно - але це не має ніякої користі. Тож перестаньте скаржитися на це!

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

4- Ти стоїш на дерев'яних ніжках?

Платформа може бути великим впливом того, що може зробити мова. На сьогоднішній день сміттєзбірники, а то й паскалі ранні спроби "вивезення сміття", можуть допомогти згасанню пам'яті (можливо, мальком більше барана ??). Комп'ютери швидше, і, звичайно, ми очікуємо, що більше наших мов. І, чесно кажучи, ми, мабуть, повинні. Однак для зручності компілятора можна створити величезну ціну для створення хеш-таблиць або рядків або різноманітних інших понять. Ці речі можуть не бути успадкованими платформою, для якої вони використовуються. Якщо сказати, що їх легко включити до мови, це просто скаже мені, що ти можеш не мати ноги, на якій можна стояти.

3- Хто в цьому винен?

Клопи. Ти знаєш. Я люблю клопів. Чому я люблю клопів. Тому що це означає, що я можу зберегти свою роботу. Без помилок було б багато закритих піцерій. Однак користувачі ненавидять помилок. Але ось трохи сплеску холодної води. Кожна помилка - це помилка програмістів. Не мова. Мова з таким суворим синтаксисом, який би значно зменшив кількість помилок, які можна було б створити, був би абсолютно марною мовою. Це, можливо, можна було б перерахувати з одного боку. Ви хочете гнучкості чи потужності? У вас є помилки. Чому? Тому що ти не ідеальний, і ти робиш помилки. Візьмемо дійсно ідентифічний приклад на мові C:

int a[10];
for (int idx = 0; idx < 15; idx++) a[idx] = 10;

Ми всі знаємо, що це робити. Однак те, що, можливо, хтось із нас не усвідомлює, це те, що функціональність може бути дуже корисною. Залежно від того, що ти робиш. Перевищення буфера - це вартість цієї функціональності. Цей код вище. Якщо я насправді випустив це на публіку. Це знову .. скажи це зі мною .. "Моя вина". Це не те, що я дозволив мені це зробити.

2 - Чи не слід ставити це в кошик?

Дуже легко вказати на особливості на мові, яку ми не розуміємо, оскільки ми не використовуємо її часто і називаємо її дурною. Поскаржись, що це там і т.д. Гото завжди мене розважає. Люди завжди скаржаться на те, що гото є мовою. Але я думаю, що ваша остання програма включала тип goto. Якщо ви коли-небудь використовували перерву чи продовження, ви використовували goto. Ось що це. Зрозуміло, це "безпечне" гото, але воно є. Гото мають їх використання. Незалежно від того, чи використовуються "неявні" gotos, як продовжувати або перервати, або явні gotos (використовуючи власне ключове слово "goto" для будь-якої мови). Не те, щоб розробники мови були бездоганними, але, як правило, ... якщо функціональність існувала ще з світанку (для цієї мови). Ймовірно, цей аспект є визначальною якістю цієї мови. Значення .. це ' s використовується і, швидше за все, не висить через зворотну сумісність. Він використовується сьогодні. Як і 5 хвилин тому. І правильно використовується. Ну .. певно, хтось також його неправильно використовує, але це стосується №3 мого списку.

1. - Все є предметом.

Ок .. ця справді є підмножиною №2. Але це, безумовно, найприємніша скарга, яку я бачу у списках ненависті. Не все є об’єктом. Існує велика кількість понять, які не належать або не повинні бути об'єктами. Розміщення речей там, де вони не належать, - це просто некрасиво і може знизити ефективність програми. Звичайно. Можливо, не сильно залежно від мови. Це також стосується №5. Це означає ... так. Глобальні в порядку. Функції, призначені для статичних методів, добре. Поєднувати програмування OO з глобальними функціями - це нормально. Тепер .. це не означає, що ми всі повинні вийти і "звільнити" наш код від об'єктних моделей. При проектуванні ділянки коду або всього проекту, що відбувається за лаштунками повиннівраховуйте при складанні. Мало того, де живе ця концепція та багато інших факторів. Навіщо обертати глобальні функції в межах класів або понять простору імен, якщо це не відповідає меті? Візьміть статичні змінні члена. Це дуже мене забавляє, тому що ... ну..Залежно від мови та впровадження курсу, але загалом кажучи, ви просто оголосили глобальним. Так, є деякі причини, щоб зафіксувати ці поняття, що не належать до ОО, в OO обгортки. Одним із них є самодокументування коду. Це може мати сенс. Так .. як я кажу. Не виходьте і не звільняйте свій код. Але будь-яка добра сучасна мова матиме глобальну концепцію поза її моделювання ОО. Так, я конкретно маю на увазі, що мова програмування OO без глобальної концепції, швидше за все, має серйозні вади дизайну. Хоча знову ж таки .. залежить від наміру та дизайну мови, тому я не намагаюся вибрати якусь конкретну мову, і тут дуже багато для аналізу. Будь-хто, Поміркуйте, де код повинен жити і бути найбільш ефективним. Додавання купового спалаху до чогось, що не додає функціональності чи підтримки, просто швидше зношує клавіатуру. Це нікому не приносить користі. Ну .. якщо вам не подобаються окуляри брауні від людини, яка, ймовірно, неправильно навчила вас, що все є предметом.

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


19
Мови не є ідеальними, і якщо ви складете список речей, які ненавидите про мову, ви можете отримати цікаві коментарі та ідеї. По-перше, це дозволяє іншим пропонувати вам рішення, про які ви не знали, що існували (перегляньте повідомлення, ви побачите, що деякі речі були вивчені). По-друге, це є зворотним зв’язком користувачів для розробників мови (хіба вам не цікаво, якби ваші користувачі придумали список 5 речей, які вони найбільше ненавидять у вашому програмному забезпеченні?), По-третє, цікаво розмірковувати про вади. ваших інструментів.
Сільвердраг

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

17
Створення виконуваних файлів із вихідного коду "не має користі"? Що?
детлей

4
Perl міг створити виконуваний файл з файлу Perl з кінця 80-х. Поширити одне, що корисно Не потрібно а) встановлювати Perl, б) встановлювати компоненти програми, в) можливо, написати сценарій, щоб встановити шляхи та виконати все це ... Так, справді марно.
xcramps

1
Але якщо ви не можете створити .exe файли з джерела, користувачі Windows не зможуть запустити його. ;)
Еван Плейс

88

П’ять речей, які я ненавиджу щодо Java (яка, на сьогодні, є моєю улюбленою мовою), не в особливому порядку.

  1. Наскільки я шанувальник Java Generics, є багато диваків, які виникають із того, як вона була розроблена. Таким чином, існує безліч набридливих обмежень із загальними характеристиками (деякі з яких є результатом стирання типу).
  2. Спосіб роботи інтерфейсів Object.clone () та Cloneable повністю порушений.
  3. Замість того, щоб взяти дорогу і зробити все об'єктом (a.la. SmallTalk), Sun wimped out створив дві різні категорії типів даних: Об'єкти та примітиви. Як результат, зараз є два уявлення про основні типи даних та цікаві цікавості, такі як бокс / розпакування та неможливість розміщення примітивів у колекції.
  4. Гойдалка занадто складна. Не зрозумійте мене неправильно: є багато цікавих речей, які можна зробити з Swing, але це чудовий приклад надмірної інженерії.
  5. Ця остання скарга однаково є виною Sun і тих, хто написав XML-бібліотеки для Java. Бібліотеки Java XML занадто складні. Для того, щоб просто читати у XML-файлі, мені часто доводиться турбуватися про те, який парсер я використовую: DOM чи SAX? API для кожного однаково заплутано. Рідна підтримка мовою для легкого розбору / запису XML була б дуже приємною.
  6. java.util.Дата смокче. Це не лише зайве ускладнення, але й усі корисні методи застаріли (і замінені іншими, що підвищують складність).

32
Ви забули про java.util.Date!
ТМ.

3
Також: Інтерфейс "Cloneable" не має методу "clone ()". Це робить інтерфейс Cloneable інтерфейсом Oxymoron. А оскільки clone () повертає Object, безпека вводиться у вікно (не з’являється жодних спроб виправити це навіть після введення Generics в J2SE 5.0).
Райан Делуччі

2
Поки ми базуємося на клонуванні, ми можемо також включати так званий серіалізаційний "інтерфейс". Кожного разу, коли я його використовую, я завжди хочу себе колоти.
wds

12
Важко робити прості речі, такі як відкрити файл і прочитати з нього.
Ерік Джонсон

3
Клону @Ryan () не обов'язково потрібно повертати "Об'єкт". З J2SE 5.0 Java представила коваріантні типи повернення, що означає, що ви можете повернути будь-який підтип базового класу. Тож можливий публічний клон MyType ()!
helpermethod

73

У Рубі є багато недоліків, пов'язаних з її швидкістю, але я їх не ненавиджу. Він також має вади, коли євангелізація громади переходить за борт, але це насправді не турбує мене. Це те, що я ненавиджу:

  • Замикання (блоки) мають 4 різних синтаксису створення, і жоден з них не є оптимальним. Елегантний синтаксис неповний і неоднозначний з хешами, а повний синтаксис - некрасивим.
  • Громада, як правило, проти реальної документації, віддаючи перевагу "прочитати код". Я вважаю це по-дитячому і ледачим.
  • Зловживання метапрограмуванням, особливо в бібліотеках, робить помилок кошмаром для пошуку.
  • У відповідній примітці повсюдне метапрограмування ускладнює комплексне IDE, якщо не неможливо.
  • Шлях, який передається блоку функціям, нерозумний. Немає причин, що блоки повинні бути передані поза списком параметрів або мати непарний спеціальний синтаксис для доступу (вихід). Я вважаю, що блокам слід було б надати менш неоднозначний синтаксис (або хеші могли використовувати різні роздільники; можливо, <>, а не {}), і передавання параметрів методам мало бути таким же, як і всі інші параметри.

    object.method(1, {|a| a.bar}, "blah")
    

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


2
недооптимальна підтримка m17n & unicode, хоча вона стає кращою. 1.9 залишається складним ...
Келтія

37
Я думав, що зловживання метапрограмуванням називається "ідіоматичним рубіном" :)
Slartibartfast

2
akway: Інші два синтаксиси - лямбда та Proc.new .
Myrddin Emrys

2
Щодо документації, я одного разу почув розмову когось, хто працював у видавництві «Прагматичні програмісти», який сказав, що коли компанія була заснована, вони хотіли книги Рубі, тому що єдина з них була японською. Тому вони могли перекласти та видати книгу їх компанією. Але те, що вони робили замість того, що читати вихідний код :-) Книга Рубі, очевидно, була однією з книг, які започаткували Прагматичні програмісти.
Артур Рейтенауер

13
Мені цікаво, що 3 з них стосуються людей, а не мови. Рубі залишається мовою, яку я найменше ненавиджу.
Toby Hede

72

Perl

  • Змішане використання сигіл

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = $array[0]; # not @array[0], you would get the length instead
    my $four = $array->[0]; # definitely not $array[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = @$array[1,2]; # coerce to array first
    
    my $length_a = @array;
    my $length_s = @$array;
    
    my $ref_a = \@array;
    my $ref_s = $array;
    
    • Наприклад, жодне з них не те саме:

      $array[0]   # First element of @array
      @array[0]   # Slice of only the First element of @array
      %array[0]   # Syntax error
      $array->[0] # First element of an array referenced by $array
      @array->[0] # Deprecated first element of @array
      %array->[0] # Invalid reference
      $array{0}   # Element of %array referenced by string '0'
      @array{0}   # Slice of only one element of %array referenced by string '0'
      %array{0}   # Syntax error
      $array->{0} # Element of a hash referenced by $array
      @array->{0} # Invalid reference
      %array->{0} # Deprecated Element of %array referenced by string '0'
      

    У Perl6ній написано :

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = @array[0];
    my $four = $array[0]; # $array.[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = $array[1,2];
    
    my $length_a = @array.length;
    my $length_s = $array.length;
    
    my $ref_a = @array;
    my $ref_s = $array;
    
  • Відсутність справжнього ОО

    package my_object;
    # fake constructor
    sub new{ bless {}, $_[0] }
    # fake properties/attributes
    sub var_a{
      my $self = shift @_;
      $self->{'var_a'} = $_[0] if @_;
      $self->{'var_a'}
    }
    

    У Perl6ній написано :

    class Dog is Mammal {
        has $.name = "fido";
        has $.tail is rw;
        has @.legs;
        has $!brain;
        method doit ($a, $b, $c) { ... }
        ...
    }
    
  • Погано розроблені функції регулярного виведення

    /(?=regexp)/;           # look ahead
    /(?<=fixed-regexp)/;    # look behind
    /(?!regexp)/;           # negative look ahead
    /(?<!fixed-regexp)/;    # negative look behind
    /(?>regexp)/;           # independent sub expression
    /(capture)/;            # simple capture
    /(?:don't capture)/;    # non-capturing group
    /(?<name>regexp)/;      # named capture
    /[A-Z]/;                # character class
    /[^A-Z]/;               # inverted character class
    # '-' would have to be the first or last element in
    # the character class to include it in the match
    # without escaping it
    /(?(condition)yes-regexp)/;
    /(?(condition)yes-regexp|no-regexp)/;
    /\b\s*\b/;              # almost matches Perl6's <ws>
    /(?{ print "hi\n" })/;  # run perl code
    

    У Perl6ній написано :

    / <?before pattern>  /;   # lookahead
    / <?after pattern>   /;   # lookbehind
    / regexp :: pattern  /;   # backtracking control
    / ( capture )        /;   # simple capture
    / $<name>=[ regexp ] /;   # named capture
    / [ don't capture ]  /;   # non-capturing group
    / <[A..Z]>           /;   # character class
    / <-[A..Z]>          /;   # inverted character class
    # you don't generally use '.' in a character class anyway
    / <ws>               /;   # Smart whitespace match
    / { say 'hi' }       /;   # run perl code
    
  • Відсутність багаторазової відправки

    sub f(   int $i ){ ... }  # err
    sub f( float $i ){ ... }  # err
    sub f($){ ... } # occasionally useful
    

    У Perl6ній написано :

    multi sub f( int $i ){ ... }
    multi sub f( num $i ){ ... }
    multi sub f( $i where $i == 0 ){ ... }
    multi sub f(     $i ){ ... } # everything else
    
  • Погана перевантаження оператора

    package my_object;
    use overload
      '+' => \&add,
      ...
    ;
    

    У Perl6ній написано :

    multi sub infix:<+> (Us $us, Them $them) |
                        (Them $them, Us $us) { ... }
    

5
Я не бачу, що брак справжнього ОО не є таким же поганим, як ви це робите. Іноді це рятівник, особливо коли модуль CPAN, який ви використовуєте, не думав викривати те, що вам потрібно. І відсутність багаторазового відправлення може бути гірше: perl міг бути сильно набраний ;-)
Tanktalus

3
Мені подобається, що Perl не надруковано, але було б корисно додати інформацію про тип.
Бред Гілберт

13
Схоже, ви вирішили критикувати мову, яка не є вашою улюбленою (ви повинні були критикувати perl6)
Frew Schmidt

5
Який сенс у порівнянні з Perl 6? Ви припускаєте, що Perl 6 вирішує ваші проблеми чи продовжує їх?
Роберт П

2
Я сумніваюся, що мені потрібно сказати більше, ніж: ozonehouse.com/mark/periodic
Arafangion

57

Я буду робити PHP, як мені подобається часом, і Python буде зроблено занадто багато.

  • Немає простору імен; все знаходиться у своєму роді дуже великого простору імен, яке в певних умовах пекло

  • Відсутність стандартів, коли мова йде про функції: функції масиву беруть голку за перший аргумент, копицю сіна як другу (див. Array_search ). Струнні функції найчастіше займають стог сіна першим, голкою другим (див. Strpos ). Інші функції просто використовують різні схеми іменування: bin2hex , strtolower , cal_to_jd

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

    $var = preg_match_all('/regexp/', $str, $ret);
    echo $var; //outputs the number of matches 
    print_r($ret); //outputs the matches as an array
    
  • Мова (до PHP6) робить все можливе, щоб поважати майже відсталу відсталу сумісність, змушуючи її виконувати погані практики та функції, коли це не потрібно (див. Mysql_escape_string vs. mysql_real_escape_string ).

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

  • Це смокче при імпорті файлів. У вас є 4 різних способи зробити це (включати, включати_конце, вимагати, вимагати_конце), всі вони повільні, дуже повільні. Насправді вся мова повільна. Принаймні, набагато повільніше, ніж python (навіть із рамкою) та RoR від того, що я збираю.

Я все ще люблю PHP. Це бензопила веб-розробки: ви хочете, щоб невеликий і середній сайт був зроблений дуже швидко і будьте впевнені, що хтось може розмістити його (хоча конфігурації можуть відрізнятися)? PHP є саме там, і це настільки повсюдно, що потрібно встановити повний стек LAMP або WAMP лише 5 хвилин. Ну, я зараз повернусь до роботи з Python ...


4
Я припускаю, що пункт 1 реалізований у 5.3 :) Хоча впорядкування парам стає кращим, імена все ще погані. Я погоджуюсь із відсталою порівнянністю.
Росс

4
Маю любов №4. Це одна з речей, яка мене найбільше турбувала.
Франц

1
Я думаю, аргумент швидкості досить суб'єктивний. Швидкість набагато більше залежить від ефективності коду, ніж від самої мови. Поганий PHP-код, ймовірно, повільніше, ніж високоякісний код python, але хороший PHP може також працювати краще, ніж поганий Python.
самообслуговування

17
no_really_now_mysql_escape_the_string_im_serious ()
Зарплата

2
простори імен schmamespaces. PHP є у всесвітній мережі, тому все повинно бути глобальним
Еван Плейс

50

Ось деякі речі, які мені не подобаються щодо Java (яка не є моєю улюбленою мовою):

  • Стирання типів дженериків (тобто відсутні рефіковані дженерики)
  • Неможливість зловити кілька винятків (різних типів) в одному блоці вилову
  • Відсутність деструкторів (finalize () є дуже поганою заміною)
  • Немає підтримки для закриття чи трактування функцій як даних (анонімні внутрішні класи - це дуже багатослівна заміна)
  • Перевіряли винятки взагалі або, більш конкретно, робили перевірені виправлення виключень (наприклад, SQLException)
  • Немає мовної підтримки для буквальних колекцій
  • Немає виводу типу, коли викликаються конструктори загальних класів, тобто параметри типу не повинні повторюватися з обох сторін '='

1
@Svish - Я думаю, справа в тому, що ви використовуєте цю конструкцію лише тоді, коли вам не байдуже, з яким типом винятку ви маєте справу. Іншими словами, коли ви хочете обробити їх усі однаково
Dónal

3
Я б не назвав відсутність деструкторів недоліком, коли мова має GC, а також GC, що з кожним випуском стає все кращим та кращим. Деструктори були пропущені в java 1.1.8, але не в java 6, оскільки gc настільки сильно вдосконалений.
Майк Ределл

7
C # виправляє все це, за винятком кількох винятків. Загальні дженерики переробляються, деструктори замінюються на використання / IDisposable, закриття реалізовано методами anon та лямбдами, винятки не перевірені, є літерали колекції, і є 'var', щоб уникнути вказівки сконструйованого типу двічі.
Даніель Ервікер

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

2
Анонні внутрішні класи НЕ закриваються: спробуйте створити зворотній виклик відвідувача з чимось на зразок "sum + = current.amount ()" у ньому, де "sum" є не остаточною змінною із вкладеної області. Близько, але сигари немає.
Робопрог

40

C ++

  1. Синтаксис шаблонів
  2. Проблеми щодо спадкування алмазів
  3. Безліч / відсутність стандартних бібліотек, якими володіють сучасні мови (хоча прискорення наближається).
  4. IOStreams
  5. Синтаксис, який використовується навколо IOStreams

Пітон

  1. Пробіли значущі (іноді)
  2. підкреслені ключові слова
  3. Обмежена підтримка потоку (принаймні, зараз)
  4. "Я" замість "цього"
  5. Пробіли значущі (іноді)

80
Ви можете позначати "себе" як "це", чого ви дійсно хочете (хоча іншим це може бути важко дотримуватися). "Я" не є ключовим словом, і ви можете назвати змінну все, що завгодно.
mipadi

36
там ви йдете, я б фактично перерахував змістовність пробілів (особливо відступ) на Python як один із найбільших його плюсів ...;)
Олівер Гісен

22
"пробіли значущі" - одна з найкращих особливостей пітона !! пс спробувати запустити це в якості перекладача «з майбутнього дужки імпорту»
HASEN

4
Я майже не згоден з усім вашим списком пітонів, за винятком підтримки потоків. Пробіл не має сенсу, відступ має сенс; є велика різниця.
Крістіан Оудар

3
Ого. Це як би ніхто не винайшов текстовий редактор, який виділяє / показує пробіли / вкладки як спеціальні символи (Що ви кодуєте в блокноті?). Крім того, якщо ви розширите вкладки на пробіли, будь ласка, помріть у пожежі.
Підроблене ім’я

37

Ціль-С

1) Немає просторів імен, а лише конвенції про ручне іменування - я не заперечую, що з точки зору розділення класів, але я сумую за тим, щоб змогти імпортувати всі визначення класів у простору імен в одному рядку (наприклад, import com.me.somelibrary. *).

2) У важливих областях, таких як підтримка RegEx, у бібліотеках є деякі дірки.

3) Синтаксис властивості трохи незграбний, для декларування властивості потрібно три рядки (у двох окремих файлах).

4) Мені подобається модель збереження / випуску, але це простіше, ніж слід, щоб випустити посилання, а потім випадково скористатися ним пізніше.

5) Хоча насправді не є мовною особливістю, Xcode настільки переплетений із використанням Objective-C, що я не можу не думати про цей аспект ... в основному автозавершення, дуже непросте. Це більше схожа на систему, яка нагороджує вас тим, що ви знайдете те, що хочете, існує, а потім представляє це як вибір. Але тоді я припускаю, що мені ніколи не подобалися двигуни автозаповнення.


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

2
Властивості Objective-C. Якщо серйозно, вони шокують, я не можу зрозуміти ажіотаж, особливо бачу, наскільки добре C # робить їх.
Джустікул

6
Насправді мені дуже сподобався той аспект Lisp та ObjC - вам просто потрібен редактор з хорошим підходом дужок, як Emacs або XCode. Зазвичай я набираю дужки парами перед тим, як щось набирати в них, тому я насправді не стикаюся з проблемами зі збігом ... і XCode також може виділити область, укладену дужкою, лише двічі клацнувши на будь-якій дужці.
Кендалл Гельмстеттер Гельнер

1
@Chris S: Ти кажеш, що YES/NOдля булів це погано? І що ще важливіше, ви кажете, що названі параметри - це погана річ ?? Я можу зрозуміти булі, але названі парами, можливо, є однією з найкращих особливостей ObjC (з точки зору читабельності).
jbrennan

3
Можливо, я мазохіст, але мені подобаються префіксні назви класів. Це робить пошук Google і документацію кришталево зрозумілим, ніколи не виникає плутанини щодо того, який рядок ви використовуєте, якщо клас називається NSString.
кубі

36

C ++

  • Струни.
    Вони не взаємодіють із рядками платформи, тому ви в кінцевому підсумку використовуєте std :: vector половину часу. Політика копіювання (копія під час запису чи глибока копія) не визначена, тому гарантії виконання не можуть бути надані для прямого синтаксису. Іноді вони покладаються на алгоритми STL, які не дуже інтуїтивно зрозумілі. Занадто багато бібліотек створюють власні, які, на жаль, набагато зручніші для використання. Якщо не доведеться їх поєднувати.

  • Різноманітність представлення рядків
    Тепер це трохи проблема платформи - але я все ще сподіваюся, що було б краще, коли раніше був би доступний менш жорсткий стандартний клас рядків. Наступні рядкові представлення, які я часто використовую:

    • загальний LPCTSTR,
    • LPC (W) STR, виділений CoTaskMemAlloc,
    • BSTR, _bstr _t
    • (w) рядок,
    • CString,
    • std :: вектор
    • власний клас ( зітхання ), який додає перевірку діапазону та основні операції до (w) char * буфера відомої довжини
  • Побудувати модель.
    Мені страждає смерть за весь час, витрачений на балаканину з тим, хто-що включає, передає декларації, оптимізуючи заздалегідь складені заголовки і включає в себе, щоб не менше примножувати час складання, переносими і т. Д. Це було чудово у вісімдесятих, але тепер? Існує так багато перешкод, щоб спакувати шматочок коду, тому його можна повторно використовувати, що навіть мам собаці нудно слухати мене.

  • Важко розібрати
    Це робить зовнішні інструменти особливо важкими для написання та отримання правильного. І сьогодні нам, хлопцям C ++, бракує в основному ланцюга інструментів. Я люблю свої C # роздуми та делегатів, але можу жити без них. Без великого рефакторингу я не можу.

  • Тематика занадто важка,
    мова навіть не розпізнає її (досі), і свободи компілятора - хоч і великі - болючі.

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


Зрозуміло, багато цього виходить за межі суворої мовної сфери, але ІМО весь ланцюжок інструментів потрібно оцінювати та потребує розвитку.


Перегляд документації на STL - це як пошук посібників про те, як побудувати графічну карту з нуля.
aviraldg

Відверто кажучи, більшість з цих пунктів звучать так, що ви ніколи не намагалися правильно вивчити C ++ ... це стає досить очевидним у №3, оскільки охоронці включення - це те, про що повинен знати кожен програміст C ++. Я також не впевнений, як зрозуміти пункт №1, чи то вас бентежить std::string? можливо, читання хорошої документації та / або підручника про std::vector(а чому ви не повинні використовуватись std::stringу місцях, де вона ніколи не була призначена), може зрозуміти це для вас.

@nebukadnezzar: Я виявив, що Мейєрс світить на STL, але це не вирішує принципових проблем. Відверто кажучи, це звучить так, що ніколи вам не довелося вести великий проект, вам ніколи не довелося шукати кругову залежність в ієрархії, що включає десятки глибин. Я знаю, що входять охоронці, але чому ми повинні турбуватися з ними? До речі. вони не вирішують кожної проблеми. Наскільки "стандартним" є std::stringякщо я не можу ним користуватися половину часу? (C ++ 0x принаймні це виправляє, але я все ще застряг із десятками бібліотек, які використовують різні представлення рядків).
peterchen

but why do we have to bother with them (inclusion guards)- оскільки у C ++ немає модулів. How "standard" is a std::string if I can't use it half of the time?- Я думаю, це залежить від способу, яким ви користуєтесь std::string. Клас рядків дозволяє отримувати доступ до даних рядків як const char*через std::string::c_str, що вже робить std::stringабсолютно сумісним з кожним класом / функцією, яка також бере const char*аргументи.

тому що у C ++ немає модулів - саме моя скарга: модель збірки антикварна (я б також прийняв будь-яке інше рішення, крім модулів). ----- абсолютно сумісний - але абсолютно несумісний з багатьма іншими сценаріями (я б заперечував, що C ++ 0x виправлення цього говорить про те, що я маю тут сенс.) Я був би радий, якби std :: string був досить поширений, щоб були прийняті як клас струн 10 років тому, але це не було - інша скарга.
peterchen

35

JavaScript :

  • ObjectПрототип може бути змінений. Кожен окремий об’єкт у вашій програмі отримує нові властивості, і щось, ймовірно, ламається.

  • Усі об’єкти є хеш-картами, але їх важко безпечно використовувати як такі. Зокрема, якщо один із ваших ключів трапився __proto__, ви переживаєте проблеми.

  • Немає закриття об'єкта в опорний час функції. Насправді, жодне закриття об'єкта - замість цього, thisвстановлюється кожного разу, коли викликається функція із позначенням об'єкта чи newоператором. Приводить до великої плутанини, особливо при створенні зворотних викликів подій, оскільки thisне встановлено те, що програміст очікує.

    • Висновок: виклик функції без позначення об'єкта або newоператора приводить до thisтого, що він буде рівний глобальному об'єкту, що призводить до великого злому.
  • Оператор додавання перевантажений, щоб також здійснювати конкатенацію рядків, незважаючи на те, що дві операції принципово відрізняються. Результат болю, коли значення, яке ви очікуєте на число, насправді є рядком.

  • ==і !=оператори виконують тип примусу. Порівняння різних типів включає перелік правил, які жоден смертний не може запам'ятати повністю. Це пом'якшується існуванням ===і !==операторів.

  • І те, nullі undefinedінше існує з тонко різними, але надмірними значеннями. Чому?

  • Дивний синтаксис для налаштування прототипів ланцюгів.

  • parseInt(s)очікує номер у стилі С, тому трактує значення з провідними нулями як восьмеричні тощо. Ви можете принаймні, parseInt(s, 10)але поведінка за замовчуванням є заплутаною.

  • Без області блоку.

  • Може оголошувати одну і ту ж змінну не один раз.

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

  • with { }.

  • Дуже складно документувати з інструментами, подібними JavaDoc.


3
Для nullта undefined: іноді вам дуже хочеться знати, чи змінній було присвоєно значення чи ні. Оскільки null - це значення, undefined - це єдиний спосіб сказати. Звичайно, єдиний раз, коли я знайшов це корисним, це створити функції геттера / сеттера.
Зак

1
"якщо один із ваших ключів стане прото ", - це зарезервоване слово з особливим значенням. це як скаржитися, що ви не можете використовувати forяк ім'я змінної.
нікф

5
@nickf: Ключ до хешу - рядок. Рядки можуть мати будь-яке значення, включаючи зарезервовані слова. Зокрема, значення "for"дійсне як хеш-ключ. __proto__не є застереженим словом. Значення спеціальних рядків, які не працюють так, як очікувалося, використовуючи хеш-ключі, порушують розумні очікування щодо того, як асоціативні масиви працюють на будь-якій мові. Вони також порушують специфікацію EcmaScript.
Даніель Кассіді

2
Томас: Ньюлайн не завжди закінчує твердження. Тому розумні кодери завершують кожне твердження крапкою з комою, щоб зробити код більш зрозумілим.
Даніель Кассіді

2
newline may or may not end a statement depending on context- це один із моїх перших 5 списків
reinierpost

34

Пітон:

  • Відсутність статичного набору тексту
  • Обробка аргументів за замовчуванням (зокрема, те, що ви можете змінити аргумент за замовчуванням для майбутніх абонентів!)
  • Занадто багато необхідних підкреслень (потрібно викликати конструктори __init__)
  • Відсутність належних приватних членів і функцій (конвенція просто говорить про те, що більшість речей, які починаються з підкреслення, є приватними, за винятком усіх подібних речей __getattr__)
  • Смішний синтаксис для printфайлу (але вони виправляють це в Python 3)

10
Що мені хотілося б - це можливість використовувати статичні типи.
Грег Хьюгілл

4
BTW: init насправді не конструктор, об’єкт був уже створений, коли ви входите туди (здогадайтесь, що таке себе ...). Конструктор гостро новий, коли ви отримуєте доступ до класу, який потрібно інстанціювати.
Андре

90
Якщо ви віддаєте перевагу статичного введення тексту, чому саме Python - ваша улюблена мова?
finnw

9
finnw: Статична типізація чудово підходить для деяких програм, а не дуже потрібна для інших типів. Я, як правило, не проти відсутності статичного набору тексту, але коли вам це потрібно, дуже приємно мати принаймні варіант.
Грег Хьюгілл

8
Я б сказав, що відсутність статичного набору тексту є особливістю, не відсутня функціональність ...
arnorhs

32

C #

  • Я б хотів, щоб я міг switch()будь-який тип, і це caseмогло бути будь-яке вираження.

  • Неможливо використовувати синтаксис об'єкта ініціалізатора з полями "readonly" / private setautoprops. Як правило, я хочу допомогти мові в створенні непорушних типів.

  • Використання в {}протягом імен та класу і методи і майна / індексатор блоків і блоків з кількома операторів і ініціалізаторів масиву . Складно зрозуміти, де ти знаходишся, коли вони далеко один від одного або невідповідні.

  • Я ненавиджу писати (from x in y ... select).Z(). Мені не хочеться повертатися до синтаксису виклику методу, оскільки в синтаксисі запиту щось не вистачає.

  • Я хочу doзастереження про синтаксис запитів, яке подібне foreach. Але це насправді не запит.

Я дійсно досягаю тут. Я думаю, що C # є фантастичним, і важко знайти багато того, що зламано.


14
+1 для перемикання на будь-який тип
жовтня

+1 для проблем з комутацією та {} проблем, про які я до цього часу не думав
Маслоу

Я ненавиджу {}. Вони занадто схожі на (). Невідповідність ніколи не була для мене великою проблемою, тому що я завжди ставлю їх на одному рівні, якщо вони в основному не є одними лайнерами.
Лорен Печтел

2
+1 для запиту linq. Особливо, коли ви хочете повернути лише один об’єкт. Замість (з x in y select) .first (), чому б не a (from x in y select top 1) або щось підходити ближче до фактичного синтаксису sql.
AdmSteck

якщо ви хочете, ви можете переключити () на будь-який тип, і цей випадок може бути будь-яким виразом, перевірте відповідність шаблонів F #. c-sharpcorner.com/UploadFile/mgold/…
gradbot

26

PHP

  1. Немає функцій налагодження, якщо ви не керуєте сервером, і навіть тоді вони неначе смоктані
  2. Надзвичайно велика кількість поганого PHP-коду, що плаває, дає всім програмістам PHP погану назву
  3. Невідповідність іменування функцій
  4. Неможливість мати статичну змінну, якщо я хочу її (я великий фанат динамічного набору тексту 90% часу)
  5. REGISTER_GLOBALS - чорт

25
REGISTER_GLOBALS одного разу з’їв мою собаку :(
Пім Джагер

2
1: Я рекомендую xdebug та клієнтський інтерфейс, такий як MacGDBp. Це дійсно полегшує деякі болі ... Я погоджуюся з іншими моментами.
Jonas Due Vesterheden

5
# 2: Боже, не запускай мене з цього. Мені завжди доводиться захищати себе як розробник PHP від ​​людей, які бачили лише безлад, який багато людей створюють із PHP.
самообслуговування

1
+1 для # 2 Я витратив занадто багато часу на захист себе як розробник PHP.
UnkwnTech

+1 за №2 - також призводить до поганої зарплати :(
Шикі

25

C (Гаразд, це не моє улюблене, але це ще не було зроблено.)

  • Синтаксис бібліотеки сокетів
  • Немає функцій перевантаження.
  • Струни в стилі C
  • Буфер перевищує.
  • Криптичний синтаксис. Я не знаю, скільки разів я шукав такі речі, як атої, ляпав по лобі і кричав "Звичайно!"

EDIT: Можливо, я міг би придумати більше, якби вдався до більшої кількості бібліотечного коду (як це робилося з сокетами, але вони особливо погані), але я вже відчував, що мене обманюють, щоб вибрати C. Це так багато мов, що існують лише для того, щоб взяти хороші частини С і замінюють погане, що це ніби биття мертвого коня.


22
Який синтаксис сокета? C не має поняття розетки.
Ферруччо

3
О, давай! Можна придумати п’ять. Чи не всмоктується арифметика вказівника просто? :)
Брайан d foy

8
+1 Я сміявся з "Струн у стилі С". І @brain_d_foy: арифметика вказівника гасить лише, якщо ви цього не розумієте.
Кріс Лутц

1
@Chris Luts: Навіть коли я вивчав звичайний C (до того, як я знав C ++ або будь-яку іншу мову ОО), я просто знав, що в масиві char не було щось не так. :)
Білл Ящірка

2
арифметика вказівника - це електропила - дуже ефективна, але ви ризикуєте взяти всю ногу
Thorbjørn Ravn Andersen

24

Звичайний Лисп:

  1. Ключові слова часто занадто багатослівні.
  2. Підтримка бібліотеки жалісна.
  3. Не працює в ОС, які хочуть більш жорстко обробляти пам'ять.
  4. Не має хороших можливостей для взаємодії з ОС.
  5. Заклад "петлі" недостатньо визначений, і, звичайно, не виглядає Ліспі.

2
"петля" може бути не липою, але що в цьому погано визначено?
Даніель Кассіді

2
Я сам не читав стандарт, я в основному продовжую фільм Пола Грема "На Ліппі". Він каже, що стандарт - це переважно приклади, і він зовсім не визначає кутові випадки.
Девід Торнлі

3
ви не маєте на увазі ключові слова - занадто багатослівні?
GClaramunt

Я погоджуюсь, що це не "ліпі", але CLtLv2 витрачає на це багато часу. Я просто думаю, що це було розроблено, щоб зробити занадто багато. sunsite.univie.ac.at/textbooks/cltl/clm/…
Hans Van Slooten

Крім "циклу", "формат" також не дуже Lisplike. Я ненавиджу "формат" і "петлю", хоча і Lisp - моя улюблена мова.
Пол Райнерс

24

BrainF * ck

  • Ваша родзинка полягає в тому, що ви Turing завершений ?! Я можу зробити більше в регулярних виразах Perl!

  • Відсутність предметів. Давай, люди! Це як привіт ...

  • Немає мережевих бібліотек. Все, що я хочу, - це обрізати веб-сторінку, GOSH.

  • Ніяких першокласних функцій. Вітаємо - ви знайомитеся зі своїми друзями на Java.

  • Нескінченна стрічка для зберігання і нічого іншого. Це настільки анально претензійно, що ми можемо так само писати Лісп.


6
Немає простору імен або динамічного модуля. Як можна очікувати, щоб писати хімічні системи управління заводами без таких основ?
Стипендіати Доналу

Немає синтаксичного цукру, наприклад> 10 (рухатись 10 разів), 0 (вставити нуль), +5 (додати 5).
Шквал

23

JavaScript

  1. числа як рядки - Математика може бути неприємною, коли числа інтерпретуються як рядки. 5 + 2 = 52? Grrr ...
  2. дозволи - всі найкращі речі вимагають дозволу користувача!
  3. оновлення екрана - для оновлення екрана браузер повинен перебувати в стабільному стані. Здається, не існує способу змусити оновлення екрана в середині сценарію.
  4. Повільно - хоча Google Chrome хороший ...
  5. Відмінності браузера роблять використання мови [цензурою].

4
Числа як рядки легко фіксуються. Якщо у вас коли-небудь є рядок, вам потрібно розібрати його (x, 10). Невдача гіганта - це коли ви виходите з 10, і він тлумачить "017" як ОКТАЛЬ
Оріон Едвардс

3
false == 0 == [] == "", але null і NaN не є. NaN! = NaN. null == null.
Джиммі

7
typeof "a string" == "string". typeof new String ("інший рядок") == "object. new String ('a'). constructor ==" a ".constructor. typeof new Array () == 'object"
Джиммі

1
for (x в об'єкт) повертає функції
Джиммі

14
-1, цей список здебільшого стосується проблем браузера, а не самої мови.
Маурісіо Шеффер

20

PHP:

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

Тим не менш, PHP - це (сценарій) мови. ;-)


Гаразд, ще лише одна річ!
Брайан d foy

4
Цілком погоджуюся з пунктом 5 - теж буде у списку Javascript.
Стів Кларідж

Я не погоджуюся з тим, що "всі погані програмісти, які не навчаються, як змусити його працювати належним чином, і дають йому неправильне ім'я". Я замінив би його "масовим набором параметрів конфігурації мови виконання".
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

18

VB6

  1. Тільки для Windows.
  2. Більше не підтримується.
  3. Масиви можуть починатися з будь-якої кількості, а не нормалізуються до 0.
  4. компільовані програми залежать від того, наскільки багато dll будуть правильно працювати.
  5. Багато складних елементів керування, як-от контроль браузера або складні фрагменти коду, як правило, порушують IDE, коли ви запускаєте код некомпільований, але працює добре, коли компілюється.

13
VB чиясь улюблена мова? О_о. Чому тут не "синтаз, який зовсім інший і несумісний з іншими мовами", і "не дає шкідливих звичок щодо інших мов" тут?
Джонта

3
Я фактично вважаю №3 дуже потужною функцією, а не помилкою - я б дуже хотів, щоб у VB.NET було таке. У AWK це є, в певному сенсі, але тоді в масивах AWK насправді є маскування :(
Джо Пінеда,

3
На 1 і 4, і .NET C # не потребує ПОЛЬНОЇ РАМКИ та операційної системи ??? (Гей, я чув, що ви монобіт ... це все ще "цілісна рамка" для вас, і я сумніваюся, що дебіанський дистриб'ютор коли-небудь їсть це). Щодо 5, жоден праводумний програміст VB6 (ще в той день) не підтримував опцію "Compile On Demand" увімкнено ...
jpinto3912

2
Досі доводиться підтримувати vb6 періодично. Pet pieves: не може ініціалізувати змінну при оголошенні, не параметризовані конструктори, один клас на файл тощо. Якщо вони вирішили ці проблеми, мова може продовжуватися ще 10 років.
AngryHacker

14
Як щодо "On Error Resume Next" ... ось як сказати "цей код є F ** KED, але давайте продовжувати його виконувати все одно. =)
StingyJack

18

Рубі - моя улюблена мова, ось що мені не подобається:

  • Зелені нитки + блокування бібліотек С = гігантський збій
  • Так болісно повільно
  • Сама стандартна бібліотека не відповідає її використанню чуб! методи
  • Модуль включати + розширення безладний.
  • "Відкрити класи" неможливо визначити - я хочу додати String # dostuff, але я не хочу, щоб він просочився до всіх сторонніх бібліотек
  • Немає рішення щодо упаковки двійкового розгортання.

3
Ви пробували Ruby 1.9.1? Він пропонує величезну швидкість у порівнянні з Ruby 1.8.6
Christian Stade-Schuldt

Спробуйте jrubyc. JVM JIT FTW!
KitsuneYMG

+1 за включення розумних проблем, на відміну від "ненависті" з найвищого рейтингу відповіді Рубі.
Фрогз

17

Delphi:

  • IDE трохи нестабільний.
  • Прозорливість коду іноді плутається.
  • Налагодження часом буває помилковим.
  • Оновлення декількох файлів проекту може бути громіздким.
  • Якщо запускається, коли один або більше пакетів недоступні, повідомлення про помилку вискакує кілька разів.

5
Все це, здається, є скаргами на Delphi IDE, а не на Delphi мовою (AKA Object Pascal)
Dónal

11
Імовірно, це тому, що Object Pascal є ідеальним ;-)
Mark Bessey

3
Я трохи запізнююся на партію, але тут все одно: - потрібно двічі записати підписи методу (інтерфейс + реалізація) - НАЗВА ОДИНИТЕ ПОВИННА, щоб бути ідентичною імені файлу. WTF?!?
Martijn

1
Я вважаю початок .. кінці вищі - вони набагато чіткіші, ніж {}. Ви витрачаєте набагато більше часу на читання коду, ніж його написання. Однак для захоплення - ви не можете використовувати визначені піддіаграми перелічених типів у справі, хоча це абсолютно законно, якщо ви оголошуєте діапазон прямо у цьому випадку. Крім того, немає прямих посилань для одиниць.
Лорен Печтел

1
@AlexanderN: Ні, ніколи не було живішим, популярним чи великим.
Андреас Рейбранд

16

JavaScript

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

  • Якщо змінна використовується, але вона не була визначена раніше, вона вважається глобальною змінною

  • Постачальники браузерів складають стандарти за своїм бажанням, роблячи кодування для нас розробників, які використовують таку прекрасну мову, важче, ніж це повинно бути

  • Чутливість до випадку - враховуючи, що не існує гідного IDE для розробки js з перевіркою часу компіляції

  • Обхідні шляхи (наприклад, використання hasOwnPropertyметоду) для виконання деяких, інакше простих операцій.


AFAIK, усі розширення мови JS (а не DOM) від постачальників браузерів принаймні були висунуті для прийняття стандартів - навіть якщо процес стандартизації цього не досяг. hasOwnProperty / обхідні шляхи: меч з двома кінцями. Щоб змусити "простоту", ми втрачаємо багато сили та гнучкості. Ця скарга мене завжди дратує. Напишіть свої петлі праворуч (і перевірте також членів об'єкта прямо)!
безвічність

15

Haskell:

  1. Космічні витоки від ледачих оцінок.
  2. Числова ієрархія не побудована щодо математичних абстракцій.
  3. Суворий монадичний IO може ускладнити налагодження.
  4. Великі реалізації обробляють введення-виведення способами, які не здаються повністю сумісними зі стандартом. (Зокрема, символи, що виводяться, виводять лише низькі 8 біт - і тоді вбудовується код, який використовує це припущення для виконання бінарних вводу / виводу. Ick.)
  5. Асоціативність ($)оператора може бути змінена, щоб зробити деякі вирази красивішими.

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

Редагувати: Була певна плутанина щодо пункту 5. Зокрема, деякі люди, здається, вважають, що я мав на увазі порядок аргументів, чого я не знаю. Замість того, щоб пояснити, що я мав на увазі, я просто вкажу людей на наступне посилання, http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociactivity , що добре виражає це.


3
Чому ви хочете змінити асоціативність ($)? дужки 'fghx' як дужки '((fg) h) x' і 'f $ g $ h $ x' як 'f (g (hx))' ...
Ерік Гесселінк

1
Я <3 Хаскелл. Стандартна бібліотека повинна включати гори математичних абстракцій, включаючи векторні простори та ін. Прелюдії також потрібен оператор, який ланцюгує так само, як ($), але зліва направо {джерело |> func1 |> фільтр func2 |> map (func3 10)}.
yfeldblum

10
Ви пропустили дійсно поганий: схильність програмістів Haskell використовувати імена змінних однієї літери.
Бенджамін Конфіно

1
Ліво-асоціативний ($) оператор - це лише функціональна програма, яка в Haskell представлена ​​символом пробілу. @ Justice: Спробуйте функцію перевернути. (|>) = flip ($)
Апокаліпс

1
Чи може хтось пояснити пункт №5? Я вважав, що правильна асоціативність - вся суть ($).
Тім Меттьюз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.