Так, "какой лучший" – обсудили; но это выродилось в сплошной флейм.
Предлагаю тему, требующую более основательных раздумий для содержательного ответа и потенциально более интересную.
Чем ПЛОХИ некоторые языки программирования? Какие ошибки были допущены при их создании?
Сходу могу назвать несколько самых распространенных ошибок:
- Попытка сделать язык похожим на человеческий – точнее, попытка приравнять понятия "похожесть на человеческий" и "выразительность языка". Результат – язык становится многословным, но понятности в СЛОЖНЫХ случаях (тогда, когда она действительно нужна) – не приобретает вообще. Яркие примеры – Basic, SQL, Pascal.
- Отсутствие непротиворечивой математической теории в основе каждой важной фичи языка. Результат – фича труднопредсказуема, ее трудно использовать, плодятся хаки, постоянно появляются задачи, для которых в языке нет изящного решения, хотя задача не выглядит такой уж сложной. Что еще хуже – такая фича, будучи с комбинированной с любой другой, даже вполне непротиворечивой, делает ее тоже противоречивой и гадкой. Самый яркий пример – шаблоны C++.
- Перенос функциональности из библиотек в сам язык. Результаты почти такие же, как в предыдущем пункте. Яркие примеры – паскалевские writeln/… , интеграция SQL/XML в язык (примеров полно).. Самый яркий пример – COBOL, наверное, хоть я его и не знаю.
- "Незамкнутость", "неуниверсальность" некоторых фич языка, неравноправие похожих вещей – например, невозможность создать массив из массивов, или параметризовать один типовый параметр другим, илиобъявить функцию внутри функции (неравноправие областей видимости), или отсутствие "typedef" (абстракция есть для переменных, но отсутствует для типов). Причина – скорее всего, фича не является математически полной и непротиворечивой; результаты как в соответствующем пункте. Даже самый маленький недочет в фиче запросто может лишить ее 90% потенциальных мощнейших применений. Примеры – массивы фортрана (вроде), генерики в Java и C#, в SQL нельзя в order by указывать алиасы столбцов результата – абсолютно непонятно почему – в результате приходится дублировать выражение для вычисления столбца; почти все не-функциональные языки не поддерживают вложенные и анонимные функции и замыкания, и трудно недооценить, насколько сильно это ограничивает их выразительную мощь.
Ффух. Потом еще что-нибудь допишу, наверное. И вы напишите.
28 ноября 2008 в 9:05
#36, Леонид maxleo Максимов
> сомневаюсь, что кому-либо и когда-либо казалось…
Напрасно. На самом деле задачи всегда ставятся на пределе и чуть-чуть выше текущих возможностей (если не считать творчество душевнобольных). При 100 операциях в секунду никто не думал о "выводе комбинированной графики", зато считалось что утроение скорости позволит задействовать "программирующие программы" (по нашему – компиляторы), отказаться от машинных кодов, и настанет Золотой Век.
28 ноября 2008 в 1:05
#36, Леонид maxleo Максимов
система real-time рекламы из двух видеокарт (может быть и больше), идет вывод комбинированной графики – несколько трейлеров в HD, анимация опять же HD графики да еще и с HDR. Уткнулся в пропускную способность.
Все это конечно на грани фола, и решается предварительной обжимкой и парой трюков с DX, но моя мысль была к тому, что увеличение производительности железа влечет за собой увеличение требований к выполняемым задачам.
Если читали, может быть, Шумила "Иди, поймай свою звезду", – там ребята встретились с компьютером планетарного масштаба, – так вот думается мне, что его программеры тоже мучались с оптимизацией и нехваткой ресурсов.
Вообще, кажется, только товарищи из майкрософт не озабочены данной проблемой, но это отдельная тема.
28 ноября 2008 в 0:01
#34, Александр LOM Дзюба
> я не так давно умудрился уткнуться в пропускную способность PCI-E
не понимаю, как вам это удалось. быть может вы пошли неверным путем?
#35, Армен "Марат" Айрапетян
> казалось – вот будет 300 – и все-все-все задачи будут решены )
сомневаюсь, что кому-либо и когда-либо казалось, что увеличение производительности в несколько раз даст возможность легко решать задачи, требующие на много порядков больше действий
27 ноября 2008 в 13:04
Быстродействие с эрой не связано – оно всегда чуть ниже, чем нужно. Я еще помню времена, когда скорость 100 операций/сек была повсеместной, и казалось – вот будет 300 – и все-все-все задачи будут решены )
Но мы начали дрейфовать в сторону от основной темы.
27 ноября 2008 в 13:01
#33
Эээ, указатели это вообще т.с. стержень
я вообще не понимаю как без них люди живут
а по поводу быстродействия – так она (техника) и сейчас не слишком быстродействующая, я не так давно умудрился уткнуться в пропускную способность PCI-E
26 ноября 2008 в 22:04
следует заметит, что C создавался в начале эры, когда вычислительная техника не отличалась быстродействием. от того и указатели.
26 ноября 2008 в 11:05
Ну, "невозможно" – это я в пылу спора!! Просто иногда куда удобнее использовать множественное наследование, чем другие подходы (типа Bridge) – и тут же всплывают виртуальные базовые классы.
Как измерить количество проблем? Я думаю, указатели в C принесли столько проблем, породили столько ошибок, извели столько времени на debug… -но как-то странно представить язык без них.
А многословность COBOLа? Не решила никаких проблем, но породила вполне реальные "кобольные пальцы". И все же без нее язык уже не тот.
26 ноября 2008 в 11:04
#29
полностью согласен.
Вообще у нас в россии каждая кухарка умеет управлять государством.
26 ноября 2008 в 11:01
Концептуальная ошибка – это решение, принятое дизайнерами языка, которое приносит больше проблем, чем решает, а те проблемы, которые оно все-таки решает, можно решить и без него, и получить при этом более простую и качественную систему.
Как это "невозможно"? Вот в джаве нет виртуальных базовых классов, и вообще множественного наследования нет. Как же на джаве пишут действительно большие и сложные системы?
Можно пример, когда без виртуальных базовых классов прямо никак нельзя?
26 ноября 2008 в 10:01
А что такое – "концептуальная ошибка"? Судя по дискуссии, это (1) то, что ты не используешь; (2) то, что тебе не нравится или не понятно.
На самом деле под любую фичу языка можно подвести "марксистскую базу".
И не обижайте виртуальные базовые классы – без них в действительно больших и сложных системах невозможно.
25 ноября 2008 в 21:03
#24
5 баллов.
25 ноября 2008 в 21:02
однозначно
рекомендую://www.ozon.ru/context/detail/id/2342923/
25 ноября 2008 в 20:05
Если Вы чего-то не используете, это еще не значит, что оно не нужно
25 ноября 2008 в 20:02
очередной холивар оляля
но вставлю и свои пять копеек
>> Надежда Kenga Поликарпова
>> 25 ноя 2008 в 18:11
>> Конечно, само деление на private и protected во всех языках C-семейства это тоже ошибка, на мой взгляд, но об этом можно дооолго спорить:) Суть модульности в ООП в том, что создателю класса нет необходимости обладать бесконечной мудростью и знать всех клиентов и потомков класса. Разделение на private и protected уже нарушает принцип модульности, но с этим вполне можно жить.
насчет private согласен целиком и полностью, с protected можно жить. Также по моему скромному мнению сюда же можно отнести и friend classes.
Виртуальный базовый класс приходилось юзать раз в жизни, и то из-за того что при начальном проектировании системы была допущена ошибка.
25 ноября 2008 в 20:00
Да, насчет private и protected согласен, вообще предлагаю protected отменить)
25 ноября 2008 в 18:05
Надежда, #19 это психбольной, в прямом смысле этого слова. Я его уже забанил. Не стоит ему отвечать где бы то ни было.
Кстати, если интересует модульность, рекомендую обратить внимание на функциональное программирование и почерпнуть идеи оттуда.
25 ноября 2008 в 18:01
#19: не очень понятно, как Ваш комментарий связан с моим постом? Конечно, само деление на private и protected во всех языках C-семейства это тоже ошибка, на мой взгляд, но об этом можно дооолго спорить:) Суть модульности в ООП в том, что создателю класса нет необходимости обладать бесконечной мудростью и знать всех клиентов и потомков класса. Разделение на private и protected уже нарушает принцип модульности, но с этим вполне можно жить. Выбор вручную между статическим и дингамическим связыванием его нарушает, но так уж сложилось, что программисты C++ унаследовали способность к самопожертвованию ради быстродействия. Но вот вирутальные базовые классы совсем уж никуда не годятся. Множественное наследование (реализации) не так широко используется в плюсах не потому что оно зло само по себе, а именно из-за таких косяков, потому что средства его поддержки в языке не развиты.
24 ноября 2008 в 23:04
простой парсер написать на SQL не так уж и сложно – не многим сложнее, чем на классических языках. да и работать будет не сильно медленнее. правда, SQL – это, в первую очередь, удобное манипулирование данными в offensive-стиле.
кстати, куда-то делось мое сообщение о том, что в SQL можно сортировать результаты по вычисляемым столбцам без дублирования выражения – просто указывать номер столбца.
24 ноября 2008 в 21:03
Жека jkff Кирпичев
На счёт сложных случаев и SQL – ты конечно загнул. просто есть особо одаренные гении, которые на SQL пытаются оперировать не наборами данных, а писать парсинг строк к примеру.
24 ноября 2008 в 21:02
Николай Митропольскийнаследование… это многие сэкономленные часы моих извилин…
24 ноября 2008 в 21:02
Надежда Kenga Поликарпова , если класс собирается быть наследуемый, тогда быть его членикам протектед, аминь!
24 ноября 2008 в 20:00
Ну, mixins это не такая уж плохая штука.
24 ноября 2008 в 19:05
П-омоему, вообще возмножность наследования реализации – концептуальная ошибка) Гораздо проще, когда все строится на агрегации и интерфейсах :p
24 ноября 2008 в 18:01
По-моему, сама возможность множественного наследования реализации – концептуальная ошибка. Ее ничем не исправить.
24 ноября 2008 в 16:02
На вскидку: ИМХО, механизм виртуальных базовых классов в плюсах – концептуальная ошибка. Дело в том, что выбор, будут ли поля повторно наследуемого класса дублироваться или нет, должен делать тот класс, который повторно наследуется (то есть "нижняя точка" ромба), а не промежуточные классы, которые даже не подозревают, что от них кто-то собирается множественно наследоваться.
22 ноября 2008 в 12:04
Наверное это можно отнести к "похожести на человеческий", но в некоторых языках очень бесит возможность сделать одно и то же двадцатью разными синтаксическими конструкциями.(Perl, Ruby).
Еще, как показала практика, часто старания разработчиков сохранить совместимость с предыдущими версиями языка/другими языками портит язык. Классический пример С++, ну и генерики жавы тоже сюда же.
21 ноября 2008 в 6:03
как уже сказано ранее каждый язык для своей цели. имхо java рулит, но она тож использует другие, например она нета без xml, серваки на ней писать без jsp, jsf и тд, а любая прога с бдбез sql, мне кажется разумнее обсуждать технологии а не языки
18 ноября 2008 в 0:04
х_Х
не гнать на vb5
16 ноября 2008 в 21:03
в VB5 недоступен пункт создать ехе хотя в VB6 это действие доступно
7 мая 2008 в 6:04
в python есть как минимум один существенный недостаток – ненастоящие потоки, их ещё и завершить (даже) из родительского потока невозможно.
1 мая 2008 в 10:03
Константин, то, что С++ или Java идеально подходит для тех задач, для которых он создавался – не значит, что они лишены концептуальных ошибок. И, в свою очередь, то, что в языке есть концептуальные ошибки (а они есть практически везде) – не значит, что язык плохой.
Цель дискуссии – не обхаять языки (в этом случае она была бы тупой), а внести ясность в вопрос "каких ошибок не следует допускать при проектировании языков". По-моему, это достаточно интересный и важный вопрос. Программисты занимаются этим вопросом с самого момента появления языков программирования, и благодаря этому языки эволюционируют и появляются все более совершенные языки.
1 мая 2008 в 10:03
Еще раз обращаю внимание всех:
****Указывайте на КОНЦЕПТУАЛЬНЫЕ ОШИБКИ****, а не на мелкие фичи или отсутствие мелких фич языка (переменное число аргументов, синтаксис комментариев итп)! Только в этом случае дискуссия приобретет ценность и не превратится в балаган.
1 мая 2008 в 10:01
тупая дисскусия
каждый язык создавался для определенных целей, для которых он подходит идеально…
а говорить в общем- так получиться что все языки плохие..
1 мая 2008 в 5:02
Pascal – неудобно создавать массивы произвольной длины (С++ в этом смысле гораздо удобнее)
1 мая 2008 в 0:03
Антон Щиров
Как мне хочется покритиковать Вами сказаное! Скажу только пару слов:
Borland/Turbo Pascal != FreePascal != Delphi также С– != С != С++ и т.д.
Помоему эта дискусия заведет нас в болото. Начнут перечислять отсутсвие фич у одних языков, которые есть у других или наличее багов у одних котрых нету уже у других. Буду сообщения типа таких:
> Ну и что, что в Паскале нету переменного количества параметров? Кто вам мешает написать функцию на Асемблере и подключить в Паскаль?
> В С макросы? Зато в С++ шаблоны и дебажить их невозможно! Зато Асемблер читабельный только с макросами.
> Ну и что, что Java кросс-платформнная и марсоходами управляет, зато она стековая, а вот LUA, например, регистровая и с линковкой находу и типов всего 7 и не больше и этого хватит на все случаи жизни.
и т.д. Итого писатели будут хаять все языки кроме своего любимого или в данный момент пользуемого. А как будут пермывать кости Эзотерическим языкам.
Что ж, посмотрим….
1 мая 2008 в 0:00
Не совсем то, что я имел в виду – то, что ты сказал – это неудобства или баги языков для конкретных задач, а не концептуальные ошибки. Но все равно спасибо за вклад
Несколько замечаний:
А зачем нужны функции с переменным числом аргументов? По-моему, единственный способ это сделать культурно – сделать как в джаве: "произвольное число аргументов" как неявный массив аргументов.
Макросы – это типичный пример недоделанной и неполной фичи, в комбинации с другими превращающей язык в кашу. К счастью, они в руках большинства людей настолько примитивны, что не то чтобы безобидны, но не смертельны
PHP – о! Прекрасный пример еще одной ошибки проектирования: Попытка наполнить язык "удобными" неявными вещами, такими как неявные преобразования типов. На практике это вырождается в полный пиздец, ад отладки и поддержки, и провоцирование на плохой код вместо удобства.
> переменные, которым можно присвоить значение только один раз и отсутствие циклов
XSL – декларативный язык; добавление в него присваиваний сделало бы из него мешанину. По-моему, хоть на нем и трудно программировать – сделать другой эффективный и концептуально целостный (!) декларативный язык описания преобразований XML было бы еще труднее. У тебя есть идеи как это сделать, кстати?
30 апреля 2008 в 23:03
Вставлю свои пять копеек (все имхо)
Pascal
1)Невозможность объявить функцию с переменным числом параметров (да, есть параметры по умолчанию, но ээто не оно). Правда можно извратиться через вариантный массив (как это сделано в функции Format())
2) Неравноправность функций объявленых в модуле System и всех остальных. Примеры Inc()/Dec() – принимают любой скалярный тип, SizeOf – принимает переменную любого типа, а также сам тип (SizeOf(Integer))? Writeln – переменное число параметров
3) Интерфейсы – с целью облегчить жизнь программистам, Delphi сама увеличивает/уменьшает счетчик ссылок. Это работает, до тех пор, пока к объекту не начинают обращаться и как кобъекту класса и как к объекту интерфейса. После этого у счетчика сносит крышу
===================
С
1) Макросы. Да именно они. Нет сами макросы вреда не несут, но то как их используют. Убивает вложенность макросов. Когда идет макрос на макросе (один раз видел до 10 вложений) – читабельность такого кода падает в разы
===================
PHP
1) И опять функции с переменным числом параметров. Тут они есть, но вот объявить в такой функции обязательные параметры невозможно
===================
JavaSсript
свойство prototype – у одних объектов оно есть у других нет
===================
XSL (пусть и оно будет языком )
Убивают переменные, которым можно присвоить значение только один раз и отсутствие циклов (в итоге люди наловчились вместо циклов использовать рекурсию), а также невозможность написать цивилизованную функцию, которая просто возвращала бы значение
Еще раз – это то, что мешает жить лично мне