- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 100
// https://wandbox.org/permlink/rAilQ54oYBNsHJ3W
struct blob_p(T,alias t_xmalloc,alias t_free)
{
blob!(T)* bl_p;
size_t
getlen
(
) @trusted
in
{
assert(bl_p != null);
}
do
{
return bl_p.len;
}
T*
getdata
(
) @trusted
in
{
assert(this.bl_p != null);
}
do
{
return cast(T*)bl_p.data;
}
static bool
cmp
(
typeof(this) a,
typeof(this) b
) @trusted
in
{
assert(a.bl_p != null);
assert(b.bl_p != null);
}
do
{
if (a.bl_p.len != b.bl_p.len)
{
return false;
}
if(memcmp(cast(void*)a.bl_p.data, cast(void*)b.bl_p.data, a.bl_p.len * T.sizeof) != 0)
{
return false;
}
return true;
}
bool
cmp
(
typeof(this) a
) @trusted
in
{
assert(a.bl_p != null);
assert(this.bl_p != null);
}
do
{
if (a.bl_p.len != this.bl_p.len)
{
return false;
}
if(memcmp(cast(void*)a.bl_p.data, cast(void*)bl_p.data, a.bl_p.len * T.sizeof) != 0)
{
return false;
}
return true;
}
T opIndex(size_t i)
in
{
assert(bl_p != null);
assert(bl_p.len > i);
}
do
{
return getdata()[i];
}
~this()
/*in
{
assert (cast(void*)bl_p != null);
}
do*/
{
t_free(cast(void*)bl_p);
}
Попробовал написать на "D" своего рода "массив" с известно каким размером
переписать на
И тогда норм.
Но какого хрена там он решил вызывать деструктор, при таком вот "проксировании" конструктора? Как это сделать лучше?
вот теперь норм. Всем спасибо за помощь )))
Но вообще хуита, надо чтоб ГОМОИКОННОСТЬ
> при таком вот "проксировании" конструктора?
> Как это сделать лучше?
Переписать на «Си».
Это какой паскализм и анскильная перепитушня.
Часто размер массива известен в компайл-тайме. См. std::array.
Зачем его вообще везде таскать?
Днище как бы не обсуждаем.
> А как лучше?
Говорю же, во многих случаях мне нравится использовать что-то вроде std::array<int16_t, 4> arr = {0, 1, 2, 3};
И размер не надо таскать. И превращается в mov rax, ...
Потому что всегда знаем в компайл-тайме, исходя из типа.
Есть одно неудобство : в Сишке нельзя написать
Да, в D тоже такую хуйню можно сделать, но только тогда ты в рантайме не сможешь генерить массив хуй знает какой длины, у тебя все длины в компилтайме должны быть вычислимыми, чтобы соотв. тип синтезировать.
> Зачем его вообще везде таскать?
Чтобы куда-то передать, если размер зависит от рантайм-хуиты.
Тут длина хранится не вместе с указателем, а вместе с самими данными непосредственно, это как "flexible array member" - см. http://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16
А, ок.
Просто много пердолинга с конструкторами, деструкторами, assert(bl_p != null);
Этот синтаксиальный мусор напоминает джава-дрисню: геттеры, сеттеры, equals.
> EXAMPLE After the declaration:
> struct s { int n; double d[]; };
Кстати пример у них какой-то мудацкий.
Даже в моём говне размер size_t https://govnokod.ru/27633#comment667053
Возьми «Nim», там такой хуйни (деструкторов) нет.
Как красиво и скилльно сделали, ах как же мне нравится мой любимый язык программирования «Nim»!
Батюшка j123123 уже показывал как окрестить Сишку в RAII
https://govnokod.ru/25526#comment471379
https://wandbox.org/permlink/btXuxt1Gk3NENoxy
Языки с деструкторами не нужны.
В «JavaScript» никаких деструкторов нет. И живут же люди.
Всё RAII можно заменить лямбдами.
Только нужно научить говноязыки нормальному инлайну этих лямбд.
Внутри close ресурса собрана логика какие подресурсы нужно закрыть.
Реализация макроса With автоматически открывает ресурс и делает close/free.
Это на словах в крестах всё просто и можно ничего не делать.
А в реальности нужно выучить пять десятков правил жизненного цикла объектов: конструкторов, деструкторов, присваиваний и ещё десяток исключений из этих правил.
Проще руками явно закрыть.
А в жовах с питонами и котлинами ты потом вынужден не забывать делать всё это клозабл и оборачивать спец хуйней
Вот такие рачки потом растут
https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/openapi/Disposable.java
RAII уровня крестов (пример с cplusplus.com)
Почему не
Ну или его старые братья.
О, наконец сделали как положено. Отстал я от жизни.
ванишд
Я за \uD83D\uDD12
П.С Блядский utf8mb4
https://pastebin.com/E1Rqpmqx
error: macro names must be identifiers #define 【(mtx) mtx.lock()
И на return/throw блокировка останется занятой.
https://ideone.com/CRz5nb
Time limit exceeded
goto, break, throw
Какое же дерьмо эти ваши кресты
Тут сразу видно скоуп лочки.
И Гораздо эстетичнее крестопарашных
С++11 С++17
https://tour.dlang.org/tour/en/gems/scope-guards
т.е. написать scope(exit) некаяхрень(); и она вызовется по выходу из скоупа
Получается стек для всего на свете, pop из которого завершению блока языка.
А как этот стек выглядит в мышиных кодах? Нет ли перепитушни.
У меня давно витает завиральная мысль. Пора бы написать.
Почему ещё никто не догадался предложить разбиение функции на три необязательных секции.
1. intro
2. body
3. outro
В intro у нас будет валидация переменных и всякая контрактная часть. Не буду расписывать, тут это неважно.
body это сама функция.
А outro это что-то вроде деструктора функции. finally, которое выполняется всегда, после завершения body.
Только в отличие от finally, которое не видит скоуп try наш outro видит переменные верхнего уровня из intro и body.
Примерно так:
По-моему это гораздо проще и решит 97% проблем освобождения ресурсов.
Это классическое говнище, которое сотни раз приводило к ошибкам.
Если бы люди постоянно не ошибались, никто бы не выдумывал RAII, умные указатели и сборщики говна.
Люди хотят писать return 42 и течь.
А не пердолиться с сохранением ответа во временную пельменную и goto в ебеня.
Соответственно в секции outer можно запретить return X, оставив её для cleanup.
Да и в классическом Паскале можно было присвоить и течь (в нём, правда, нельзя было читать это значение).
Раньше мне этот подход совсем не нравился. Т.к. нужно было писать Exit Sub/Function. Но возможно в этом что-то есть.
Сразу понимают, какое си говно. Ни функцию посчитать, ни переменную назначить, ни степень посчитать язык не может.
У математиков нет присвоения в том смысле, в котором оно есть в императивных ЯП. В императивные ЯП оно пришло из ассемблера, потому что там приходится переиспользовать регистры.
У математиков есть уравнения, формулы, функции — это связт между переменными, которые верны всегда, а не только в конкретный момент.
Если нужно посчитать что-то новое, математик не переиспользует переменную, а объявляет новую.
Правда, переиспользуемые переменные у математиков всё же есть: они используются под знаком суммы или произведения последовательности (ряда), интеграла, предела.
> У математиков нет присвоения в том смысле, в котором оно есть в императивных ЯП.
Возможно вас заинтересует:
https://govnokod.ru/27639
Единственный язык, о котором мне известно, где есть отдалённо похожая на мою идею фича, разбиения ф-ции на секции это Кобол.
Там есть довольно упоротая/оригинальная возможность разбивать процедуру на подпроцедуры (т.н. секции).
А в хедере писать PERFORM и указывать порядок их выполнения, смешивая образы до полного безумия.
Причём эти подпроцедуры работают на общем контексте функции, благодаря этому можно шарить код и не таскать параметры всего контекста.
Если выразить это в условном сишном синтаксисе выглядит примерно так
Ага.
Но я описал perform очень и очень упрощённо.
Во-первых, вызовы секций могут быть описаны не только в хедере.
И внутри секций можно писать вызовы других секций (рекурсивно с нахлёстом)
Во-вторых PERFORM это аналог For, While, Repeat.. Until в одном флаконе, что кратно добавляет пиздеца.
Последовательное исполнение за которое я написал это Basic PERFORM.
Но там есть более интересные применения
Пример
Описание у IBM с мозговзрывными блок-схемами
https://www.ibm.com/docs/en/cobol-zos/4.2?topic=statements-perform-statement
https://www.ibm.com/docs/en/cobol-zos/6.2?topic=statement-perform-varying-phrase
По-моему один этот оператор настолько сложен, что сам по себе полностью Тьюринг полный.
Теперь понял, чего мне в языках программирования не хватало. Иногда шаг алгоритма хочется выделить, но он ещё не настолько самостоятелен, чтобы под него нужно было создавать функцию. Получается либо лапша на тысячи строк, либо куча функций, которые вызываются только в одном месте.
Но это больше смахивает на замыкания.
А в «Кобол» это логические блоки, скоупы. Больше похожие на метки.
И эта фича довольно сильно меняет отношение к кодингу. Сразу чувствуется что у людей своя интерпрайзная атмосфера.
Во-первых, код больше не уходит вбок на глубину (на экранах в 70х это было важно).
Каждый скоуп просто выносится вниз. «Кобол» кстати ругали за то, что тело цикла может быть отделено от PERFORM.
Во-вторых, бряк на метку и выход из двух сразу циклов перестаёт быть проблемой.
Можно сделать выход из секции.
Такой язык просрали. У меня из-за бряков не туда была куча ночей отладки. Гост с его проблемами от безобидного var нервно курит в сторонке.
Появилось три опции вместо двух? Решил, что if недостаточно красив? Сосни, сучечка.
Если там этот scope(exit) не завернут в какие-нибудь условия (т.е. этот вызов scope(exit) может быть, а может и не быть), никакого "стека" не требуется, т.к. это можно переписать как вызов этой питушни перед соответствующей "}"
* Он может вертеться на другом хосте, кстати. Network transparency, хо!
Всё не нужно, что сломалось
Всё не нужно, чего нет
а напиши для трех ресурсов
Именно поэтому я за «Си».