LINUX.ORG.RU

Си с классами

 , ,


0

7

Тупнячка принёс, извиняйте.

Начинаю проект (личный), выбираю на чём писать: C или C++.

Ситуация такая: с плюсами возиться не хочется, да и не знаю я их толком, учил ещё в школе, до сих пор не выучил, но и на чистой сишечке, с другой стороны, писать как-то лениво.

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

Насколько такой суперсет C / сабсет C++ ака «Си с классами» может быть кошерен?

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

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

Помежуточные боссы — Александра Оказио Кортес и Бен Аффлек, а финальный — Джо Байден (на самом деле нет. спойлеры).

на самом деле, это не Байден, а Боря Моисеев (я их постоянно путаю).

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

У вас каша в голове. Вы путаете UB (например, последствия переполнения знаковых целых чисел) и результат непреднамеренной ошибки разработчика, который умудрился сложить метры с секундами

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

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

Более того, в C++11/14 подобные библиотеки стали намного удобнее, т.к. в язык добавили user-defined-literals. Специально для этих целей. Пример можно найти даже в stdlib, благодаря которой сейчас можно писать 100ms или 10s

Годнота, признаю.

AlgDT в C++17 прямо из коробки в виде std::variant
Чего в C++ пока нет, так это паттерн-матчинга. И на это преимущество F# я указывал ранее. Если бы вы читали то, что вам пишут, то не пришлось бы ходить по кругу

Сюрприз — ADT с паттерн матчингом есть под Си:

https://github.com/melt-umn/ableC-algebraic-data-types

Что никак не отменяет того факта, что пользоваться ими неудобно из-за низкоуровневости языка. Мало просто сделать библиотеку — нужно как-то решить вопрос с «std::variant<std::string, void const*>», которыми усыпан весь код. Причем, в Rust дело обстоит еще хуже с ёлочками, несмотря на наличие более продвинутого вывода типов. И макросы в этом не помогают, потому что с типами данных приходится работать, раскрывая и запаковывая их, и потому макросы создают еще больше сущностей в и так сложном коде.

Вы так говорите, как будто в C++ нет const. Может просто не в курсе?

В курсе. Более того, в Си есть const. Только им почти не пользуются. Даже оптимизатор в компиляторе им не пользуется, потому что кто-то возьмет ссылку и кастанет в указатель на изменяемое значение, как это принято делать. Для получения гарантий неизменяемости приходится делать методы доступа, что делает определение банальных структур данных вырвиглазным. Особенно заядлые кодеры на Java/C# сталкиваются с этим постоянно, но просто перестали обращать на это внимание. На то, что ЯП мешает писать код.

Да знаменитой статье Саттера «Free lanch is over» уже больше 15 лет. Или вы тогда еще в школе учились?

На заборе тоже много чего написано. Сказать, и написать код, который использует более одного ядра — это две разные вещи. Sun сделал ставку на процессоры с большим числом ядер — и где сейчас Sun? Что мы имеем по состоянию на 2020? Нода-питон на сервере, однопоточные нативные GUI или однопоточный JS в браузере на клиенте. Вот тебе и «lunch is over».

многопроцессное приложение из однопоточных процессов сделанное таковым из соображений надежности (+ безопасности)

Sic. Бездумное использование многопотоков неизбежно ведет к падучему и зависающему приложению. То есть, специфика твоей профессиональной деятельности подразумевает написание подобных приложений? Я сам подобным занимался много лет, и оглядываясь назад я бы сказал, что потоки создали больше проблем, чем их решили. То есть «у нас приложение тормозит при выполнении тяжелой фоновой работы. Давайте вынесем ее в поток». И теперь приложение тормозит с фоновым потоком, плюс к тому же изредка случайно падает или зависает.

Но я высокоуровневые инструменты применяю, которые позволяют мне использовать Actor Model и/или CSP

Сочувствую. Гугл заменил C++ на Go не просто так. При том, что в отдельных моментах Go будет низкоуровневее крестов.

Итого, по факту, всего два плюсика пока что

Неа, я настаиваю на единственном плюсе, и этот плюс — высокоуровневость кода, описывающего логику вместо внутренней шелухи.

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

2015-й – это уже C++14, причем уже доступный в компиляторах.
А Rust официально зарелизился в 2015 (а стабилизировался перед этим, насколько помню, во второй половине 2014). Rust 2010-го и Rust 2015 – это две большие разницы

C++11 появился в компиляторах только в 2013. Потому, хорошо, не 2015, но 2013.

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

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

Создатели хаскеля изначально эти самые проблемы себе задумали, чтобы их героически решать. Более того, эти самые проблемы притягивают любителей острых ощущений, как ни странно. Это монады и ленивые вычисления. Что характерно, обе фичи есть в F#, но активировать их нужно явно. А от хаскелевого MTL у меня мозги потекли через нос.

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

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

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

От этого и получается обычно балаган и священные войны.

Форум - базар.

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

Пиши на Ada, хошь тебе процедурный, хошь тебе объектный, хошь тебе просто дурный.

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

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

Я вынужден иметь дело с тем, что вы пишете. А пишите вы откровенную херню. И продолжаете это делать, что характерно:

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

Еще раз: UB – это когда вы не знаете, что будет в результате выражения a+b, если сумма не укладывается в отведенный тип. Равно как и не знаете, что будет при попытке сделать v[n]=0, если n выходит за границы v.

Фокус, однако, в том, что UB здесь не просто так, а для получения максимальной производительности. Попробуйте сделать рантайм, который будет контролировать арифметические переполнения, и увидите, что у вас не будет сравнимой с C++ скорости.

А вот когда в a+b вы складываете килограммы с секундами, то это уже алгоритмическая ошибка разработчика. При этом в C++ вы можете использовать инструменты, которые защищают вас от подобных ошибок.

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

Сюрприз — ADT с паттерн матчингом есть под Си:

И при чем здесь C++? Если вы забыли, то мы здесь сравниваем высокоуровневость C++ и F#. Так вот, в C++ АлгТД есть прямо в языке. А вот паттерн-матчинга пока нет.

И нет, нормальный паттерн-матчинг без поддержки со стороны компилятора вы в язык никак не затащите. Хоть макросами, хоть шаблонами с constexpr.

В курсе. Более того, в Си есть const. Только им почти не пользуются.

Это проблемы Сишников. В C++ const есть и применяется широко. По крайней мере в нормальных командах. Так что в C++ вы спокойно можете иметь иммутабельные данные.

Особенно заядлые кодеры на Java/C# сталкиваются с этим постоянно, но просто перестали обращать на это внимание. На то, что ЯП мешает писать код.

Не нужно кивать в сторону Java/C# при обсуждении возможностей C++. Вероятно, про Java/C# вы знаете больше, чем про C++. Но сравнению C++ с F# это никак не помогает.

На заборе тоже много чего написано. Сказать, и написать код, который использует более одного ядра — это две разные вещи.

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

Или вам так уж неймется излить в мир все те заблуждения и фобиии, которые бурлят в вашей башке?

Sic. Бездумное использование многопотоков неизбежно ведет к падучему и зависающему приложению.

Бездумное использование чего угодно неизбежно ведет к падучему и зависающему коду. Многопоточность здесь не исключение.

Многопроцессные приложения, состояние из группы однопоточных процессов, по соображениям надежности и безопасности делают потому что:

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

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

Я вашего кода не видел. Может там лютый звиздец (ну судя по тому, насколько связно вы изглагаете кашу из своей головы). Так что аппеляция к опыту здесь вообще никак не показатель.

Сочувствую.

Сочувствете тому, что у меня нет проблем с многопоточным кодом в C++?

Спасибо, не нужно.

Гугл заменил C++ на Go не просто так.

Вы уж определитесь с темой разговора: либо вас интересуют мои проблемы при написании многопоточного кода на C++, либо причины появления Go в Google.

Неа, я настаиваю на единственном плюсе, и этот плюс — высокоуровневость кода, описывающего логику вместо внутренней шелухи.

Похоже, что для вас «высокоуровневость» – это ваше личное ощущение комфорта. Ну вот обсудать ваши личные ощущения вряд ли имеет смысл.

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

C++11 появился в компиляторах только в 2013. Потому, хорошо, не 2015, но 2013.

Юноша, поддержка C++0x начала появляться в C++ компиляторах уже в 2010-ом году. Говорю вам как человек, который осенью 2010 начинал новый проект как раз на C++0x. Да, еще до официального принятия C++11.

Можете почитать официальные описания релизов gcc 4.4 и 4.5 если на слово не верите.

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

Предложения по добавлению в C++ паттерн-матчинга уже есть. И это направление было признано одним из приоритетных для C++23/26.

Кстати, что думаешь по этим предложениям? По-моему, какая-то куча вонючего говна. Авторы как будто не видели как pattern matching работает в других языках, а придумали своё и переусложнили до предела. Я буду очень удивлён, если это примут в C++23 или даже 26.

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

Кстати, что думаешь по этим предложениям?

Я бы лично хотел бы видеть это уже в C++20. Но даже этого придется ждать еще (хз сколько) лет.

По-моему, какая-то куча вонючего говна.

А предметнее?

Я далек от разработки ЯП, поэтому мне сложно сказать, как должно выглядеть хорошо. Но C++ сам по себе такой язык, что в нем уже, кажется, просто и понятно не бывает. Наиболее яркий пример – это модули из C++20.

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

Уточнил

Ты покажешь, что уточнил? Пока ты пишешь «масло масленное» и переливаешь из пустого в поржнее.

Идинственный кто уточнил - это фсб4000 с «inline».

При этом никто не среагировал на мой хелловорлд Си с классами (комментарий) . Пока я подробно не расписал, чем отличается вывод типов от шаблонов/обобщений Расписал по памяти то, что отложилось на основе собственного опыта. Только после этого появились уточнятели-умники с гуглом и оффтопным компилятором под рукой.

А ты даже это не можешь, пишешь народными присказками - «масло масленное», и не понятно как и к чему это применить.

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

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

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

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

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

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

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

уточнение лишь к подаче твоей, она как всегда однобока без попыток понять твоих оппонентов

В чем однобокость?

Что неправильно понял eao197? Что означает его «спасибо»? Непонимание?

Что неправильно понял фсб4000? Что ему пришлось найти в гугле «наше всё» - inline. Который работает совсем не как «вывод типов по Хиндли-Милнеру».

А вот что однозначно видно - это твоя однобокость: видите ли, я неправильно сравнил «let» и «template». Адназначна!

На себя посмотри, «эксперт по однобокости».

Еще раз задам вопрос: что ты нового сказал про вывод типов? Критикуешь - предлагай. Расскажи про вывод типов правильно и неоднобоко.

Жду.

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

Вперед!

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

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

Опыт работы начальником «заправочной станции» …

anonymous
()

C с классами - это Objective-C, Swift. Всё уже есть, есть Crystal, Go (если ООП нахрен не нужен), Nim, D - все эти языки вполне кошерны

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

У D отключаемый, но кому это нужно? Трём одарённым?

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

Да я уже посмотрел. Предложение не становится проще. Нагромождение разных типов паттернов удручает/устрашает:

wildcard pattern
identifier pattern
expression pattern
structured binding pattern
alternative pattern
parenthesized pattern
case pattern
dereference pattern
extractor pattern

Для сравнения в Скале сколько там типов паттернов? https://docs.scala-lang.org/tour/pattern-matching.html

А всё потому, что в C++ нет алгебраических типов данных на самом деле. В тех языках, где эти типы данных есть, pattern matching по ним не представляет трудностей.

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

@X512

Зацени scope_exit в C: https://gcc.godbolt.org/z/6qxo3q

Можно ещё #ifdef __cplusplus и реализовать такой же по использованию scope_exit через лямбду, деструктор и макрос на стандартном С++. Будет переносимый С/С++ код с автоматическим освобождением ресурсов…

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

Зацени scope_exit в C: https://gcc.godbolt.org/z/6qxo3q

__attribute__((__cleanup__ (cleanup_deferred)))

Нестандартное расширение: x64 msvc v19.14 (WINE): <Compilation failed>.

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

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

Будет переносимый С/С++ код

Что подразумевается под переносимостью? С <–> C++ лямбды на Си? -std=gnu99?

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

Что подразумевается под переносимостью?

Сборка одного исходного кода на:

  • C clang

  • C gcc

  • C++ MSVC

  • C++ g++

  • C++ clang++

  • Другие компиляторы С++.

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

Сборка одного исходного кода на:

C clang

C gcc

Зачем это нужно если в gcc и clang Си и С++ имеют общую реализацию? Или вы собираетесь под TCC компилировать? Он вроде бы не поддерживает __attribute__((__cleanup__)).

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

в C++ нет алгебраических типов данных на самом деле.

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

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

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

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

Разве std::unique_ptr не достаточно?

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

Зачем это нужно если в gcc и clang Си и С++ имеют общую реализацию?

не имеет.

gcc и clang по разному реализуют лямбды в С.

clang позволяет использовать С-block из objective-c в обычном С.

gcc позволяет определять вложенные функции у которых есть доступ к переменным.

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

-std=gnu99

Другие компиляторы С++.

Где-то здесь противоречие.

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

clang позволяет использовать С-block из objective-c в обычном С.

gcc позволяет определять вложенные функции у которых есть доступ к переменным.

Компилятороспецифичные фичи не нужны (вернее они нужны только для поддержки платформоспецифичного функционала вроде stdcall/ccall). Вложенные функции можно сделать в C++ через лямбды или классы внутри функций.

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

Для сравнения в Скале сколько там типов паттернов?

Да как бы немало (https://www.scala-lang.org/files/archive/spec/2.12/08-pattern-matching.html):

Variable Patterns
Typed Patterns
Pattern Binders
Literal Patterns
Stable Identifier Patterns
Constructor Patterns
Tuple Patterns
Extractor Patterns
Pattern Sequences
Infix Operation Patterns
Pattern Alternatives
XML Patterns
Regular Expression Patterns
Irrefutable Patterns
eao197 ★★★★★
()
Ответ на: комментарий от X512

Вложенные функции можно сделать в C++ через лямбды или классы внутри функций.

Да. И будет код который можно собрать основными компиляторами С, и всеми компиляторами С++.

@anonymous

-std=gnu99

Другие компиляторы С++.

Где-то здесь противоречие.

Вот для анонима специально:

https://gcc.godbolt.org/z/dzGhzd

Понятно ещё всяких concept можно навесить или ещё чего-нибудь…

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

основными компиляторами С

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

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

Разве std::unique_ptr не достаточно?

Это даже до линейных типов не дотягивает.

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

-std=gnu99

Другие компиляторы С++.

-std=c++20

Противоречий стало больше. Другие компиляторы не появились.

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

Так что зачем заморачиваться совершенно не понятно.

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

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2542.pdf

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

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

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

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

UB – это когда вы не знаете, что будет в результате выражения a+b, если сумма не укладывается в отведенный тип. Равно как и не знаете, что будет при попытке сделать v[n]=0, если n выходит за границы v...

А вот когда в a+b вы складываете килограммы с секундами, то это уже алгоритмическая ошибка разработчика. При этом в C++ вы можете использовать инструменты, которые защищают вас от подобных ошибок

Блин, ну ты снова пишешь так, будто кроме крестов в мире ничего не существует. Выход за пределы массива — это в том числе «складывание килограммов с секундами», только вместо килограммов можешь подставить размер одного массива, а вместо секунд — другого.

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

Если вы забыли, то мы здесь сравниваем высокоуровневость C++ и F#. Так вот, в C++ АлгТД есть прямо в языке. А вот паттерн-матчинга пока нет

Во-первых, ADT в сишечке: https://en.cppreference.com/w/c/language/union

Во-вторых, паттерн-матчинг эксплуатирует вывод типов и вообще саму систему типов языка, позволяя крайне лаконично описывать паттерн «посетитель». который является одним из столпов языка. C/C++ уже построен на другом фундаменте, и попытка ввода паттерн-матчинга в эти языки — это натягивание совы на глобус, что приводит к появлению лишних прослоек и тяжелых объявлений типов, что в итоге мешает вести разработку, а не помогает.

Это проблемы Сишников. В C++ const есть и применяется широко. По крайней мере в нормальных командах. Так что в C++ вы спокойно можете иметь иммутабельные данные

Еще раз: неизменяемые данные реализуемы в Си, и с некоторым натягом реализуемы в ассемблере. Разговор вообще не об этом, а о том, насколько это удобно делать. Описания неизменяемых структур данных в разы больше в C++/C#/Java, чем в том же F# (если не считать базовых примитивных типов).

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

Да, я вспомнил кто ты и как я первый раз с тобой познакомился. А именно, я крайне скептически оценил твою либу. Если тебя так беспокоит этот момент, то я могу несколько обновить свою позицию.

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

Вот как делаются простейшие акторы в F# на Akka.NET:

let handleMessage (mailbox: Actor<'a>) msg =
    match msg with
    | Some x -> printf "%A" x
    | None -> ()

let aref = spawn system "my-actor" (actorOf2 handleMessage)
let blackHole = spawn system "black-hole" (actorOf (fun msg -> ()))

Я думаю, что мне не нужно тебе объяснять, насколько сложнее аналогичный код будет описываться в C/C++. И насколько выше шансы угробить систему кривыми руками в C++, и тем более в C.

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

Похоже, что для вас «высокоуровневость» – это ваше личное ощущение комфорта. Ну вот обсудать ваши личные ощущения вряд ли имеет смысл...
Сочувствете тому, что у меня нет проблем с многопоточным кодом в C++?

Сочувствую, что ты кроме кактуса ничего не пробовал. Мне очень тяжело на этом фоне объяснить, что «удобно» определяется не только длиной иголок.

Вы уж определитесь с темой разговора: либо вас интересуют мои проблемы при написании многопоточного кода на C++, либо причины появления Go в Google

Нет, я не ошибся — причиной появления Go стали проблемы написания многопоточного кода на C++. У Go весьма долгая история в виде Limbo (1995) и Alef (1992), которые оба решали проблему многопоточного кода на C/C++ через введение CSP в язык. Причем у более раннего Alef даже не было сборки мусора, то есть, он ни разу не был попыткой заменить жаву — особенно учитывая тот факт, что жава появилась на несколько лет позже.

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

Юноша, поддержка C++0x начала появляться в C++ компиляторах уже в 2010-ом году. Говорю вам как человек, который осенью 2010 начинал новый проект как раз на C++0x. Да, еще до официального принятия C++11

Так я ж не спорю, что чухаться начали раньше. И в расте чухаться начали раньше. Но релиз для GCC был в 2013, а у раста, соответственно, в 2015.

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

придумали своё и переусложнили до предела

Суть 92,87% фич C++.

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

Что ему пришлось найти в гугле «наше всё» - inline. Который работает совсем не как «вывод типов по Хиндли-Милнеру»

Чего вы так привязались к Хиндли-Милнеру? Его вообще кто-то нынче использует без изменений? Некоторые еще и умудряются говорить, что в Scala вывод делается по Хиндли-Милнеру, несмотря на то, что этот весь язык построен на фундаменте отказа от Хинлди-Милнера в пользу более прогрессивного локального вывода типов. У оригинального Хиндли-Милнера много ограничений, потому предлагаю не равняться на него.

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

У Swift неотключаемый ARC

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

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

Зацени scope_exit в C: https://gcc.godbolt.org/z/6qxo3q

Не в Си, а в GCC, который пишут не совсем адекватные ребята, и очень скоро, на мой взгляд, они докатятся до того, что не смогут компилировать GCC при помощи самого GCC другой версии, после чего создатели дистрибутивов просто не смогут скомпилировать GCC для своего дистра и перейдут на clang, как это сделал FreeBSD.

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

Но разница есть. В Скале эти паттерны выглядят естественно и не так сильно отличаются друг от друга. В них практически всегда конструкторы для ADT. Какой конструктор подошел, тот паттерн и выбран. А в этом предложении не только все паттерны выглядят по-разному, они ещё и изобрели свой язычёк специально для паттернов, например, [.lhs: (*!) l] => { print_leftmost(l); } - что это за херня?

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

Так я ж не спорю, что чухаться начали раньше. И в расте чухаться начали раньше. Но релиз для GCC был в 2013, а у раста, соответственно, в 2015.

Речь не про спор, а про незнание предмета. Rust между 2010 и 2014 кардинально поменялся, на разных стадиях его рождения это были разные языки.

А вот в C++ все было принципиально не так. И появление полной поддержки C++11 в компиляторах никак не приводило к необходимости переписывать код, разработанный в 2010-ом на C++0x.

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

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

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

Вот несколько ярчайших примеров.

В разговоре про С++ вы смешиваете понятие UB (данное понятие тупо существует на уровне языка) и алогоритмические ошибки разработчика. Когда вам на это указываешь, вы бежите куда-то в сторону:

Блин, ну ты снова пишешь так, будто кроме крестов в мире ничего не существует.

Так разговор идет про C++. Если в разговоре про C++ вы путаете важные понятия, то без разницы, что еще в мире существует. Вы элементарно не разбираетесь в том, о чем говорите.

Далее, вы стенаете, что в 2020-ом настоящая проблема писать многопоточный код и использовать более одного вычислительного ядра. На что вам указывают, что это уже несколько десятков лет вообще не проблема.

Как вы реагируете? А вот так:

Да, я вспомнил кто ты и как я первый раз с тобой познакомился. А именно, я крайне скептически оценил твою либу.

Меня не беспокоит ни то, как вы что-то оцениваете (а так же ваша способность адекватно оценивать вообще хоть что-либо), ни то, вспомнили ли вы меня или нет.

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

Ну и вишенка на торте. Я вас прошу определиться с тем, что вы хотите обсуждать: мои проблемы при написании многопоточного кода или же причины появления языка Go в Google.

Вам нужно выбрать одно из двух. Выбрать, Карл, одно из двух! И что?

Нет, я не ошибся — причиной появления Go стали проблемы написания многопоточного кода на C++.

«Нет, я не ошибся» – это вообще о чем?

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

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

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

https://en.cppreference.com/w/c/language/union

Это не АлгТД, т.к. union-ы в C не позволяют самодостаточно хранить объекты с нетривиальными деструкторами. Т.е. вы можете засунуть в union структуру с указателями на размещаемые в динамической памяти данными. Но уничтожать экземпляр такого union-а вам придется вручную. При этом вам еще как-то придется разбираться, какое именно значение в union-е хранится.

В тоже время плюсовый std::variant сам разбирается с тем, что в нем лежит и самостоятельно вызывает деструктор у нужного значения.

А стало это возможным благодаря наличию соответствующих языковых возможностей в C++, коих нет в чистом Си. Что и служит очередным подтверждением того, что C++ более высокоуровневый, чем Си.

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

Я думаю, что мне не нужно тебе объяснять, насколько сложнее аналогичный код будет описываться в C/C++. И насколько выше шансы угробить систему кривыми руками в C++, и тем более в C.

Как раз нужно. Только касательно C++, чистый Си меня не интересует.

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

#include <so_5/all.hpp>

using namespace so_5;

template<typename Msg>
struct demo : public agent_t {
   demo(context_t ctx) : agent_t{ctx} {
      so_subscribe_self().event(
         [](mhood_t<Msg> cmd) { std::cout << *cmd << std::endl; });
   }
};

int main() {
   so_5::launch([](environment_t & env) {
         auto [str_mbox, int_mbox] = env.introduce_coop([](coop_t & c) {
                  return std::make_tuple(
                        c.make_agent< demo<std::string> >()->so_direct_mbox(),
                        c.make_agent< demo<int> >()->so_direct_mbox());
               });

         send<std::string>(str_mbox, "Hello, World!");
         send<int>(int_mbox, 42);

         env.stop();
      });

   return 0;
}

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

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

eao197 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.