Re[15]: Наследие Си
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 22.09.25 21:44
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>Но платить-то придется за весь банкет, поскольку любой throw или try/catch непременно потянет за собой все зависимости, предназначенные для обработки исключений.


А что это за зависимости, можно узнать? По-моему, там всё довольно минималистично
Маньяк Робокряк колесит по городу
Re[17]: Наследие Си
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 22.09.25 21:47
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Это относится к его применению. В тех же *nix, OS/2 и Windows весь API заточен под C и его ABI, поэтому любая неигрушечная реализация должна этому следовать.


Разве C? А не Паскаль? Я ёще помню те времена, когда в объявлениях практически всех виндовых функций использовался макрос PASCAL
Маньяк Робокряк колесит по городу
Re[26]: Наследие Си
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.09.25 05:16
Оценка:
Здравствуйте, so5team, Вы писали:

S>И где в D макросы?

https://dlang.org/articles/ctarguments.html
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[27]: Наследие Си
От: so5team https://stiffstream.com
Дата: 23.09.25 06:06
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>И где в D макросы?

S>https://dlang.org/articles/ctarguments.html

Макросы там где? Это чистой воды D-шные шаблоны.
Которые в совокупности с mixin-ами и дают возможности метапрограммирования.

Но никакими макросами они не являются.

Или ваши познания на одном уровне с г.Музыченко и вы считаете C++ные шаблоны разновидностью макросов?
Re: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 23.09.25 08:06
Оценка:
Здравствуйте, σ, Вы писали:

σ>
  https://www.computerenhance.com/p/the-big-oops-anatomy-of-a-thirty
σ>https://www.youtube.com/watch?v=wo84LFzx5nI
Смотрел несколько дней назад, уже всего точно не помню, но вот некоторые моменты:


Посмотрел это видео, как много пустых слов. И товарищ основательно преувеличивает. Вариации на тему entity component system в геймдеве были лет на 15 раньше, чем он указывает. Я портировал на TypeScript игру 84го года, и там уже было подобие это entity component system

Ну и api операционных систем того времени это вобщем вариации на ту же тему.
Re[16]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 08:55
Оценка:
Здравствуйте, Marty, Вы писали:

M>мне всегда проще было сделать что-то рекурсивно, чем итерационно.


Если алгоритм изначально рекурсивный — неудивительно.

M>Ты про каких-то неосиляторов


Я почему-то очень сильно сомневаюсь, что Вы хотя бы более-менее понимаете, как работают "магические" шаблоны в той же Loki. Не в смысле общих принципов, а в смысле внесения туда осмысленных правок с сохранением работоспособности.

M>что тебе сешает сделать свой компилятор своего "C++"?


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

M>Если выкинуть шаблоны


Я не смогу их выкинуть, ибо использую. Не на уровне магии, но все же.

M>такой коспилятор пишется за месяц, ну, окей, за три.


За три месяца он пишется до состояния "устойчиво работает, дает работоспособный код". Мне такого будет мало. Если б взялся лет 20-30 назад, то где-нибудь за год довел бы до ума. Но меня каждый раз останавливала мысль "зачем мне это делать, разработчики ж не дураки — скоро обязательно кто-нибудь добавит в существующие компиляторы удобные фичи". И ведь были к тому предпосылки — те же __if_exists/__if_not_exists, __is_xxx/__has_xxx в VC++. Но потом на все это забили — видать, "традиционный подход" возобладал и там.

M>Примеры помогут, по-моему, мало кто понимает, как твои макросы должны работать


Тому, кто намертво залип на принципах вроде "любой макрос обязан полностью раскрываться на стадии лексического анализа", примеры не помогут.
Re[25]: Наследие Си
От: so5team https://stiffstream.com
Дата: 23.09.25 09:25
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>в более продвинутых случаях, на уровне AST не подвергшегося еще семантическому анализу (например, процедурные макросы Rust-а, которые получают и возвращают TokenStream-ы).

S>Макросы раста работают не с синтаксическим материалом, а лексическим. То есть ещё до построения AST.

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

Для эксперимента возьмем простой процедурный макрос из категории derive:
use proc_macro2::{self, Ident, Span};

#[proc_macro_derive(MyTrait)]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = proc_macro2::TokenStream::from(input);
    let demo = Ident::new("Demo", Span::call_site());
    let first = input.into_iter().skip(3).next().unwrap();
    match first {
        proc_macro2::TokenTree::Ident(id) if demo == id => panic!("Only Demo is expected"),
        ref _other => {}
    };
    format!("fn answer() -> String {{ \"{first}\".to_string() }}").parse().unwrap()
}

Он порождает ошибку компиляции, если будет применяться к структуре с именем Demo.

И простейший пример его использования:
use mytrait_derive::MyTrait;

#[allow(dead_code)]
#[derive(MyTrait)]
struct Demo {
    x: i32, y: i32
}

fn main() {
    let a = answer();
    println!("The answer is {a}");
}


При компиляции получаем ожидаемое:
   Compiling demo v0.1.0 (experiment-1\demo)
error: proc-macro derive panicked
 --> src\main.rs:4:10
  |
4 | #[derive(MyTrait)]
  |          ^^^^^^^
  |
  = help: message: Only Demo is expected

error[E0425]: cannot find function `answer` in this scope
  --> src\main.rs:10:13
   |
10 |     let a = answer();
   |             ^^^^^^ not found in this scope

For more information about this error, try `rustc --explain E0425`.
error: could not compile `demo` (bin "demo") due to 2 previous errors

Теперь намеренно внесем в определение Demo синтаксическую ошибку:
struct Demo {
    x: i32, y: /*i32*/
}

и при попытке компиляции у нас сперва получается сообщение об ошибке в декларации Demo, а уже затем сообщение об ошибке от макроса:
   Compiling demo v0.1.0 (experiment-1\demo)
error: expected type, found `}`
 --> src\main.rs:7:1
  |
5 | struct Demo {
  |        ---- while parsing this struct
6 |     x: i32, y: /*i32*/
7 | }
  | ^ expected type

error: proc-macro derive panicked
 --> src\main.rs:4:10
  |
4 | #[derive(MyTrait)]
  |          ^^^^^^^
  |
  = help: message: Only Demo is expected

error[E0425]: cannot find function `answer` in this scope
  --> src\main.rs:10:13
   |
10 |     let a = answer();
   |             ^^^^^^ not found in this scope

For more information about this error, try `rustc --explain E0425`.
error: could not compile `demo` (bin "demo") due to 3 previous errors


Т.е. выглядит все так, что сперва компилятор делает разбор (в том числе и синтаксический) фрагмента, для которого написан derive, только затем вызывает derived-макрос куда отдает набор лексем. Но при этом, полагаю, у самого компилятора вполне в распоряжении уже есть AST.
Re[17]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: so5team https://stiffstream.com
Дата: 23.09.25 09:32
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Тому, кто намертво залип на принципах вроде "любой макрос обязан полностью раскрываться на стадии лексического анализа", примеры не помогут.


Вас уже тыкали фейсом в макросы Rust-а. Они как раз работают уже после лексического анализа.

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

В случае же шаблонов C++ или D, у нас уже не куски исходного текста -- по крайней мере на входе уже известные компилятору сущности языка, вроде типов или объектов.

Хотя в D все еще веселее: там на входе известные компилятору сущности, на выходе может быть текст, который скармливается компилятору через специальный вариант mixin. Хотя есть и особый mixin template.

Так что есть ощущение, что ваши собеседники и видели, и пробовали разное. А вот вы только какие-то свои пустопорожние грезы описываете. Поэтому и в примеры не можете.
Re[16]: Наследие Си
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 09:59
Оценка:
Здравствуйте, Marty, Вы писали:

M>А что это за зависимости


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

M>По-моему, там всё довольно минималистично


Минималистичным оно могло бы быть, если б throw мог выбрасывать только значения интегральных типов (оптимально — указатель). Ну, или если б можно было сказать компилятору "мы будем выбрасывать только интегральные типы, и сами разберемся, что было выброшено по факту".

А так добавление SEH в минимальный main для VC++ дает прирост где-то в 3%, а добавление туда же исключений C++ (которые реализованы поверх SEH) — дополнительные 25%. По большому счету, это не так много, но это явное нарушение того самого принципа о плате и использовании.
Re[18]: Наследие Си
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 10:08
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>Разве C? А не Паскаль?


В виндовых SDK/DDK/WDK никогда не было объявлений интерфейсов для Pascal. Только для C/C++, MIDL и других стандартных средств от MS.

M>в объявлениях практически всех виндовых функций использовался макрос PASCAL


Макрос PASCAL раскрывался в сишный модификатор _pascal.

Это пошло еще с первых реализаций C/Pascal: в первом возможны функции с переменным количеством параметров, поэтому стек очищает вызывающий код, а во втором их нет, поэтому стек очищает вызываемая функция. Соответственно, модификаторы вроде _pascal были добавлены в C для подключения процедур/функций на Pascal. По объему кода второй вариант более компактен, поэтому в ABI последующих систем обоснованно решили использовать его, а модификатор был уже готовый.
Re[26]: Наследие Си
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 10:11
Оценка:
Здравствуйте, so5team, Вы писали:

S>для того, чтобы применить макрос из категории derive компилятору Rust-а нужно сперва завершить парсинг того участка (блока) к которому макрос применяется. А для этого недостаточно только разбиения входного потока на лексемы (токены), нужен еще и синтаксический анализ.


Все это не обязательно жестко постулировать раз и навсегда для всего языка. Можно выбрать режим разбора/анализа по умолчанию, и менять его отдельно для каждого макроса или фрагмента кода.
Re[27]: Наследие Си
От: so5team https://stiffstream.com
Дата: 23.09.25 10:15
Оценка: +1 :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>для того, чтобы применить макрос из категории derive компилятору Rust-а нужно сперва завершить парсинг того участка (блока) к которому макрос применяется. А для этого недостаточно только разбиения входного потока на лексемы (токены), нужен еще и синтаксический анализ.


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


А еще в праздных разговорах можно наделить понятие "макроса" еще 100500 дополнительными смыслами.
Re[18]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 11:27
Оценка: :)
Здравствуйте, so5team, Вы писали:

S>Вас уже тыкали фейсом в макросы Rust-а. Они как раз работают уже после лексического анализа.


Это я про то, как Вы несколько дней подряд бились головой о стену: "они работают ДО компилятора! ДО! ДО! ДО!".

S>Но фокус в том, что макросы манипулируют кусками исходного текста (как на входе, так и на выходе) и полученные в результате работы макроса куски текста затем должны обрабатываться компилятором.

S>В случае же шаблонов C++ или D, у нас уже не куски исходного текста -- по крайней мере на входе уже известные компилятору сущности языка, вроде типов или объектов.

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

А если позволить программисту записывать эти "метаконструкции" на языке, похожем на основной (как это и сделано в том же PL/1), то их функциональность будет практически не ограничена, и при этом не так уж сложно обеспечить понятность, прозрачность, поддержку отладки как на стадии компиляции, так и на стадии исполнения.

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

S>в примеры не можете.


Я в примеры могу, но не хочу. Вы вот могли бы задавать уточняющие вопросы, но тоже не хотите, все ждете готовых примеров...
Re[28]: Наследие Си
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 11:56
Оценка:
Здравствуйте, so5team, Вы писали:

S>можно наделить понятие "макроса" еще 100500 дополнительными смыслами.


Нет надобности его чем-то "наделять". Оно изначально предельно общее, буквально вытекающее из смысла слова "macro" (надеюсь, найдете самостоятельно). И оно испокон веку обозначало все, что подпадает под технологию "сгенерировать результат из указанной текстовой конструкции". Ну а потом выросли поколения, которые уже знали макросы исключительно по их реализациив в C/C++, m4 и подобных средствах, а про иные способы реализации даже не догадывались, и стали придумывать разные искусственные разделения.

Настаивая на том, чтоб называть обработку текста программ, выходящую за пределы чисто лексической, непременно "метапрограммированием", а термина "макрос" в данном контексте избегать, попробуйте представить, как будет выглядеть реализация языка с подобным разделением. Вот надо Вам сделать почти чисто текстовую подстановку, но так, чтоб текст содержал, скажем, имя текущей функции. Сейчас для этого есть встроенные макросы вроде __FUNCTION__, но это уже читерство — препроцессор (которым, по-Вашему, обязан быть любой макропроцессор) ни о каких функциях не знает. А в "метаконструкциях для рефлексии" Вам предложат богатый инструментарий для манипуляции типами, объектами, перебора методов классов и т.п., но банальной склейки двух подстрок не дадут, ибо это уже "типичная макрооперация", пожалте в препроцессор. И будете опять изворачиваться в попытках скрестить ежа с ужом, как тот комсомолец, который не может без трудностей.
Отредактировано 23.09.2025 11:57 Евгений Музыченко . Предыдущая версия .
Re[19]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: so5team https://stiffstream.com
Дата: 23.09.25 12:03
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>Вас уже тыкали фейсом в макросы Rust-а. Они как раз работают уже после лексического анализа.


ЕМ>Это я про то, как Вы несколько дней подряд бились головой о стену: "они работают ДО компилятора! ДО! ДО! ДО!".


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

А пока семантики нет, пока все крутится на уровне лексики/синтаксиса (а то и до того, как в случае Си-ного препроцессора), то речь идет о макросах.
Re[29]: Наследие Си
От: so5team https://stiffstream.com
Дата: 23.09.25 12:07
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>И оно испокон веку обозначало все, что подпадает под технологию "сгенерировать результат из указанной текстовой конструкции"


Именно что из текстовой конструкции, а не из кода.
В текстовой конструкции мы может даже не знать что означает символ `>`.
А в коде мы точно знаем что это.

ЕМ>Настаивая на том, чтоб называть обработку текста программ, выходящую за пределы чисто лексической, непременно "метапрограммированием", а термина "макрос" в данном контексте избегать, попробуйте представить, как будет выглядеть реализация языка с подобным разделением. Вот надо Вам сделать почти чисто текстовую подстановку, но так, чтоб текст содержал, скажем, имя текущей функции. Сейчас для этого есть встроенные макросы вроде __FUNCTION__, но это уже читерство — препроцессор


Который в современном C++ нахер не нужен для конкретно этой задачи: https://en.cppreference.com/w/cpp/utility/source_location/current.html

Блин, когда скудоумие умножается на ограниченность кругозора, то просто караул.
Re[19]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: rg45 СССР  
Дата: 23.09.25 12:08
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

S>>Вас уже тыкали фейсом в макросы Rust-а. Они как раз работают уже после лексического анализа.


ЕМ>Это я про то, как Вы несколько дней подряд бились головой о стену: "они работают ДО компилятора! ДО! ДО! ДО!".


А ты с этим не согласен?
--
Справедливость выше закона. А человечность выше справедливости.
Re[20]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: so5team https://stiffstream.com
Дата: 23.09.25 12:13
Оценка: :)
Здравствуйте, rg45, Вы писали:

S>>>Вас уже тыкали фейсом в макросы Rust-а. Они как раз работают уже после лексического анализа.


ЕМ>>Это я про то, как Вы несколько дней подряд бились головой о стену: "они работают ДО компилятора! ДО! ДО! ДО!".


R>А ты с этим не согласен?


Он про абстрактные макросы в вакууме своей головы.
Эти неведомые и никем не виданные звери могут все что угодно и работают там и тогда, когда г.Музыченко будет удобно.
Re[21]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: rg45 СССР  
Дата: 23.09.25 12:23
Оценка: :)
Здравствуйте, so5team, Вы писали:

S>Он про абстрактные макросы в вакууме своей головы.

S>Эти неведомые и никем не виданные звери могут все что угодно и работают там и тогда, когда г.Музыченко будет удобно.

Я всё меньше вижу смысла дискутировать с ним о чём-либо. У него там в голове такой зоопарк, что поди отдели бульдогов от носорогов.
--
Справедливость выше закона. А человечность выше справедливости.
Re[20]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.09.25 12:38
Оценка: :)
Здравствуйте, so5team, Вы писали:

S>Компилятор занимается лексическим и синтаксическим разбором, после чего анализирует семантику, после чего делает оптимизации и генерирует объектный код.

S>Для метапрограммирования необходимо завершение стадии анализа семантики. Ведь именно тогда у компилятора появляется точная информация что есть что -- тот самый код который пойдет на вход метапрограмме в качестве параметра.

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