Обновить
66
@NeoCoderead⁠-⁠only

Programmer

1
Рейтинг
105
Подписчики
Отправить сообщение
Ответил выше: простота языка — это перекладывание проблем на плечи пользователей, все чего нет в языке им придется допиливать вручную. Все равно придется, только вместо единой реализации в языке будет 100500 кривых реализаций «на местах».
Потому что нужно писать — и компиляторы, и документацию — как следует, а не как попало. Простота языка — это перекладывание проблем на плечи пользователей, все чего нет в языке им придется допиливать вручную. А сложность языка — это результат того, что во-первых, не все бывает сразу ясно (когда создавался С++ многие вещи были еще неочевидны, в Java и C# их учли), во-вторых — страх сломать «обратную совместимость». Сейчас уже более-менее все очевидно по фичам, ну и делать нужно с нуля, а не издеваться над С++.
Простота их тоже порождает. Вот brainfuck прост до безобразия, а попробуйте ка на нем написать хоть что-то серьезное без ошибок:)))
Нет, не думаю. Просто некоторые старые языки — такие например как Smalltalk — могут содержать немало интересных идей, поэтому иногда здесь появляются статьи, и мы их с удовольствием читаем…
Я считаю, что компилятор соответствует языку (иначе это уже компилятор другого языка, пусть и очень похожего). То что в жизни компиляторы не всегда соответствуют стандартам языков — это вообще говоря проблема, а не нормальное явление. Сами посудите: вот переходите вы на новый компилятор — а программа не компилируется или не так работает. Оно вам надо?
В общем, такого категорически не должно быть. Поэтому лучше, чтобы все фичи были официально задокументированы в стандарте языка, и — что не менее важно — чтобы не было никаких фич, не описанных в стандарте.
Как обычно — то что встроено непосредственно в язык и поддерживается компилятором. Например, операторы if/else. Для сравнения, операторы консольного ввода/вывода (всякие printf, println, WriteLine) — это библиотечные возможности, компилятор о них не знает.
Boost это некоммерческая разработка. GСС тоже (в gcc можно посмотреть например gcc.gnu.org/onlinedocs/gcc/C-Extensions.html и gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html — тоже много интересного). Языки D и Nim тоже некоммерческие. Go — продукт Гугла, но истоки в системе Plan9 и ее языках Alef и Limbo. Rust — продукт Мозиллы, но они для себя разрабатывают, и продукт полностью открытый. Нет, я не склонен увязывать сюда коммерцию, сейчас вообще почти все языки и IDE бесплатные.

По рефлексии — если компилятору известно чуть больше, это уже языковая фича. Конкретные применения этой фичи (например запись в xml, json, binary) — это действительно должно быть в библиотеках, но если в компиляторе нет ничего для базовой поддержки — то остаются только нагромождения костылей (как это и есть в С++). Одна маленькая фича в компиляторе позволит выкинуть множество неестественных и ненадежных нагромождений в библиотечном и прикладном коде. В этом и смысл языковых фич.

О балансе — в С++ нарушением баланса (ИМХО конечно) являются не сами шаблоны, а метапрограммирование на них. А сами шаблоны вполне сбалансированы. По изначальному замыслу предполагалось, что шаблоны будут вот для таких конструкций
template<class T, int N>
struct Array
{
  T data[N];
}; 

а не для написания полноценных парсеров времени компиляции (boost.spirit) или compile-time коллекций типов и операций над ними (boost.mpl). Но то, что эти библиотеки появились, и что ими, несмотря на сложности, пользуются — признак того, что соответствующие возможности реально востребованы.
Это есть такая эпичная тема на rsdn: Синтаксический оверхед Про нее даже на Лурке написано…
Как рефлексия может работать в компонентах, если от компилятора требуется например связать объект с его строковым именем (которое известно только на этапе компиляции) и предоставить эту информацию другим частям программы? Тут или рефлексия, или ручками прописывать — других вариантов нет.

Шаблоны при правильной реализации никакой связи с кодом не лишают. Даже обычный оператор присваивания — это шаблон, потому что в конечном итоге для целых чисел вызывается один набор ассемблерных команд, для float — другой, а для строк вообще третий. Вы же не утверждаете что оператор присваивания лишает вас связи с кодом?

«Никто не знает, насколько та или иная фича нужна в языке» — почему же, практикующие программисты знают. Я приводил в пример Буст — это все не с потолка придумано, а для решения конкретных задач. Другое дело, что идеологически многое там — не полноценные фичи, а мегакостыли на костылях… Могу еще из своей жизни привести пример: я регулярно и достаточно давно заношу в evernote разные идеи по языковым фичам, возникающие из реальной практики. Таких записей сотни…
А у меня есть подозрение, что Overengineering как-то связан с нехваткой полноценных языковых фич и с неполнотой/несовершенством стандартных библиотек. Люди, закладывая универсальность в свои программы, раз за разом пишут по сути некие околобиблиотечные/околофреймворковые вещи, которые по уму должны быть как-то реализованы стандартно, чтобы их не писать, а просто брать и пользоваться… Надо будет подумать над этим.
О, олдскульный сайтик на народе… они еще существуют:) Когда-то давно во времена диалапа я по крупицам собирал интересную информацию с таких вот страничек…
Самый простой язык это не оберон, а brainfuck — всего 4 оператора и ничего больше. И разумеется, на нем можно писать программы. Но нужно ли?
Фичи — это не просто какой-то «синтаксический сахар» (вообще странное словосочетание:) ), это нечто, дающее новые возможности.

Например, рефлексия. Она есть в обероне? А это необходимая фича для автоматического связывания кода программы с внешними данными (например сериализация в xml). Разумеется, это можно сделать вручную — не забыв аккуратно прописать для каждого поля каждой структуры процедуру чтения и процедуру записи. Все можно сделать вручную. Более того, любую программу можно написать на ассемблере и даже в машинных кодах вручную. Но нужно ли?

Или те же самые шаблоны и метапрограмминг. Да, это следующий уровень программирования, и конечно, он может быть проэмулирован вручную — аккуратным написанием тех же векторов, списков и алгоритмов для каждого типа. Но зачем, если есть удобный инструмент под названием «метапрограммирование»? То что он в С++ поехал не в ту степь — да, это нужно пофиксить (и ввести новые фичи, специально спроектированные для решения задач, для которых в С++ используют метапрограммирование на шаблонах), но зачем отказываться?

В той статье я не затронул многие вещи. Например, особенности добавления фич в современные языки. В большинстве случаев они добавляются бессистемно и, что самое печальное, они слабо связаны между собой. Вот это реально проблема. А количество фич — оно вполне разумно во всех существующих языках, я еще не встречал такого языка чтобы можно было запутаться в его синтаксисе. И стремиться их минимизировать вообще странно, это всего лишь инструменты — удобные инструменты для решения соответствующих задач; какой смысл например при создании чего-то (строительстве дома или там космического корабля) стремиться ограничить себя в инструментах???
Согласен полностью. У меня среди evernote-заметок, где я храню различые идеи по языкам программирования, немаленький раздел посвящен IDE; при проектировании языка учитываю связку с IDE (в частности, синтаксис языка должен строиться таким образом, чтобы было удобно работать автокомпилиту, построителю деревьев классов и прочим инструментам IDE, которые должны работать «на лету»); я даже указываю специальные рекомендации к IDE, к организации проектов и т.п., что обычно в язык не входит. А одна из первых вещей с чего я начал эксперименты со своим компилятором (форком D) — это написал простейшую IDE на Qt и делаю визуализатор AST (а затем будут визуализаторы всех преобразований внутри компилятора, вплоть до кодогенератора). То есть не только пользоваться компилятором, но даже разрарабывать его без графического интерфейса неудобно.
Или наоборот пропиарить? Типа Гугл со своими успехами в области ИИ настолько крут…
Интерпретируемый во время компиляции, конечно же:)
Расскажите подробнее, чувствуется что вы знаете что-то интересное. Насчет Sun OBI, SGI Delta C++, DTS C++…
Для любого X всегда найдется Y, такой, что X — всего лишь инструмент для Y :)
Да, это уже лучше (хотя синтаксис все равно производит странное впечатление, но по смыслу лучше).
В общем, философия метапрограмминга сводится к тому, что должно быть два контекста:
1. компилируемый код (и конструкции для подстановки такого кода в произвольные места — шаблоны), ключевое слово template
2. интерпретируемый во время исполнения код — macro; макросы кстати могут писаться на приизвольных языках, не обязательно на том же языке что и код. Главное, чтобы из них был доступ к AST DOM и API компилятора.

При этом в контексте компилируемого кода можно вставлять интерпретируемые на этапе компиляции конструкции (в D — static if, в C++ с некоторой натяжкой — препроцессор). Это ограниченное подмножество операторов «условной компиляции» — для более сложных вещей прелполагаются макросы.
А в интерпретируемый на этапе компиляции код можно вставлять компилируемые вставки — «квазицитаты».
Получается что два контекста симметричны друг относительно друга, и это должно быть отражено на уровне синтаксиса.
Бессистемно как-то (по крайней мере впечатление такое, особенно после просмотра исходников компилятора). Метапрограмминг на строках вместо специальных квазицитат:
string s = "int y;";
mixin(s);  // ok
y = 4;     // ok, mixin declared y

По сути работа со строками лишает программиста возможности использовать систему типов и концепций. Если я хочу макрос, который должен принимать первым аргументом тип, вторым — имя и третьим — операторный блок, то на строках это никак не указать явно. Пока не передам в такой макрос что-то левое и не получу загадочные ошибки компиляции…
Хотя конечно по сравнению с С++ это реальный прогресс. Надо будет собраться с мыслями и уже для Хабра сделать статейку про связь шаблонов и макросов.
В общем D вовсе не плох, но допиливать там надо многое — таково мое ИМХО :)
Да, такой вопрос есть. Однозначного ответа я пока не придумал, хотя разные мысли есть…
Наверное, если библиотека реально пользуется какой-то функциональностью, и это обусловлено логикой, смыслом библиотеки — то она должна быть включена. С другой стороны, если библиотека пользуется динамическим выделением памяти и предполагается, что она должна работать как в конфигурации со сборкой мусора так и без нее, то язык должен предоставлять более абстрактные примитивы «выделить память» и «освободить память», которые будут уже подключаться — или к обычному аллокатору, или к сборке мусора (тогда «освобождение» просто сведется к обнулению ссылки)

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность