LINUX.ORG.RU

Функциональщина на C++

 , ,


0

5

По мотивам: Си с классами

бери с++20 с концепциями, корутинами и ренжами. игнорируй всё из с++17, сфинае, не пиши упоротые шаблоны, вообще шаблоны старайся не писать, и всё будет ок.
концепции уже вроде работают, ренжи тоже есть, корутины ещё не подъехали, но в будущем пригодятся, генераторы там всякие, всё такое. ещё будет проще потом перелезть на экзекюторы и т.д. потом ещё модули затащишь.

Как эффективно учиться? (комментарий)

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

Конкретно мне интересен функционально-процедурный подход к написанию кода на крестах, что-то похожее на Rust, только без абсурдной помешанности на безопасности памяти, так сказать «си с плюшками», но совсем НЕ «си с классами», как было в упомянутом треде. Для примера: Qt и UE — это примеры плохой архитектуры в данном контексте. Например, fstream — это плохая реализация файловых операций, поскольку скатывается в классы и исключения, в ней даже нельзя без исключений получить конкретную ошибку файловых операций.

Итак: какие есть конкретные хорошо проработанные приемы и библиотеки для писания на крестах в функционально-процедурном стиле?

★★★

Ответ на: комментарий от byko3y

i = i % 2 == 0

прошу заметить — тут у тебя по ходу дела меняется тип значения — тоесть логика одной переменной меняется налету. Да произойдет каст из, полагаю, int в bool, и потом снова в int, но логика переменной изменяется.

safocl ★★ ()
Ответ на: комментарий от anonymous

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

safocl ★★ ()
Ответ на: комментарий от safocl

по поводу кодов ошибок — ты как раз никогда не сможешь понять откуда оно вышло

Если код целочисленный, то да, всё плохо. Если же код более структурирован (как в Boost Outcome), то может тащить за собой сколько угодно контекста, да еще и обрастать им по пути. Точно так же, как и с исключениями.

На мой сугубо субъективный взгляд, структурированные коды ошибок дают лучший визуальный контроль потока управления, но сильно «замусоривают» текст программы макросами. Кроме того, машинный код от них таки сильно распухает, и в моем случае — в разы. Так что я юзаю исключения для сообщения об ошибках и перехожу на коды там, где исключения уже начинают использоваться для control flow.

aist1 ★★ ()
Ответ на: комментарий от aist1

а я с помощь исключений даже определяю необходимость пересоздавания swapchain в vulkan-hpp — если уж такая производительнозависимая сущность поддерживает исключения — считаю их наиоптимальнейшим вариантом.
Просто это все багаж си-стайла — коды возврата — и гугл по сути своей просто не хочет переделывать свой код стайл, что бы использовать исключения.
Можно и о Торвальдсе сказать тоже самое — про неиспользование си++.

safocl ★★ ()
Ответ на: комментарий от safocl

а я с помощь исключений даже определяю необходимость пересоздавания swapchain в vulkan-hpp — если уж такая производительнозависимая сущность поддерживает исключения — считаю их наиоптимальнейшим вариантом.

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

Что касается приложений, чувствительных к задержкам, то тут еще и толстый хвост распределения можно словить на ровном месте, если использовать исключения для control flow.

aist1 ★★ ()
Ответ на: комментарий от safocl

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

Siborgium ★★★ ()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от byko3y
class Q {
	int data;
	Q() {}
public:
	static std::pair<Q, bool> construct() {
		Q q;
		q.data = 5;
		return {q, true};
	}
};

int main() {
	if (auto [q, res] = Q::construct(); res) {
	}
}

в ней даже нельзя без исключений получить конкретную ошибку файловых операций

Реальный пример, когда нужно получить конкретную ошибку файловых операций? Мне ни разу не надо было. Авторы fstream понимая это намеренно абстрагировались до - «норм, не вышло, вообще караул!».

kvpfs ()
Последнее исправление: kvpfs (всего исправлений: 1)
Ответ на: комментарий от kvpfs

Еще код ошибки можно возвращать из конструктора out-параметром. Оно нормально работает и с инициализацией базовых классов. Но для удобства в коде всё равно придется метод-фабрику использовать, как у тебя.

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

aist1 ★★ ()
Ответ на: комментарий от byko3y

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

А зачем мне их знать все? Либо отлов данного исключения продуман и есть соответствующий catch(), либо исключение улетает и сбрасывает корку в дебаге или перезапускаем всю задачу в релизе.

Правда у дошколят могут возникнуть трудности - могут юзать везде std::logic_error, например. Но это проблемы не исключений, а дошколят.

kvpfs ()
Последнее исправление: kvpfs (всего исправлений: 1)
Ответ на: комментарий от aist1

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

Да, возможно иногда разумно. Включил бы исключения у фстрим и мозг бы не парил себе.

kvpfs ()
Последнее исправление: kvpfs (всего исправлений: 1)
Ответ на: комментарий от safocl

ты как раз никогда не сможешь понять откуда оно вышло

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

Исключения лишь обернутые в понятия объекта коды ошибок с паразитическим побочным эффектом ветвления потока исполнения.

anonymous ()
Ответ на: комментарий от safocl

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

С rust Result все это легко делается.

anonymous ()
Ответ на: комментарий от anonymous

с паразитическим побочным эффектом ветвления потока исполнения.

мде.. ты же лучше создателей языка разбираешься где побочные эффекты, где лучше другое...
твое мнение не построено ни на одном из реальных аксиомных фактов.
просто тебе ктото рассказал, что исключения что-то несут оверхедное — однако это ересевая ахинеальная бредятина.
Тут же ты оговариваешь про сами классы исключений — но throw не обязан бросать именно какой либо объект класса исключения — он может кинуть все что тебе пожелается.
А сама работа кидания исключений в core языка — отчетливо проводит черту сопровождения меньшего по объему кода и максимальной производительности.

safocl ★★ ()
Ответ на: комментарий от safocl

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

anonymous ()
Ответ на: комментарий от byko3y

Процедурное программирование является разновидностью императивного, и отличительной его чертой является использование изолированных императивных модулей.

Эмм, модули - это уже про модульное программирование. Процедурное программирование предполагает структурирование программ посредством процедур ака подпрограмм. Под процедурными языками обычно понимаются вполне конкретные языки 60-70 годов типа Си и Паскаля. Употреблять слово «процедурный» по отношению к эмелю и прочей функциональщине не принято. Обычно говорят, что они поддерживают императивную парадигму в том числе. Но впрочем это все терминологические придирки, я понял, что ты имел в виду. Хоть горшком назови.

Я вот только не понимаю, откуда у этого тренда ноги растут. Так-то я вижу до сих пор, что все-таки несмотря на этот тренд стиль класс-ориентированного программирования остается мейнстримом.

Сложно сказать. С одной стороны императивное и объектно-ориентированное программирование встало колом и давно не развивается. Там уже нечему развиваться. Какие например новые императивные операторы добавились в языки за последние десятилетия в дополнение ко всяким if/for/while? Или может быть что-то принципиально новое добавилось к классам, интерфейсам и паттернам ООП проектирования? С другой стороны производительность программ уже давно не является ограничивающим фактором в большинстве случаев. Вплоть до 90-х ФП крайне хреново работало на тогдашнем железе, а сейчас даже тормозной питон вполне отлично заходит. Поэтому в последнее время возник всплеск интереса к ФП и какие-то отдельные фичи начали растаскивать в разные языки. Но индустрия по историческим причинам плотно оккупирована ООП и императивным подходом, так что ООП было и будет мейнстримом в обозримом будущем.

Но тренд в C# прям очень заметный, даже заметнее аналогичного крестового.

Глянул изменения в шарпе 8.0, 9.0, 10.0 - ну да. Тащат из эфшарпа все что плохо лежит. Выглядит правда как дешманская китайская подделка по сравнению с оригиналом, но по-другому скорее всего и не получится.

archie ()
Ответ на: комментарий от aist1

C++ сильно отстает в плане тулинга: нет интегрированного с компилятором сборщика проектов с динамическим графом зависимостей, нет своего пакетного менеджера, невозможно делать рефлексию и вот это вот всё, что сейчас нужно для программирования в большом.

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

У меня есть Memoria. В данном контексте она дает функциональные/персистентные структуры данных, которые уже могут использоваться в функциональном стиле программирования для распараллеливания.

Выглядит круто! Как я понимаю, это не general-purpose ФП фреймворк с различными алгоритмами и комбинаторами, а узкоспециализированная библиотека для работы с персистентными структурами данных?

archie ()
Ответ на: комментарий от safocl

тут у тебя по ходу дела меняется тип значения

Не меняется /i = i % 2 == 0 читается как «определить функцию с аргументом i, возвращающую i % 2 == 0».

monk ★★★★★ ()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от archie

Какие например новые императивные операторы добавились в языки за последние десятилетия в дополнение ко всяким if/for/while?

sync/async/await/yield/launch

что-то принципиально новое добавилось к классам, интерфейсам и паттернам ООП проектирования

Трейты, миксины, бета-наследование.

monk ★★★★★ ()
Ответ на: комментарий от safocl

Несколько мест это в тему копипасты кода обработки исключений прилетевших насквозь без обработки во внутренней функции/методе.

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

cobold ★★★ ()
Ответ на: комментарий от kvpfs

Ну например написать юзеру permission denied или file not found чтобы тот понял быстро проблема в том что sudo надо написать или он отпечатался в пути.

А в стандартной библиотеке обстрагировались от этого потому что а фиг знает на какой системе будет собран код, может на msdos с fat и там нет никакого permission denied в принципе

cobold ★★★ ()
Последнее исправление: cobold (всего исправлений: 1)
Ответ на: комментарий от safocl

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

Какое «другое»? Какое «лучше»? При чем тут «разбираешься», если есть вполне очевидный антипатерн, когда исключения начинают бездумно плодить и использовать как альтернативную ветку ветвления потока исполнения. Хочешь сказать что никогда такого не видел и не слышал?

твое мнение не построено ни на одном из реальных аксиомных фактов.

Назови мне хоть один «реальный аксиомный фактор», что бы это не значило в твоем понимании, а то очень похоже на бред какой-то.

просто тебе ктото рассказал

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

А сама работа кидания исключений в core языка — отчетливо проводит черту сопровождения меньшего по объему кода и максимальной производительности.

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

Тут же ты оговариваешь про сами классы исключений

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

но throw не обязан бросать именно какой либо объект класса исключения

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

anonymous ()
Ответ на: комментарий от aist1

Это всё в значительной степени лечится, и я, например, в своих проектах использую Clang-based кодогенераторы для расшивки узких мест TMP и автоматизации бойлерплейта

Ага, макросы. Я несколько сообщений назад тоже высказал необходимость макросов в крестах:

Функциональщина на C++ (комментарий)

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

Выглядит это примерно так. На входе специальным образом аннотированные классы, которые задают конфигурацию для кодогенератора. Есть объектная модель проекта, в рамках которой питоновские обработчики делают основную работу. На выходе будет большое количество заголовочных файлов и исходников, рассортированных по нужным библиотекам. Всё это интегрировано с Cmake

Кстати, забавно, что AWS Rust SDK написано в подобном стиле, с кучей генерированных однотипных сорцов.

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

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

byko3y ★★★ ()
Ответ на: комментарий от fsb4000

Зачем ты вообще используешь исключения для ifstream?

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

byko3y ★★★ ()
Ответ на: комментарий от kvpfs

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

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

byko3y ★★★ ()
Ответ на: комментарий от no-such-file

Не тупи, libstdc++

[21:38:35 1 ~/tmp] $ cat bad_alloc.cpp

int main()
{
    char* c = new char[4000000000U];
}
[21:38:58 1 ~/tmp] $ g++ bad_alloc.cpp
[21:39:06 1 ~/tmp] $ ./a.out
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted
[21:39:07 1 ~/tmp] $ g++ -fno-exceptions bad_alloc.cpp
[21:39:16 1 ~/tmp] $ ./a.out
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted

Да, можно собрать libstdc++ с "-fno-exceptions", и тогда отдельные функции вместо исключений будут сразу дергать abort — что есть еще хуже, поскольку в таком случае вообще нет возможности обработать ошибки для отдельных функций.

byko3y ★★★ ()
Ответ на: комментарий от anonymous

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

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

byko3y ★★★ ()
Ответ на: комментарий от byko3y

Эх, а до появления всей этой теоркат-дрочерской тусни а понятие функционального программирования как раз и вкладывали то, что ты называешь функционально-процедурным.

Princesska ★★★ ()
Ответ на: комментарий от Princesska

Эх, а до появления всей этой теоркат-дрочерской тусни а понятие функционального программирования как раз и вкладывали то, что ты называешь функционально-процедурным

Называли функционально-императивным. Это это называю «функционально-процедурным», поскольку за 50 лет программисты научились организовывать наборы инструкций в независимые единицы с локальным состоянием, и даже более того — это независимые единицы внутри тоже структурированы, отсюда и «структурированное программирование». В противовес коболу с фортраном, в которых глобальное состояние и разные варианты goto.

byko3y ★★★ ()
Ответ на: комментарий от no-such-file

И какая связь с ФП? В Хаскеле нету исключений? Вроде есть

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

byko3y ★★★ ()
Ответ на: комментарий от Siborgium

части языка — они входят в стандарт — все входящее в стандарт — часть языка. просто язык состоит из нескольких чапстей — одна из которых — стандартная либа.

safocl ★★ ()
Ответ на: комментарий от anonymous

исключения действительно несут чуть больше накладных расходов чем просто коды ошибок

ну да ну да — напомни как ты проверяешь коды ошибок — не через if ли?

safocl ★★ ()
Ответ на: комментарий от anonymous

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

так нет же никакого объектного каркаса в самой возможности кидать исключения — сами классы исключений енто уже совсем иное — сама возможность предлагает пробрасывать какую то информацию через раскрутку стека при нужном условии. тут не обязательно кидать объекты классов — кидай те же коды ошибок через throw

safocl ★★ ()
Ответ на: комментарий от byko3y

Ну классика жанра — либо всё продумано, либо падаем в корку. А если серверу нельзя падать в корку? Если из любой ошибки нужно корректно выйти и продолжить работу дальше?

Я ведь специально написал

перезапускаем всю задачу в релизе

Т.е. если для тебя это критично, то начинаешь задачу заново на некотором уровне, например, перезапускаешь сервер. Ты сейчас, наверное, скажешь - а как понять что не так пошло? Можно стек трейс скинуть в лог (примерный код с цпп23, сейчас просто кода больше будет):

basic_stacktrace trace;


extern "C" void __cxa_throw(void *e, void *i, void (*dest)(void *)) {
	type_info *ti = (std::type_info*)(i);
	if (*ti = typeid(Any_exception_type))
		tracce = basic_stacktrace::current();
	using throw_t = void (*)(void*,void*,void(*)(void*));
	static throw_t rethrow = (throw_t)dlsym(RTLD_NEXT, "__cxa_throw");
	rethrow(e, i, dest);
}

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

kvpfs ()
Ответ на: комментарий от byko3y

Между прочим, в C# очень интенсивно идет переход именно в функционально-процедурном направлении.

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

Отсюда термин функционально-процедурное программирование выглядит как сухо-влажная уборка и холодно-горячекатанная сталь. В контексте императивного/функционального программирования функция != процедуре, потому что функция имеется в виду математическая, которая чистая, а не функция из информатики, которая та же процедура только с возвратом, она же подпрограмма.

EDIT:

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

Тут уже понятнее. Процедурно-функциональный язык еще как-то понятно, в отличие от функционально-процедурного направления. Хотя «язык поддерживающий императивное и функциональное программирование» звучит более благозвучно, как по мне.

yetanother ()
Последнее исправление: yetanother (всего исправлений: 1)
Ответ на: комментарий от byko3y

В крестах же положено вообще все ошибки через исключения бросать.

Неправда, это только говнокодеры лепят исключения во все щели не понимая области применимости.

kvpfs ()
Последнее исправление: kvpfs (всего исправлений: 3)
Ответ на: комментарий от Princesska

Не называли, были отдельно процедурные языки, и отдельно функциональные, с системой Хиндли-Милнера, с удобными фвп и с минимизацией использования изменяемых переменых. Типичные представители ML семейство и hope, появились уже в 70 годы, задолго даже до прородителя хаскеля и почти одновремено с си и паскалем.

anonymous ()
Ответ на: комментарий от kvpfs

Так приличней (запустил, без стектрейса, никто пока в стд не умеет)

extern "C" void __cxa_throw(void *e, void *i, void (*dest)(void *)) {
	type_info *ti = reinterpret_cast<std::type_info*>(i);
	if (*ti == typeid(Any_exception_type))
		tracce = basic_stacktrace::current();
	using throw_t = decltype(__cxa_throw);
	static throw_t *rethrow = (throw_t*)dlsym(RTLD_NEXT, "__cxa_throw");
	rethrow(e, i, dest);
}

PS: если кто будет юзать, то линковать бинарь с __cxa_throw() надо с флагом -rdynamic (ну или сунуть __cxa_throw() в какую-нибудь .so, которая первая в limk map’e через LD_PRELOAD).

kvpfs ()
Последнее исправление: kvpfs (всего исправлений: 2)
Ответ на: комментарий от cobold

А в стандартной библиотеке обстрагировались от этого потому что а фиг знает на какой системе будет собран код, может на msdos с fat и там нет никакого permission denied в принципе

errno, как раз позволяет писать пользователю это: https://gcc.godbolt.org/z/ad5Yv5z8x

fsb4000 ★★★★★ ()
Ответ на: комментарий от archie

Выглядит круто! Как я понимаю, это не general-purpose ФП фреймворк с различными алгоритмами и комбинаторами...

Нет, разумеется. Но желающие могут написать.

а узкоспециализированная библиотека для работы с персистентными структурами данных

Она не узкоспециализированная в обычном понимании. Она оптимизирована под большие объемы хранимых и обрабатываемых данных. Там Git-подобная (бранчи, коммиты) модель персистентности, и в рамках одного коммита можно группировать сколько угодно апдейтов в разные контейнеры. Тогда как в ФСД у тебя каждый апдейт создает новую версию СД и нужен сборщик мусора, чтобы оперативно выметать версии, на которые больше не никто не ссылается.

Мемория нужна для разработки, например, функциональных БД и/или файловых систем. Ближе всего тут будет Big Data и всякий продвинутый инжиниринг данных по всей вертикали стека от голого железа и до пользовательского уровня.

aist1 ★★ ()
Ответ на: комментарий от byko3y

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

Это не совсем так. Есть предлагаемое расширение для рефлексии времени компиляции и там можно создавать код в компайл-тайме через квотинг.

У меня тоже есть свой форк Clang, сделанный над тем самым предлагаемым вариантом Reflection TS, но добавляющий полноценные компилируемые метафункции, вызываемые компилятором. Полное множество С++, включая треды, ввод-вывод, доступ к AST и квотинг.

archie, там будет встроенный build tool (JBT), построенный над Меморией в качестве хранилища данных проекта. И это будет show case для технологии.

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

Я только «за». Хуже всего — это когда тебя просто не замечают))

На самом деле стратегия тут простая. Очень сложно продвигать продвинутые фичи языка, когда под них еще нет практических задач. А у меня и такие задачи есть, и средства для них есть (Мемория).

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

aist1 ★★ ()
Ответ на: комментарий от byko3y

Одна из первых проблем, с которой сталкивается желающий писать на «си с плюшками» — это возврат ошибок при инициализации обЪекта/структуры

Одна из первых проблем, с которой сталкивается желающий писать на «си с плюшками» — это идиоты сторонящиеся исключений и затем сами себе же противоречащие

как в Rust

в котором основной подход - unwrap, т. е. те самые исключения.

anonymous ()