LINUX.ORG.RU

про то, как видеть C++

 , ,


2

3

Ещё не выздоровел до конца после темы с воспалением легких и легко устаю, и вот посреди одного доклада по C++ на конференции я натурально уснул, и во сне приснилось удивительное.

Проснувшись я стал смотреть на синтаксис C++ и видеть его сквозь призму того, что читал о Haskell (никогда не программировал на нём, а только писал хэлловорлды), и своего небольшого опыта со Scala - всякие scalaz, cats, итп.

Если в глазах иметь своеобразный фотошоп, который выбрасывает из синтаксиса C++ __Уродливые_Идентификаторы и [квадратно](гнездовые) -> конструкции, то на поверхность проступает красота и логичность происходящего. Ты видишь аппликативные функторы и произростающие из них монады, которые просто томятся в застенках из покосившехся скобочкек и отсутствия базовых вещей вроде каррирования.

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

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

Подскажите, верно ли моё восприятие? Как двигаться в этом направлении? Нужно ли мне углубляться в Haskell параллельно с изучением C++?

★★★☆☆

Если в глазах иметь своеобразный фотошоп, который выбрасывает из синтаксиса C++ __Уродливые_Идентификаторы и [квадратно](гнездовые) -> конструкции, то на поверхность проступает красота и логичность происходящего.

И наверняка такой фотошоп встроен в глаза любого практика, включается буквально через месяц использования.

Нет. Даже практики признают уродливость всего этого

SZT ★★★☆ ()

http://aras-p.info/blog/2018/12/28/Modern-C-Lamentations/ про то, как современный C++ видят практики, писавшие на нем 20 лет:

Maybe that is mother tongue to someone, but to me this feels like someone decided that “Perl is clearly too readable, but Brainfuck is too unreadable, let’s aim for somewhere in the middle”. And I’ve been programming mostly in C++ for the past 20 years. Maybe I’m too stupid to get this, okay.

SZT ★★★☆ ()

Не понимаю, почему C++ упарываются по __идентификаторам. Открыл как-то исходники STL и тут же закрыл - нечитабельно. Ту же джаву открываешь какой-нибудь HashMap, абсолютно читаемый код. А тут как будто конкурс по нечитабельности устроили. Выбросить бы всё уродство из С++ и был бы приятный язык.

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

Не понимаю, почему C++ упарываются по __идентификаторам. Открыл как-то исходники STL

Просвещайся

https://timsong-cpp.github.io/cppwp/n4659/lex.name#3

In addition, some identifiers are reserved for use by C++ implementations... Each identifier that contains a double underscore __

и тут же закрыл

Отлично. Больше не открывай и вообще о C++ не думай.

Выбросить бы всё уродство из С++ и был бы приятный язык.

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

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

Исходники STL это детали реализации. Никаких __ там быть не должно.

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

Да он уже и так всех отсеял, радуйся.

Legioner ★★★★★ ()
Последнее исправление: Legioner (всего исправлений: 2)

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

https://www.youtube.com/watch?v=Wp_K8prLfso

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

Не понимаю, почему C++ упарываются по __идентификаторам. Открыл как-то исходники STL и тут же закрыл - нечитабельно. Ту же джаву открываешь какой-нибудь HashMap, абсолютно читаемый код. А тут как будто конкурс по нечитабельности устроили. Выбросить бы всё уродство из С++ и был бы приятный язык.

В сишке такая же хрень. Взять тот же Glibc, например. Мало того, что нечитабельный, так ещё и сегфолтится и всем пофиг.

EXL ★★★★★ ()

Да.

Как обычно, читать STL, Boost, Loki.

Опыт с хаскелем (Окамлом, F#) полезен.

И это, поднажми еще на свое лечение! Может, новым Степановым станешь.

anonymous ()

Словил фейспалм посередине поста. Посмотри лучше на Rust — там не надо 10 лет ждать, пока на нем станет приятно писать (да, реклама, ну и что).

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

Не понимаю, почему C++ упарываются по __идентификаторам. Открыл как-то исходники STL и тут же закрыл - нечитабельно.

Вот здесь пояснение от члена комитета по стандартизации C++ от России: https://habr.com/ru/company/yandex/blog/323972/#comment_10133110

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

про то, как современный C++ видят практики, писавшие на нем 20 лет:

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

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

Всем, кто заявляет о якобы «красивости» C++ я советую почитать исходники Boost

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

eao197 ★★★★★ ()

Нужно ли мне углубляться в Haskell параллельно с изучением C++?

А сейчас придётся ну, самостоятельно заниматься расширением сознания

Покупаешь грибов. Идёшь в парк. Ешь грибы. Наслаждаешься жизнью.

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

Не понимаю, почему C++ упарываются по __идентификаторам. Открыл как-то исходники STL и тут же закрыл - нечитабельно.

__идентификаторы зарезервированы как раз для стандартной библиотеки. Чтоб не конфликтовать с пользовательским кодом.

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

Ту же джаву открываешь какой-нибудь HashMap, абсолютно читаемый код.

Там:

  • нет макросов, которые могут поломать код библиотеки
  • нет переопределений операторов (STL должен работать даже с типами, которые переопределяют амперсанд или запятую)
  • код библиотеки не включается в код приложения во время компиляции
  • нету «безсмысленных» родительских классов чтобы сэкономить 4/8 байт (empty base optimization)
  • возможности языка не разнятся от компиляции к компиляции
xaizek ★★★★★ ()
Ответ на: комментарий от Legioner

some identifiers are reserved for use by C++ implementations... Each identifier that contains a double underscore __

Исходники STL это детали реализации. Никаких __ там быть не должно.

В реализации не должно быть идентификаторов особого вида, зарезервированного для этой реализации? Да ты совсем конченый дебил, как я вижу.

anonymous ()

Я считаю, что также как и любому, желающему программировать на функциональном языке надо изучить один из вариантов Lisp, желающим программировать на чистом языке с развитым статическим полиморфизмом (а C++ уже такой) надо обязательно изучить Haskell. Параллельно можно найти работу на той же Скале.

А что касается будущего C++, то оно омрачается тем, что он принципиально не чистый (для оптимизаций), а также кроссплатформенный (что выливается в слишком мощные макросы). Ждём C++20, посмотрим что они в итоге наворотят. КМК, должен появиться strictest C++ диалект, с тривиальным интеропом с обычным C++. А может это будет отдельный язык, что-то на тему Scala/Kotlin. А ещё хочется, что бы появились какие-то формализмы для работы с эффектами, связанными с выделением памяти (КМК все чистые языки сейчас абстрагируются от них за счет управлением памятью с GC).

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

Не, ну так-то зачем? =)

Исходники STL это детали реализации. Никаких __ там быть не должно.

Подчёркивание или двойное подчёркивание, как правило, ставится в каком-то внутреннем для библиотеки или директив компилятора (в случае двойного подчёркивания) идентификаторе, например, __builtin* и иже с ними. Эти символы для внутренней реализации и программисту как правило сугубо фиолетово сколько там подчёркиваний, т.к. область видимости идентификаторов с «_» вообще ограничена если не блоком кода, так файлом и не более. Так повелось исторически, ещё со времён стандарта ANSI-C. Программисты об этом как правило, либо помнят, либо знают и в трезвом уме и здравой памяти не будут в своём namespace использовать идентификаторы, начинающиеся либо с «_», либо с «__» (если только они не пишут какую-то свою внутреннюю реализацию, куда другой программист не полезет просто так). Если для С, то вот http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf ISO/IEC 9899:201x, где параграф 7.1.3 прямо говорит об этом:

All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

И:

All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

В частности, в доке на libc об этом прямо сказано (https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html):

In addition to the names documented in this manual, reserved names include all external identifiers (global functions and variables) that begin with an underscore (‘_’) and all identifiers regardless of use that begin with either two underscores or an underscore followed by a capital letter are reserved names. This is so that the library and header files can define functions, variables, and macros for internal purposes without risk of conflict with names in user programs.

В С++ соглашения остались практически полностью аналогичными, учитывая специфику языка, конечно.

Для Вас либо библиотека есть чёрный ящик и детали реализации Вам не важны (привет принципам ООП и модульности в программировании!), либо Вы лезете внутрь либы, готовые воспринять соглашения о наименованиях, если принимаете решение там что-нибудь «поправить». Т.е., либо Вы являетесь программистом, пишущем на данном языке, либо нет. В последнем случае ничего страшного. Есть масса других прекрасных, гибких, мощных и выразительных языков... Подберите себе по вкусу. Ни в чём себе не отказывайте. =)

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

Может, дело просто в руках?

Мало того, что нечитабельный, так ещё и сегфолтится и всем пофиг.

Читая такие громогласные заявления я порой вспоминаю поговорку про, простите, тесные и глубокие отношения дурака и стеклянного полового члена. Простите великодушно ещё раз... =)))

Moisha_Liberman ()
Ответ на: Не, ну так-то зачем? =) от Moisha_Liberman

область видимости идентификаторов с «_» вообще ограничена если не блоком кода, так файлом и не более.

А бывает область видимости, не ограниченная файлом (translation unit в терминах стандарта)?

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

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

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

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

Это кривулина. Но так бывает.

А бывает область видимости, не ограниченная файлом (translation unit в терминах стандарта)?

Программиста ни что не ограничивает от использования глобальных переменных на уровне какого-то проекта в целом. И никто не может ему запретить использовать глобальные для проекта переменные с символами подчёркивания в префиксе. Компилятор тут ни чего не скажет. Он посчитает использование данных переменных вполне валидным при отсутствии конфликта имён.

Но это просто плохой стиль. Не более.

Moisha_Liberman ()
Ответ на: Это кривулина. Но так бывает. от Moisha_Liberman

Таки как понимать «область видимости ограничена файлом, не более»? Чем это выделяет идентификаторы с __? Бывает область видимости более файла?

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

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

Так захотят - всё равно поломают. #define front back, например. Ну гуру придумают что-нибудь поинтересней, я уверен.

И на всё вышеперечисленное должны быть улучшения языка, а не какой-то бред в реализации. Хотя бы потому, что любой программист может хотеть писать библиотеку. Но ни один не захочет писать её в таком стиле (тем более, что пользовательской библиотеке по идее даже те гарантии типа __ не переопределено не доступны).

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

Только вот будет ли его мнение более объективным, чем мнение того практика с 20-летним отытом, кому C++ не нравится?

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

Я вот смотрю на эти метапрограммирования с шаблонами и констэкспрами в C++, и что-то мне совсем-совсем не кажется, что в этом всем есть что-то хорошее.

Критики современного C++ почему-то забывают одну простую вещь: у вас никто не забирает те возможности старого C++, которыми вы пользовались раньше. Не хотите использовать шаблоны, constexpr и лямбды — да не используйте. Пишите как диды завещали. И, что характерно, ваш код вполне себе будет компилироваться современными компиляторами.

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

eao197 ★★★★★ ()
Ответ на: Не, ну так-то зачем? =) от Moisha_Liberman

Эти символы для внутренней реализации

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

Для Вас либо библиотека есть чёрный ящик и детали реализации Вам не важны (привет принципам ООП и модульности в программировании!), либо Вы лезете внутрь либы, готовые воспринять соглашения о наименованиях, если принимаете решение там что-нибудь «поправить».

Вообще когда я изучаю любой язык, я в первую очередь лезу в его стандартную библиотеку по любому поводу. Документации всегда недостаточно, а иногда она даже врёт. Код не врёт. Кроме того это позволяет увидеть, как положено писать на этом языке, какие-то идиомы. Этот подход работает для Java, Kotlin, Rust, например. Но вот для C++ он не работает и это плохо. Кстати для Scala он тоже не работал, когда я последний раз туда лазил. Правда, насколько я знаю, они осознают, что это проблема и вроде даже чего-то улучшали, давно не интересовался.

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

Для начала выкинуть семантику #include-ов, хотя бы в отношении новых исходников. Пишешь там в заголовке файла module vector и в твой уютный файлик уже не пролазят никакие сторонние define-ы. Только те, которые ты заимпортишь через какой-нибудь use define или вообще никакие, пора бы в C++ объявить их устаревшими, вроде средств языка для замены должно хватать. Насчёт переопределения операторов амперсанда и запятой не знаю, я не очень понимаю, как это мешает писать код стандартной библиотеки, но если мешает, или запретить использовать такие классы в качестве элементов контейнера, или оставить как есть. По-мне не надо было такое изначально разрешать. Остальные пункты я не понял.

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

Для начала выкинуть семантику #include-ов, хотя бы в отношении новых исходников.

Какие, пилять, новые исходники. Стандартные заголовочные файлы, в которые вы заглядываете, имеют историю в несколько десятков лет развития. По крайней мере первые реализации STL — это район 1992-1993 годов, с 1994-го их начали затаскивать в stdlib.

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

Насчёт переопределения операторов амперсанда и запятой не знаю, я не очень понимаю
Остальные пункты я не понял.

Еще один «малолетний дебил» (с) выступает за все хорошее против всего плохого. Не знаю, не понимаю, но мнение имею.

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

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

Java-макака пытается в мыслительную деятельность? Лол.

Препроцессору плевать на твою область видимости локальных переменных. На любую область видимости плевать, он не оперирует такими понятиями.

anonymous ()

верно ли моё восприятие?

Define верно

Как двигаться в этом направлении?

Написать свою реализацию: придумать такой язык, компилер/транслятор в другие языки к нему и посмотреть как пипл это схавает.

Нужно ли мне углубляться в Haskell параллельно с изучением C++?

Если кто-то заставляет

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

Бывает область видимости дальше файла?

Бывает. Глобальные переменные так не зря называются.

Файл file.h:

extern int __stupid_global;

Файл file1.c:

#include "file.h"

__stupid_global = 1;

Файл file2.c:

#include "file.h"

__stupid_global = 2;

В принципе, можно и без header обойтись. Но название переменной я не зря такое взял. Этот подход чреват неуёмным сексом в последствии. Хоть компиль даже и не ругнётся. С областями видимости разобрались? =)

Чем это выделяет идентификаторы с __?

С «__» это, как правило, идентификаторы каких-то директив компилятору. Например, __LINE__, __FILE__, вот тут ещё горсточка — https://software.intel.com/sites/landingpage/IntrinsicsGuide/# Это интеловские инстриники, по сути директивы компилятору. Или вот — https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html

Давайте посмотрим на один из примеров:

typedef int v4si __attribute__ ((vector_size (16)));

v4si a = {1,2,3,4};
v4si b = {5,6,7,8};
v4si mask1 = {0,1,1,3};
v4si mask2 = {0,4,2,5};
v4si res;

res = __builtin_shuffle (a, mask1);       /* res is {1,2,2,4}  */
res = __builtin_shuffle (a, b, mask2);    /* res is {1,5,3,6}  */

Здесь явно сказано компилятору считать тип v4si имеющим атрибут, определяющий данную переменную как переменную векторного типа с размерностью в 16 int, а __builtin_shuffle означает что мы работаем тут с векторами (и это тоже директива компилятору). Более подробно здесь — http://www.rowleydownload.co.uk/arm/documentation/gnu/gcc/Vector-Extensions.html

Но в обоих случаях несложно заметить что «__» это именно директивы компилятору. Которыми нужно пользоваться с умом, либо не пользоваться вовсе. Таким образом, ответ на вопрос «чем это выделяет», будет «наличием мозгов у программиста». Такой ответ устроит? =)))

Таки как понимать «область видимости ограничена файлом, не более»?

При написании библиотеки внутренняя переменная как правило живёт только внутри одного файла. Её нет смысла выносить в глобальное пространство имён. Т.е., например, у Вас есть некая libastral.so. К ней идёт header-файл libastral.h, который Вы должны в своём коде #include <libastral.h>. Так вот, у грамотного программиста вероятность найти там __stupid_global (см.пример в начале) стремится к нулю. Но компилятор этого не запрещает.

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

Бывает

Не вижу доказательства. Было бы, если бы без #include "file.h" идентификатор __stupid_global был видим.

А с #include "file.h" это просто область видимости начинающаяся после объявления extern int __stupid_global; и заканчивающаяся в конце file1(2).c

https://timsong-cpp.github.io/cppwp/n4659/basic.scope#namespace-3

The outermost declarative region of a translation unit is also a namespace, called the global namespace. A name declared in the global namespace has global namespace scope (also called global scope). The potential scope of such a name begins at its point of declaration and ends at the end of the translation unit that is its declarative region. A name with global namespace scope is said to be a global name.

utf8nowhere ★★ ()
Последнее исправление: utf8nowhere (всего исправлений: 1)

Та успоґокойся ты уже с этим говном. Уже давно сделали стандарт C++ 2045 со встроенным хаскелем - Rust. Нету смысла ждать пока из С++ задепрекейтитят все дерьмо

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

Документации всегда недостаточно, а иногда она даже врёт.

Трепло, ты бы для начала что такое стандарт узнал.

Код не врёт. Кроме того это позволяет увидеть, как положено писать на этом языке, какие-то идиомы

Хорошо, из этого(https://github.com/rust-lang/rust/blob/master/src/libcore/option.rs#L268) следует, что писать положено с unsafe? А методичка говорит обратное - объясняйся.

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

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

А чье мнение и на основании чего считать объективным и почему? Судьи кто?

Критики современного C++ почему-то забывают одну простую вещь: у вас никто не забирает те возможности старого C++, которыми вы пользовались раньше. Не хотите использовать шаблоны, constexpr и лямбды — да не используйте. Пишите как диды завещали. И, что характерно, ваш код вполне себе будет компилироваться современными компиляторами.

Всё немного не так. Рассмотрим такой сценарий:

1. Стандартизаторы добавляют в плюсы очередную фичу
2. Какие-то программисты пишут код с использованием фичи и выкладывают его в опенсорс
3. Программист Вася использует программу, в котором используется та фича, и сталкивается с необходимостью что-то в программе поменять, дабы адаптировать под свои потребности, или пофиксить баги
4. Программист Вася вынужден разбираться с фичей, придуманной плюсовыми стандартизаторами, т.к. код написан с использованием данной фичи, и выбора у него особо нет.

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

SZT ★★★☆ ()