vaa>Мне кажется это признак хорошего ЯП, если писать и отлаживать можно без опоры на сложные инструменты.
Это прежде всего признак маленького короткоживущего проекта. В любом большом или долгоживущем проекте рано или поздно
1 приходится добавлять требования, которые ломают ранее принятые решения. Проводить такие изменения без адекватных инструментов мягко говоря нерационально
2 добавлять/менять членов команды, и новички не понимают ранее принятые решения.
C>>Этот код "на ди" выглядит как С++ в котором #include заменили на import K>Как только привлечёшь классы и шаблоны, с++ превратится в нечитаемую кашу.
Блин, меня особенно классы доканывают... зачем они вообще ...
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, vaa, Вы писали:
vaa>>Код на ди делает все тоже самое, но без синтаксического шума: CC>Этот код "на ди" выглядит как С++ в котором #include заменили на import
Как только привлечёшь классы и шаблоны, с++ превратится в нечитаемую кашу.
Сипиписники в своей агонии готовы лепить что угодно, только не признавать, что их язык давно устарел, а его неуклюжесть не лечится никакими новыми стандартами.
Здравствуйте, vaa, Вы писали:
vaa>Просто сравните код на Rust и С++ они практически одинаково не человеко-читаемы.
Покажи, сравним
Как по мне так если С++ код не человекочитаемый то это лишь означает что писавшему руки ровнять надо.
Здравствуйте, Слава, Вы писали:
С>Здравствуйте, kaa.python, Вы писали:
KP>>Смотреть во что сейчас превратился D нет времени,
С>А если у вас настолько нет времени (и вероятно этим гордитесь), то что вы делаете на форуме?
Время на форум есть. Времени на красивый, но мертворождённый язык нет. Ещё вопросы?
Здравствуйте, vaa, Вы писали:
vaa>Код на ди делает все тоже самое, но без синтаксического шума:
Этот код "на ди" выглядит как С++ в котором #include заменили на import
Так что опять таки непонятно нафига нужен ди если уже есть С++
Здравствуйте, vaa, Вы писали:
S>>Вы реально видите какую-то принципиальную разницу между двумя приведенными вами вариантами?
vaa>Ес, оф кос.
Ахринеть не встать. Там же все 1-в-1, только форма буковок чутка отличается. Замените в Rust-овом варианте первое guess на line, последний match на обычный if, а в D-варианте запишите try-catch не в одну строку и вы получите практически двух близнецов-братьев.
vaa>Считаю что наоборот сейчас ди выходит на уверенное развитие.
Что-то мне кажется я что-то такое слышал несколько раз, и первый раз лет 15 назад.
ИМХО язык D уже не взлетел и мертв. Чтобы он вдруг ожил и полетел, должно случиться что-то неординарное, я даже не могу представить что.
Другой вопрос, почему-же он все-таки не взлетел... язык, я так понимаю, хороший.
На этот вопрос у меня ответа нет... Но, видимо, уже давно мир так устроен, что язык не может взлететь, если за ним не стоит какая-то серьезная коммерческая организация...
Здравствуйте, kaa.python, Вы писали:
KP>И пока они там занимаются сексом с корутинами (о них ещё в 2016(2017?) на CppCon от Гора слышал как о прорыве) и никак не изродят ничего годного для промышленного использования
2015 (CppCon 2015: Gor Nishanov “C++ Coroutines — a negative overhead abstraction"). Как сейчас помню, Гор кричал "Negative overhead!" А потом оказалось, что на каждую корутину надо память выделять. Negative overhead my ass.
Здравствуйте, vaa, Вы писали:
vaa>Мне кажется это признак хорошего ЯП, если писать и отлаживать можно без опоры на сложные инструменты.
Нет, это признак того, что автору хотелось стоя, в гамаке, и на лыжах.
Здравствуйте, vaa, Вы писали:
vaa>А тогда, если нет разницы зачем платить больше?
Дык он и не платил больше. А так пришлось и переписать и с багом компилера побороться
Причём писал по сути в С стиле.
Так что не понятно нафига было лезть в этот гамак.
Здравствуйте, vaa, Вы писали:
vaa>плюс то плюс, но вот F# требует отступы на основе пробелов, если в редакторе настройки не поменять то придется исправлять,
Так надо поменять настройки или IDE
Это куда меньшая проблема чем кривые стили в С++.
Здравствуйте, Skorodum, Вы писали:
S>Это куда меньшая проблема чем кривые стили в С++. CC>>А что тебе мешает писать на С++ нормально? S>Вы уже перестали пить коньяк по утрам?
Ясно, значит руки мешают.
Бывает...
Тогда не ной про "кривые стили в С++", это не стили кривые.
Здравствуйте, vaa, Вы писали:
I>>Это прежде всего признак маленького короткоживущего проекта. В любом большом или долгоживущем проекте рано или поздно I>>1 приходится добавлять требования, которые ломают ранее принятые решения. Проводить такие изменения без адекватных инструментов мягко говоря нерационально I>>2 добавлять/менять членов команды, и новички не понимают ранее принятые решения.
vaa>Я этого не отрицаю. Любой инструмент лишь добавляет мощи. vaa>Я лишь хочу сказать, что ди один из лучших на сегодня ЯП. Достаточно сравнить:
К сожалению или к счастью, лучшесть языка проявляется в том, насколько эффективно он занимает головы и ниши.
1 Если язык пиарится 20 лет, а никакой ниши не занял, то это плохой язык.
2 А если без особых усилий проникает в каждую дырку, то это хороший, годный язык. И тренд здесь такой, что уродцы в норме берут верх над правильными выверенными языками.
Здравствуйте, kaa.python, Вы писали: KP>Зелёные потоки — это абстракция над обычными потоками ОС, которые позволяют использовать нескольким зелёным потокам один реальный поток ОС. Концепция очень хорошо прижилась и является более чем современной и активно используемой. Вернёмся к "отсталость и абсурд", что с ними не так?
Исчерпывающе: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1364r0.pdf
Кратко: бесстековые корутины заруливают самодельные потоки в минуса.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, ksandro, Вы писали:
K>ИМХО язык D уже не взлетел и мертв. Чтобы он вдруг ожил и полетел, должно случиться что-то неординарное, я даже не могу представить что. K>Другой вопрос, почему-же он все-таки не взлетел... язык, я так понимаю, хороший.
На это я могу ответить, как потенциальная целевая аудитория этого языка.
На момент около 2010-го года язык D выглядел как реальная замена языка C++. Там было всё, что в C++ (причём оно там было сделано с человеческим лицом) и плюс ещё множество других, более удобных и современных концепций. А от C++ в это время (когда было десятилетие без развития) начало реально попахивать нафталином. Так что очень многие тогда смотрели на D и не переходили вот так сразу только из-за неразвитости инфраструктуры, сообщества, библиотек и т.п. Но были уже не далеки от принятия решения о переходе в недалёком будущем.
А дaлee вышел C++11. В котором во-первых появилась где-то 1/3 модных возможностей D, а во-вторых появились свои инновационные (на тот момент отсутствующие вообще в каких-либо других языках и при этом очень мощные) возможности. Это однозначно заставило отложить принятие решения, чтобы посмотреть на развитие ситуации. Если бы скажем старые тенденции сохранились (C++ опять замер бы на десятилетие, а D впитал бы все современные инновации и остался бы на вершине развития), то всё равно со временем многие перешли бы на D. Но всё пошло совсем не так...
C++ неожиданно начал очень быстро развиваться, выкатывая по новому стандарту каждые 3 года. Причём развивая и свои уникальные фичи и беря новое из других языков. Причём и из D (теперь в C++ наверное уже больше половины фич D перекочевало), так и из других (например сопрограммы).
А в D наоборот, после выхода в релиз развитие замерло. Не были добавлены ни новейшие идеи из C++ (типа семантики перемещения), ни трендовые идеи индустрии (типа сопрограмм). Видимо авторы языка решили что он уже совершенен (как когда-то решили авторы IE6) и надо только его дошлифовывать и развивать инфраструктуру.
Ну и собственно глядя на такой расклад, все потенциальные пользователи D (типа меня например) мгновенно забыли про его существование (хотя раньше хорошо знали язык в теории и выбирали момент для перехода к практике).
Ну и для сравнения можно посмотреть на ситуацию с Rust. Rust в 2020-ом занимал наверное в точности такую же позицию относительно C++, как и D в 2010-ом. Но он показал правильное отношение к развитию языка (к примеру в первой версии языка (2015) сопрограмм не было, а в 2019-ом уже появились). И в итоге сейчас на него реально перебегают толпами...
I>Это прежде всего признак маленького короткоживущего проекта. В любом большом или долгоживущем проекте рано или поздно I>1 приходится добавлять требования, которые ломают ранее принятые решения. Проводить такие изменения без адекватных инструментов мягко говоря нерационально I>2 добавлять/менять членов команды, и новички не понимают ранее принятые решения.
Я этого не отрицаю. Любой инструмент лишь добавляет мощи.
Я лишь хочу сказать, что ди один из лучших на сегодня ЯП. Достаточно сравнить:
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..101);
loop {
println!("Please input your guess.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
Если в том же F# матч это матч, то в расте наркоме похоже писали
Код на ди делает все тоже самое, но без синтаксического шума:
import std.stdio;
import std.random;
import std.conv;
void main()
{
writeln("Guess the number!");
auto secret_number = uniform(1, 101);
writeln("The secret number is: ", secret_number);
while (true)
{
writeln("Please input your guess.");
auto line = readln;
auto guess = 0
try { guess = parse!uint(line); } catch (Exception e) { continue; }
writeln("You guessed: ", guess);
if (guess < secret_number)
writeln("Too small!");
else if (guess > secret_number)
writeln("Too big!");
else
{
writeln("You win!");
break;
}
}
}
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, vaa, Вы писали:
vaa>>Андрей Александреску так не считает CC>И? Этот персонаж ещё за свой STL должен извиниться.
Здравствуйте, CreatorCray, Вы писали:
vaa>>Андрей Александреску так не считает CC>И? Этот персонаж ещё за свой STL должен извиниться. CC>Стиль сего персонажа это как раз тот самый ужас-ужас, про который нам тут рассказывают те, кто на промышленном С++ толком не пишет.
Это мягко говоря преувеличение, что никто не пишет. Пишут, еще как.
С++ это примерно три враждующие между собой группировки, между которыми общего только компилятор:
1 Си-с-классами, макросы, сырые указатели, итд. Это как бы легаси, но больше всего кода написанно именно так.
2 Умеренный С++, RAII, STL и тд. На нынешний день здесь пишется больше всего кода.
3 Александреску-стайл. Сторонники этой ветви ислама создают либы, которыми пользуются первые две ветви.
Собеседования как правило заканчиваются еще на старте, если кандидат и интервьюер принадлежат различным группировкам, т.к. с т.з. одного второй не знает или не умеет, а с т.з. другого первый это хипстер, который вместо дела играется с компилятором.
Здравствуйте, reversecode, Вы писали:
R>всегда можно найти какую то синтетическую конструкцию которая лучше реализована в том или другом языке R>вон хаскель постоянно противоставляют по лаконичности и краткости R>а толку ?
Rust и C++ приблизительно равны по большей части возможностей языков. Единственная область, где Rust однозначно сильнее — это метапрограммирование. И данный пример это демонстрирует. В идеале для решения данной крайне распространённой (а вовсе не синтетической) задачи от языка требуется наличия в нём какого-либо вида интроспекции (для производительных языков очевидно подходит только статическая). Этого нет ни в C++, ни в Rust (а в D кстати есть). Но при этом метапрограммирование (синтаксические макросы) Rust'а позволило красиво и удобно решить эту проблему, а метапрограммирование C++ нет.
R>но код в расте дует очевидно его концепция R>из за которой все обрастает боксами рефцелами и прочей мишурой на ровном месте R>итог 20 строчек раста R>заменяются двумя на С++ R>а огромный проект на расте R>двумя файликами на С++
Смешной ты. Ты же должен сам понимать, что вот можно взять практически любой C или C++ код и буквально дословно перевести его в код Rust'а, просто засунув в один большой unsafe блок.
Поэтому если где-то на Rust'е пишут более многословный код (без unsafe), то это не потому что по другому нельзя, а потому что хотят добиться от компилятора каких-то дополнительных проверок. Чтобы он что-то там ещё (помимо привычного в C++) постоянно контролировал сам. И вот чтобы объяснить ему правила этих дополнительных требований и требуется дополнительный объём кода.
Более того, как раз из-за этой возможности (возложить на компилятор дополнительную работу) многие и переходят на Rust.
R>а когда довезут паттерн мачинг в С++ R>так вообще раст уйдет за D
Лучше бы они рефлексию наконец родили. Которую комитет C++ уже более 10 лет обсуждает, но никак не может родить. Хотя бы банально стащить реализацию из D, работающую уже более десятилетия. И то было бы не плохо. Но не могут никак договориться...
Здравствуйте, vaa, Вы писали:
vaa>Андрей Александреску так не считает, раз один из признанных гуру C++ посвятил 10 лет развитию ДИ2 vaa>Видимо есть нюансы
Только он не разработчик, а евангелист. В свое время одним из первых понял насколько извращенно можно использовать шаблоны в плюсах, но это не значит, что так надо.
Здравствуйте, D. Mon, Вы писали:
_>>А в D наоборот, после выхода в релиз развитие замерло. Не были добавлены ни новейшие идеи из C++ (типа семантики перемещения), ни трендовые идеи индустрии (типа сопрограмм). Видимо авторы языка решили что он уже совершенен (как когда-то решили авторы IE6) и надо только его дошлифовывать и развивать инфраструктуру. DM>Файберы были, про move-семантику тоже что-то было. DM>https://dlang.org/library/std/algorithm/mutation/move.html DM>Просто в языке с GC несколько другие акценты и приоритеты.
Угу, язык с GC, в котором всё можно сделать без GC.
DM>Развитие не замерло, оно стало хаотичным. Кучу времени и сил потратили на @nogc, чтобы угодить вечно ворчащим плюсовикам. DM>Потом еще был betterC, где GC даже не линкуется, но бесплатные в рантайме штуки вроде статической интроспекции и шаблонов еще доступны. DM>Потом была эпопея с @live, попытка поиграть в Раст и добавить контроль лайфтаймов. Недоделанная, как обычно. DM>Теперь недавно Уолтер включил чуть ли не целый компилятор Си, чтобы еще легче было импортировать сишные штуки. Опять недоделанное решение, конечно же, без препроцессора. DM>Между ними еще что-то развивали, во все стороны. GC улучшили, например. DM>Какого-то единого видения и направления развития не было и нет, потому "лебедь, рак и щука" — девиз развития Ди.
Согласен. Но всё же думаю что если бы C++ не проснулся (в 2011-ом), то вся эта орда инфраструктурных программистов всё же начала сбегать на D, прогнув его при этом в сторону однозначно системного языка. Ну а так, он в итоге сохранил своё непонятное лицо, при этом потеряв шанс на взлёт...
DM>По мне так если бы язык просто был таким, что был описан в книжке Александреску, ну может с более удобной и регулярной статической интроспекцией и нормальной имплементацией компилятора, он был бы вполне прекрасен. Постоянно его растить и делать монстра типа С++ не надо.
C++ монстр не потому что развивается, а потому что так вышло. ))) Если же развиваться по нормальному, впитывая современные тенденции индустрии, то всё будет нормально. Вот добавление синтаксиса бесстековых сопрограмм никак не ухудшило ни Rust, ни Python. И в D тоже было бы вполне уместно. Это просто как популярный пример естественно, а не как что-то принципиально важное. )))
Здравствуйте, alex_public, Вы писали:
_>А в D наоборот, после выхода в релиз развитие замерло. Не были добавлены ни новейшие идеи из C++ (типа семантики перемещения), ни трендовые идеи индустрии (типа сопрограмм). Видимо авторы языка решили что он уже совершенен (как когда-то решили авторы IE6) и надо только его дошлифовывать и развивать инфраструктуру.
Развитие не замерло, оно стало хаотичным. Кучу времени и сил потратили на @nogc, чтобы угодить вечно ворчащим плюсовикам.
Потом еще был betterC, где GC даже не линкуется, но бесплатные в рантайме штуки вроде статической интроспекции и шаблонов еще доступны.
Потом была эпопея с @live, попытка поиграть в Раст и добавить контроль лайфтаймов. Недоделанная, как обычно.
Теперь недавно Уолтер включил чуть ли не целый компилятор Си, чтобы еще легче было импортировать сишные штуки. Опять недоделанное решение, конечно же, без препроцессора.
Между ними еще что-то развивали, во все стороны. GC улучшили, например.
Какого-то единого видения и направления развития не было и нет, потому "лебедь, рак и щука" — девиз развития Ди.
По мне так если бы язык просто был таким, что был описан в книжке Александреску, ну может с более удобной и регулярной статической интроспекцией и нормальной имплементацией компилятора, он был бы вполне прекрасен. Постоянно его растить и делать монстра типа С++ не надо.
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Здравствуйте, vaa, Вы писали:
vaa>>Я написал высокочастотную торговую платформу на D
SVZ>Если кратко, то: "я не использовал ничего из стандартных средств D, поэтому сделал всё быстро и хорошо". Ну как бы так себе реклама.
Мне кажется это признак хорошего ЯП, если писать и отлаживать можно без опоры на сложные инструменты.
1) Очень информативные сообщения компилятора
2) простой синтаксис не требовательный к форматированию(python, F#)
3) полное соответствие расположению модулей файловой системе(как в java).
Здравствуйте, BlackEric, Вы писали:
BE>D проиграл Rust. За ним никого нет. BE>Поэтому шанс занять нишу C++ есть только у Rust.
Мне кажется что D победил ни Rust (этот вообще ХЗ что победил там), а сначала Java, а потом Go. Наличие GC является логической отправной точкой для такого сравнения.
Здравствуйте, kaa.python, Вы писали:
KP>Здравствуйте, BlackEric, Вы писали:
BE>>D проиграл Rust. За ним никого нет. BE>>Поэтому шанс занять нишу C++ есть только у Rust.
KP>Мне кажется что D победил ни Rust (этот вообще ХЗ что победил там), а сначала Java, а потом Go. Наличие GC является логической отправной точкой для такого сравнения.
На hh.ru по D вакансий нет вообще. Это как бы показатель.
Хотя язык не плохой, да.
Здравствуйте, Stanislav V. Zudin, Вы писали:
vaa>>Вот тут немного другой перевод https://habr.com/ru/post/596387/ SVZ>Этот перевод гораздо лучше.
А почему просто не прочитать оригинал?
SVZ>Что же вы такое городите, что сообщения компилятора становятся неинформативными?
Зависит от компилятора. Некоторые писаны человеконенавистниками.
Например ICC ещё 10+ лет назад выдавал куда более короткие и информативные сообщения чем вижуаловский компилер.
vaa>>2) простой синтаксис не требовательный к форматированию(python, F#) SVZ>По сравнению с современным С++ синтаксис, действительно, простой.
Если смотреть не на совершенно укуренный дизайн STL а на сам язык то в С++ достаточно простой синтаксис и достаточно выразительных средств чтоб писать код внятно.
Просто сравните код на Rust и С++ они практически одинаково не человеко-читаемы.
В отличии от Ди код которого почти также прост как питон.
Но при этом способен заменить любой из 3-х монстров(C/C++/Rust).
Считаю что наоборот сейчас ди выходит на уверенное развитие.
у него есть все то же самое что и у раста, но без этого жуткого синтаксиса.
Rust может нравится либо C++ т.к. все же удобнее тулинг, либо тому кто еще ни пробовал си(без плюсов)/ди|c#.
Кстати в vala вроде владение ссылками реализовано аналогично Rust.
Здравствуйте, Marty, Вы писали:
M>Ну вот если бы он был бы под JVM — то имхо было бы интересно. Мне джава совсем не зашла, хотя я её смотрел в последний раз 8ой версии — 11я может и получше. C++ (в то время 0x03, 0x11 тока-тока взлетал, и я его не трогал) был горозда удобнее как язык. Котлин — потыкал немножко, но тоже как-то не зашло, тем более уже начал 11/14/17 использовать; хотя он сильно отличается и от джавы и от плюсов — он мне понравился больше джавы. А вот почти как C++, с возможностью писать для большой джавы и для андроидов — это было бы интересно
Если любишь ломать голову над системами типов, хитрыми фичами компилятора и т.д. — Scala то что тебе надо. Как по мне, то на её фоне даже C++ простой язык, но в целом концепции там очень интересные.
Здравствуйте, CreatorCray, Вы писали:
CC> и зачастую не следует смотреть на следующую в этом же файле пока не починил первую.
Когда-то давно, когда деревья были большими, а компиляторы тупыми, они умели выдавать ровно 1 ошибку и сразу падать. И люди мечтали, что компиляторы будут выдавать все возможные ошибки сразу.
Govno Compiler Collection повернул время вспять и люди больше не хотят видеть больше одной ошибки.
И да, когда у тебя консоль, то листать лог, выискивая начало — это капец.
Здравствуйте, Слава, Вы писали:
С>Мы заменили авокадо на картошку, говядину на сосиски по акции, а соус песто — на майонез, но в целом получилось хорошо.
Как бы тем, кто пробовал и Rust, и D хотя бы на уровне HelloWorld-а, очевидно, что ваша аналогия в корне не верна, а вы вынуждены прибегать к кривым аналогиям вовсе не от хорошей жизни.
Здравствуйте, Слава, Вы писали:
CC>>То, что от него пропёрло Александреску как раз довольно таки плохой знак.
С>На КЫВТе остро не хватает Царя Сишки с ЛОРа.
Ну тот-то совсем поехавший, грешно же смеяться над больными.
Здравствуйте, kaa.python, Вы писали:
KP>Зелёные потоки — это абстракция над обычными потоками ОС, которые позволяют использовать нескольким зелёным потокам один реальный поток ОС. Концепция очень хорошо прижилась и является более чем современной и активно используемой. Вернёмся к "отсталость и абсурд", что с ними не так?
Угу. Сначала придумываем многозадачность, потом делаем костыли чтобы она хоть как-то работала "подожди, диск доформатирую", наконец, делаем доступные многоядерные процессоры — казалось бы, вот оно счастье, и тут на новый, зеленый круг
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Sinclair, Вы писали:
S>Вопрос не про цвет потоков, а про то, используете ли вы stackful coroutines или stackless. S>Если посмотреть с этой точки зрения — вот вам нахрена стек в вашей задаче?
Да мне вообще всё равно что там, пока оно мало памяти ест (это так и для Го и для Эрланга) и не требует код соплями async/await обмазывать. А внутри потоки хоть дрочить в присядку могут, я не возражаю.
всегда можно найти какую то синтетическую конструкцию которая лучше реализована в том или другом языке
вон хаскель постоянно противоставляют по лаконичности и краткости
а толку ?
но код в расте дует очевидно его концепция
из за которой все обрастает боксами рефцелами и прочей мишурой на ровном месте
итог 20 строчек раста
заменяются двумя на С++
а огромный проект на расте
двумя файликами на С++
а когда довезут паттерн мачинг в С++
так вообще раст уйдет за D
Здравствуйте, vaa, Вы писали:
CC>>Так что опять таки непонятно нафига нужен ди если уже есть С++ vaa>Так это одна из киллер-фич — плюсовикам не нужно ломать мозг.
Дык плюсовикам он и вовсе не впёрся, ибо не предлагает ничего такого чтобы оправдать хотя бы гемор с нестабильным компилером.
Здравствуйте, Serginio1, Вы писали: S>Я так понимаю, что зеленые потоки это файберы https://habr.com/ru/post/185706/ то бишь стекфул ?
Ага. S>Ну в .Net для рекурсивных обхода взяли yield и его же по сути для async await вместо файберов. S>Возможно, что бы упростить работу сборщика мусора, что бы еще не держать информацию о стеке файбера
В основном — по соображениям эффективности. Я тут уже давал ссылку на статью с подробным исследованием вопроса.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, vaa, Вы писали:
SVZ>>Если кратко, то: "я не использовал ничего из стандартных средств D, поэтому сделал всё быстро и хорошо". Ну как бы так себе реклама.
vaa>Вот тут немного другой перевод https://habr.com/ru/post/596387/
Этот перевод гораздо лучше.
vaa>
vaa>Не использовались ни IDE, ни отладчик.
vaa>Мне кажется это признак хорошего ЯП, если писать и отлаживать можно без опоры на сложные инструменты.
Но тут надо делать поправку на характер данных и на проект.
Там идёт большой объем (предположительно правильных) данных, на которых отладчик совсем не помощник.
Скажем, при работе с геометрией логи совсем не помогают. Нужен собственный графический отладчик, который еще надо написать
vaa>1) Очень информативные сообщения компилятора
Что же вы такое городите, что сообщения компилятора становятся неинформативными?
vaa>2) простой синтаксис не требовательный к форматированию(python, F#)
По сравнению с современным С++ синтаксис, действительно, простой.
vaa>3) полное соответствие расположению модулей файловой системе(как в java).
Ну это так себе достижение.
У D были другие плюшки. Смутно припоминаю описание контрактов прямо в коде, что-то для юнит-тестирования. Тот же GC может где-то пригодиться.
Давно на него посматриваю, но устраивать в проекте зоопарк из языков пока не готов.
Но статьи в стиле "как я рожал ёжиков" с удовольствием читаю.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, vaa, Вы писали:
vaa>2) простой синтаксис не требовательный к форматированию(python, F#)
В смысле как в питине или не так как в питоне?
Если второе, то это минус. Единообразие форматирования и стиля это ОГРОМНЫЙ плюс.
Здравствуйте, kaa.python, Вы писали:
KP>Мне кажется что D победил ни Rust (этот вообще ХЗ что победил там), а сначала Java, а потом Go. Наличие GC является логической отправной точкой для такого сравнения.
Мне кажется, проблема D заключается в том, что у него никогда не было сколь-либо многочисленной community.
Преимуществом Go является то, что именно в построение community и экосистемы было вложено чуть ли не больше сил, чем в сам язык.
Здравствуйте, Serginio1, Вы писали:
S> Угу. Все зависит от сложности алгоритма. Не говоря уж о всяких ООП где переопределение виртуальных методов или методов интерфейсов так сразу и не увидишь. S>Без отладчика ну никак. Ну и интеллисенс, рефакторинг это ооочень удобно!!
Здравствуйте, T4r4sB, Вы писали:
TB>В случае с Govno Compiler Collection много-то и не надо. TB>https://rextester.com/XTFLG76850
Не ну гнусь всегда отличалась, но на ошибки всегда надо смотреть по порядку, и зачастую не следует смотреть на следующую в этом же файле пока не починил первую.
Так что тут всё ещё нормально.
TB>https://rextester.com/HSLZ45412
Тут типичный гнусный линкер, да.
Нормальный линкер (вижуалка) говорит внятно:
Здравствуйте, CreatorCray, Вы писали: CC>Так что опять таки непонятно нафига нужен ди если уже есть С++
Так это одна из киллер-фич — плюсовикам не нужно ломать мозг.
Здравствуйте, CreatorCray, Вы писали:
CC>Дык плюсовикам он и вовсе не впёрся, ибо не предлагает ничего такого чтобы оправдать хотя бы гемор с нестабильным компилером.
Андрей Александреску так не считает, раз один из признанных гуру C++ посвятил 10 лет развитию ДИ2
Видимо есть нюансы
Здравствуйте, NGPraxis, Вы писали:
NGP>Я ни тот ни другой язык не смотрел. Там термином "Зелёный поток" названо что-то нестандартное? Не то же самое, что на допотопных платформах называлось симуляцией многопоточности?
Зелёные потоки — это абстракция над обычными потоками ОС, которые позволяют использовать нескольким зелёным потокам один реальный поток ОС. Концепция очень хорошо прижилась и является более чем современной и активно используемой. Вернёмся к "отсталость и абсурд", что с ними не так?
Здравствуйте, Kolesiki, Вы писали:
K>ИНформативности и полезности у этого чтива — ноль, но радует то, что люди не сходят с ума на С++, а используют мощных преемников.
Если бы я видел только это одно высказывание, я бы ломал голову — о каких приеемниках речь: Java? C#? Может Go?
Но подумать о давно почившем в бозе D — скорее всего не пришло бы на ум.
CC>И? Этот персонаж ещё за свой STL должен извиниться.
Всего 4 буквы достаточно поменять в слове "хлеб", чтобы получилось "пиво". Александреску перепутать со Степановым хоть и сложнее, но нет в этом мире ничего невозможного
CC>Признанный настолько что даже есть такая болезнь третьего курса меда новичков, под названием "укус Александреску", когда поцыент лютобешенно пишет всё на темплейтах где всё всем параметризуется.
Сам Александреску хвост-те когда уже отошёл от "синдрома имени себя", и даже публично признавал бесперспективность дальнейшего упарывания шаблонной магией C++, после перехода в лагерь куда более человеко-читаемого D.
CC>Наблюдал течение такой болезни на расстоянии вытянутой руки, благо тогда винда была 32 бита и у компилера кончилась память раньше чем собрался hello world проект-попытка доказать "всем вам" какая это "офигенная тема". Так что пацЫент таки сравнительно быстро пошёл на поправку.
А вот многие укушенные так и не оклемались, продолжая клепать всё более и более монструозных франкенштейнов, наподобие mpl и hana. Где уже не просто "всё всем параметризуется", а происходит программирование времени компиляции на шаблонах.
Здравствуйте, alex_public, Вы писали:
_>Ну и для сравнения можно посмотреть на ситуацию с Rust. Rust в 2020-ом занимал наверное в точности такую же позицию относительно C++, как и D в 2010-ом. Но он показал правильное отношение к развитию языка (к примеру в первой версии языка (2015) сопрограмм не было, а в 2019-ом уже появились). И в итоге сейчас на него реально перебегают толпами...
Только правильное отношение — это раскрутка Mozilla и Google.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
_>>Ну и для сравнения можно посмотреть на ситуацию с Rust. Rust в 2020-ом занимал наверное в точности такую же позицию относительно C++, как и D в 2010-ом. Но он показал правильное отношение к развитию языка (к примеру в первой версии языка (2015) сопрограмм не было, а в 2019-ом уже появились). И в итоге сейчас на него реально перебегают толпами... lpd>Только правильное отношение — это раскрутка Mozilla и Google.
Раскрутка от Mozilla безусловно присутствовала для Rust. Но всё же в данной области качество продукта намного важнее раскрутки. ) Для сравнения можешь посмотреть например на ситуацию с популярностью языка Dart (он совсем из другой области, но зато "раскручиваемый" Гуглом).
Здравствуйте, kaa.python, Вы писали:
KP>А если я просто хочу обработать много входящих соединений с автоматической балансировкой между реальными потоками, то я всю остальную машинерию буду ручками писать, да?
Если вы хотите обрабатывать много входящих соединений с автоматической балансировкой между реальными потоками, то вам зелёные потоки противопоказаны. Используйте бесстековые корутины aka async/await.
KP>Честно не читал. Это же С++-ники, даже больше коммитет С++-ников! У них часто всё через жопу, "потому что эффективно и надо охватить все вот 100500 потенциальных случаев". И пока они там занимаются сексом с корутинами (о них ещё в 2016(2017?) на CppCon от Гора слышал как о прорыве) и никак не изродят ничего годного для промышленного использования, реализации зелёных потоков в Го и Эрланге уже десятилетия шикарно решают реальные, а не гипотетически проблемы.
При чём тут C++-ники? Это ребята сели и честно рассмотрели всю историю зелёных потоков от первых реализаций до Go и Эрланга. Прочитайте, там не так много текста.
KP>Посему я полностью согласен — с корутинами можно решить кучу проблем которые невозможно решить на зелёных потоках. Но зелёные потоки уже сейчас легко и изящно решают вообще все проблемы что у меня есть, а корутины в современном C++ даже близко не подобрались к такому уровню что бы решить тоже самое с теми же затратим временных ресурсов.
Я не знаю, что там у них в С++. Наверное, опять закат солнца вручную. Все остальные уже просто пишут async код, и о зелёных потоках даже не задумываются.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Вопрос не про цвет потоков, а про то, используете ли вы stackful coroutines или stackless. S>Если посмотреть с этой точки зрения — вот вам нахрена стек в вашей задаче?
господин большой теоретик?))
можете назвать основной плюс и минус стекфул и стеклесс
и сколько высоконагруженных сетевых приложений на первых и вторых вы уже написали
Здравствуйте, Sinclair, Вы писали:
S>Тогда вас устроят и обычные настоящие потоки. Чем плохо-то?
Обычные настоящие потоки хороши пока их количество укладывается в тысячу штук (хотя лучше бы в сотню). На трех-четырех десятках тысяч обычных потоков можно уже поиметь неприятные приключения.
Тогда как зеленые потоки (stackful coroutines) позволяют писать код в стиле обычных тредов, но не иметь этих самых проблем при одновременной работе нескольких десятков тысяч зеленых потоков.
Здравствуйте, Sinclair, Вы писали:
S>>Тогда как зеленые потоки (stackful coroutines) позволяют писать код в стиле обычных тредов, но не иметь этих самых проблем при одновременной работе нескольких десятков тысяч зеленых потоков. S>Ну, только при этом нужно использовать особенные примитивы синхронизации,
Конечно. Только вот если у вас двум независимым и параллельно работающим stackless coroutines потребуется доступ к одним и тем же разделяемым данным, то и им так же нужно будет использовать особенные примитивы синхронизации.
S>и надо всё обмазывать yield в отличие от обычных тредов.
Не обязательно все. Передача управления может выполняться неявно в специальных функциях, предназначенных для использования в зеленых потоках (типа lock, release, send, receive, listen, accept и т.д.)
S>А иначе на трёх-четырёх десятках тысяч зелёных потоков всё станет плохо.
С чего бы это? И почему этого не произойдет на 30-40K одновременно запущенных stackless coroutines?
_>>>>Вот в обратную сторону (то, что автоматизировано в Rust и хрен сделаешь в C++) я могу легко привести пример...
fk0>>> Приведи.
KP>Такое же в C++ очевидно что не сделать настолько же коротко, хотя решения с Cereal или boost.archive будут не так что бы критично длиннее.
Будет критично длиннее. Потому что ты похоже не понял о чём здесь речь или просто не знаешь Rust.
В данном примере речь шла не о наличие какой-то библиотеки сериализации (такого добра в любых языках полно), а о библиотеке Serde, в которой лежат макросы по сути дела реализующие статическую интроспекцию для произвольных типов языка. А уже потом подключаются различные библиотеки сериализации, которых в инфраструктуре Rust'а десятки (и все они умеют использовать данные Serde).
Если говорить про C++, то единственным отдалённо похожим решением является BOOST_FUSION_ADAPT_STRUCT. Надеюсь тебе не надо рассказывать про всю уродливость этого решения? Ну и естественно и речи нет о том, чтобы все библиотеки сериализации C++ умели в BOOST_FUSION_ADAPT_STRUCT и считали это стандартом. Что впрочем логично как раз из-за уродливости.
KP>В то же время исходя из моего опыта этот пример крутой фичи с серриализаций довольно бесмысленный. Ну можешь ты что-то запаковать и распаковать в Rust, а дальше что?
Тебе реально надо объяснять в чём разница когда мы пишем код руками или когда его пишет за нас компилятор?
Особенно забавен этот твой вопрос на фоне восторженного упоминания Protobuf, который делает такую же (правда только в один убогий формат) автоматизацию, но сторонними средствами и с помощью отдельного "языка программирования".
KP>Это можно как-то так же бесшовно распаковать в Python или в C++? Потому как если нет, то фича эта прикольная, но в проде окажется Protobuf
Protobuf у нас на проде точно никогда не окажется в силу его крайне низкой эффективности (см. например табличку здесь https://blog.logrocket.com/rust-serialization-whats-ready-for-production-today/). Благо сейчас нет никаких проблем писать код со всех сторон (и на сервере и на клиенте, в том числе в браузере) на Rust.
Здравствуйте, so5team, Вы писали:
S>Зато сделать это проще, чем расставлять повсюду co_await, co_return и co_yield. Уж с co_ интрузивнее дальше некуда.
Ну, то есть для начала надо сделать fiber-аналоги основных процедур, а уж потом оно само.
S>Не говоря уже про то, что ментальная модель кода на простых потоках (нативных или зеленых) сильно проще, чем с co_await/co_return, т.к. с co_ далеко не сразу очевидно кто на ком стоял, особенно если реализации co_await умеют перекидывать короутины с одного контекста на другой.
co_await и co_return — это как я понимаю как раз артефакты тех местностей, куда не завезли языковых реализаций. Потому, что там, где завезли — там async/await, и код вполне себе выглядит и работает.
S>И при чем здесь память? Если к stackfull coroutine привязано 10K вместо 1K у stackless, это же не значит, что в активный working set будет входить все эти 10K.
Ну так чудес-то не бывает. Тем более, что 1к для stackless — это явно перебор. Там обычно десятки байт.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_>>Обсуждаемая статья — это отголосок известной попытки MS продавить свою реализацию сопрограмм в комитете C++. ))) И автор этой статьи был так сказать главным идеологом всего этого. Кстати, в итоге решение было довольно забавным. Решили принять в стандарт бесстековые сопрограммы (с логичной аргументаций что стекфул хорошо себя чувствуют и без стандарта, в виде библиотек), но не в реализации MS. ))) S>Это интересно. А чем реализация MS так отличалась от того, что попало в 20й стандарт?
Оно кстати ещё в 17-ом было, в виде TS, так что в некоторых компиляторах уже работало (с нужной опцией).
Про реализацию детали уже не помню конечно же. Но в целом изначальная версия от MS была такая совсем простенькая, в стиле .net (ну и кстати помнится там приставки co_ не было, хотя это конечно же не важно). А в итоге в стандарте имеем классического обобщённого монстрика, кастомизируемого в куче точек под все возможные ситуации. )))
_>>Разве что ты там вызовешь внутри какую-то внешнюю функцию, при этом не являющуюся сопрограммой и при этом требующую мегабайт стека. Но это опять же высосанный из пальца сценарий: на практике (а единственное место где вообще актуальна эта тема — это нагруженные сервисы) мы вполне себе представляем как выглядит обычный код таких сопрограмм. S>Почему внешнюю? Нужно тащить весь стек. Смотрите: авторы Go были вынуждены отказаться от сегментированного стека из-за просада производительности. При этом дефолтный размер стека горутины у них был 8 килобайт. S>Это всё ещё примерно в сто раз больше, чем размер замыкания для типичной сопрограммы.
Я про проблемы Go не в курсе. ) Хотя могу предположить, что там специфика заключается в том, что там это основной способ реализации параллелизма. Т.е. оно должно нормально работать во всех случаях. В то время как в том же C++ — это один из многих способов, используемый в специфическом случае (обычно высоконагруженный сервис и т.п.). С весьма характерным профилем кода.
_>>Эм, основная проблема системных потоков как раз не в потребление памяти, а в том что при переключение между ними происходит прыжок в нулевое кольцо. В итоге на переключение может уходить времени больше чем на сами "вычисления". S>Ну а с зёлёными потоками у нас возникает проблема неравномерной загрузки, т.к. не всегда можно заранее предсказать объём работы в процедуре. Перемещать зелёные потоки между потоками ОС не осилил никто, несмотря на многолетние усилия.
Чтобы было сразу понятно. Лично я для задач типа высоконагруженных сервисов использую как раз бесстековые сопрограммы (в реализации Rust'а) с рантаймом tokio. Т.е. я тут не занимаюсь защитой зелёных потоков и т.п. (хотя для стековых сопрограмм на мой взгляд опять же есть своё место под солнцем, про которое я тоже писал). Мои комментарии относились в основном к сомнительной аргументации (расход памяти на самом деле там не будет решать ничего) подобного выбора и сомнительных списков плюсов и минусов (пропущены важнейшие различия, а всякая мелочь подчёркивалась как главное).
Здравствуйте, alex_public, Вы писали:
_>Тебе реально надо объяснять в чём разница когда мы пишем код руками или когда его пишет за нас компилятор?
_>Особенно забавен этот твой вопрос на фоне восторженного упоминания Protobuf, который делает такую же (правда только в один убогий формат) автоматизацию, но сторонними средствами и с помощью отдельного "языка программирования".
Не менее забавно то, что ты пропустил мой вопрос про версионирование. Как эта фича которой ты так восхищаешься решает вопрос с версионированием? Из того что я вижу — никак, а это очень сильно усложняет развёртывание крупной системы.
И да, отдельный язык описания структур идея хорошая, т.к. он тебя отвязывает от какого-то реального языка. То что у вас сейчас всё на Расте вообще ни разу не аргумент, если ты только что-то короткоживущее не пишешь, причем маленькой командой.
_>Protobuf у нас на проде точно никогда не окажется в силу его крайне низкой эффективности (см. например табличку здесь https://blog.logrocket.com/rust-serialization-whats-ready-for-production-today/). Благо сейчас нет никаких проблем писать код со всех сторон (и на сервере и на клиенте, в том числе в браузере) на Rust.
Какого размера у вас R&D? Хотя бы сотня человек есть? Подход который тебя радует не масштабируется
Здравствуйте, kaa.python, Вы писали:
_>>Тебе реально надо объяснять в чём разница когда мы пишем код руками или когда его пишет за нас компилятор? _>>Особенно забавен этот твой вопрос на фоне восторженного упоминания Protobuf, который делает такую же (правда только в один убогий формат) автоматизацию, но сторонними средствами и с помощью отдельного "языка программирования". KP>Не менее забавно то, что ты пропустил мой вопрос про версионирование. Как эта фича которой ты так восхищаешься решает вопрос с версионированием? Из того что я вижу — никак, а это очень сильно усложняет развёртывание крупной системы.
Естественно никак, потому что версионирование ортогонально вопросу автоматической генерации кода. Потому что оно очевидно не должно зависеть от формата данных (скажем мы ещё те же данные будем в виде json передавать — и где там версионированние будет?).
KP>И да, отдельный язык описания структур идея хорошая, т.к. он тебя отвязывает от какого-то реального языка. То что у вас сейчас всё на Расте вообще ни разу не аргумент, если ты только что-то короткоживущее не пишешь, причем маленькой командой.
Отдельный язык или нет — это на самом деле не очень принципиально. Т.е. конечно же удобнее как в Rust с одним языком только иметь дело, но и с Proto в принципе не сложно. При условии что он позволял бы генерировать код сериализации во все нужные форматы (JSON, MessagePack, XML, и любые другие, подключаемые как отдельные библиотеки). А так, с одним сомнительным форматом — только вредная потеря времени.
Да, и по поводу "привязки к реальному языку". Например если взять в качестве формата MessagePack (https://msgpack.org/ — намного эффективнее Protobuf), то можно легко увидеть, что там есть поддержка более 50 языков программирования. Но если в C++ тебе придётся описывать формат руками в коде (https://github.com/msgpack/msgpack-c/tree/cpp_master), то соответствующая библиотека для Rust умеет работать с Serde и соответственно просто сама берёт все нужные данные из структуры Rust. Теперь надеюсь понимаешь о чём здесь шла речь?
_>>Protobuf у нас на проде точно никогда не окажется в силу его крайне низкой эффективности (см. например табличку здесь https://blog.logrocket.com/rust-serialization-whats-ready-for-production-today/). Благо сейчас нет никаких проблем писать код со всех сторон (и на сервере и на клиенте, в том числе в браузере) на Rust. KP>Какого размера у вас R&D? Хотя бы сотня человек есть? Подход который тебя радует не масштабируется
Т.е. это ты сейчас пытаешься обосновать увеличение трафика сервера в 2-4 раза на пустом месте (от использование Protobuf вместо нормальных форматов) с помощью рассуждений о размере команды? )))
Здравствуйте, alex_public, Вы писали: _>В случае необходимости в версионирование на уровне формата данных (обычно это происходит, когда протокол общения написан не нами) второй вариант кажется заметно лучше, т.к. является не зависимым от самого формата данных (одно и тоже поле version может быть и в JSON и в MessagePac и в XML и где угодно).
Ну так проблема в некотром роде в том, как определяется порядок полей. Например, XML схема — штука жёсткая, в ней порядок потомков узла строго фиксирован.
Поэтому если мы написали, что тег <version> первым идёт в теге <message>, то так оно и будет — и мы можем на это рассчитывать. И любой способ чтения XML — хоть через DOM, хоть sax, хоть XPath — корректно вынут версию из документа, в который сложили дополнительный контент.
А в расте как-то гарантируется порядок обхода полей структуры?
Не получится случайно так, что в версии 2 на том месте, где были байты поля "версия", оказались байты поля "длина текста", а версия уехала в хвост?
Ведь тогда читатель, полагающийся на фиксированное расположение байтов, прочтёт мусор.
_>Но помимо этого возможно версионирование на уровне протокола (когда при происходит договорённость о версии в момент соединения). Это позволяет получить все плюсы явного версионирования, избежав при этом оверхеда на передачу и проверку версии в каждом сообщение.
Для этого должно быть версионирование на уровне протокола.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Что и следовало ожидать — удаление поля из середины или изменения порядка полей ломает всю сериализацию
_>Если протокол свой, то это делается элементарно.
При использовании сторонних генераторов, пусть будет не Protobuf с которым у тебя что-то не срослась, а что-то более быстрое и компактнее, эта проблема решается из коробки. А для большого проекта над которым работают разные команды это серьёзная проблема. Я понимаю что для той примитивщины над которой ты работаешь это не критично, но у взрослых дядей оно так
вроде бы ему понравились возможности функционального программирования ДИ и скорость превосходная скорость работы результирующего кода не уступавшую плюсам.
А тогда, если нет разницы зачем платить больше?
Здравствуйте, Skorodum, Вы писали:
S>Здравствуйте, vaa, Вы писали:
vaa>>2) простой синтаксис не требовательный к форматированию(python, F#) S>В смысле как в питине или не так как в питоне? S>Если второе, то это минус. Единообразие форматирования и стиля это ОГРОМНЫЙ плюс.
плюс то плюс, но вот F# требует отступы на основе пробелов, если в редакторе настройки не поменять то придется исправлять, при этом ide(vs, code) до сих пор на сложных участках
когда списки содержат сложные выражения тупит. ну а в ди за счет использования {}
можно хоть как все равно скомпилится
void f() {
}
void f()
{
}
void f() {}
ди появился когда еще это не считалось чем-то важным, вероятно
но да коде-стайл желательно иметь единый. сейчас вроде развивается https://github.com/dlang-community/dfmt
vaa>Мне кажется это признак хорошего ЯП, если писать и отлаживать можно без опоры на сложные инструменты.
Угу. Все зависит от сложности алгоритма. Не говоря уж о всяких ООП где переопределение виртуальных методов или методов интерфейсов так сразу и не увидишь.
Без отладчика ну никак. Ну и интеллисенс, рефакторинг это ооочень удобно!!
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, kaa.python, Вы писали:
NGP>>Зелёные потоки это ж отсталось и абсурд. Почему ты их в плюс выставляешь?
KP>Я боюсь что не могу понять твоего утверждения. А ты не мог бы прояснить в чем зелёные потоки из Go или BEAM это отсталость и абсурд?
Я ни тот ни другой язык не смотрел. Там термином "Зелёный поток" названо что-то нестандартное? Не то же самое, что на допотопных платформах называлось симуляцией многопоточности?
Здравствуйте, vaa, Вы писали:
CC>>Так что опять таки непонятно нафига нужен ди если уже есть С++ vaa>Так это одна из киллер-фич — плюсовикам не нужно ломать мозг.
Ну вот если бы он был бы под JVM — то имхо было бы интересно. Мне джава совсем не зашла, хотя я её смотрел в последний раз 8ой версии — 11я может и получше. C++ (в то время 0x03, 0x11 тока-тока взлетал, и я его не трогал) был горозда удобнее как язык. Котлин — потыкал немножко, но тоже как-то не зашло, тем более уже начал 11/14/17 использовать; хотя он сильно отличается и от джавы и от плюсов — он мне понравился больше джавы. А вот почти как C++, с возможностью писать для большой джавы и для андроидов — это было бы интересно
Здравствуйте, T4r4sB, Вы писали:
TB>И да, когда у тебя консоль, то листать лог, выискивая начало — это капец.
У меня чит: я ищу первый instance подстроки "error:"
Ну и консоль перед каждым разом надо очищать, да.
Каждый такой раз скучаю по классической вижуалке (последней вменяемой — 2008й, а не по тому стрёмному УГ что щас выпускают)
Благо свои личные проекты пишу в ней и там просто расслабуха: сказало ёк — жмёшь F4 и сразу попадаешь в проблемное место в коде
Здравствуйте, vaa, Вы писали:
vaa>Андрей Александреску так не считает
И? Этот персонаж ещё за свой STL должен извиниться.
Стиль сего персонажа это как раз тот самый ужас-ужас, про который нам тут рассказывают те, кто на промышленном С++ толком не пишет.
vaa> раз один из признанных гуру C++ посвятил 10 лет развитию ДИ2
Признанный настолько что даже есть такая болезнь третьего курса меда новичков, под названием "укус Александреску", когда поцыент лютобешенно пишет всё на темплейтах где всё всем параметризуется.
Наблюдал течение такой болезни на расстоянии вытянутой руки, благо тогда винда была 32 бита и у компилера кончилась память раньше чем собрался hello world проект-попытка доказать "всем вам" какая это "офигенная тема". Так что пацЫент таки сравнительно быстро пошёл на поправку.
vaa>Видимо есть нюансы
"Нюансы они разные бывают, Петька" (С)
То, что от него пропёрло Александреску как раз довольно таки плохой знак.
Здравствуйте, so5team, Вы писали:
S>Ахринеть не встать. Там же все 1-в-1, только форма буковок чутка отличается. Замените в Rust-овом варианте первое guess на line, последний match на обычный if, а в D-варианте запишите try-catch не в одну строку и вы получите практически двух близнецов-братьев.
Мы заменили авокадо на картошку, говядину на сосиски по акции, а соус песто — на майонез, но в целом получилось хорошо.
Здравствуйте, T4r4sB, Вы писали:
TB>Он тебе не поможет вот тут: https://rextester.com/VMF62727
Я к счастью гнусью не пользуюсь, у нас clang а личные проекты вообще пишу под ICC — там всё хорошо.
TB>Найди в бесполезном тупорылом высере этого недокомпилятора хоть одно упоминание строки 12.
I feel you pain
Здравствуйте, mrTwister, Вы писали:
T>Здравствуйте, vaa, Вы писали:
vaa>>Мне кажется это признак хорошего ЯП, если писать и отлаживать можно без опоры на сложные инструменты.
T>Или плохих инструментов
В ди с этим норм. vs, code полный фарш(форматирование/отладка/навигация/интеллект/автокомплит/кодчекер).
TB>Он тебе не поможет вот тут: https://rextester.com/VMF62727 TB>Ошибка в строке 12. Найди в бесполезном тупорылом высере этого недокомпилятора хоть одно упоминание строки 12.
хаха, у меня хромиум завис после нескольких попыток поискать там Ctrl+F-ом.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, alex_public, Вы писали:
_> Но всё же в данной области качество продукта намного важнее раскрутки. )
)))
Впрочем да, Rust, имеет фичи, которые некоторые люди со склонностью к компилерству относят к киллер-. Его либо любят, либо ненавидят(когда попадается).
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, Pzz, Вы писали:
Pzz>Мне кажется, проблема D заключается в том, что у него никогда не было сколь-либо многочисленной community.
Верно, язык был пущен в свободное плавание.
А как ему там плавать, если практически весь платформенный код написан на Си? ))
С++ в этом смысле паразитирует на популярности Си, т.е. если бы D мог точно так же паразитировать, имея непосредственный доступ к заголовкам Си, история языка могла быть другой.
Но это сложно хотя бы из-за строкового типа, который в D не null-terminated (что есть правильно, это отдельная тема для обсуждения).
Pzz>Преимуществом Go является то, что именно в построение community и экосистемы было вложено чуть ли не больше сил, чем в сам язык.
Одно без другого не работает, поэтому выхлоп всё-равно слабоват. ))
Go в основном вытесняет/подменяет теряющие популярность многочисленные скриптовые и/или слаботипизированные языки, типа тех же Перла и Эрланга.
Мейнстримовые не вытесняет толком...
Прикрутили бы нормальные генерики лет 10 назад, картинка могла бы быть несколько иной.
Сравнить с C#, который на третий год после первого официального релиза стал вполне зрелым ЯП.
Java стала зрелой примерно на 4-5-й год (для своего времени) и т.д.
Т.е. де-факто Golang продолжает кучу лет обитать в статусе "сырого" языка, поэтому "кривая роста" слабовата.
Думаю, в недрах Гугла победит скорее Dart. Язык более молодой, но намного более покрытый фичами и библиотеками, Golang такого и не снилось.
Опять же, Dart выкатили программеры из Гугла, т.е. им собственный гугловый Golang не показался удовлетворительным.
Здравствуйте, ksandro, Вы писали:
K>Другой вопрос, почему-же он все-таки не взлетел... язык, я так понимаю, хороший.
В базе слабо совместим с Си-подобными АПИ.
Т.е. вслух утверждается обратное, а на деле — фигвам.
Там натуральная пропасть как идеологического плана в деле построения АПИ, так и банальная "механическая" пропасть — невозможность прямого импорта заголовочных файлов Си.
(да, есть кое-какие проекты-обёртки, которые автоматизируют перевод объявлений Си в D, но они справляются не со всеми ситуациями)
K>На этот вопрос у меня ответа нет... Но, видимо, уже давно мир так устроен, что язык не может взлететь, если за ним не стоит какая-то серьезная коммерческая организация...
ИМХО, основная причина — проклятое legacy языка Си.
Когда 640kB было достаточно для любой программы, идеология Си-подобного АПИ была уместной, но сегодня слишком устарела и слишком небезопасна.
От одного лишь факта передачи строкового NULL-terminated типа через простой указатель меня плющит последние лет ~25. ))
Но возможность передавать структуры по значению и возвращать в виде результата была добавлена в стандарт ANSI C относительно недавно, т.е. слишком поздно.
Всё уже произошло и теперь не очень понятно, что со всем этим делать...
Здравствуйте, lpd, Вы писали:
lpd>))) lpd>Впрочем да, Rust, имеет фичи, которые некоторые люди со склонностью к компилерству относят к киллер-. Его либо любят, либо ненавидят(когда попадается).
Ну, вообще Mozilla не такая уж богатая организация. И я бы не сказал, что раст как-то очень уж серьезно раскручивали.
ИМХО создатели всех языков — убийц С++, считали главной проблемой С++ его сложность, и решать ее предлагали единственным споcобом: добавлением сборщика мусора.
Раст, единственный язык, который сделал попытку пойти другим путем, создатели Раста, единственные, кто изначально не ставил задачу сделать язык максимально простым.
Здравствуйте, ути-пути, Вы писали:
УП>Угу. Сначала придумываем многозадачность, потом делаем костыли чтобы она хоть как-то работала "подожди, диск доформатирую", наконец, делаем доступные многоядерные процессоры — казалось бы, вот оно счастье, и тут на новый, зеленый круг
Реальный поток стоит довольно дорого в любой современной ОС общего назначения (возможно есть какие-то специальные ОС с дешёвыми потоками, но я о них не знаю). Ты не можешь себе позволить создать 1КК потоков, даже 1К уже очень высокая нагрузка на систему. При этом в тех же серверных приложениях поток обычно просто висит и ждёт I/O, т.е. если он не зелёный, а реальный — это крайне дорого и сильно сокращает возможности держать нагрузку.
Что бы из бесстековых любых корутин получить зелёные потоки, тебе ещё надо добавить пул реальных потоков сбоку, а потом весь свой код поверх этого пула потоков обмазывать async/await. Если очень хорошо всё распланировать, то, скорее всего, выйдет быстрее чем решение на зелёных потоках где за тебя раскидыванием задач по реальным потокам занимается универсальный диспетчер и контролировать пул потоков ты обычно тоже не можешь. Но вот в общем случае будет дольше писать, сложнее поддерживать и куда как кривее, т.к. хорошо распланировать у всех вряд ли выйдет.
Здравствуйте, vdimas, Вы писали:
V>Думаю, в недрах Гугла победит скорее Dart. Язык более молодой, но намного более покрытый фичами и библиотеками, Golang такого и не снилось. V>Опять же, Dart выкатили программеры из Гугла, т.е. им собственный гугловый Golang не показался удовлетворительным.
Я, возможно, что-то упускаю, но если зайти на https://dart.dev/, то первое что бросается в глаза — Дарт для мобильных приложений с UI. Что бы писать на Го мобильное приложение с UI надо быть слабо адекватным человеком, либо обладать огромными запасами лишнего времени. Насколько я могу судить, Дарт и Го вообще в разных сегментах и никакой конкуренции между ними нет и быть не может.
Здравствуйте, reversecode, Вы писали:
R>ага прям бегут и падают
R>я вот периодически пытаюсь учить раст R>но не для того что бы на нем кодить R>а что бы портянки избыточного кода в красивый компактный С++ переводить
R>не ну капец, когда два тома "войны и мир" кода на расте R>компактно портируются в два не больших файлика на С++ R>это же красота!
У меня тут недавно на этом форуме была дискуссия на сходную тему с одним яростным фанатом C++ (который правда не особо его знал, как и Rust впрочем). Так вот я показал ему простейший код на Rust из несколько строчек и предложил показать их аналог на C++. Т.е. не сделать короче, а сделать хотя бы не сильно длиннее. Только он что-то резко слился после этого...
_>>>Вот в обратную сторону (то, что автоматизировано в Rust и хрен сделаешь в C++) я могу легко привести пример...
fk0>> Приведи.
Такое же в C++ очевидно что не сделать настолько же коротко, хотя решения с Cereal или boost.archive будут не так что бы критично длиннее.
В то же время исходя из моего опыта этот пример крутой фичи с серриализаций довольно бесмысленный. Ну можешь ты что-то запаковать и распаковать в Rust, а дальше что? Это можно как-то так же бесшовно распаковать в Python или в C++? Потому как если нет, то фича эта прикольная, но в проде окажется Protobuf
UPD. бегло посмотрел документацию и не ясно что с версионарованием таких структур в архиве. Что если был изменен порядок полей? Что если добавили новое поле посередине структуры? У меня серьёзные подозрения что это просто такая пиписькамерка "а у других такого нету".
Здравствуйте, kaa.python, Вы писали: KP>Что бы из бесстековых любых корутин получить зелёные потоки
Делать зелёные потоки не надо вообще. Ну, точнее, "зелёный поток" эмулируется через бесстековую корутину примитивнейшим образом — просто берём и записываем thread proc в виде вот такой корутины, запускаем. KP>тебе ещё надо добавить пул реальных потоков сбоку, а потом весь свой код поверх этого пула потоков обмазывать async/await. Если очень хорошо всё распланировать, то, скорее всего, выйдет быстрее чем решение на зелёных потоках где за тебя раскидыванием задач по реальным потокам занимается универсальный диспетчер и контролировать пул потоков ты обычно тоже не можешь. Но вот в общем случае будет дольше писать, сложнее поддерживать и куда как кривее, т.к. хорошо распланировать у всех вряд ли выйдет.
Эмм, я думаю, всё же лучше прочитать статью. Там очень-очень подробно описаны проблемы файберов, и почему передовое человечество смотрит на корутины, а не на ещё одно N:M решение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, kaa.python, Вы писали: KP>Реальный поток стоит довольно дорого в любой современной ОС общего назначения (возможно есть какие-то специальные ОС с дешёвыми потоками, но я о них не знаю). Ты не можешь себе позволить создать 1КК потоков, даже 1К уже очень высокая нагрузка на систему. При этом в тех же серверных приложениях поток обычно просто висит и ждёт I/O, т.е. если он не зелёный, а реальный — это крайне дорого и сильно сокращает возможности держать нагрузку.
Зелёный поток тоже выходит дорогим. Stackless корутины гораздо экономичнее.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Делать зелёные потоки не надо вообще. Ну, точнее, "зелёный поток" эмулируется через бесстековую корутину примитивнейшим образом — просто берём и записываем thread proc в виде вот такой корутины, запускаем.
А если я просто хочу обработать много входящих соединений с автоматической балансировкой между реальными потоками, то я всю остальную машинерию буду ручками писать, да?
S>Эмм, я думаю, всё же лучше прочитать статью. Там очень-очень подробно описаны проблемы файберов, и почему передовое человечество смотрит на корутины, а не на ещё одно N:M решение.
Честно не читал. Это же С++-ники, даже больше коммитет С++-ников! У них часто всё через жопу, "потому что эффективно и надо охватить все вот 100500 потенциальных случаев". И пока они там занимаются сексом с корутинами (о них ещё в 2016(2017?) на CppCon от Гора слышал как о прорыве) и никак не изродят ничего годного для промышленного использования, реализации зелёных потоков в Го и Эрланге уже десятилетия шикарно решают реальные, а не гипотетически проблемы.
Посему я полностью согласен — с корутинами можно решить кучу проблем которые невозможно решить на зелёных потоках. Но зелёные потоки уже сейчас легко и изящно решают вообще все проблемы что у меня есть, а корутины в современном C++ даже близко не подобрались к такому уровню что бы решить тоже самое с теми же затратим временных ресурсов.
Здравствуйте, Sinclair, Вы писали:
S>Если вы хотите обрабатывать много входящих соединений с автоматической балансировкой между реальными потоками, то вам зелёные потоки противопоказаны. Используйте бесстековые корутины aka async/await.
Почему нам противопоказаны, а Гуглу с Го и Вацапу с Эрлангом нет? Кстати, а кто по реальным потокам кто будет эти корутины раскидывать?
S>При чём тут C++-ники? Это ребята сели и честно рассмотрели всю историю зелёных потоков от первых реализаций до Go и Эрланга. Прочитайте, там не так много текста.
Шикарный документ! Эрланг они, конечно же забыли упомянуть, слишком успешное решение вышло. Про Го сказали, и в сказаном ключевое то, что подход который использует Го не сработает на C++!
Pointer adjustment is possible to do in a programming language with precise garbage collector, such as Go, but
unfeasible in more traditional languages where it is not possible to freely move objects in memory and adjust all
of the pointers pointing to them
Все остальные моменты относящиеся к неудачам так же сильно завязаны на само модель управления памятью системой. Т.е. все провалы относящиеся к WIndows, Solaris и т.д. не потому что зеленые потоки плохи, а потому что зеленые потоки и ручное управление памятью пока ни у кого не удалось совместить.
S>Я не знаю, что там у них в С++. Наверное, опять закат солнца вручную. Все остальные уже просто пишут async код, и о зелёных потоках даже не задумываются.
Еще раз, кто эти остальные? Я обычно использую C++ — тут не осилить потоков зеленых о чем Гор и написал, Python — тут хотя бы обычные дали бы и уже счастье, Go — зеленые потоки есть и на них всё и построено, Elixir — зеленые потоки есть и на них всё вертится.
UPD. поличтал документацию по Akka и похоже что она тоже фактически на концептах зеленых потоков крутится.
Здравствуйте, so5team, Вы писали:
KP>>UPD. поличтал документацию по Akka и похоже что она тоже фактически на концептах зеленых потоков крутится.
S>А можно с этого места поподробнее? Хотя бы ссылку на документацию по Akka, где это описывается?
Я не прав тут, оказывается спутал с неким Quasar. Akka используют обычный пул потоков и асинхронно обрабатывают сообщения.
Здравствуйте, kaa.python, Вы писали: KP>Почему нам противопоказаны, а Гуглу с Го и Вацапу с Эрлангом нет?
В эрланге, афаик, как раз что-то вроде корутин, а не зелёные потоки. KP>Кстати, а кто по реальным потокам кто будет эти корутины раскидывать?
Ну, а зелёные потоки по реальным потокам раскидывает кто?
Рантайм, вестимо. KP>Шикарный документ! Эрланг они, конечно же забыли упомянуть, слишком успешное решение вышло. Про Го сказали, и в сказаном ключевое то, что подход который использует Го не сработает на C++! KP>
Pointer adjustment is possible to do in a programming language with precise garbage collector, such as Go, but
KP>unfeasible in more traditional languages where it is not possible to freely move objects in memory and adjust all
KP>of the pointers pointing to them
KP>Все остальные моменты относящиеся к неудачам так же сильно завязаны на само модель управления памятью системой. Т.е. все провалы относящиеся к WIndows, Solaris и т.д. не потому что зеленые потоки плохи, а потому что зеленые потоки и ручное управление памятью пока ни у кого не удалось совместить.
Почему же не удалось? Удалось. Просто через жо.
KP>Еще раз, кто эти остальные? Я обычно использую C++ — тут не осилить потоков зеленых о чем Гор и написал, Python — тут хотя бы обычные дали бы и уже счастье, Go — зеленые потоки есть и на них всё и построено, Elixir — зеленые потоки есть и на них всё вертится.
Дотнет, node.js, quasar в java. KP>UPD. поличтал документацию по Akka и похоже что она тоже фактически на концептах зеленых потоков крутится.
Вопрос не про цвет потоков, а про то, используете ли вы stackful coroutines или stackless.
Если посмотреть с этой точки зрения — вот вам нахрена стек в вашей задаче?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, kaa.python, Вы писали:
KP>>>UPD. поличтал документацию по Akka и похоже что она тоже фактически на концептах зеленых потоков крутится.
S>>А можно с этого места поподробнее? Хотя бы ссылку на документацию по Akka, где это описывается?
KP>Я не прав тут, оказывается спутал с неким Quasar.
Здравствуйте, Sinclair, Вы писали:
S>Вопрос не про цвет потоков, а про то, используете ли вы stackful coroutines или stackless.
А чем принципиально green thread от stackful coroutine отличается, особенно если green thread не поддерживаются рантаймом языка и его стандартной библиотекой?
Здравствуйте, so5team, Вы писали: S>А чем принципиально green thread от stackful coroutine отличается, особенно если green thread не поддерживаются рантаймом языка и его стандартной библиотекой?
Ничем. Это два названия примерно одного и того же.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, reversecode, Вы писали: R>господин большой теоретик?)) R>можете назвать основной плюс и минус стекфул и стеклесс
Плюс стекфул — легко реализовать в библиотеке. Можно напилить на более-менее любом языке. Минус — затраты на поддержание стека.
Плюс стеклесс — хорошая масштабируемость. Минус — затраты в разработке платформы; не во всякий язык ложатся хорошо. По-хорошему, нужна поддержка от компилятора.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, kaa.python, Вы писали:
KP>Я, возможно, что-то упускаю, но если зайти на https://dart.dev/, то первое что бросается в глаза — Дарт для мобильных приложений с UI.
Изначально Dart разрабатывался для клиентских приложений, верно.
KP>Что бы писать на Го мобильное приложение с UI надо быть слабо адекватным человеком
GUI пишут на Golang аж бегом.
KP>Насколько я могу судить, Дарт и Го вообще в разных сегментах и никакой конкуренции между ними нет и быть не может.
В таком ключе сложно рассуждать о мультипарадигменных языках с большим кол-вом фич.
Dart сегодня является универсальным языком, писать на нём серверную/асинхронную/многопоточную часть кода проще, чем на Golang.
Взять даже специфичную фишку Golang — типизированные каналы.
Во-первых, эта функциональность легко покрывается какой-нить либой в других мультипарадигменных языках.
Во-вторых, рядом с полноценным async-await каналы и рядом не стояли, бо последовательности async/await создают типизированный асинхронный "канал" из произвольных типов в каждой точке асинхронного алгоритма. В этом смысле типизированные каналы из Golang — убожество, нищета разума. Это наложение серьёзных ограничений на майл-боксы в исходной модели акторов.
Здравствуйте, kaa.python, Вы писали: KP>Да мне вообще всё равно что там, пока оно мало памяти ест (это так и для Го и для Эрланга) и не требует код соплями async/await обмазывать. А внутри потоки хоть дрочить в присядку могут, я не возражаю.
Тогда вас устроят и обычные настоящие потоки. Чем плохо-то?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, reversecode, Вы писали: R>>господин большой теоретик?)) R>>можете назвать основной плюс и минус стекфул и стеклесс S>Плюс стекфул — легко реализовать в библиотеке. Можно напилить на более-менее любом языке. Минус — затраты на поддержание стека. S>Плюс стеклесс — хорошая масштабируемость. Минус — затраты в разработке платформы; не во всякий язык ложатся хорошо. По-хорошему, нужна поддержка от компилятора.
Я так понимаю, что зеленые потоки это файберы https://habr.com/ru/post/185706/ то бишь стекфул ?
Ну в .Net для рекурсивных обхода взяли yield и его же по сути для async await вместо файберов.
Возможно, что бы упростить работу сборщика мусора, что бы еще не держать информацию о стеке файбера
и солнце б утром не вставало, когда бы не было меня
ну не совсем то что я ожидал услышать будь то вы практикующий нетворк дев
конкретный вопрос, чем плохи стекфул и стеклесс корутины относительно языка С++
и об этом явно все говорят
как минимум, что полухин, что то другой лектор курса С++ про корутины
и о чем знает любой практикующий нетворк дев который их попробовал
жаль вы пока еще не знаете
ну у вас еще все в переди)
Здравствуйте, so5team, Вы писали:
S>Обычные настоящие потоки хороши пока их количество укладывается в тысячу штук (хотя лучше бы в сотню). На трех-четырех десятках тысяч обычных потоков можно уже поиметь неприятные приключения. S>Тогда как зеленые потоки (stackful coroutines) позволяют писать код в стиле обычных тредов, но не иметь этих самых проблем при одновременной работе нескольких десятков тысяч зеленых потоков.
Ну, только при этом нужно использовать особенные примитивы синхронизации, и надо всё обмазывать yield в отличие от обычных тредов. А иначе на трёх-четырёх десятках тысяч зелёных потоков всё станет плохо.
В этом смысле async/await масштабируются гораздо лучше.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, reversecode, Вы писали:
R>конкретный вопрос, чем плохи стекфул и стеклесс корутины относительно языка С++
Увы, С++ меня не интересует. Проблемы файберов в нём изучены достаточно хорошо. А что там у них со stackless — я вообще не в курсе, завезли ли уже?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>Не обязательно все. Передача управления может выполняться неявно в специальных функциях, предназначенных для использования в зеленых потоках (типа lock, release, send, receive, listen, accept и т.д.)
S>>А иначе на трёх-четырёх десятках тысяч зелёных потоков всё станет плохо.
S>С чего бы это? И почему этого не произойдет на 30-40K одновременно запущенных stackless coroutines?
Ну для асинхрошщины как раз используются WaitAsync https://docs.microsoft.com/ru-ru/dotnet/api/system.threading.semaphoreslim.waitasync?view=net-5.0
и прочие асинхронные замены синхронным блокировщикам потоков. Вопрос насколько эффективны это другой вопрос. Суть в том, что бы не блокировать очередь потоков.
Здесь обсуждали http://rsdn.org/forum/dotnet/7947025.flat
Здравствуйте, so5team, Вы писали: S>Конечно. Только вот если у вас двум независимым и параллельно работающим stackless coroutines потребуется доступ к одним и тем же разделяемым данным, то и им так же нужно будет использовать особенные примитивы синхронизации.
Всё верно, тут 1:1. Просто это рушит на корню идею "я просто передам уже готовую и отлаженную thread proc в код старта зелёного потока". S>Не обязательно все. Передача управления может выполняться неявно в специальных функциях, предназначенных для использования в зеленых потоках (типа lock, release, send, receive, listen, accept и т.д.)
А то. Получается крайне интрузивная концепция — не выходит просто взять и заменить обычный thread на зелёный. Надо ещё и спец.функциями пользоваться. S>>А иначе на трёх-четырёх десятках тысяч зелёных потоков всё станет плохо. S>С чего бы это? И почему этого не произойдет на 30-40K одновременно запущенных stackless coroutines?
Потому, что потребление памяти у них всё ещё отличается на порядок.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Serginio1, Вы писали: S>>Я так понимаю, что зеленые потоки это файберы https://habr.com/ru/post/185706/ то бишь стекфул ? S>Ага. S>>Ну в .Net для рекурсивных обхода взяли yield и его же по сути для async await вместо файберов. S>>Возможно, что бы упростить работу сборщика мусора, что бы еще не держать информацию о стеке файбера S>В основном — по соображениям эффективности. Я тут уже давал ссылку на статью с подробным исследованием вопроса.
Да здесь еще обсуждали http://rsdn.org/forum/philosophy/8038391.flat
Здравствуйте, Sinclair, Вы писали:
S>>Не обязательно все. Передача управления может выполняться неявно в специальных функциях, предназначенных для использования в зеленых потоках (типа lock, release, send, receive, listen, accept и т.д.) S>А то. Получается крайне интрузивная концепция — не выходит просто взять и заменить обычный thread на зелёный. Надо ещё и спец.функциями пользоваться.
Зато сделать это проще, чем расставлять повсюду co_await, co_return и co_yield. Уж с co_ интрузивнее дальше некуда. Не говоря уже про то, что ментальная модель кода на простых потоках (нативных или зеленых) сильно проще, чем с co_await/co_return, т.к. с co_ далеко не сразу очевидно кто на ком стоял, особенно если реализации co_await умеют перекидывать короутины с одного контекста на другой.
S>>>А иначе на трёх-четырёх десятках тысяч зелёных потоков всё станет плохо. S>>С чего бы это? И почему этого не произойдет на 30-40K одновременно запущенных stackless coroutines? S>Потому, что потребление памяти у них всё ещё отличается на порядок.
И при чем здесь память? Если к stackfull coroutine привязано 10K вместо 1K у stackless, это же не значит, что в активный working set будет входить все эти 10K.
Ужас насколько всё не верно. ))) Ну по пунктам:
S>Плюс стекфул — легко реализовать в библиотеке. Можно напилить на более-менее любом языке.
Можно даже не пилить библиотеку, т.к. оно есть например в АПИ некоторых ОС (например Винды). Но это не плюс, а мелкое следствие из реального преимущества. Которое заключается в том, что при использование таких сопрограмм не надо модифицировать существующий код! В противоположность бесстековым, в которых обязательным условием является модификация всего стека вызова (заражение его async'ами).
Я на этом форуме даже когда-то приводил простенький пример. Берём классический парсер (большой и сложный код) чего-то там и передаём ему в качестве исходных данных не обычный std:string, а "асинхронный" string (у которого функция вернуть буфер, является сопрограммой). В итоге получаем реактивный парсер, в который можно заталкивать данные порциями. И всё это было реализовано с помощью библиотеки boost::coro (там стекфул сопрограммы) в пару строк.
В случае же бесстековых сопрограмм тебе для тех же целей пришлось бы переписывать (ну как минимум расставлять везде async и await) весь сложный код парсера.
S>Минус — затраты на поддержание стека.
Это как раз ерунда. Потому что размер стека же указывается программистом. Т.е. максимум что тут можно высосать из пальца, это необходимость программисту включить мозг для оценки этого значения (у бесстековых это делает компилятор).
Реальный же минус смотри ниже, там где плюс бесстековых. )))
S>Плюс стеклесс — хорошая масштабируемость.
Ну вообще то в большинстве языков разницы практические не будет. )))
И только в таких языках как C++ и Rust возможно небольшое преимущество по производительности у бесстековых. Однако совсем не по тем причинам, что ты тут описывал. А в силу максимально развитого оптимизатора, который может банально инлайнить наш конечный автомат (а в стекфул сопрограммах наоборот ещё и немного процессорного времени тратится на сохранение состояния регистров).
Но это будет преимущество именно в потребление ЦПУ, которое не всегда коррелирует с масштабируемостью.
S>Минус — затраты в разработке платформы; не во всякий язык ложатся хорошо. По-хорошему, нужна поддержка от компилятора.
Поддержка компилятора нужна не "по-хорошему", а обязательно. Потому что иначе просто невозможно — кто ещё будет делать преобразование кода сопрограммы в конечный автомат? ))) Но я бы не стал называть это минусом.
А реальный минус указан выше (заражение всего стека вызовов), в описание плюсов стекфул сопрограмм.
Синхронизирующие примитивы ядра. Мьютексы, Семафоры и т. д. Это и есть основной источник проблем с производительностью. Недостаточно продуманная работа с синхронизирующими примитивами может приводить к десяткам тысяч, а в особо запущенных случаях — и к сотням тысяч переключений контекста в секунду. [источник не указан 2477 дней]
Здравствуйте, alex_public, Вы писали: _>Можно даже не пилить библиотеку, т.к. оно есть например в АПИ некоторых ОС (например Винды). Но это не плюс, а мелкое следствие из реального преимущества. Которое заключается в том, что при использование таких сопрограмм не надо модифицировать существующий код! В противоположность бесстековым, в которых обязательным условием является модификация всего стека вызова (заражение его async'ами).
Опять же — унылая история файберов хорошо описана в обсуждаемой статье. _>Я на этом форуме даже когда-то приводил простенький пример. Берём классический парсер (большой и сложный код) чего-то там и передаём ему в качестве исходных данных не обычный std:string, а "асинхронный" string (у которого функция вернуть буфер, является сопрограммой). В итоге получаем реактивный парсер, в который можно заталкивать данные порциями. И всё это было реализовано с помощью библиотеки boost::coro (там стекфул сопрограммы) в пару строк. _>В случае же бесстековых сопрограмм тебе для тех же целей пришлось бы переписывать (ну как минимум расставлять везде async и await) весь сложный код парсера.
Да, совершенно верно. Но этот парсер работает ненамного лучше, чем блокирующее ожидание на основе какого-нибудь pipe. Попытка применить этот парсер для разбора чего-нибудь типа строк, массово приезжающих в http-сервер, будет очень активно кушать память и адресное пространство. А уплотнять ничего нельзя — в стек могут ссылаться активные указатели.
_>Это как раз ерунда. Потому что размер стека же указывается программистом. Т.е. максимум что тут можно высосать из пальца, это необходимость программисту включить мозг для оценки этого значения (у бесстековых это делает компилятор).
У бесстековых потребность в памяти гораздо меньше. Если бы можно было просто заткнуть все дыры уменьшением размера стека, можно было бы не заморачиваться никакими файберами, а просто передать этот размер в CreateThread.
_> Поддержка компилятора нужна не "по-хорошему", а обязательно. Потому что иначе просто невозможно — кто ещё будет делать преобразование кода сопрограммы в конечный автомат? ))) Но я бы не стал называть это минусом.
Отчего же? Можно просто потребовать переписать всю программу в терминах явных continuations и всё, никакой стейт-машины не надо. Вот только читаться это будет настолько плохо, что лучше всё же иметь нормальный язык с соответствующим компилятором. _>А реальный минус указан выше (заражение всего стека вызовов), в описание плюсов стекфул сопрограмм.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, T4r4sB, Вы писали:
TB>Когда-то давно, когда деревья были большими, а компиляторы тупыми, они умели выдавать ровно 1 ошибку и сразу падать. И люди мечтали, что компиляторы будут выдавать все возможные ошибки сразу.
Гугл говорит, что и сейчас умеют:
Здравствуйте, Sinclair, Вы писали:
S>>Зато сделать это проще, чем расставлять повсюду co_await, co_return и co_yield. Уж с co_ интрузивнее дальше некуда. S>Ну, то есть для начала надо сделать fiber-аналоги основных процедур, а уж потом оно само.
Я не понял, если мы собираемся использовать вызовы send/receive/accept/listen и им подобные из stackless короутин, то они как-то автоматически станут асинхронными?
S>>Не говоря уже про то, что ментальная модель кода на простых потоках (нативных или зеленых) сильно проще, чем с co_await/co_return, т.к. с co_ далеко не сразу очевидно кто на ком стоял, особенно если реализации co_await умеют перекидывать короутины с одного контекста на другой. S>co_await и co_return — это как я понимаю как раз артефакты тех местностей, куда не завезли языковых реализаций. Потому, что там, где завезли — там async/await, и код вполне себе выглядит и работает.
Каким-то высокомерным снобизмом пахнуло. Только вот мы находимся в теме, посвященной D, C, C++ и, отчасти, Rust-у. Еще в контексте обсуждения упоминались Go, Erlang и Elixir. Можете показать куда из вышеперечисленного завезли async/await? Ну и, чтобы два раза не вставать, можете рассказать, чем co_wait/co_return/co_yield принципиально отличаются от async/await в ... (тут сами выберите что вам ближе)?
S>>И при чем здесь память? Если к stackfull coroutine привязано 10K вместо 1K у stackless, это же не значит, что в активный working set будет входить все эти 10K. S>Ну так чудес-то не бывает. Тем более, что 1к для stackless — это явно перебор. Там обычно десятки байт.
Тем не менее, для того, чтобы получить серьезную просадку производительности нужно, чтобы размер working set у разного типа короутин различался существенно. Что вряд ли будет иметь место на практике, если у нас короутины выполняют одинаковый тип работы.
Здравствуйте, so5team, Вы писали:
S>Я не понял, если мы собираемся использовать вызовы send/receive/accept/listen и им подобные из stackless короутин, то они как-то автоматически станут асинхронными?
Нет, не станут. Тут опять 1:1. Ну, кроме того, что в stackless у нас чуть больше контроля за тем, что происходит — в частности, возможность какие-то вещи принудительно сделать синхронно, а в каких-то случаях уступить управление.
S>Каким-то высокомерным снобизмом пахнуло.
не-не, никакого снобизма. Я было подумал, что это какая-то очередная велобиблиотека на макросах с шаблонами. Понятно, что объехать стейт машину, генерируемую компилятором, так не получится.
S>Только вот мы находимся в теме, посвященной D, C, C++ и, отчасти, Rust-у. Еще в контексте обсуждения упоминались Go, Erlang и Elixir. Можете показать куда из вышеперечисленного завезли async/await?
Ну так вроде в С++ как раз же и завезли. S>Ну и, чтобы два раза не вставать, можете рассказать, чем co_wait/co_return/co_yield принципиально отличаются от async/await в ... (тут сами выберите что вам ближе)?
Оказывается — ничем. Тогда не очень понятны опасения по поводу переключения co_wait в другой контекст.
S>Тем не менее, для того, чтобы получить серьезную просадку производительности нужно, чтобы размер working set у разного типа короутин различался существенно. Что вряд ли будет иметь место на практике, если у нас короутины выполняют одинаковый тип работы.
С учётом вашего профиля, вы скорее всего правы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_>>Можно даже не пилить библиотеку, т.к. оно есть например в АПИ некоторых ОС (например Винды). Но это не плюс, а мелкое следствие из реального преимущества. Которое заключается в том, что при использование таких сопрограмм не надо модифицировать существующий код! В противоположность бесстековым, в которых обязательным условием является модификация всего стека вызова (заражение его async'ами). S>Опять же — унылая история файберов хорошо описана в обсуждаемой статье.
Обсуждаемая статья — это отголосок известной попытки MS продавить свою реализацию сопрограмм в комитете C++. ))) И автор этой статьи был так сказать главным идеологом всего этого. Кстати, в итоге решение было довольно забавным. Решили принять в стандарт бесстековые сопрограммы (с логичной аргументаций что стекфул хорошо себя чувствуют и без стандарта, в виде библиотек), но не в реализации MS. )))
_>>Я на этом форуме даже когда-то приводил простенький пример. Берём классический парсер (большой и сложный код) чего-то там и передаём ему в качестве исходных данных не обычный std:string, а "асинхронный" string (у которого функция вернуть буфер, является сопрограммой). В итоге получаем реактивный парсер, в который можно заталкивать данные порциями. И всё это было реализовано с помощью библиотеки boost::coro (там стекфул сопрограммы) в пару строк. _>>В случае же бесстековых сопрограмм тебе для тех же целей пришлось бы переписывать (ну как минимум расставлять везде async и await) весь сложный код парсера. S>Да, совершенно верно. Но этот парсер работает ненамного лучше, чем блокирующее ожидание на основе какого-нибудь pipe. Попытка применить этот парсер для разбора чего-нибудь типа строк, массово приезжающих в http-сервер, будет очень активно кушать память и адресное пространство. А уплотнять ничего нельзя — в стек могут ссылаться активные указатели.
Это был всего лишь форумный пример задачки, которую бесстековые сопрограммы не способны решить в принципе. А не какое-то реальное решение из жизни. Так что смотри не на частность, а на общий принцип: бесстековые не позволяют тебе использовать уже разработанный код, если он написан не как сопрограмма. Это весьма фундаментальный минус.
_>>Это как раз ерунда. Потому что размер стека же указывается программистом. Т.е. максимум что тут можно высосать из пальца, это необходимость программисту включить мозг для оценки этого значения (у бесстековых это делает компилятор). S>У бесстековых потребность в памяти гораздо меньше.
С чего бы это? Там фундаментальная разница будет только в размер контекста регистров (~350 байт для х86 с SIMD). Все локальные переменные из стека сопрограммы точно так же обязаны храниться в состояние конечного автомата. Разве что ты там вызовешь внутри какую-то внешнюю функцию, при этом не являющуюся сопрограммой и при этом требующую мегабайт стека. Но это опять же высосанный из пальца сценарий: на практике (а единственное место где вообще актуальна эта тема — это нагруженные сервисы) мы вполне себе представляем как выглядит обычный код таких сопрограмм.
S>Если бы можно было просто заткнуть все дыры уменьшением размера стека, можно было бы не заморачиваться никакими файберами, а просто передать этот размер в CreateThread.
Эм, основная проблема системных потоков как раз не в потребление памяти, а в том что при переключение между ними происходит прыжок в нулевое кольцо. В итоге на переключение может уходить времени больше чем на сами "вычисления".
_>> Поддержка компилятора нужна не "по-хорошему", а обязательно. Потому что иначе просто невозможно — кто ещё будет делать преобразование кода сопрограммы в конечный автомат? ))) Но я бы не стал называть это минусом. S>Отчего же? Можно просто потребовать переписать всю программу в терминах явных continuations и всё, никакой стейт-машины не надо. Вот только читаться это будет настолько плохо, что лучше всё же иметь нормальный язык с соответствующим компилятором.
Ну так тогда это просто перестанет быть сопрограммой, банально из определения этого термина. ))) Это будет обычное асинхронное программирование, которое собственно изначально так и возникло. А только потом возникла идея "выпрямления" лапши из коллбэков с помощью сопрограмм в нечто похожее на классическое многопоточное программирование. Т.е. сами по себе сопрограммы — это просто синтаксический сахар для внешней красоты (где образцом являются те самые медленные системные потоки).
Но бесстековых сопрограмм без поддержки компилятора в принципе быть не может. ))) Ну разве что в теории в языке с очень развитым метапрограммированием, где можно будет самому закодировать нужную трансформацию (но я бы за такое не стал браться).
Здравствуйте, Sinclair, Вы писали:
S>Ну, кроме того, что в stackless у нас чуть больше контроля за тем, что происходит — в частности, возможность какие-то вещи принудительно сделать синхронно, а в каких-то случаях уступить управление.
Как раз в каких-то сценариях возможность неявно сделать yield без явного указания co_yield/co_await в коде может быть отличным подспорьем. Представьте, что мы используем некий фреймворк, который дает нам аналоги Go-шных каналов (отсюда вызовы send/receive) и средства для асинхронной работы с сетью (или с СУБД, или еще с чем-то). Все это в виде обычных синхронных методов.
Мы тогда просто пишем свой код в простом линейном виде (та самая thread_proc), а уже ручками настройки фреймворка переключаем -- должны ли под капотом быть нативные нити или же зеленые. Это очень круто, вообще-то.
S>>Ну и, чтобы два раза не вставать, можете рассказать, чем co_wait/co_return/co_yield принципиально отличаются от async/await в ... (тут сами выберите что вам ближе)? S>Оказывается — ничем. Тогда не очень понятны опасения по поводу переключения co_wait в другой контекст.
Так вот как раз в C++ не очень понятно, где, когда и что будет выполняться, когда вызывается co_await. Там несколько точек кастомизации на co_await и есть подозрение, что временами сложно будет понять к чему именно приведет co_await и где и что потом будет работать. У упоминавшегося здесь Полухина была статья с примерами на эту тему: https://habr.com/ru/company/yandex/blog/420861/
Здравствуйте, alex_public, Вы писали:
_>Обсуждаемая статья — это отголосок известной попытки MS продавить свою реализацию сопрограмм в комитете C++. ))) И автор этой статьи был так сказать главным идеологом всего этого. Кстати, в итоге решение было довольно забавным. Решили принять в стандарт бесстековые сопрограммы (с логичной аргументаций что стекфул хорошо себя чувствуют и без стандарта, в виде библиотек), но не в реализации MS. )))
Это интересно. А чем реализация MS так отличалась от того, что попало в 20й стандарт?
_>Это был всего лишь форумный пример задачки, которую бесстековые сопрограммы не способны решить в принципе. А не какое-то реальное решение из жизни. Так что смотри не на частность, а на общий принцип: бесстековые не позволяют тебе использовать уже разработанный код, если он написан не как сопрограмма. Это весьма фундаментальный минус.
Да, к сожалению, это так.
Но я вообще скептически отношусь к серебряным пулям, которые берут и превращают готовый отлаженный код во что-то другое. Так не бывает. Нельзя просто взять и щелчком пальцев превратить apache с его классическим 1 процесс на реквест в nginx или lighttpd.
_>С чего бы это? Там фундаментальная разница будет только в размер контекста регистров (~350 байт для х86 с SIMD). Все локальные переменные из стека сопрограммы точно так же обязаны храниться в состояние конечного автомата.
Нет, не все. А только те, которые нужны в продолжении. Компилятор очень хорошо умеет определять такие вещи. _>Разве что ты там вызовешь внутри какую-то внешнюю функцию, при этом не являющуюся сопрограммой и при этом требующую мегабайт стека. Но это опять же высосанный из пальца сценарий: на практике (а единственное место где вообще актуальна эта тема — это нагруженные сервисы) мы вполне себе представляем как выглядит обычный код таких сопрограмм.
Почему внешнюю? Нужно тащить весь стек. Смотрите: авторы Go были вынуждены отказаться от сегментированного стека из-за просада производительности. При этом дефолтный размер стека горутины у них был 8 килобайт.
Это всё ещё примерно в сто раз больше, чем размер замыкания для типичной сопрограммы.
_>Эм, основная проблема системных потоков как раз не в потребление памяти, а в том что при переключение между ними происходит прыжок в нулевое кольцо. В итоге на переключение может уходить времени больше чем на сами "вычисления".
Ну а с зёлёными потоками у нас возникает проблема неравномерной загрузки, т.к. не всегда можно заранее предсказать объём работы в процедуре. Перемещать зелёные потоки между потоками ОС не осилил никто, несмотря на многолетние усилия.
_>Ну так тогда это просто перестанет быть сопрограммой, банально из определения этого термина. ))) Это будет обычное асинхронное программирование, которое собственно изначально так и возникло. А только потом возникла идея "выпрямления" лапши из коллбэков с помощью сопрограмм в нечто похожее на классическое многопоточное программирование. Т.е. сами по себе сопрограммы — это просто синтаксический сахар для внешней красоты (где образцом являются те самые медленные системные потоки).
А то.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Это был всего лишь форумный пример задачки, которую бесстековые сопрограммы не способны решить в принципе. А не какое-то реальное решение из жизни. Так что смотри не на частность, а на общий принцип: бесстековые не позволяют тебе использовать уже разработанный код, если он написан не как сопрограмма. Это весьма фундаментальный минус.
Чему будет равно значение регистра r4 после переключения состояния туда-обратно?
_>>Ну так тогда это просто перестанет быть сопрограммой, банально из определения этого термина. ))) Это будет обычное асинхронное программирование, которое собственно изначально так и возникло. А только потом возникла идея "выпрямления" лапши из коллбэков с помощью сопрограмм в нечто похожее на классическое многопоточное программирование. Т.е. сами по себе сопрограммы — это просто синтаксический сахар для внешней красоты (где образцом являются те самые медленные системные потоки). S>А то.
// Т.е. сами по себе сопрограммы — это просто синтаксический сахар для внешней красоты
при правильном использовании сопрограмм таки есть ненулевая вероятность реализовать на базе corutins lock free ? есть ли вероятность, что реализовывалось частично для этого?
да еще есть вероятность, что co_yeld и yeld вещи то разные. yeld — это просто "системный" вызов функции так и называется yeld, планировщик если увидит свободный поток передаст ему управление, но может и не передавать, но касается вроде как системного потока, а не передачи управления в случае с co_. Но вот со случаем co_ это именно (ну я предполагаю, мне кажется именно так — логично) передача управление другой корутине, но если с локфри, вообще все интереснее.
Здравствуйте, uncommon, Вы писали:
U>Здравствуйте, kaa.python, Вы писали:
KP>>И пока они там занимаются сексом с корутинами (о них ещё в 2016(2017?) на CppCon от Гора слышал как о прорыве) и никак не изродят ничего годного для промышленного использования
U>2015 (CppCon 2015: Gor Nishanov “C++ Coroutines — a negative overhead abstraction"). Как сейчас помню, Гор кричал "Negative overhead!" А потом оказалось, что на каждую корутину надо память выделять. Negative overhead my ass.
патамуша так вот думают, первый-же намек глядя на структуру идеи — реализовать неблокирующий малтисрединг в языке.
DM>>Развитие не замерло, оно стало хаотичным. Кучу времени и сил потратили на @nogc, чтобы угодить вечно ворчащим плюсовикам.
тут можно было и не угождать.
_>Согласен. Но всё же думаю что если бы C++ не проснулся (в 2011-ом), то вся эта орда инфраструктурных программистов всё же начала сбегать на D, прогнув его при этом в сторону однозначно системного языка. Ну а так, он в итоге сохранил своё непонятное лицо, при этом потеряв шанс на взлёт...
DM>>По мне так если бы язык просто был таким, что был описан в книжке Александреску, ну может с более удобной и регулярной статической интроспекцией и нормальной имплементацией компилятора, он был бы вполне прекрасен. Постоянно его растить и делать монстра типа С++ не надо.
да хватит этого вот честно утомляет нытье. вы простите, но это вы наехали на моего любимого монстра, будем драться?? Он не монстр, это джаз чувствовать надо ..
_>C++ монстр не потому что развивается, а потому что так вышло. ))) Если же развиваться по нормальному, впитывая современные тенденции индустрии, то всё будет нормально. Вот добавление синтаксиса бесстековых сопрограмм никак не ухудшило ни Rust, ни Python. И в D тоже было бы вполне уместно. Это просто как популярный пример естественно, а не как что-то принципиально важное. )))
так ессно импровизация всегда — "так вышло", а еще на джаз квартирниках есть один принцип — чем-то похож на дедукцию. еще ниразу не пробовали, но вот я их упрошу, и запишем типа клипа.
KP>И да, отдельный язык описания структур идея хорошая, т.к. он тебя отвязывает от какого-то реального языка. То что у вас сейчас всё на Расте вообще ни разу не аргумент, если ты только что-то короткоживущее не пишешь, причем маленькой командой.
не уверен, protobuf в плюсах выглядел ужасно. причем, надо понимать, что постоянно в таких решениях присутствует — генерация кода. в нашем случае С++. и все это как правило обязательно где-то упадет, скривит и еще добавит кучу гемороя, только для того чтобы перебрать поля ?? Вообще все это связано именно с отсутствием рефлекшина, конечно же compile time хотя бы, чтобы как у ди, но вообще ту версию, что я скидывал на базе llvm — там куда интереснее уже — ct reflection.
_>>Protobuf у нас на проде точно никогда не окажется в силу его крайне низкой эффективности (см. например табличку здесь https://blog.logrocket.com/rust-serialization-whats-ready-for-production-today/). Благо сейчас нет никаких проблем писать код со всех сторон (и на сервере и на клиенте, в том числе в браузере) на Rust.
KP>Какого размера у вас R&D? Хотя бы сотня человек есть? Подход который тебя радует не масштабируется
И как 9 мам в один месяц укладываются ?
_>// Т.е. сами по себе сопрограммы — это просто синтаксический сахар для внешней красоты _> при правильном использовании сопрограмм таки есть ненулевая вероятность реализовать на базе corutins lock free ? есть ли вероятность, что реализовывалось частично для этого?
lock free ортогонален сопрограммам. Можно делать lock-free безо всяких сопрограмм, а можно делать сопрограммы, которым нужна блокировка.
Реализовывались они в первую очередь для того, чтобы записывать сложные вещи простым образом.
_>да еще есть вероятность, что co_yeld и yeld вещи то разные. yeld — это просто "системный" вызов функции так и называется yeld, планировщик если увидит свободный поток передаст ему управление, но может и не передавать, но касается вроде как системного потока, а не передачи управления в случае с co_. Но вот со случаем co_ это именно (ну я предполагаю, мне кажется именно так — логично) передача управление другой корутине, но если с локфри, вообще все интереснее.
Смотря где и что. В с++ co_yield — это аналог yield return в C# — возврат значения из генератора. Для асинхронного программирования co_yield и yield return не применяются, вместо них работают await/co_await. Тот же yield(), который из зелёных потоков, семантически отличается от обоих вариантов. Можно с натяжкой считать его аналогом await, который ждёт void-вызов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Про реализацию детали уже не помню конечно же. Но в целом изначальная версия от MS была такая совсем простенькая, в стиле .net (ну и кстати помнится там приставки co_ не было, хотя это конечно же не важно). А в итоге в стандарте имеем классического обобщённого монстрика, кастомизируемого в куче точек под все возможные ситуации. )))
Просто при беглом сравнении того, что попало в стандарт, с .Net, вырисовывается практически 1-в-1 соответствие архитектуры.
Так что непонятно, почему вы считаете, что предложение от МС "отклонили".
_>Я про проблемы Go не в курсе. ) Хотя могу предположить, что там специфика заключается в том, что там это основной способ реализации параллелизма. Т.е. оно должно нормально работать во всех случаях. В то время как в том же C++ — это один из многих способов, используемый в специфическом случае (обычно высоконагруженный сервис и т.п.). С весьма характерным профилем кода.
_>Чтобы было сразу понятно. Лично я для задач типа высоконагруженных сервисов использую как раз бесстековые сопрограммы (в реализации Rust'а) с рантаймом tokio. Т.е. я тут не занимаюсь защитой зелёных потоков и т.п. (хотя для стековых сопрограмм на мой взгляд опять же есть своё место под солнцем, про которое я тоже писал). Мои комментарии относились в основном к сомнительной аргументации (расход памяти на самом деле там не будет решать ничего) подобного выбора и сомнительных списков плюсов и минусов (пропущены важнейшие различия, а всякая мелочь подчёркивалась как главное).
Ну, ок.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, serj.e, Вы писали:
SE>Александреску перепутать со Степановым хоть и сложнее, но нет в этом мире ничего невозможного
В два ночи сонному и не такое можно перепутать. Выдыхай, бобёр.
SE>Сам Александреску хвост-те когда уже отошёл от "синдрома имени себя"
Это к счастью излечимо, да.
SE>А вот многие укушенные так и не оклемались, продолжая клепать всё более и более монструозных франкенштейнов, наподобие mpl и hana. Где уже не просто "всё всем параметризуется", а происходит программирование времени компиляции на шаблонах.
Увы.
И?
Здравствуйте, alex_public, Вы писали:
_>Естественно никак, потому что версионирование ортогонально вопросу автоматической генерации кода. Потому что оно очевидно не должно зависеть от формата данных (скажем мы ещё те же данные будем в виде json передавать — и где там версионированние будет?).
Вот ничего не понимая в бинарных протоколах, могу сказать за json.
Этот формат позволяет работать как минимум в двух режимах версионирования:
1. Неявная обратная совместимость.
Например, мы обязываем клиента игнорировать все неизвестные атрибуты. Это разрешает серверу добавлять новые атрибуты в респонс до тех пор, пока это не нарушает семантику.
При этом клиент версии 1.1 гарантированно сможет успешно прочитать данные, отправленные сервером версии 1.2.
Аналогичным образом, если мы запрещаем серверу добавлять новые обязательные атрибуты в обрабатываемые им реквесты, то запрос от клиента версии 1.1 гарантированно будет совместим с сервером версии 1.2.
Никогда не будет такого, что кто-то из них прочитает из потока, скажем, номер счёта вместо суммы.
2. Явное версионирование
Мы можем заложить в протокол наличие атрибута { "version" = "..."}, что даёт нам ещё больше гибкости — например, мы можем менять семантику существующих атрибутов. Любой из участников коммуникации может прочесть версию и принять решение о том, как разбирать остальные части сообщения. Например, в версиях 1.х у нас идентификатором пользователя был емейл, а в версиях 2.х по соображениям privacy применяем GUID.
В любом протоколе возникают вопросы:
1. Можем ли мы прочитать "заголовок" сообщения и изменить способ разбора в зависимости от переданной там версии?
2. Можем ли мы добавлять атрибуты в сообщения обратно-совместимым образом, чтобы не знающий о новых атрибутах партнёр мог хотя бы корректно прочитать известные ему старые?
Ну, и, факультативно — можем ли мы менять область значений атрибута обратно-совместимым образом?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_>>Про реализацию детали уже не помню конечно же. Но в целом изначальная версия от MS была такая совсем простенькая, в стиле .net (ну и кстати помнится там приставки co_ не было, хотя это конечно же не важно). А в итоге в стандарте имеем классического обобщённого монстрика, кастомизируемого в куче точек под все возможные ситуации. ))) S>Просто при беглом сравнении того, что попало в стандарт, с .Net, вырисовывается практически 1-в-1 соответствие архитектуры. S>Так что непонятно, почему вы считаете, что предложение от МС "отклонили".
Ты как-то странно прочитал моё сообщение, хотя я вроде ясно всё написал. У MS было по сути уже готовое работающее решение (оно вроде даже в их компиляторе уже было, если я ничего не путаю). В теории его можно было просто взять (в MS были очень "за") и обозвать стандартом, как делали скажем со многими кусками из Boost. Но в комитете решили тут по другому и написали новое решение, "с нуля". При этом среди авторов был опять же Гор, но уже как один из многих...
Что же касается разницы, то она весьма существенная, если залезть во внутренности (и это я совсем не про компилятор). Грубо говоря потому что там всё основано на "шаблонной магии". ))) И да, если во все точки кастомизации поставить дефолтные заглушки, то внешне получится работа весьма похожая на вариант из .net. Только нюанс в том, что в .net это собственно и есть единственный вариант, а тут это всего лишь работа при дефолтной реализации (кстати ещё одно отличие в том, что грубо говоря каждый разработчик обязан создавать "свою реализация" в каждом проекте, хотя понятно что на практике большинство будет копипастить дефолтную).
Начальные детали можешь глянуть здесь https://habr.com/ru/company/yandex/blog/420861/ например. Обрати внимание, сколько "сервисного" кода необходимо добавить в проект, чтобы просто появилась возможность использовать сопрограмму.
Здравствуйте, Sinclair, Вы писали:
_>>Естественно никак, потому что версионирование ортогонально вопросу автоматической генерации кода. Потому что оно очевидно не должно зависеть от формата данных (скажем мы ещё те же данные будем в виде json передавать — и где там версионированние будет?). S>Вот ничего не понимая в бинарных протоколах, могу сказать за json. S>Этот формат позволяет работать как минимум в двух режимах версионирования: S>1. Неявная обратная совместимость. S>... S>2. Явное версионирование S>...
В случае необходимости в версионирование на уровне формата данных (обычно это происходит, когда протокол общения написан не нами) второй вариант кажется заметно лучше, т.к. является не зависимым от самого формата данных (одно и тоже поле version может быть и в JSON и в MessagePac и в XML и где угодно).
Но помимо этого возможно версионирование на уровне протокола (когда при происходит договорённость о версии в момент соединения). Это позволяет получить все плюсы явного версионирования, избежав при этом оверхеда на передачу и проверку версии в каждом сообщение.
Здравствуйте, alex_public, Вы писали:
_>Ты как-то странно прочитал моё сообщение, хотя я вроде ясно всё написал. У MS было по сути уже готовое работающее решение (оно вроде даже в их компиляторе уже было, если я ничего не путаю). В теории его можно было просто взять (в MS были очень "за") и обозвать стандартом, как делали скажем со многими кусками из Boost. Но в комитете решили тут по другому и написали новое решение, "с нуля". При этом среди авторов был опять же Гор, но уже как один из многих...
При этом, что характерно, в обсуждаемом документе про это решение — ни слова.
_>Что же касается разницы, то она весьма существенная, если залезть во внутренности (и это я совсем не про компилятор). Грубо говоря потому что там всё основано на "шаблонной магии". ))) И да, если во все точки кастомизации поставить дефолтные заглушки, то внешне получится работа весьма похожая на вариант из .net. Только нюанс в том, что в .net это собственно и есть единственный вариант, а тут это всего лишь работа при дефолтной реализации (кстати ещё одно отличие в том, что грубо говоря каждый разработчик обязан создавать "свою реализация" в каждом проекте, хотя понятно что на практике большинство будет копипастить дефолтную).
Вы как-то неверно понимаете устройство "варианта из .net".
Там нет никакой "единственности". Когда компилятор встречает метод, помеченный async, он смотрит на атрибут AsyncMethodBuilderAttribute, которым помечен возвращаемый методом тип.
Значение свойства BuilderType определяет, кто будет строить стейт-машину для этого метода.
А при использовании await компилятор, грубо говоря, делает на результате вызванного метода .ContinueWith() со ссылкой на строящийся метод.
То есть опять же — конкретные детали зависят от того, какой код написан автором в ContinueWith().
Просто из коробки в дотнете обработаны пять возвращаемых типов, отсюда кажется, что "есть единственный вариант".
В реальности — гибкости ровно столько же, сколько в С++.
_>Начальные детали можешь глянуть здесь https://habr.com/ru/company/yandex/blog/420861/ например. Обрати внимание, сколько "сервисного" кода необходимо добавить в проект, чтобы просто появилась возможность использовать сопрограмму.
Ну да — те же точки расширения, плюс-минус особенности неуправляемой платформы, вот только реализаций awaitable object в коробку не положили. Бывает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_>>В случае необходимости в версионирование на уровне формата данных (обычно это происходит, когда протокол общения написан не нами) второй вариант кажется заметно лучше, т.к. является не зависимым от самого формата данных (одно и тоже поле version может быть и в JSON и в MessagePac и в XML и где угодно). S>Ну так проблема в некотром роде в том, как определяется порядок полей. Например, XML схема — штука жёсткая, в ней порядок потомков узла строго фиксирован. S>Поэтому если мы написали, что тег <version> первым идёт в теге <message>, то так оно и будет — и мы можем на это рассчитывать. И любой способ чтения XML — хоть через DOM, хоть sax, хоть XPath — корректно вынут версию из документа, в который сложили дополнительный контент. S>А в расте как-то гарантируется порядок обхода полей структуры? S>Не получится случайно так, что в версии 2 на том месте, где были байты поля "версия", оказались байты поля "длина текста", а версия уехала в хвост? S>Ведь тогда читатель, полагающийся на фиксированное расположение байтов, прочтёт мусор.
В Rust'е порядок обхода определяется по AST, которое генерирует компилятор на основе соответствующего кода и передаёт как параметр синтаксическому макросу (https://github.com/serde-rs/serde/blob/master/serde_derive/src/internals/ast.rs#L183). Очевидно, что это не плавающая упорядоченность.
_>>Но помимо этого возможно версионирование на уровне протокола (когда при происходит договорённость о версии в момент соединения). Это позволяет получить все плюсы явного версионирования, избежав при этом оверхеда на передачу и проверку версии в каждом сообщение. S>Для этого должно быть версионирование на уровне протокола.
Здравствуйте, kaa.python, Вы писали:
_>>В Rust'е порядок обхода определяется по AST, которое генерирует компилятор на основе соответствующего кода и передаёт как параметр синтаксическому макросу (https://github.com/serde-rs/serde/blob/master/serde_derive/src/internals/ast.rs#L183). Очевидно, что это не плавающая упорядоченность. KP>Что и следовало ожидать — удаление поля из середины или изменения порядка полей ломает всю сериализацию
Ужас то какой))) А если удалить параметр или изменить их порядок в вызове любой функции ОС АПИ, то вообще приложение вылетит с непредсказуемой ошибкой. Надо срочно переделать все ОС АПИ и т.п. на Protobuf!
Да, и кстати особо забавна твоя "последовательность" в дискуссии. То мы яростно обсуждали пользу наличия версионности, то резко забываем про её существование.
_>>Если протокол свой, то это делается элементарно. KP>При использовании сторонних генераторов, пусть будет не Protobuf с которым у тебя что-то не срослась, а что-то более быстрое и компактнее, эта проблема решается из коробки. А для большого проекта над которым работают разные команды это серьёзная проблема. Я понимаю что для той примитивщины над которой ты работаешь это не критично, но у взрослых дядей оно так
Если под взрослыми дядями ты подразумеваешь классический энтерпрайз (т.е. решение стандартных задач огромной толпой дешёвых специалистов), то я действительно таким никогда не занимался и не планирую. Я предпочитаю обитать в области инноваций (где решают сложные задачи маленькой командой за большие деньги). Но это всё уже глубокий оффтопик...