singlepost

Недостатки языков программирования << На главную или назад  

Так, "какой лучший" – обсудили; но это выродилось в сплошной флейм.
Предлагаю тему, требующую более основательных раздумий для содержательного ответа и потенциально более интересную.

Чем ПЛОХИ некоторые языки программирования? Какие ошибки были допущены при их создании?

Сходу могу назвать несколько самых распространенных ошибок:
- Попытка сделать язык похожим на человеческий – точнее, попытка приравнять понятия "похожесть на человеческий" и "выразительность языка". Результат – язык становится многословным, но понятности в СЛОЖНЫХ случаях (тогда, когда она действительно нужна) – не приобретает вообще. Яркие примеры – Basic, SQL, Pascal.
- Отсутствие непротиворечивой математической теории в основе каждой важной фичи языка. Результат – фича труднопредсказуема, ее трудно использовать, плодятся хаки, постоянно появляются задачи, для которых в языке нет изящного решения, хотя задача не выглядит такой уж сложной. Что еще хуже – такая фича, будучи с комбинированной с любой другой, даже вполне непротиворечивой, делает ее тоже противоречивой и гадкой. Самый яркий пример – шаблоны C++.
- Перенос функциональности из библиотек в сам язык. Результаты почти такие же, как в предыдущем пункте. Яркие примеры – паскалевские writeln/… , интеграция SQL/XML в язык (примеров полно).. Самый яркий пример – COBOL, наверное, хоть я его и не знаю.
- "Незамкнутость", "неуниверсальность" некоторых фич языка, неравноправие похожих вещей – например, невозможность создать массив из массивов, или параметризовать один типовый параметр другим, илиобъявить функцию внутри функции (неравноправие областей видимости), или отсутствие "typedef" (абстракция есть для переменных, но отсутствует для типов). Причина – скорее всего, фича не является математически полной и непротиворечивой; результаты как в соответствующем пункте. Даже самый маленький недочет в фиче запросто может лишить ее 90% потенциальных мощнейших применений. Примеры – массивы фортрана (вроде), генерики в Java и C#, в SQL нельзя в order by указывать алиасы столбцов результата – абсолютно непонятно почему – в результате приходится дублировать выражение для вычисления столбца; почти все не-функциональные языки не поддерживают вложенные и анонимные функции и замыкания, и трудно недооценить, насколько сильно это ограничивает их выразительную мощь.

Ффух. Потом еще что-нибудь допишу, наверное. И вы напишите.

37 ответов в теме “Недостатки языков программирования”

  1. 37
    Армен Айрапетян ответил:

    #36, Леонид maxleo Максимов
    > сомневаюсь, что кому-либо и когда-либо казалось…

    Напрасно. На самом деле задачи всегда ставятся на пределе и чуть-чуть выше текущих возможностей (если не считать творчество душевнобольных). При 100 операциях в секунду никто не думал о "выводе комбинированной графики", зато считалось что утроение скорости позволит задействовать "программирующие программы" (по нашему – компиляторы), отказаться от машинных кодов, и настанет Золотой Век.

  2. 36
    Александр Дзюба ответил:

    #36, Леонид maxleo Максимов

    система real-time рекламы из двух видеокарт (может быть и больше), идет вывод комбинированной графики – несколько трейлеров в HD, анимация опять же HD графики да еще и с HDR. Уткнулся в пропускную способность.
    Все это конечно на грани фола, и решается предварительной обжимкой и парой трюков с DX, но моя мысль была к тому, что увеличение производительности железа влечет за собой увеличение требований к выполняемым задачам.
    Если читали, может быть, Шумила "Иди, поймай свою звезду", – там ребята встретились с компьютером планетарного масштаба, – так вот думается мне, что его программеры тоже мучались с оптимизацией и нехваткой ресурсов.
    Вообще, кажется, только товарищи из майкрософт не озабочены данной проблемой, но это отдельная тема.

  3. 35
    Леонид Максимов ответил:

    #34, Александр LOM Дзюба

    > я не так давно умудрился уткнуться в пропускную способность PCI-E

    не понимаю, как вам это удалось. быть может вы пошли неверным путем?

    #35, Армен "Марат" Айрапетян

    > казалось – вот будет 300 – и все-все-все задачи будут решены :) )

    сомневаюсь, что кому-либо и когда-либо казалось, что увеличение производительности в несколько раз даст возможность легко решать задачи, требующие на много порядков больше действий

  4. 34
    Армен Айрапетян ответил:

    Быстродействие с эрой не связано – оно всегда чуть ниже, чем нужно. Я еще помню времена, когда скорость 100 операций/сек была повсеместной, и казалось – вот будет 300 – и все-все-все задачи будут решены :) )
    Но мы начали дрейфовать в сторону от основной темы.

  5. 33
    Александр Дзюба ответил:

    #33
    Эээ, указатели это вообще т.с. стержень :)
    я вообще не понимаю как без них люди живут
    а по поводу быстродействия – так она (техника) и сейчас не слишком быстродействующая, я не так давно умудрился уткнуться в пропускную способность PCI-E

  6. 32
    Леонид Максимов ответил:

    следует заметит, что C создавался в начале эры, когда вычислительная техника не отличалась быстродействием. от того и указатели.

  7. 31
    Армен Айрапетян ответил:

    Ну, "невозможно" – это я в пылу спора!! Просто иногда куда удобнее использовать множественное наследование, чем другие подходы (типа Bridge) – и тут же всплывают виртуальные базовые классы.

    Как измерить количество проблем? Я думаю, указатели в C принесли столько проблем, породили столько ошибок, извели столько времени на debug… -но как-то странно представить язык без них.
    А многословность COBOLа? Не решила никаких проблем, но породила вполне реальные "кобольные пальцы". И все же без нее язык уже не тот.

  8. 30
    Дима Мироводин ответил:

    #29

    полностью согласен.

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

  9. 29
    Жека Кирпичев ответил:

    Концептуальная ошибка – это решение, принятое дизайнерами языка, которое приносит больше проблем, чем решает, а те проблемы, которые оно все-таки решает, можно решить и без него, и получить при этом более простую и качественную систему.

    Как это "невозможно"? Вот в джаве нет виртуальных базовых классов, и вообще множественного наследования нет. Как же на джаве пишут действительно большие и сложные системы?
    Можно пример, когда без виртуальных базовых классов прямо никак нельзя?

  10. 28
    Армен Айрапетян ответил:

    А что такое – "концептуальная ошибка"? Судя по дискуссии, это (1) то, что ты не используешь; (2) то, что тебе не нравится или не понятно.
    На самом деле под любую фичу языка можно подвести "марксистскую базу".
    И не обижайте виртуальные базовые классы – без них в действительно больших и сложных системах невозможно.

  11. 27
    Дима Мироводин ответил:

    #24

    5 баллов.

  12. 26
    Александр Дзюба ответил:

    однозначно :)
    рекомендую://www.ozon.ru/context/detail/id/2342923/

  13. 25
    Alexander Zubakov ответил:

    Если Вы чего-то не используете, это еще не значит, что оно не нужно ;)

  14. 24
    Александр Дзюба ответил:

    очередной холивар оляля :)

    но вставлю и свои пять копеек :)

    >> Надежда Kenga Поликарпова
    >> 25 ноя 2008 в 18:11
    >> Конечно, само деление на private и protected во всех языках C-семейства это тоже ошибка, на мой взгляд, но об этом можно дооолго спорить:) Суть модульности в ООП в том, что создателю класса нет необходимости обладать бесконечной мудростью и знать всех клиентов и потомков класса. Разделение на private и protected уже нарушает принцип модульности, но с этим вполне можно жить.

    насчет private согласен целиком и полностью, с protected можно жить. Также по моему скромному мнению сюда же можно отнести и friend classes.
    Виртуальный базовый класс приходилось юзать раз в жизни, и то из-за того что при начальном проектировании системы была допущена ошибка.

  15. 23
    Николай Митропольский ответил:

    Да, насчет private и protected согласен, вообще предлагаю protected отменить)

  16. 22
    Жека Кирпичев ответил:

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

  17. 21
    Надежда Поликарпова ответил:

    #19: не очень понятно, как Ваш комментарий связан с моим постом? Конечно, само деление на private и protected во всех языках C-семейства это тоже ошибка, на мой взгляд, но об этом можно дооолго спорить:) Суть модульности в ООП в том, что создателю класса нет необходимости обладать бесконечной мудростью и знать всех клиентов и потомков класса. Разделение на private и protected уже нарушает принцип модульности, но с этим вполне можно жить. Выбор вручную между статическим и дингамическим связыванием его нарушает, но так уж сложилось, что программисты C++ унаследовали способность к самопожертвованию ради быстродействия. Но вот вирутальные базовые классы совсем уж никуда не годятся. Множественное наследование (реализации) не так широко используется в плюсах не потому что оно зло само по себе, а именно из-за таких косяков, потому что средства его поддержки в языке не развиты.

  18. 20
    Леонид Максимов ответил:

    простой парсер написать на SQL не так уж и сложно – не многим сложнее, чем на классических языках. да и работать будет не сильно медленнее. правда, SQL – это, в первую очередь, удобное манипулирование данными в offensive-стиле.

    кстати, куда-то делось мое сообщение о том, что в SQL можно сортировать результаты по вычисляемым столбцам без дублирования выражения – просто указывать номер столбца.

  19. 19
    Дима Мироводин ответил:

    Жека jkff Кирпичев

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

  20. 18
    Пишу Сиплюсплюс ответил:

    Николай Митропольскийнаследование… это многие сэкономленные часы моих извилин…

  21. 17
    Пишу Сиплюсплюс ответил:

    Надежда Kenga Поликарпова , если класс собирается быть наследуемый, тогда быть его членикам протектед, аминь!

  22. 16
    Жека Кирпичев ответил:

    Ну, mixins это не такая уж плохая штука.

  23. 15
    Николай Митропольский ответил:

    П-омоему, вообще возмножность наследования реализации – концептуальная ошибка) Гораздо проще, когда все строится на агрегации и интерфейсах :p

  24. 14
    Жека Кирпичев ответил:

    По-моему, сама возможность множественного наследования реализации – концептуальная ошибка. Ее ничем не исправить.

  25. 13
    Надежда Поликарпова ответил:

    На вскидку: ИМХО, механизм виртуальных базовых классов в плюсах – концептуальная ошибка. Дело в том, что выбор, будут ли поля повторно наследуемого класса дублироваться или нет, должен делать тот класс, который повторно наследуется (то есть "нижняя точка" ромба), а не промежуточные классы, которые даже не подозревают, что от них кто-то собирается множественно наследоваться.

  26. 12
    Николай Митропольский ответил:

    Наверное это можно отнести к "похожести на человеческий", но в некоторых языках очень бесит возможность сделать одно и то же двадцатью разными синтаксическими конструкциями.(Perl, Ruby).

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

  27. 11
    Дмитрий Захаров ответил:

    как уже сказано ранее каждый язык для своей цели. имхо java рулит, но она тож использует другие, например она нета без xml, серваки на ней писать без jsp, jsf и тд, а любая прога с бдбез sql, мне кажется разумнее обсуждать технологии а не языки

  28. 10
    Леонид Максимов ответил:

    х_Х
    не гнать на vb5

  29. 9
    Серега Губченко ответил:

    в VB5 недоступен пункт создать ехе хотя в VB6 это действие доступно

  30. 8
    Сергей Бутаков ответил:

    в python есть как минимум один существенный недостаток – ненастоящие потоки, их ещё и завершить (даже) из родительского потока невозможно.

  31. 7
    Жека Кирпичев ответил:

    Константин, то, что С++ или Java идеально подходит для тех задач, для которых он создавался – не значит, что они лишены концептуальных ошибок. И, в свою очередь, то, что в языке есть концептуальные ошибки (а они есть практически везде) – не значит, что язык плохой.

    Цель дискуссии – не обхаять языки (в этом случае она была бы тупой), а внести ясность в вопрос "каких ошибок не следует допускать при проектировании языков". По-моему, это достаточно интересный и важный вопрос. Программисты занимаются этим вопросом с самого момента появления языков программирования, и благодаря этому языки эволюционируют и появляются все более совершенные языки.

  32. 6
    Жека Кирпичев ответил:

    Еще раз обращаю внимание всех:
    ****Указывайте на КОНЦЕПТУАЛЬНЫЕ ОШИБКИ****, а не на мелкие фичи или отсутствие мелких фич языка (переменное число аргументов, синтаксис комментариев итп)! Только в этом случае дискуссия приобретет ценность и не превратится в балаган.

  33. 5
    Константин Дерец ответил:

    тупая дисскусия
    каждый язык создавался для определенных целей, для которых он подходит идеально…
    а говорить в общем- так получиться что все языки плохие..

  34. 4
    Максим Вальтер ответил:

    Pascal – неудобно создавать массивы произвольной длины (С++ в этом смысле гораздо удобнее)

  35. 3
    Ярослав Паныч ответил:

    Антон Щиров
    Как мне хочется покритиковать Вами сказаное! Скажу только пару слов:
    Borland/Turbo Pascal != FreePascal != Delphi также С– != С != С++ и т.д.

    Помоему эта дискусия заведет нас в болото. Начнут перечислять отсутсвие фич у одних языков, которые есть у других или наличее багов у одних котрых нету уже у других. Буду сообщения типа таких:
    > Ну и что, что в Паскале нету переменного количества параметров? Кто вам мешает написать функцию на Асемблере и подключить в Паскаль?
    > В С макросы? Зато в С++ шаблоны и дебажить их невозможно! Зато Асемблер читабельный только с макросами.
    > Ну и что, что Java кросс-платформнная и марсоходами управляет, зато она стековая, а вот LUA, например, регистровая и с линковкой находу и типов всего 7 и не больше и этого хватит на все случаи жизни.

    и т.д. Итого писатели будут хаять все языки кроме своего любимого или в данный момент пользуемого. А как будут пермывать кости Эзотерическим языкам.
    Что ж, посмотрим….

  36. 2
    Жека Кирпичев ответил:

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

    Несколько замечаний:

    А зачем нужны функции с переменным числом аргументов? По-моему, единственный способ это сделать культурно – сделать как в джаве: "произвольное число аргументов" как неявный массив аргументов.

    Макросы – это типичный пример недоделанной и неполной фичи, в комбинации с другими превращающей язык в кашу. К счастью, они в руках большинства людей настолько примитивны, что не то чтобы безобидны, но не смертельны :)

    PHP – о! Прекрасный пример еще одной ошибки проектирования: Попытка наполнить язык "удобными" неявными вещами, такими как неявные преобразования типов. На практике это вырождается в полный пиздец, ад отладки и поддержки, и провоцирование на плохой код вместо удобства.

    > переменные, которым можно присвоить значение только один раз и отсутствие циклов

    XSL – декларативный язык; добавление в него присваиваний сделало бы из него мешанину. По-моему, хоть на нем и трудно программировать – сделать другой эффективный и концептуально целостный (!) декларативный язык описания преобразований XML было бы еще труднее. У тебя есть идеи как это сделать, кстати?

  37. 1
    Антон Щиров ответил:

    Вставлю свои пять копеек (все имхо)

    Pascal
    1)Невозможность объявить функцию с переменным числом параметров (да, есть параметры по умолчанию, но ээто не оно). Правда можно извратиться через вариантный массив (как это сделано в функции Format())

    2) Неравноправность функций объявленых в модуле System и всех остальных. Примеры Inc()/Dec() – принимают любой скалярный тип, SizeOf – принимает переменную любого типа, а также сам тип (SizeOf(Integer))? Writeln – переменное число параметров

    3) Интерфейсы – с целью облегчить жизнь программистам, Delphi сама увеличивает/уменьшает счетчик ссылок. Это работает, до тех пор, пока к объекту не начинают обращаться и как кобъекту класса и как к объекту интерфейса. После этого у счетчика сносит крышу

    ===================
    С
    1) Макросы. Да именно они. Нет сами макросы вреда не несут, но то как их используют. Убивает вложенность макросов. Когда идет макрос на макросе (один раз видел до 10 вложений) – читабельность такого кода падает в разы

    ===================
    PHP
    1) И опять функции с переменным числом параметров. Тут они есть, но вот объявить в такой функции обязательные параметры невозможно

    ===================
    JavaSсript
    свойство prototype – у одних объектов оно есть у других нет

    ===================
    XSL (пусть и оно будет языком :) )
    Убивают переменные, которым можно присвоить значение только один раз и отсутствие циклов (в итоге люди наловчились вместо циклов использовать рекурсию), а также невозможность написать цивилизованную функцию, которая просто возвращала бы значение

    Еще раз – это то, что мешает жить лично мне

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.