Извините, что не разжевал всё до мельчайших деталей. Понимаю, поиск это сложно:
- Python. Актуальный master, разжёвано донельзя, утверждают, что "computed gotos" быстрее на 15-20% -
- Dalvik VM. Актуальный master. Также всё расписано.
- Tarantool. Актуальный вики содержащий в том числе графики сравнения. Был представлен на Google Summer of Code 2021.
Вот такой вот 1959. Ой, простите за сарказм. Это всё 2021. Там, кстати, ссылки, на них можно кликать. Если вдруг вы не только поиск не умеете.
Я думаю вам не составит труда предоставить какие-то бенчмарки со своей стороны, коль скоро вы столь безапелляционно заявляете о доминировании, прости меня бог Computer Science, паттерна State.
Я же говорю, вы своим авторитетом растоптали всех разработчиков и исследователей, короткий список из которых я привёл. Ребята из Google или Tarantool заламывают руки, что в далёком 1959 они не догадались использовать "паттерн State из ООП". Команда наиболее актуальной VM для Erlang, языка известного тем, что он само воплощение actor model, уволилась всем составом. При такой диспозиции кто я такой чтобы с вами спорить, конечно я капитулирую.
Современный аналог DoEvents — это await Task.Yield();, а никак не то что вы написали.
Вы сейчас на полном серьёзе говорите, что метод в официальной документации звучащий как [do not rely on await Task.Yield(); to keep a UI responsive](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.yield) лучше, чем Dispatch.Invoke, который MS [сам использует для симулации DoEvents](https://github.com/search?q=org%3Adotnet+doevents+DispatcherPriority&type=code)? Есть какие-то аргументы, что они чего-то не знает о своём продукте? А то как дураки вводили в том же Dispather отдельно метод Yield, в котором DispatcherPriority.Background из моего примера и Dispatcher.InvokeAsync под капотом. Видимо не хотели, чтобы люди выстреливали себе в ногу полагаясь на волатильный SynchronizationContext.Current.
Да и отмечен бы данный подход как "изредка будут делать", а не рекомендуемый. Что основывается на статистике гитхаба. Вот так повелось, используют. Не IAwaitable единым живёт мир многопоточности, некоторые ортодоксы могу использовать тредпулы напрямую, BackgroundWorker, BackgroundService и т.п. А так получилось, что обновление UI из них рекомендуют делать через семейство методов Dispatcher.Invoke.
Нет, это ненормальный подход, поскольку он не позволяет создавать несколько экземпляров конечного автомата или актора.
Судя по фразе "несколько экземпляров" вы пытаетесь натянуть весь богатый мир софта на свой опыт в ООП и считаете, что если в какой-нибудь Akka оверхед на актора всего 300 байт, то и любой ембеддед затащит (хотя и в Akka instance-per-message не является рекомендуемым).
Начнём с того, что речь шла о языке 59 года рождения, там не то что объектами не пахло, там свитчей не было, сердца всех аляповатых FSM. И выживали за счёт динамических goto пока [Multi-way branching replaces the computed goto](https://en.wikipedia.org/wiki/Goto).
А вот нормальные FSM, которых вы своим авторитетным мнением растоптали - это Google с их Dalvik VM, Erlang Beam VM (ни разу не связан с акторными моделями), Python, GCC, GNU Forth, Tarantool, Ruby, Lua и много других. Ссылки предоставить или сами справитесь? Благо "computed goto", "branch table", "jump tables" - техники про которые написаны сотни научных работ, читаются в большинстве технических ВУЗов. Даже как-то странно всё это разжёвывать в мире где можно ввести пару слов в поиск гитхаба и увидеть мировую практику использования того или иного подхода.
И в целом не понял, какая связь между FSM, акторными моделями и состоянием в "экземплярами". У меня дизайн не может использовать чистые функции с referential transparency и всеми выгодами FP в том числе для потокобезопасной разработки? И ваш вопрос превращается в "не позволяет создавать несколько экземпляров функции".
Костылём здесь может являться сама стековая реализация исключений, но это совершенно допустимый код. Факт его наличия не говорит, что объект Err потом не исследуется и не осуществляется соответствующая диагностика. Как бы вы себе видели это иначе (без использования maybe монады)? Сделать rethrow исключения, которое уже возникло, а потом его отдельно ловить или просто проверить Err после выполнения функции? А вообще "silencing" часто помогает централизовать обработку ошибок, чтобы достичь хорошего SoC и не тащить в математичекую функцию логгеры, диагностику и т.п.
Во-первых, никаких BackgroundWorker в .NET 1.0, 1.1 не было. И в целом странно критиковать Windows Forms, которая сохранилась для обеспечения совместимости с древними версиями API. Во-вторых, добро пожаловать в мир однопоточных UI и буферизации изменений для обеспечения оптимальной скорости перерисовки. Которые можно найти начиная от древнего досовского Turbo Vision с его Application.Update|Refresh до современных веб-фреймворков вроде React с его реконсиляциями, shouldComponentUpdate, forceUpdate и т.п. Придумайте что-нибудь лучше, вам весь мир будет благодарен. То, что вы отгрузите сложные вычисления в BackgroundWorker - это решение lvl 1. На lvl 2 вам понадобится управление этим воркером из основного потока, чтобы иметь возможность остановить эти вычисления, дождаться остановки вычисления очередного шарда и т.п. На lvl 3 у вас уже скорее всего какие-нибудь реактивные стриминговые асинхронные модели, которые забудут про BackgroundWorker вообще и изредка будут делать DoEvents, только это будет скорее WPF и увидим мы какие-то замысловатые Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })). Что суть тоже самое
Совершенно нормальный подход для FSM или акторных моделей обработки.
"Программируйте на уровне интерфейсов, а не реализаций" - это не про качество абстракций, а про полиморфизм. Абстракции могут быть такими же уродливыми, как и их первые реализации. Зачастую так и происходит. Но не вводя их и улучшать нечего. За качество отвечают уже другие инструменты. Например, ISP, DIP и т.п.
Да, это возможности отлаживать, рефакторить, работать с VCS, профайлерами. Поэтому IDE не просто "запускают тулзы" а предлагают расширяемость через те же плагины, их вызов в контексте конкретного блока кода, автоматизацию через скриптовые языки. Умеют искать не просто текст в файлах, а конкретные виды (идентификаторы, референсы, имплементации интерфейсов и т.п.). Документацию они автоматом соберут, обновят и покажут preview в отдельном табе. Я уж не говорю, что большинство более-менее современных IDE тут же обеспечат удобный интерфейс к СУБД, докеру, TeamCity и т.п. У меня на некоторых виндовых серверах стоит FAR, но это дико не удобно, что я даже в такой среде чаще использую VIM+SSH.
Чтобы стать fluent в использовании языка его надо много раз использовать.
Ничто из мной перечисленного не отменяет написания кода. Просто влияет на его качество.
И уж естественно новички не начинают с приложений на 1000+ LOC.
Речь шла о преподавателях. Их опыте.
А на крошечных обучающих примерах хорошие практики нередко только переусложняют программу.
Осмысленные имена переменных, использование DEFINE констант вместо казуально возникающих чисел, doxygen-стайл документация к функциями вместо собственного колхоза, несколько ассертов для проверки edge-cases, нормальная IDE вряд ли "переусложняют". После первой же демонстрации студенты практически не отлипали от хороших практик. А многое я ещё на школьниках 5-11 классов опробовал)) Моя любимая шутка за их авторством (когда я сказал, что используемый на курсе wgcc не обновлялся с 2007) была: "Кажется препод последний раз обновлялся ещё раньше"))
И в программировании — вначале учишься понимать как код вообще пишется и работает на низком уровне а уже затем — как его организовать на высоком уровне чтобы это было удобно.
Когда им вбрасывают быструю сортировку без объяснения рекурсии, просто как данность, нагрузив их неокрепший мозг работой с указателями - это какой уровень?
И вот все что Вы пишите — это, имхо, как раз в стажировку должно входить
То есть на семинарах нужно преподавать то, как не стоит писать код, а на стажировке всё это исправлять?))
А из других ВУЗов сейчас кто-то хорошую программу на Ваш взгляд дает?
Увы, у меня пока очень маленькая и очень печальная выборка...
1. Полное непонимание, что код не только пишут, но и читают. Были просто дикие решения, которые я мог с трудом прочитать. Например два прохода по файлу с практически автономной логикой заворачивались в цикл от 1 до 2 с диким количеством тернарных операторов внутри (получалось в итоге медленно, нечитаемо и более вербозно). Именование идентификаторов - тоска, я уж молчу про формирование ubiquitous language.
2. Пропахший нафталином стандарт, что самые крутые программисты пишут в FARе, а отладка осуществляется исключительно printf'ами. За CLion били по рукам.
3. C89. Такое захочешь - не откопаешь.
4. TDD вообще не в почете. Хотя бы простыми assert'ами специфицировать условия задачи.
5. Роль header/implementation файлов вообще не объяснена, хотя абстракция/реализация - ключевые концепты в нашем деле и можно было бы её красиво подать.
6. Умение проводить декомпозицию не прививается. Ни на модульном, ни на функциональном уровне. Такое устойчивое ощущение, что преподаватель никогда не писал приложений даже на жалкие 1000 LoC.
В общем дрессируют мыслить линейно, императивно, когда мир активно движется в сторону декларативнго, type-oriented подхода, а приложения - это сложные конструкции. Ключевым вызовам ИТ - масштабируемости, реакции на изменения, командной работе даже близко не соответствует. Что интересно, все эти подходы нисколько не усложняют образовательный процесс, а делают его более органичным.
В прошлом году помогал студентам мехмата МГУ. Уровень преподавания - полное дно. Что парадоксально, восхваляемого математического мышления с абстракциями, блэк-джеком и прочими куртизанками там и не ночевало.
Все пропало... столько лет стараний и стертые до крови пальцы... Звание идеального ушло от меня куда в вакуум, осталось довольствоваться скромным титулом реального программиста.
Было что-то похожее недавно. Нужно было отжимать приходящие CSV размером от 5ГБ. Через имеющийся стриминг (NiFi, Kafka) ползало, но очень печально. Решением оказался Clickhouse. Отправка родному клиенту на stdin 5ГБ с последующей выдачей ключевых метрик (по датасету из 19М строк) на Kafka connector занимало буквально 6-7 секунд. И это на достаточно простом стенде, данные на который вливались с ноута по воздуху и внутри был фактически ещё один ETL stage, то есть импортированный датасет трансформировался в новый с обогащением, конвертацией и т.п.
Так шустро в райдере или в решарпере? Райдер у меня достаточно бодро работает, правда там другие заморочки. Но это уже моя специфика, не всем нужна поддержка iOS Local Device с hot reset.
Видимо тратите время на выполнение руками операций, которые могла бы выполнить машина
У меня постоянное ощущение, что машина стараниями решарпера выполняет слишком много операций)) Уже не первый год пытаюсь заставить себя на него пересесть. Рефакторинг, подсказки, неплохой тест-раннер, всё круто, беру. Но как начинается суровая работа… он своей скоростью убивает на порядок больше, чем даёт производительности труда. Буквально на днях пришло очередное обновления, после которых он любит опять включаться, хотя я ему сказал суровое "disable". Не очень большой проект, гдето 150K LoC. Вытерпел первую загрузку, с тотальным фризом секунд на десять и минутным подтормаживанием то там, то сям. Думаю, сейчас прокэшируется и дальше должно быть лучше. Но любой чих, любая навигация, любая подсказка — это +0.5-2с (Ryzen 5950X, RAM 128G, NVMe PCIe 4.0). Вроде казалось бы ерунда, но лично меня просто жутко выбешивает. Прыжки между фичами вообще беда. Может это исключительно мой паттерн. У меня в силу SRP/ISP огромное количество навигаций. А для рефакторинга я его могу раз в неделю включить и спокойно навести красоту.
А статистика именно по компаниям, склонным к использованию .NET или в целом? Потому что у меня эмпирические картины сильно отличаются. Там где fluentd редко наблюдается .NET. Там где .NET наиболее частая связка serilog+filebeat+logstash.
Странно, ни разу не сталкивался с таким мнением. Проектов на .NET было предостаточно. Северная Америка, Южная, Европа, Океания. От мелких бизнесов до транснациональных. В одном только ООН его море. Кто-то из доверия к бренду, кто-то в силу остального ландшафта в компании, кто-то из-за инструментов. WebForms/WPF были особенно в ходу, поскольку Delphi был не так распространён за пределами СНГ, а какой-нибудь MFC давался сильной болью. Огромное количество бизнес-софта, скажем тот же немецкий Sage (что-то в духе нашего 1С).
И почему все считают, что Бейсик тут отстаивается как самодостаточный функциональный современный ЯП?
Я сравнивал BASIC с Pascal. Так что вы ошиблись адресатом.
Бейсик поддерживает и массивы — первый шаг к структурам.
Я бы спросил, а куда делать следующий шаг, поскольку речь шла о массиве кругов. Но уже понятно, что с вами шагать очень долго. У детей темп намного выше))
Извините, что не разжевал всё до мельчайших деталей. Понимаю, поиск это сложно: - Python. Актуальный master, разжёвано донельзя, утверждают, что "computed gotos" быстрее на 15-20% - - Dalvik VM. Актуальный master. Также всё расписано. - Tarantool. Актуальный вики содержащий в том числе графики сравнения. Был представлен на Google Summer of Code 2021.
Вот такой вот 1959. Ой, простите за сарказм. Это всё 2021. Там, кстати, ссылки, на них можно кликать. Если вдруг вы не только поиск не умеете.
Я думаю вам не составит труда предоставить какие-то бенчмарки со своей стороны, коль скоро вы столь безапелляционно заявляете о доминировании, прости меня бог Computer Science, паттерна State.
Я же говорю, вы своим авторитетом растоптали всех разработчиков и исследователей, короткий список из которых я привёл. Ребята из Google или Tarantool заламывают руки, что в далёком 1959 они не догадались использовать "паттерн State из ООП". Команда наиболее актуальной VM для Erlang, языка известного тем, что он само воплощение actor model, уволилась всем составом. При такой диспозиции кто я такой чтобы с вами спорить, конечно я капитулирую.
Вы сейчас на полном серьёзе говорите, что метод в официальной документации звучащий как [do not rely on await Task.Yield(); to keep a UI responsive](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.yield) лучше, чем Dispatch.Invoke, который MS [сам использует для симулации DoEvents](https://github.com/search?q=org%3Adotnet+doevents+DispatcherPriority&type=code)? Есть какие-то аргументы, что они чего-то не знает о своём продукте? А то как дураки вводили в том же Dispather отдельно метод Yield, в котором DispatcherPriority.Background из моего примера и Dispatcher.InvokeAsync под капотом. Видимо не хотели, чтобы люди выстреливали себе в ногу полагаясь на волатильный SynchronizationContext.Current.
Да и отмечен бы данный подход как "изредка будут делать", а не рекомендуемый. Что основывается на статистике гитхаба. Вот так повелось, используют. Не IAwaitable единым живёт мир многопоточности, некоторые ортодоксы могу использовать тредпулы напрямую, BackgroundWorker, BackgroundService и т.п. А так получилось, что обновление UI из них рекомендуют делать через семейство методов Dispatcher.Invoke.
Судя по фразе "несколько экземпляров" вы пытаетесь натянуть весь богатый мир софта на свой опыт в ООП и считаете, что если в какой-нибудь Akka оверхед на актора всего 300 байт, то и любой ембеддед затащит (хотя и в Akka instance-per-message не является рекомендуемым).
Начнём с того, что речь шла о языке 59 года рождения, там не то что объектами не пахло, там свитчей не было, сердца всех аляповатых FSM. И выживали за счёт динамических goto пока [Multi-way branching replaces the computed goto](https://en.wikipedia.org/wiki/Goto).
А вот нормальные FSM, которых вы своим авторитетным мнением растоптали - это Google с их Dalvik VM, Erlang Beam VM (ни разу не связан с акторными моделями), Python, GCC, GNU Forth, Tarantool, Ruby, Lua и много других. Ссылки предоставить или сами справитесь? Благо "computed goto", "branch table", "jump tables" - техники про которые написаны сотни научных работ, читаются в большинстве технических ВУЗов. Даже как-то странно всё это разжёвывать в мире где можно ввести пару слов в поиск гитхаба и увидеть мировую практику использования того или иного подхода.
И в целом не понял, какая связь между FSM, акторными моделями и состоянием в "экземплярами". У меня дизайн не может использовать чистые функции с referential transparency и всеми выгодами FP в том числе для потокобезопасной разработки? И ваш вопрос превращается в "не позволяет создавать несколько экземпляров функции".
Костылём здесь может являться сама стековая реализация исключений, но это совершенно допустимый код. Факт его наличия не говорит, что объект Err потом не исследуется и не осуществляется соответствующая диагностика. Как бы вы себе видели это иначе (без использования maybe монады)? Сделать rethrow исключения, которое уже возникло, а потом его отдельно ловить или просто проверить Err после выполнения функции? А вообще "silencing" часто помогает централизовать обработку ошибок, чтобы достичь хорошего SoC и не тащить в математичекую функцию логгеры, диагностику и т.п.
Во-первых, никаких BackgroundWorker в .NET 1.0, 1.1 не было. И в целом странно критиковать Windows Forms, которая сохранилась для обеспечения совместимости с древними версиями API. Во-вторых, добро пожаловать в мир однопоточных UI и буферизации изменений для обеспечения оптимальной скорости перерисовки. Которые можно найти начиная от древнего досовского Turbo Vision с его Application.Update|Refresh до современных веб-фреймворков вроде React с его реконсиляциями, shouldComponentUpdate, forceUpdate и т.п. Придумайте что-нибудь лучше, вам весь мир будет благодарен. То, что вы отгрузите сложные вычисления в BackgroundWorker - это решение lvl 1. На lvl 2 вам понадобится управление этим воркером из основного потока, чтобы иметь возможность остановить эти вычисления, дождаться остановки вычисления очередного шарда и т.п. На lvl 3 у вас уже скорее всего какие-нибудь реактивные стриминговые асинхронные модели, которые забудут про BackgroundWorker вообще и изредка будут делать DoEvents, только это будет скорее WPF и увидим мы какие-то замысловатые Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })). Что суть тоже самое
Совершенно нормальный подход для FSM или акторных моделей обработки.
"Программируйте на уровне интерфейсов, а не реализаций" - это не про качество абстракций, а про полиморфизм. Абстракции могут быть такими же уродливыми, как и их первые реализации. Зачастую так и происходит. Но не вводя их и улучшать нечего. За качество отвечают уже другие инструменты. Например, ISP, DIP и т.п.
Да, это возможности отлаживать, рефакторить, работать с VCS, профайлерами. Поэтому IDE не просто "запускают тулзы" а предлагают расширяемость через те же плагины, их вызов в контексте конкретного блока кода, автоматизацию через скриптовые языки. Умеют искать не просто текст в файлах, а конкретные виды (идентификаторы, референсы, имплементации интерфейсов и т.п.). Документацию они автоматом соберут, обновят и покажут preview в отдельном табе. Я уж не говорю, что большинство более-менее современных IDE тут же обеспечат удобный интерфейс к СУБД, докеру, TeamCity и т.п. У меня на некоторых виндовых серверах стоит FAR, но это дико не удобно, что я даже в такой среде чаще использую VIM+SSH.
Ничто из мной перечисленного не отменяет написания кода. Просто влияет на его качество.
Речь шла о преподавателях. Их опыте.
Осмысленные имена переменных, использование DEFINE констант вместо казуально возникающих чисел, doxygen-стайл документация к функциями вместо собственного колхоза, несколько ассертов для проверки edge-cases, нормальная IDE вряд ли "переусложняют". После первой же демонстрации студенты практически не отлипали от хороших практик. А многое я ещё на школьниках 5-11 классов опробовал)) Моя любимая шутка за их авторством (когда я сказал, что используемый на курсе wgcc не обновлялся с 2007) была: "Кажется препод последний раз обновлялся ещё раньше"))
Когда им вбрасывают быструю сортировку без объяснения рекурсии, просто как данность, нагрузив их неокрепший мозг работой с указателями - это какой уровень?
То есть на семинарах нужно преподавать то, как не стоит писать код, а на стажировке всё это исправлять?))
Увы, у меня пока очень маленькая и очень печальная выборка...
Я из Double Commander не вылезаю... когда мне надо работать с файлами. А речь идёт о разработке.
Кабы их учили работать с make-файлами, да ещё бы объяснили, что сборка - это не только компиляция и линковка.
Очень много аспектов. Как пример:
1. Полное непонимание, что код не только пишут, но и читают. Были просто дикие решения, которые я мог с трудом прочитать. Например два прохода по файлу с практически автономной логикой заворачивались в цикл от 1 до 2 с диким количеством тернарных операторов внутри (получалось в итоге медленно, нечитаемо и более вербозно). Именование идентификаторов - тоска, я уж молчу про формирование ubiquitous language.
2. Пропахший нафталином стандарт, что самые крутые программисты пишут в FARе, а отладка осуществляется исключительно printf'ами. За CLion били по рукам.
3. C89. Такое захочешь - не откопаешь.
4. TDD вообще не в почете. Хотя бы простыми assert'ами специфицировать условия задачи.
5. Роль header/implementation файлов вообще не объяснена, хотя абстракция/реализация - ключевые концепты в нашем деле и можно было бы её красиво подать.
6. Умение проводить декомпозицию не прививается. Ни на модульном, ни на функциональном уровне. Такое устойчивое ощущение, что преподаватель никогда не писал приложений даже на жалкие 1000 LoC.
В общем дрессируют мыслить линейно, императивно, когда мир активно движется в сторону декларативнго, type-oriented подхода, а приложения - это сложные конструкции. Ключевым вызовам ИТ - масштабируемости, реакции на изменения, командной работе даже близко не соответствует. Что интересно, все эти подходы нисколько не усложняют образовательный процесс, а делают его более органичным.
В прошлом году помогал студентам мехмата МГУ. Уровень преподавания - полное дно. Что парадоксально, восхваляемого математического мышления с абстракциями, блэк-джеком и прочими куртизанками там и не ночевало.
Все пропало... столько лет стараний и стертые до крови пальцы... Звание идеального ушло от меня куда в вакуум, осталось довольствоваться скромным титулом реального программиста.
Наверно стоит в список когнитивных искажений внести способность везде видеть конгитивные искажения))
Было что-то похожее недавно. Нужно было отжимать приходящие CSV размером от 5ГБ. Через имеющийся стриминг (NiFi, Kafka) ползало, но очень печально. Решением оказался Clickhouse. Отправка родному клиенту на stdin 5ГБ с последующей выдачей ключевых метрик (по датасету из 19М строк) на Kafka connector занимало буквально 6-7 секунд. И это на достаточно простом стенде, данные на который вливались с ноута по воздуху и внутри был фактически ещё один ETL stage, то есть импортированный датасет трансформировался в новый с обогащением, конвертацией и т.п.
Так шустро в райдере или в решарпере? Райдер у меня достаточно бодро работает, правда там другие заморочки. Но это уже моя специфика, не всем нужна поддержка iOS Local Device с hot reset.
Значит перепутал. Адресовал вопрос этой фразе, думал частота была в смысле статистической величины:
А наверно речь шла о периодической. Год используют, год — нет))
У меня постоянное ощущение, что машина стараниями решарпера выполняет слишком много операций)) Уже не первый год пытаюсь заставить себя на него пересесть. Рефакторинг, подсказки, неплохой тест-раннер, всё круто, беру. Но как начинается суровая работа… он своей скоростью убивает на порядок больше, чем даёт производительности труда. Буквально на днях пришло очередное обновления, после которых он любит опять включаться, хотя я ему сказал суровое "disable". Не очень большой проект, гдето 150K LoC. Вытерпел первую загрузку, с тотальным фризом секунд на десять и минутным подтормаживанием то там, то сям. Думаю, сейчас прокэшируется и дальше должно быть лучше. Но любой чих, любая навигация, любая подсказка — это +0.5-2с (Ryzen 5950X, RAM 128G, NVMe PCIe 4.0). Вроде казалось бы ерунда, но лично меня просто жутко выбешивает. Прыжки между фичами вообще беда. Может это исключительно мой паттерн. У меня в силу SRP/ISP огромное количество навигаций. А для рефакторинга я его могу раз в неделю включить и спокойно навести красоту.
А статистика именно по компаниям, склонным к использованию .NET или в целом? Потому что у меня эмпирические картины сильно отличаются. Там где fluentd редко наблюдается .NET. Там где .NET наиболее частая связка serilog+filebeat+logstash.
Странно, ни разу не сталкивался с таким мнением. Проектов на .NET было предостаточно. Северная Америка, Южная, Европа, Океания. От мелких бизнесов до транснациональных. В одном только ООН его море. Кто-то из доверия к бренду, кто-то в силу остального ландшафта в компании, кто-то из-за инструментов. WebForms/WPF были особенно в ходу, поскольку Delphi был не так распространён за пределами СНГ, а какой-нибудь MFC давался сильной болью. Огромное количество бизнес-софта, скажем тот же немецкий Sage (что-то в духе нашего 1С).
Я сравнивал BASIC с Pascal. Так что вы ошиблись адресатом.
Я бы спросил, а куда делать следующий шаг, поскольку речь шла о массиве кругов. Но уже понятно, что с вами шагать очень долго. У детей темп намного выше))