Информация

Дата основания
Местоположение
Россия
Сайт
praktikum.yandex.ru
Численность
101–200 человек
Дата регистрации

Блог на Хабре

Обновить
Комментарии 109

А есть ли смысл изучать сейчас плюсы, если есть Go? Действительно интересно.

Вместо Go подставьте любой популярный не С/С++ язык, и задайте этот вопрос снова.
Изучать стоит то, на чем собираешься работать.
А знание основ С++ дает возможность более легкого вхождения в изучение другого ЯП.

Знание основ хоть какого-нибудь ЯП даёт возможность более лёгкого вхождения в изучение другого ЯП.

В моем вопросе речь была совершенно про другое. Я не спрашивал про первый язык. Вопрос был именно про Go vs С++, в контексте того что у Go сообщество развивается стремительно, интересные запросы по работе. Так же не в одной статье видел про то что на данный момент лучше изучать Go чем С++. Поэтому и спросил у автора поста, учитывая его опыт.

Для back-end'а — да, пожалуй Go больше распространен. Но если не ограничиваться вебом — на фоне плюсов Вы Go даже не заметите. А «интересно» — это субъективно, я вот вообще не понимаю, что в вебе может быть интересного.

Во-первых, на C++ уже написано очень много кода — тот же Chromium. Или Кликхаус. Ну и разные сервисы в больших компаниях, в которые вам может захотеться поконтрибьютить изнутри. Сюда же можно отнести большое комьюитини и огромное количество библиотек под разные платформы.
Во-вторых, Go стремится к низкому порогу входа, и из-за этого некоторые задачи на нём решаются более многословно. (Но местами Go, безусловно, компактнее.)


Мне пока не кажется, что один язык полностью заменит другой. Скорее, будет как с Java или C#, и каждый займёт свою нишу.
Поглядим лет через 50 :)

Спасибо за развернутый ответ. Таки же мысли были, но учитывая ваш опыт, было интересно услышать ваше мнение.

А это спорный вопрос — есть ли Rust? Я активно с ним работал, он мне очень нравится, но с моей точки зрения его ещё нет. В стабильном Rust, например, нет способа определить оффсет поля не прибегая к тому, что является UB, хотя и работает на практике. И много чего ещё нет, много недоделанного. Везде строительные леса, подпорки и чего-то законченного в обозримом будущем (ближайшие несколько лет) не ожидается.

Более того, его в обозримом будущем и не будет. Мозилла явно не в лучшей форме, чтобы его тянуть, а больше он особо никому и не нужен. Rust ждёт судьба языка D — по всем статьям лучше плюсов, но нет никого, кто бы его протянул в мир реального программирования.

Небольшая надежда есть только на то, что где-нибудь в США кто-то топнет ногой и скажет «всё, блин, ПО для атомных станций и самолётов больше писать на сишке нельзя, только Rust или что-то с не меньшей степенью защиты». Вот тогда да, появятся и вакансии и проекты.
Мозилла явно не в лучшей форме, чтобы его тянуть, а больше он особо никому и не нужен.

А вы можете так нагло не врать? Если уж на то пошло, Rust изначально был разработан Грейдоном Хоаром в качестве личного проекта, к спонсированию которого Mozilla подключилась значительно позднее. А помимо Mozilla, Rust используется в проде у Cloudflare, Amazon, Dropbox, NPM, 1Password и ещё дофига других компаний, так что нет, Rust в обозримом будущем с таким количеством заинтересованных в нём лиц никуда не денется.

Без сомнения. Для небольших критических модулей или новых проектов. И все, кто его попробовал, приходят к мнению, что переписывать ВЕСЬ код на С/С++ на расте тупо не выгодно. Затраты на мероприятие не окупятся потенциальной прибылью от меньшего количества багов.

Гм. А в Firefox именно что заменяют код, написанный на C++

При первых же финансовых проблемах Мозилла в первую очередь попёрла команду Servo и Rust-программеров. Как после этого можно серьёзно относится к их попыткам заменить код?

Можно вспомнить годовую компенсацию Митчелл Бейкер и понять их приоритеты.

Ходили слухи, что для спутников, электронного голосования и пр. код на Cobol, и никто ножкой не топнул. Не знаю, насколько правда, но если правда — то от С вообще никогда не избавятся…
Дело может изменить какая-нибудь большая катастрофа.

Вам придётся изучать и C и C++ хотя бы уже для того, чтобы писать рабочие и качественные обертки для интеропа раста с массой уже существующих библиотек на этих языках (если вы в бизнес-проекте заикнетесь про RIIR всего подряд, вашему руководству это вряд ли понравится), а также отлаживать интероп в случае необходимости. В идеале хорошо бы изучить ещё и ассемблер, если в ваши задачи входит написание высокопроизводительного кода — вам придётся периодически пялиться в asm output, понимать, что там происходит и что там "не совсем так".

У нас на работе у парочки джунов Rust — первый язык. У нас RIIR во все щели, мы им даем переписывать сишные утилиты. С они не знают, читают код чисто семантически, без понимания тонкостей всех приседаний. А для оберток и интеропа надо уметь читать. И то, не С, а документацию.

Ну для обучения переписывать небольшие сишные утилиты, руководствуясь «пролетарским классовым чутьем» — это нормально. Другое дело, когда вам придется взаимодействовать с большими сторонними библиотеками, которые вы не сможете переписать силами пары джунов. А третье — когда вам придется всю эту связку еще и отлаживать. Одного умения читать документацию (которая к тому же бывает разного качества) может не хватить, а пока вы будете дергать upstream библиотеки на предмет «вылечите баг по симптомам», процесс разработки будет стоять. Upstream'ы, кстати, вообще предпочитают, когда им присылают сразу патчи. Впрочем, дело хозяйское.

Есть и другие варианты подстановки. Но с частью до второго слеша я полностью согласен.

Вот бы на собеседовании в Яндексе был вопрос про while do и ты такой — "ну вот представьте, есть в холодильнике торт… "

Умение объяснить сложную вещь простыми словами всегда в цене.
Другое дело, что про while знают почти все, а вот когда нужно новичку за десять минут объяснить устройство сложной продакшен-архитектуры — тут и аналогия с тортиками подойдёт :)
Вот и мне тоже стало интересно, без холодильника эти студенты с циклами смогут работать?)
По теме, могу порекомендовать отличный доклад Kate Gregory под названием «Stop Teaching C», основная мысль которого: перед освоением C++ вовсе нет нужды в обязательном порядке сначала обучать студентов C, а если вы это делаете, то четко разграничивайте и объясняйте разницу между «C++» и «C с классами».

Спасибо! Доклад правда очень хорош, мы им вдохновлялись ещё при разработке «Белого пояса» на Курсере.

Знакомый недавно пошел на этот самый курс и вскоре попросил помощи. Дескать задача совсем простая, но он не понимает что не работает.
Суть задачи — даются два вещественных числа и нужно написать равны ли они, а если не равны, то их разницу.
Показывает свое решение — код прошел 10 тестов из 31. Смотрю на код — вроде все верно. Если равны, то сообщение; если одно число больше, то вычитаем из большего меньшее.
В логике ошибок не вижу. Говорит, что причины ошибок указаны такие:
Вы не считаете размер половинок вещественным числом
Вы неправильно обрабатываете случай, когда первая часть больше
Вы неправильно обрабатываете случай, когда первая часть меньше

В результате оказалось, что товарищ в коде делал:
cout << to_string(a-b); // выведет, например «0.900000»
А надо было:
cout << a-b; // выведет, «0.9».
Говорит, что вроде в лекциях упоминали или использовали именно to_string. Про точность в ответе в задаче я не увидел.
Учитывая, что ситуация один-в-один гуглится прям сразу, то выглядит это не хорошо. Особенно для одной из первых задач.
За исключением этого момента курс хвалил, но опять же занимается еще не долго, посмотрим, что скажет в конце.
У С++ на Яндекс Практике пока очень много проблем.
1) Рваное повествование, зачастую блоки не связаны с друг другом и повествование очень поверхностное и постоянно прыгает в разные темы и обратно, но радует что хоть и поверхностно но все необходимые темы затронуты.
2) Очень много ошибок в тренажере.
3) Очень долго отвечает поддержка и не в тему часто.
4) Очень мало времени с преподавателем, всего один час за 2 недели, а все остальное время как хочешь так и выкручивайся ищи и читай сам, иногда именно немного и не сразу помогает наставник или студенты. Например в других местах каждое занятие проводит учитель и проверяет так же учитель с которым можно что то обсудить в отличие от тестов.
5) Основной проект всего курса строго фиксированный и с сильно навязанным кодом, если с чем то не согласен то нет возможности внести изменения, так как проверяет выходную работу каждого спринта с начала автоматический тест, который ни кто переписывать не собирается. Например учат что существует только одна кодировка ASCII и что символы выше 127 не обрабатываются и в коде спокойно не используются cctype а берется прямо c >= '\0' && c < ' '; Хотя на самом деле существует множество кодировок и даже если ограничиться ASCII то символ 127 \x7F \177 backspace character (DEL) обрабатывается как обычная буква.
6) Нет возможности выбирать себе нагрузку. Например нельзя параллельно выбирать себе еще темы если есть свободное время(но есть небольшой раздел с заданиями не относящимися к темам курса, где можно что то порешать совместно). Весь курс разбит на жесткие спринты и дедлайны. Например в других местах есть возможность брать несколько направлений одновременно, если есть возможность заниматься больше времени.
И еще много проблем с которыми нужно работать.
Но в целом это лучший курс который можно найти в российском интернете, в других местах нет такого размаха интересных и актуальных тем по C++

Спасибо за фидбек.


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


Ваш отзыв мы отдельно обсудим с командой и, если вы готовы, вернёмся с вопросами к вам лично, чтобы вместе обсудить, что можно улучшить.

5 пункт, вы прям совсем хардкор описали. Я когда заходил посмотреть курс, столкнулся с куда более тривиальными проблемаи:
Сначала дают нотацию, всегда заврешать с «endl», а потом сами же ее и нарушают, так, что ни один тест в задании не проходит. (проверил, испраивли, теперь принимает и с и без «endl»)
Дальше некоторые задачки с оч скудными условиями. В том же 3 уроке, про for всё оч неочеивдно, и вроде логично на реагировать на лог и дополнять условия (брутфорсим вместо внятной поставленой задачи), но доходит до того, что лог никаких ошибок не выдает кроме как «Задача прошла 14/15 проверок» — называется побудь экстрасенсом. (проверил, с июля единственное изменение — выдает «Задача прошла 15/16 проверок»)
Тех поддержка не то что долгая, а для нее практикум как побочка, просто в доп нагрузку. По началу отписки вместо ответов. И скорее пришлют готовый ответ (код), чем дадут на тесты глянуть (точнее без «скорее», так и сказали что тесты показать не могут).
Давно хочу попробовать такой подход в обучении с++. Но все думаю о такой проблеме. Вот вы учите новому с++, а тут студент начинает гуглить, а в интернете (да и в книжках) большинство примеров чего-либо написаны как раз на старом Си с классами.
Что ему делать в таком случае? Или на практике все не так плохо?

Ваши сомнения отчасти оправданы: студентам всё же придётся узнать про new и delete; не только для понимания внутреннего устройства контейнеров, но и для чтения страшного кода.
Но я считаю, что не так всё и страшно, чтобы готовить к этому с самого начала. Гугление может привести как к старому коду, так и к смелому эксперименту с C++23. Поэтому в числе прочего важно научить, скажем, смотреть в нужное место на cppreference вместо рандомных поисковых запросов.

Я своим на каждую тему рассказываю: вот вы будете её гуглить, вам будет выпадать такая-то и такая-то фигня (гуглю самостоятельно перед лекцией), вот её читать не надо потому и потому.


Например, если вам в теме "наследование" вам начинают рассказывать, что яблоко наследуется от фрукта, а вентилятор — от электрического двигателя, и вы не понимаете, почему их игрушечный пример без виртуальных функций хоть какое-то отношение к реальности имеет — это нормально, никакого не имеет. Или если где-то написано iostream.h/conio.h — бегите оттуда. А вот ISO C++ FAQ и cppreference читать как раз можно и нужно тренироваться.

Не попадайте в ловушку джокера, не учите ни си ни плюсы ни си с классами

… ни вообще все это программирование.

У меня к вам вопрос, а как вы учите студентов пользоваться вектором правильно. В моём мире 100% людей работающих с плюсами (и даже сеньоры) иногда да возьмут да и сохранят указатель/ссылку на элемент вектора, а потом возьмут да и добавят новый элемент в вектор, а потом поработают с ссылкой. Я думаю для вас не секрет, что это довольно часто нормально сработает, но вот иногда все будет печально. Так вот как ваши студенты воспринимают первые встречи с УБ и как вы их учите с ними справляться? Учить с++ и не учить как жить в мире с УБ это пустая трата времени и вашего и студентов, а потом ещё и того парня который будет это все чинить.

Не автор, но отвечу: на первой же лекции минут 15-30 посвящается UB и вбиванию в головы запрета на мышление "тут ошибка, но очевидно же, что компилятор поведёт себя так и так" с кучей интерактивных примеров под разными ОС и компиляторами, сравнением с другими языками и фразой про то, почему так.


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


Как ловить — показываю санитайзеры, Valgrind, статический анализ (предупреждения компилятора, clang-tidy, cppcheck), обязательная компиляция под разными компиляторами. Это, разумеется, всё равно покрывает далеко не всё, так что на лекциях регулярно всплывают UB, которые вообще никем не ловятся и молча ломают программу. Иногда. А иногда не ломают. Типичный пример — static initialization order fiasco.


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

Ну если это правда, а у меня нет причин не верить, тогда сразу +100 к качеству курса. Может ещё расскажите, что помимо того, что вы учите студентов писать с++ код (что в общем то не рокет сайнс) вы ещё и ЧИТАТЬ с++ код учите?

Что я имею ввиду ?- упражнение типа перечислите все ошибки, которые вы можете найти в таком то продакшн учебном коде. Я бы это вообще частью выпускного экзамена сделал, на бумажке (т.к. на код ревью в реальности нет доступа ни к исходникам ни к IDE). Если нашёл меньше минимального количества багов — сразу просто незачёт не взирая ни на что другое.

Есть ещё один навык который я называю умением читать код — перед тем как копипастить со стэка писать свой велосипед нужно сначала поискать, а что уже есть в стандартной библиотеке и/или другом фрэймворке который используется в проекте и наконец у каждого большого проекта есть своя библиотека типа Tools/всякое_полезное и там почти всегда как с попаданием в кэш уже можно найти готовый к употреблению код.

Ну и самое частое люди обычно находят место в коде куда нужно добавить новый функционал и прямо туда его и фигачат сплошной простыней, а то что используются разные уровни абстракции вообще ни каких сомнений не вызывает. Вот пример для наглядности
void implementLotsOfLogicHere()
{
DoHighLevelA();
DoHighLevelB();

// new code added here
Container anotherViewOnTheData;
while (x: container)
{
if(x == ...)
{
anotherViewOnTheData.push_back( Y{ x } );
}
}
callback(anotherViewOnTheData);

// previous code conitnue
DoHighLevelC();
}

И это еще идеально если DoHighLevelX кто-то уже написал, а в реальности там вместо этих функций тоже смесь кода с разной степенью абстракции — в одной строчке зарождение вселенной, а рядом байтики копируется в цикле из одного вектора в другой.

Если вы еще и читать код ваших студентов учите, то это прямо вообще респект и уважуха.

Ваш комментарий содержит уйму полезных и важных идей.
Про часть из них уверенно скажу, что да, учим. Во второй половине курса есть тема (вот прямо сейчас делаем) про красоту кода, читаемость, масштабируемость и работу с чужим кодом. И одна из задач там — взять чужой сложный код, доработать его под себя и отдать на ревью. Другая задача — взять небольшую чужую библиотеку и приспособить её под нужды своего большого проекта. И тоже отдать на ревью.
Простите за рекламу, но наличие на курсе ревьюеров — это заметное преимущество Практикума перед Курсерой. К слову, я сам в своё время учил C++, проводя ревью студентов :)

У вас похоже действительно годный курс. У меня есть пара пожеланий, пожалуйста не продвигайте использование shared_ptr и любой другой инкарнации — это просто ад, большинство девелоперов в независимости от их опыта имеют ложные ожидания при использовании шаредных указателей, в реальном мире люди ожидают предопределенный порядок вызова деструкторов в многопоточном коде который шарит указатель. Это проблема номер 2, а проблема номер 1 и вообще ошибка на миллиард это деструкторы — опаснее кода в с++ не найти. Колл стэк значительно более половины всех крашей содержит вызов хотя бы одного деструктора. Так хохмы ради проведите опрос среди ваших сеньоров и спросите, а какой код в деструкторы НЕ УБ, т.к. примерно 146% кода в дестукторах из реального мира содержит хотя бы одно уб. Для проверки истинности ответа рекомендую либо стандарт либо тоже самое, но для людей cppreference. Самое печальное обе проблемы поставляются в комплекте.

Ну про shared_ptr рассказывать все равно надо. Если не они, то кто-нибудь другой расскажет. А с деструкторами, да, беда. Нужно сильнее вдалбливать в людей идею RAII и самое главное объяснять что далеко не любой деструктор это RAII
самое главное объяснять что далеко не любой деструктор это RAII

Это вы про что?

RAII — «Получение ресурса есть инициализация». Но далеко не всегда мы получаем именно ресурс. То есть, если мы написали какой-то код в деструкторе, то очень редко этот код связан с каким-то ресурсом.
Ресурсом может быть память (new — выделили, delete — освободили), файл (open — открыли, close — закрыли). Да и то насчет файла уже можно поспорить. Особо больше новых ресурсов и не придумать даже. Почти все остальные сущности в программе ресурсом не являются (ну по крайней мере, в тех программах, где слишком много деструкторов)
(т.к. на код ревью в реальности нет доступа ни к исходникам ни к IDE)


На CodeReview есть (и должен быть) доступ и к исходникам и к IDE.

Другое дело, что на практике: если тебе пришлось выкачивать ветку, чтобы разобраться что же CodeReview делает — это признак что в процессе что-то не так (да может быть это сложная задача в сложной предметной области, но на каждую такую «необходимую» сложную задачу приходится несколько где человек просто поленился нормально разбить свои правки).

На курсере ребята довольно подробно объясняли инвалидацию ссылок/указателей/итераторов и показывали на примерах для разных std контейнеров, за что им респект :) Наверняка и в Практикум это завезли.

Завезли :) Это не в самом-самом начале, но довольно рано.
А при первом знакомстве с вектором показываем, что при выходе за границы вас не поймают за руку — и это плата за эффективность.

А при первом знакомстве с вектором показываем, что при выходе за границы вас не поймают за руку — и это плата за эффективность.

Это та самая плата, которая даёт дай бог один процент оверхеда в подавляющем большинстве приложений?

1% оверхеда на кластере — это сотни тысяч долларов
А данные про один процент оверхеда будут? Или тут нужно просто поверить?
C++ изучать, во-первых, поздно. А во-вторых — это не самый стройный и органичный язык. Компромисс между возможностями железа 40 лет назад и представлениями того времени о, как теперь оказалось, переоценённом ООП. Эдакое древнее здание с земляным полом и кучей хаотичных пристроек более поздних годов.
А какой язык стоит изучать? А не знаю, мы дошли до того, что теперь нет единого стандарта на компилируемый язык программирования.
А какой язык стоит изучать? А не знаю, мы дошли до того, что теперь нет единого стандарта на компилируемый язык программирования.

ИМХО стоит изучать несколько языков, чтобы представлять спектр возможностей. Ну там, C++ для низкоуровневой ерунды и чтобы представлять, как не надо делать метапрограммирование, Rust для более типобезопасной низкоуровневой ерунды, Haskell для функциональщины и какой-нибудь Idris для хардкорного упарывания типами.

А так ли оно плохо, это метапрограммирование в с++?
Покажите мне другой язык который умеет то-же самое без привлечения рантайма и с прогнозируемыми накладными расходами? Раст обещал доступ к AST стабилизировать еще до версии 1.0, одноко продвинулись они пока не сильно.

Haskell с его, собственно, Template Haskell. Накладные расходы в рантайме нулевые. В компилтайме можно выполнять любой код из любой библиотеки — можно хоть какой-нибудь алгоритм на графах из библиотеки, ничего не знающей про TH, взять, можно хоть пойти на сервер и взять XSD со схемой, а потом по ней сгенерить типы и функции для общения по этой схеме.


Совсем упарываться — любой язык с зависимыми типами и инструментами для гарантии стирания типов (coq со стиранием в Prop, idris с quantitative type theory, позволяющей помечать аргументы как иррелевантные в рантайме, agda с похожей концепцией runtime irrelevance).

А почему, кстати, Haskell не имеет почти никакого коммерческого применения?

А почему он не имеет? Как-то вполне имеет, ИМХО. Я как раз вот прям сейчас мозгую, на какой из двух офферов соглашаться, в обоих из которых порядком хаскеля. При этом эти компании я не искал, они почти что сами меня нашли.


Ну и я вполне использовал хаскель в продакшене даже тогда, когда моя официальная лычка была «senior c++ engineer».

Вы вроде какой-то исследовательский проект пилили за спасибо? Похоже деньги заканчиваются, а спасибо чето не очень вкусное и надо идти добывать масло на хлеб. Я бы тоже хотел свой "Раст" запилить, но… Подожду маленько. Вы хоть "отчёт" о своем исследовании опубликуйте, а то и непонятно "стоило" оно того или нет, понятное дело что вам в кайф, но нам то со стороны виднее.

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

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


Вы хоть "отчёт" о своем исследовании опубликуйте, а то и непонятно "стоило" оно того или нет, понятное дело что вам в кайф, но нам то со стороны виднее.

Не уверен, что из этого получится хабровский формат. Там слишком много технических деталей, которые будут интересны довольно узкому кругу людей (например, последние 4-5 месяцев я тупо потратил на формализацию куска работы, и формализовал где-то от трети до половины всего, что нужно).


Впрочем, оно всё в опенсорсе, и, в частности, даже гитхабовский CI собирает периодически свежие версии статьи-описания (там черновик пока, правда, и его ещё допиливать надо, но идея понятна, вроде как). Так что можно как-то что-то посмотреть.

Половины матерных слов из вашей статьи я не понимаю за не именем соответствующего бэкграунда, но суть мне вроде бы далась. Было бы интересно почитать в переводе на простой и понятный программистский язык. Примеры в ведении были очень хороши и рассказали мне больше чем вся остальная часть. Скажу сразу, что всю мякотку с лемами теоремами и корректностью я даже не пытался осилить. Мне нравится идея жидких типов, но мне это интересно только с точки зрения как это реализовать. Меня вполне устроит знать, что где то кто-то доказал, что это не чушь суть доказательства меня не волнует. Не могли бы вы подсказать где найти код/описание как реализовать эти типы, на каком нибудь народном языке, а не на вашем птичьем агдесе, в котором вот честно вообще нихера не понять.

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

Если реализовать — вы же первым будете возмущаться, фигли тут так много кода и вообще так всё сложно навёрнуто.

Скажу сразу, что всю мякотку с лемами теоремами и корректностью я даже не пытался осилить. Мне нравится идея жидких типов, но мне это интересно только с точки зрения как это реализовать. Меня вполне устроит знать, что где то кто-то доказал, что это не чушь суть доказательства меня не волнует.

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


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

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

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

> то нашёл три дырки в чужих системах типов
А где и как были описаны эти системы типов?

В виде таких же статей (только где-то опубликованных, а не черновиков), и в виде таких же диаграмм.


Только они не занимались формализацией своих систем на всяких агдах-коках, а дъявол, как известно, в деталях, которые в доказательствах на бумаге часто заметаются под «Доказательство очевидной индукцией ∎»

Справедливости ради — GHCi рантайм TH не отменяет, про остальные не в курсе как они работают, но подозреваю что там та же история с VM внутри, а это не честное сравнение.
Трудно сказать реализовано TH делает мета-программирование как то принципиально лучше чем C++, тут скорее вопрос что высыпается в консоль когда в шаблонах ошибка. Скорее всего что-то более удобоваримое чем из c++98, а вот с кодом на концептах сравние уже интереснее звучит.

Справедливости ради — GHCi рантайм TH не отменяет, про остальные не в курсе как они работают, но подозреваю что там та же история с VM внутри, а это не честное сравнение.

Я не понял эту фразу. ghci — это репл, нужный для быстрых экспериментов или быстрой проверки, что код всё ещё тайпчекается. ghc без i на конце выдаёт после компиляции нативный код без каких-либо VM внутри.


Трудно сказать реализовано TH делает мета-программирование как то принципиально лучше чем C++, тут скорее вопрос что высыпается в консоль когда в шаблонах ошибка. Скорее всего что-то более удобоваримое чем из c++98, а вот с кодом на концептах сравние уже интереснее звучит.

Ну вот когда на C++ в компилтайме можно будет взять какой-нибудь nlohmann json, прочитать жсон с диска, распарсить его этим nlohmann'ом и сгенерировать какие-нибудь классы (или, обратно, взять какие-нибудь классы, по ним нагенерить данных и сериализовать в жсончик nlohmann'ом), то тогда можно будет сравнивать.

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


Касательно второго примера -это кодогенерация а не мета программирование.

Любое метапрограммирование (то есть, преобразование AST в другое AST) может быть заменено кодогенерацией. Вопрос в том, можно ли обойтись без кодогенерации, и насколько удобно это сделать.


А то в плюсовом мире уже лет 25 как есть moc, например.

Тут вы путаете, никакое преобразование AST -> AST вам не позволит «прочитать жсон с диска, распарсить его этим nlohmann'ом и сгенерировать какие-нибудь классы».
В свою очередь кодогенерация не прибита к AST а значит сгенерировать что то под конкретные вызовы функций не получится. В этом плане TH крут как раз тем что он совмещает эти концепции, и можно написать шаблон в духе «если передана функция от 2х аргументов скачай json с интернета»

moc это не валидный аргумент, moc завезли во времена когда поддержка мета-программирования популярными на тот момент компиляторами была «не очень». В современном С++ от moc можно избавиться, но т.к. его синтаксис не соответсвует принятому в С++ придётся все эти мета-определения переписывать, а бизнес не очень любит переписывать, так что moc остаётся.
Тут вы путаете, никакое преобразование AST -> AST вам не позволит «прочитать жсон с диска, распарсить его этим nlohmann'ом и сгенерировать какие-нибудь классы».

Позволит, если язык, на котором описываются преобразования, достаточно мощен. В случае TH это весь хаскель, включая все имеющиеся библиотеки (с малыми оговорками), в том числе, про TH ничего не знающие. Не нужно никаких constexpr/consteval.


В свою очередь кодогенерация не прибита к AST а значит сгенерировать что то под конкретные вызовы функций не получится.

Почему? Берёте libclang условный, парсите ваш условный код на плюсах и генерируете что угодно.


В современном С++ от moc можно избавиться,

Как? Без макросов только.

Позволит, если язык, на котором описываются преобразования, достаточно мощен.

Язык тут не причем, можно парсинг джсона и на шаблонах c++ написать, но компилятор не позволяет вам читать файлы во время компиляции.


Берёте libclang…

Так можно и парсилку джсона из вашего примера сделать, к языку C++ это отношение не имеет.


Как? Без макросов только

С макросами, т.к. это единственный способ получить одновременно и имя символа и его строковое представление (нужно для мок объекта), но макросы это часть языка описанная в стандарте. Все еще интересно?

Язык тут не причем, можно парсинг джсона и на шаблонах c++ написать

А в хаскеле — не нужно ничего на шаблонах писать. Я просто могу взять ту же самую либу, которую я использую для парсинга жсона в рантайме, и выполнить её код в компилтайме. Metaprogramming done right.


но компилятор не позволяет вам читать файлы во время компиляции.

А в хаскеле — позволит. Я просто беру обычную функцию readFile и вызываю её во время компиляции. Например. Или у меня на одной прошлой работе была библиотека, которая брала XSD-схему с диска (я тот пример не просто так придумал) и генерила по ней кучу всяких типов вместе с эффективными сериализаторами-десериализаторами.


Более того, в хаскеле можно, например, в компилтайме распарсить строку с шаблоном ассемблерного кода, сделать над ней какие-то преобразования, а потом определить функцию, которая выполняет этот ассемблерный код. Я даже соответствующий proof-of-concept-пакет сделал, почитайте вот ридмишку.


Так можно и парсилку джсона из вашего примера сделать, к языку C++ это отношение не имеет.

Можно. Только я бы предпочёл её делать на тех же плюсах, и не наворачивать сложности в процессе сборки.


С макросами, т.к. это единственный способ получить одновременно и имя символа и его строковое представление (нужно для мок объекта), но макросы это часть языка описанная в стандарте. Все еще интересно?

Да с макросами понятно. Но макросы к C++ прикручены настолько сбоку, что от кодогенерации внешними инструментами они не сильно отличаются.

Скажите, если знаете/обоснованно предполагаете, а насколько сложно взять условный шланг и запилить в нем «беру обычную функцию readFile и вызываю её во время компиляции» ну скажем для плюсов или раста? Я знаю такое почти работает в D, там в компайл тайме много чего можно сгенерить по строковым литералам, но по моему «readFile и вызываю её во время компиляции» для зачитывания этих строк пока не сделано.

Ну, по крайней мере, пропозалы есть. Вроде где-то даже были реализации — если начать гуглить по ключевым словам из таблички в 5.1.1 (по phd::embed, в частности), то что-то нагугливается. Объём патчей и сложность реализации я не смотрел.


Но, опять же, это какие-то костыли, для добавления которых требуются пропозалы. Нельзя просто взять std::ifstream и дёрнуть его на этапе компиляции.

Да я почитал проползал, это вообще ни о том. Я имел ввиду выполнение произвольного кода на с++ как часть компиляции произвольного кода на с++. Я так понимаю это то что умеет хаскель. Что то мне подсказывает для этого интерпретатор с++ должен быть встроен в компилятор или есть другие подходы к этому? Т.е. сложность задачи сводиться к созданию интерпретатора.

Интерпретатор уже есть: иначе constexpr-функции никак не реализовать.

На практике нет ничего сложного получить содержимое файла для компиляции — берем условный bin2c, и добавляем его вызов в систему сборки.
Другое дело — выполнить условный fopen во время компиляции — тут надо и окружение c++ запустить, и слинковаться, и разрулить как то глобальные переменные. А теперь представьте что это все происходит в кросс-компиляторе, и объявление того же fopen не совпадает с системным, и например нужна еще другая пачка дефайнов.

но компилятор не позволяет вам читать файлы во время компиляции.

#include «data.json»
C++ изучать, во-первых, поздно

Напомнило, как Остап Бендер бегал по киностудии, пытаясь продать свой сценарий и ему отвечали, что он не подходит для немого кино, так как его уже нет и не подходит для звукового кино, так как его ещё нет. Так и тут — плюсов, оказывается, уже нет, но на их месте тоже пока ещё ничего нет. Ни Rust, ни Go не заняли нишу, а писать всякие там операционки, базы данных и браузеры на чём-то надо.
И почему-то всякие там операционки до сих пор пишутся на си без плюсов. Странно, да?

Потому что легаси. Когда начинали писать большинство ядер современных ОС, C++ ещё только начинал захватывать мир, был сыроват, не имел кучи вещей, которые имеет сегодня, а возможности железа заставляли экономить выделение каждого байта. Ну, а в Linux например во главе разработки вообще стоит благородный диктатор Линус, отношение которого к C++ он сам описывал как «А просто не нравится и всё» без каких-либо существенных аргументов (а те, что звучали, навевают мысль о том что он просто хейтит то что не умеет нормально готовить) и с ним уже давно все расхотели спорить.
Есть и контр-примеры ядер ОС на C++, например EPOC32 и Symbian, которые прекрасно работали на устройствах с дохлыми процессорами и крохотной памятью, а ещё BeOS (и ее наследница Haiku). Все они были отличными ОС в техническом плане и умерли исключительно из-за факапов менеджмента. Ещё можно назвать ряд микроядер L4 (вариацию NICTA которого Qualcomm использует в своих чипах для телефонов), ну и частично ядро Zircon, которое Google пилит для своей новой Fuchsia.


А вот огромное количество довольно сложного и критичного к производительности софта типа графических движков AAA-игр никому в голову не придет писать на Си вместо C++ в наше время. Вполне очевидно, почему.

И почему-то всякие там операционки до сих пор пишутся на си без плюсов. Странно, да?

Ядра, но не юзерспейс. Вот код терминала Windows, вод код калькулятора Windows — это всё плюсы.

А у ядра огромное использование. Даже плюс одна инструкция к коду вызова какой-нибудь функции выделения памяти или переключения потоков — это какие-то невероятные цифры потерь в мировом масштабе, учитывая распространённость ОС и количество вызовов подобных функций каждую секунду.

Только на плюсах можно написать ещё более эффективный код чем на Си.

Правда? А чем это обусловлено?

Я говорю в контексте ядра ОС.


C++ поддерживает почти весь синтаксис Си, а его компилятор столь же эффективен на Си подмножестве (да и обычно это один и тот же компилятор). А так как С++ более развит, есть места где его компилятор может лучше оптимизировать код.


Это конечно если не ударяться в создание фабрики фабрик классов и не обмазываться стандартной библитекой.

Метапрограммировать на темплейтах проще, чем на макросах.

макросы vs метапрограммирование, которое позволяет инстанцировать (подставить в зависимости от шаблона) реализацию для конкретных типов, а не для (..., char *elem, size_t elem_size).

ПС
А уж как интересно, когда у вас в C-структуре есть паддинг (заполненный мусором) и вы считаете одинаковые элементы разными ;)

Тут мне кажется есть несколько оснований:


  1. Легаси.
  2. Зачем что-то переписывать? Существующие ОС не развиваются прям семимильными шагами, что новый код приходит тоннами. Си на минималках знают все, соответсвенно и патчи прислать могут и т.д.
  3. Нет специалистов. Ну нет столько людей, которые одновременно знают и умеют в планировщики/ФС/драйвера и т.д., и при этом, являются фанатами С++/rust/haskell и вообще языковой темой.
  4. Си — это основа основ. Это то, что лежит поверх железа и предоставляет минимальный API/ABI. И даже если ядро ОС будет написано на С++/Rust, то оно будет предоставлять тупые сисколы которые идеально будут соответсвовать Си. Да и вообще Сишное ABI — это стандарт для взаимодействия между разными языками.
Блин, в наше время после программирования на ассемблере C++ казался божественным языком. Может стоит так делать и сейчас?

Хочешь сделать человеку хорошо? Сделай сначала плохо, а потом верни как было.

Может и плохо прочитал статью, но не нашёл упоминания про code style
Стараюсь студентов сразу приучать к осмысленному именованию переменных, обговариваем с ними о соглашении как хорошо писать и как плохо писать код, нормы оформления.
Считаю этот момент тоже важным при обучении программированию.

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

Programming is a creative art form based in logic. Every programmer is different and will code differently. Do not waste your time on coding style it is the output that matters. John Romero. Я считаю так же, что навязывать стиль кода это очень плохо так как это убивает креативность, но убедить в той или иной технике это возможно, при условии того что человек может и не соглашаться с доводами и сам решать как он форматирует свой код. Так же такие жесткие рамки приводят к ужасным и деспотичным перекосам. Вот пример кодстиля из одной крупной Российской компании(обратите внимание на пункт 3):
1. Размер единичного отступа составляет 2 пробела. Для форматирования кода не используются символы табуляции.
2. Фигурные скобки {} располагаются на отдельной строке и имеют тот же отступ, что и соответствующий им заголовок функционального блока — декларация функции либо условие if / switch / for / while.
3. Параметры функций располагаются на отдельной строке, имеют префикс _и предваряются двойным отступом относительно заголовка функции.
4. Отсутствие в коде неиспользуемого функционала (выражений либо переменных, закомментированных участков устаревшего или отладочного кода)
Форматирование — это только часть Code style. Туда ещё входит адекватное именование переменных, отсутствие переусложненных конструкций, отсутствие функций по 300 строк и т.п.

Имхо вот как раз форматирование кода не имеет с креативностью вообще ничего общего. И правила форматирования должны быть зафиксированы, но так, чтобы о них не думать от слова совсем (ну то есть использовать автоформаттеры).
С перекосами согласен.
А вот с тем, что каждый пишет код как хочет и не придерживается единого стиля — не соглашусь. Разработка одиночками ушла немного в прошлое. Сейчас всё больше работа в команде. Поэтому нужно вырабатывать в командах единые правила, иначе будет сложно собирать единый код из разных кусочков.
Грамотно установленные правила форматирования кода понижают вероятность ошибок по невнимательности (от которых не застрахован никто, вообще никто). Особенно те, что относятся к комментариям, выравниванию кода, обязательным {} даже для однострочных блоков, скобок в условиях, и т.д.

(точно так же как и -Wextra -Wpedantic -Wall -Werror могут спасти от многих часов головной боли).

А что до мелочей, типа количества табов/пробелов и переносов скобок после сигнатур, то никто не запрещает вам при большом желании написать свой конфиг для .clang-format и настроить post-checkout и pre-commit хуки в Git, чтобы у вас в редакторе код выглядел так, как нравится вам, а в общей репе соответствовал установленному в команде стандарту.
Linus Torvalds: “C++ is a horrible language. It’s made more horrible by the fact that a lot of substandard programmers use it, to the point where it’s much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.”

LOL… Торвальдса заминусовали на Хабре…
Цитата вырвана из кучи контекстов.

Во-первых, это было в 2007 году, за 4 года до выхода стандарта С++11, а значит относилось к С++ версии 1998 года(!). Трудно не согласиться с тем, что это был ужасный язык.

Во-вторых, это был ответ на письмо, которое начиналось вот так: «When I first looked at Git source code two things struck me as odd 1. Pure C as opposed to C++. No idea why. Please don't talk about portability, it's BS.». Что он должен был ответить человеку, который начинает разговор с фразы «твой код — дерьмо, потому что не С++»?

Ну и в третьих, это был разговор с программером из Microsoft, идеологическим, так сказать, врагом (ну по крайней мере так это выглядело в 2007 году).
Знаете, я не хочу устраивать тут длинную дискуссию про контексты. Но от того, что этому монстру немного обновили фасад с 1998 года, он, увы, не стал образцом архитектуры, достойным изучения в университетах.
У вас какие-то забавные представления об окружающей действительности. Языки изучают не потому, что они являются каким-то «образцом архитектуры», а потому, что на них написана куча кода, который нужно поддерживать, развивать, писать новый и стыковать старый код с новым кодом. Чисто «академические» языки же типа Хаскеля (да простит меня deadfood) или Пролога (преподносившегося как next-gen в свое время) прозябают в безвестности.
И тем ни менее, его там изучают :)

Справедливости ради, там всё-таки заявление, что "Мне кажется странным, что тут Си вместо плюсов. Почему? И нет, не говорите про проблемы с переносимостью, это бред.". Или я чего-то не понимаю?


От себя: сама цитата в основном про то, что у плюсов ниже порог вхождения, что приводит (по мнению Линуса) к более низкому качеству контрибуций от тех, кто пишет на нём. К самому языку там претензий, кроме как "на нём проще писать лютую хрень, чем на Си", не высказывается.

>
Внутрь цикла while надо добавить: «откусить кусок торта; отойти от холодильника» — иначе, если в холодильнике есть торт, цикл бесконечный

О обучении есть 2 подхода:


  1. Вы рассказываете теорию, а потом ставите задачу для проверки усвоения.
  2. Вы ставите задачу и подсказываете обучающемуся что надо изучить для решения этой задачи.

2-й подход более эффективен но требует другой инфраструктуры. Сразу нужны и книги и оборудование/наглядный материал. По этому практически везде используется не особо эффективный 1-й подход.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.