LINUX.ORG.RU

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

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

Вообще-то в хаскеле есть исключения. Как и во многих других функциональных языках — в systemd треде я пояснял, что в ФП неизбежно возникает потребность срезать углы, обходя нормальный поток вызовов функций. В Rust нет способов легко описать подобный алгоритм. В ФП обычно «ошибка» — это не более чем некий алгебраический тип, который возвращает «найденная позиция или не найдено», «ответ на запрос или код ошибки». То есть, ошибка — это не совсем ошибка. а вариант успеха. Настоящие же ошибки плана «ответ не распознан» или «сервер не найден» обрабатываются иным механизмом.

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

Странная у тебя диллема. А куда отправляют те, кто ратуют за упрощение, чтобы минимальным набором фич реализовывать максимально сложные алгоритмы?

В раст вкатиться и начать выдавать приличный код куда проще чем в С++, при этом по скорости он особо проигрывать не будет

Откуда инфа? «На расте нельзя ковырять вилкой двадцатилетний код» — это сомнительный аргумент, при желании можно найти и код на расте под старый компилятор, который уже никто не помнит как работает.

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

С одной стороны да, с другой – был уже один такой, которому нормальный ООП был поперёк жопы. Эйхом звали. И как он только не сдох от засранной тысячами разрабов кармы. В итоге мелкомягкие таки-впилили в TS классы

Это когда было? В 0.9 уже были классы:

https://devblogs.microsoft.com/typescript/announcing-typescript-0-9/

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

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

«В идеале» можно было бы включить в бенч специализированный ящик который бы решал задачу вызовом единственной функции. Или делать расчеты на GPU. Если бы так можно было, то и питон бы выехал на первое место. Программа на Си, занявшая первое место, хоть и сложная, но всё решение содержится в ней. В программе на Rust почти всё решение содержится в подключаемой библиотеке — по правилам такая программа должна была быть дисквалифицирована, но ее почему-то оставили. При этом полностью идеоматичного кода на Rust там нет вообще, хотя есть идеоматичный код, например, на Си — это к вопросу об объективности сравнения.

«Оставить долю UB» звучит как «быть немного беременной». Ну а если без аналогий, то мне кажется, что с меньшими гарантиям раст был бы менее интересен: в конце-концов С++ уже есть

Rust немножко беременный в любом случае, потому что в крупном проекте неизбежно потребует применения unsafe.

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

Гуглить статью «Закон сохранения сложности» на РСДН

Почитал статью. 20-30 минут жизни потратил на чтение сравнений коров с килограммами и рецептов плана «ведро воды херак туды, охапку дров — и плов готов». Автор декларирует закон сохранения сложности, и чуть ниже опровергает его, приводя пример с разными реализациями одной задачи, которые имеют сильно разную сложность — зачем тогда было изначально декларировать этот «закон»?

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

Почитал статью. 20-30 минут жизни потратил на чтение сравнений коров с килограммами и рецептов плана «ведро воды херак туды, охапку дров — и плов готов».

Я в своё время поступил умнее: понял идею из первого абзаца, а последующее умоблудие пропустил. :)

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

Это когда было?

Не когда, а где: в JS

В JS прототипы были с самого первого релиза. Классы — это тупо сахар над прототипами.

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

В JS прототипы были с самого первого релиза.

Сами это говно жрите. Без сахара.

Классы — это тупо сахар над прототипами.

А языки высокого уровня – сахар над машкодами. (Это кажется был твой аргумент выше по ветке?)

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

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

Какой контейнер? Или я тебя не понимаю или ты постоянно «слегка» меняешь тему: сначала говорил о «бессмысленных усложнениях», потом про необходимость писать let mut (это ещё можно назвать «многословностью», но никак не усложнением), теперь вот распаковка контейнеров.

Ну и когда я писал на С++, то const auto& встречалось ну просто очень часто. В этом случае в расте будет просто let.

«Прекрасно» это будет, когда будешь копипастить функции для изменения типов.

Как это?

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

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

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

Ну да, такого сахара в расте нет. Есть RFC на тему, но видимо не считается приоритетным. И если честно, так оно и есть. Видел несколько библиотек, которые через макросы подобное делали.

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

Я приводил в начале треда пример с Arc, где с ходу получилось найти UB с дедлоком, которые закрыты assert-ами, но не до конца — дедлок остался.

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

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

Ключ unsafe в C# в том, что он меняет семантику выражений внутри себя. Например, убирает проверки в математике.

Разве проверки в математике отключает не unchecked?

Ну и я вижу следующее:

The unsafe keyword denotes an unsafe context, which is required for any operation involving pointers

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

Не звучат, потому что С++ развивается не одним только гуглом.

Так и раст тоже.

Ну и если по честному, то тут важно не только кто числится в комитете, а может ли одна корпорация продавить фичу, которая нужна только им. Или ещё хуже: фичу, которая мешает другим.

Это прослойка к С с классами.

Да, но на возможность, скажем, вызывать шаблонные функции я бы и не рассчитывал.

При чем здесь С++? Речь идет про раст. Зачем вы пытаетесь переводить стрелки?

Хочется.

Да и можно подумать, что скорость раста сравнивается не с С++.

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

так Д же есть, вот приблизительно оно бы и вышло.

Не думаю, всё-таки D изначально под это дизайнился (наверное), в итоге у них обратная проблема: отвязать стандартную библиотеку от GC.

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

Rust немножко беременный в любом случае, потому что в крупном проекте неизбежно потребует применения unsafe.

С какого количества строк начинается крупный проект?

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

Вообще-то в хаскеле есть исключения.

Я сказал что их там нет?

То есть, ошибка — это не совсем ошибка. а вариант успеха.

и поэтому они там не нужны особо, а в расте есть паника.

Странная у тебя диллема. А куда отправляют те, кто ратуют за упрощение, чтобы минимальным набором фич реализовывать максимально сложные алгоритмы?

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

Откуда инфа?

откуда инфа что нет?

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

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

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

Какой контейнер? Или я тебя не понимаю или ты постоянно «слегка» меняешь тему: сначала говорил о «бессмысленных усложнениях», потом про необходимость писать let mut (это ещё можно назвать «многословностью», но никак не усложнением), теперь вот распаковка контейнеров
Ну и когда я писал на С++, то const auto& встречалось ну просто очень часто. В этом случае в расте будет просто let

Очень тяжело обсуждать не опираясь на конкретные примеры. Естественно, «let mut» — это только малая доля модификаторов-контейнеров. В соседнем треде приводили пример wake.rs, где почему-то для виртуальной таблицы понадобилось писать 300 строк:

https://doc.rust-lang.org/stable/src/core/task/wake.rs.html

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

«Прекрасно» это будет, когда будешь копипастить функции для изменения типов.

Как это?

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

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

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

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

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

С какого количества строк начинается крупный проект?

Десятки тысяч строк, в данном случае. И я сейчас не имею в виду целенаправленное вынесение unsafe фич в отдельный проект — нет, unsafe фичи написанные для реализации проекта считаются единым целым с проектом.

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

То есть, ошибка — это не совсем ошибка. а вариант успеха.

и поэтому они там не нужны особо, а в расте есть паника

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

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

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

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

Я то же самое могу сказать про Rust, только это происходит меньше лет, потому меньше масштаб. Вот как в язык в районе 2009-2010 года были заложены хорошие идеи, так с 2010 новые создатели языка и компилятора клали болт на удобство пользования им. Просто C++ в этом плане старше.

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

В соседнем треде приводили пример wake.rs, где почему-то для виртуальной таблицы понадобилось писать 300 строк:

Примерно половина - комментарии.

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

По прежнему не вижу проблемы в «описаниях типов аргументов». Это как тыкать в код на С и спрашивать почему так часто встречается void* и int.

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

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

Два варианта: либо писать просто копипастой, либо писать сложно обобщениями.

Опять же, не понимаю суть претензии. А как иначе? В любом языке выбор будет именно такой, ну разве что если ограничения языка (например, нет дженериков) уменьшают твой выбор. Ну можно добавить ещё кодогенерацию (макросы или какую-нибудь внешнюю).

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

Вон в С++, на первый взгляд, шаблоны проще: не надо расписывать ограничения, никаких тебе «трейт на трейте трейтом погоняет». Вот только к этому «простому инструменту» постоянно прикручивают всякие усложнения. Видимо не всё так просто?..

трейт на трейте трейтом погоняет, и все это (как в wake.rs) только для того, чтобы дернуть одну функцию.

Во первых, не одну. Во вторых, в этом коде как раз никаких трейтов почти и нет. Ну как обычно.

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

Десятки тысяч строк, в данном случае.

Мне откровенно лень сейчас искать, тем более, что поиск усложняется наличием всяких deny(unsafe_code) и прочего, что содержит слово «unsafe». Прям сейчас под рукой есть маленький проект (~20к строк), где ансейфа вообще нет, но исходники показать не могу.

Но вообще оспорить утверждение хочется. Если когда-нибудь будет не лень, то дам знать. (:

И я сейчас не имею в виду целенаправленное вынесение unsafe фич в отдельный проект — нет, unsafe фичи написанные для реализации проекта считаются единым целым с проектом.

Это ты заранее заготовил путь к отступлению, если такой проект найдётся? Мол если в самом проекте нет ансейфа и даже во «внутренних» библиотеках тоже, то в хоть какой-нибудь из используемых уж точно найдётся. Кстати, в чём тут вообще принципиальная разница брать готовое (с ансейфом внутри) или самому завернуть абстракцию в модуль/библиотеку?

Ну и в целом я не считаю ансейф проблемой. Если он вынесен в отдельную библиотеку (с безопасным интерфейсом и тестами) - так вообще замечательно. Опять же, в реальной жизни может понадобится сишную либу использовать (а ffi - unsafe) или бывает удобно пометить трейт как ансейф. В общем, это удобный инструмент и избегать его «просто потому что ансейф» смысла мало. Очень может оказаться, что твоё утверждение окажется справедливым. Но я всё равно считаю, что растовый (явный) ансейф намного лучше сишного.

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

для виртуальной таблицы понадобилось писать 300 строк

Не 300, а 100 - остальное комментарии, пустые строки и фигурные скобки на отдельной строке. И не для виртуальной таблицы вообще (для этого есть трейт-объекты), а для интерфейса к waker’у тасков, предоставляемого разными асинк рантаймами, который должен быть нетипизированным. Сама виртуальная таблица с функцией для её создания занимает 20 строк из которых 6 - атрибуты специфические для stdlib и 3 - закрывающие фигурные скобки.

Остальное - определение типизированных безопасных интерфейсов к этой vtable и вспомогательные методы вроде Debug.

Вот в gcc11.1 есть libstdc++-v3\include\std\ranges на 3000 строк. Нет желания выкинуть их и писать всё циклом for или обосновать необходимость каждой строчки? Ну так и тут сырую vtable не стали выставлять.

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

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

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

Я то же самое могу сказать про Rust, только это происходит меньше лет, потому меньше масштаб. Вот как в язык в районе 2009-2010 года были заложены хорошие идеи, так с 2010 новые создатели языка и компилятора клали болт на удобство пользования им. Просто C++ в этом плане старше.

Удобство меня волнует в меньшей мере, мне важно чтобы язык не заставлял меня запоминать аспекты своего использования (хотя бы какую-то часть), и не компилировал проблемный код, в этом плане подвижки есть. С++ мне может предложить, поставить иде с линтером, санитайзер, вчитываться в ворнинги, и новые фантики на старый страх господень (поясню, сначала были указатели, потом их завернули в итераторы, потом к этому делу еще и умные указатели соорудили, теперь в помощь к итераторам у нас ренжи подоспели) все это классно, но сам язык все равно даже не думают менять, он как не помогал, так и не помогает писать на себе, лишь с завидным постоянством обнавляют гайдлайны хороших практик, на конференциях рассказываю о новых ужасах препарирования языка которые вскрылись на рабочих кейсах, все это сильно напоминает не работу, а изучение созданного чудовища, его повадок, поведения и т.п. Это ли инструмент для работы? А раст… тоже ничего хорошего, но хоть что-то и нет этого бекграунда многолетнего со всеми его фейлами, тут пока еще есть надежда.

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

В соседнем треде приводили пример wake.rs, где почему-то для виртуальной таблицы понадобилось писать 300 строк:

Примерно половина - комментарии

Чуть больше половины. И, тем не менее, 130 строк для описания «ничего» — это как-то странно.

По прежнему не вижу проблемы в «описаниях типов аргументов». Это как тыкать в код на С и спрашивать почему так часто встречается void* и int

Да, это как тыкать в код на Си и спрашивать «почему так часто встречаются void * и int», а также спрашивать «чем же тогда Rust лучше?». Не так давно я был уверен, что Rust еще и владение данными выводит самостоятельно, но нет — borrow checker-а нужно с ложечки кормить руками. Падать ниц пред языком я должен только лишь за безопасность указателей, что меня возмутило. (да, я понимаю, что есть некоторые другие плюшки и я утрирую, но всё же)

Объяснять каждую строчку не готов, но большая часть кода там вполне очевидна...
Если нечто похожее приходится несколько раз писать в каждом проекте, то да - это проблема языка, что он не облегчает написание распространённого кода. Если же это экзотика, то и фиг с ним.

Код не просто очевиден — она ничего не делает и по сути не нужен, потому что это повторяющиеся объявления указателей функций и однострочные пробросы их вызовов. Об этом как бы и вопрос — зачем эти строчки там нужны? Я приводил пример стенок однотипных объявлений в Rayon, еще такое было в FFT. Я подчеркиваю, что это не просто какие-то оптимизации, вроде записи развернутых циклов или предварительно вручную подсчитанных констант — это объявления, которые не выполняют никаких алгоритмов, это тупо объявления для компилятора. Да, они не в каждой функции, но в каждой второй-третьей, грубо говоря.

Два варианта: либо писать просто копипастой, либо писать сложно обобщениями.

Опять же, не понимаю суть претензии. А как иначе? В любом языке выбор будет именно такой, ну разве что если ограничения языка (например, нет дженериков) уменьшают твой выбор. Ну можно добавить ещё кодогенерацию (макросы или какую-нибудь внешнюю)

Как в хаскеле — писать просто на обобщениях. Потому что там нет бесконечных ёлочек, потому что вывод типов работает на уровне функций. В чем причина популярности динамических языков? У них обобщения точно так же по умолчанию, но с диспетчеризацией в рантайме, что не есть хорошо. Практика показала, что все хотят писать:

fn sum(a, b) {
    a + b
}

Всё. Чисто, просто, понятно. Ваши типы на каждой второй строчке, ёлки формальных контейнеров, модификаторы указатели на изменяемые/неизменяемые данные — почти никому не нужны. Но индустрия настолько застряла в средних веках, что не смогла выдать ЯП, который позволял бы писать программы просто, и при этом статически компилироваться с мономорфизацией. Причем, индустрия настолько утонула в плодах трудов инквизиции, объявившей ересью всё за пределами ООП, что в какой-то период времени даже статически компилируемые языки генерировали полиморфный рантайм, из-за чего медленно ползали и жрали много памяти (Java).

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

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

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

Меня удивило, что в последних стандартах кресты таки начали чистить. В кои-то века. Ну и они переходят на типоклассы. которые являются более адекватной вариацией обобщений — но я сомневаюсь, что это можно достаточно годно реализовать, не поломав совместимости со старым C++.

Конкретно неограниченный рост числа трейтов/структур/прочих абстракиций в расте вызван именно помешанностью на безопасности указателей — что есть бессмысленно, поскольку проекты неизбежно приходят к unsafe, а перегруженность кода вспомогательными конструкциями приводит к возникновению алгоритмических ошибок, которые Rust совсем никак не помогает искать.

трейт на трейте трейтом погоняет, и все это (как в wake.rs) только для того, чтобы дернуть одну функцию.

Во первых, не одну. Во вторых, в этом коде как раз никаких трейтов почти и нет. Ну как обычно

Код является оболочкой над ровно одной функцией — это wake. Всё остальное — это служебные функции, которые обслуживают сами себя и имеют смыслом передачу единственного аргумента этой функции wake.

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

Прям сейчас под рукой есть маленький проект (~20к строк), где ансейфа вообще нет, но исходники показать не могу

Ну это на грани, можете начинать заготавливать ансейфы «на вырост». Вы же не используете в этом проекте ящики от васяна?

И я сейчас не имею в виду целенаправленное вынесение unsafe фич в отдельный проект — нет, unsafe фичи написанные для реализации проекта считаются единым целым с проектом.

Это ты заранее заготовил путь к отступлению, если такой проект найдётся?

Это я сейчас про поехавших, которые угробят проект, пролюбят все дедлайны по два раза, но напишут без ансейфов. Или что-то вроде приведенного выше примера с разыменованием указателей — в расте арифметика с указателями является безопасной операцией, а опасно только разыменование. Сделай «отдельным независимым» проектом одну единственную функцию — «безопасного» разыменования указателя, и тогда в «безопасном» расте можно будет творить любой трэшак. Зато формально всё безопасно же ж.

Кстати, в чём тут вообще принципиальная разница брать готовое (с ансейфом внутри) или самому завернуть абстракцию в модуль/библиотеку?

Вот и я о том же. Челы с becnhmarking game выставили напоказ программу, которая завязана на ящик от васяна. Пусть васян и проверенный, пусть он много труда вложил в отладку и доводку либы, но это по прежнему не std.

Ну и в целом я не считаю ансейф проблемой. Если он вынесен в отдельную библиотеку (с безопасным интерфейсом и тестами) - так вообще замечательно

И тогда единственная существенная разница между C++ и Rust — это что последний больше бьет по рукам за кривое применение интерфейсов unsafe либы. Стоит ли эта «фича» усложнения кода и замедления компиляции?

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

Кстати, sqlx (~50к строк) ансейф использует только для SQLite, zola (~17к) вообще не использует

В sqlx половина строк — это тесты, которые находятся прямо в сорцах. А половина от оставшейся половины — это объявления констант. В zola без тестов будет где-то 6 тысяч строк.

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

Вот в gcc11.1 есть libstdc++-v3\include\std\ranges на 3000 строк. Нет желания выкинуть их и писать всё циклом for или обосновать необходимость каждой строчки?

Есть. Я использую ренжи как эталон overbloat-а.

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

мне важно чтобы язык не заставлял меня запоминать аспекты своего использования (хотя бы какую-то часть)

Что? То есть, ты подразумеваешь, что Rust не заставляет тебя запоминать аспекты своего использоваться? Вот как идеи появляются в голове — так сразу их записываешь и они работают, да? Спасибо расту за это.

и не компилировал проблемный код

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

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

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

Касательно же итераторов с умными указателями — весь сыр-бор крутится вокруг «небезопасного» стиля писания кода, с интенсивным повторным использованием указателей на структуры. Предпочитай значения указателям/итераторам, и будет твой коды безопаснее... Но и медленнее. Это вообще универсальное правило, независимо от языка, просто Rust сделал его частью компилятора и заставляет небезопасный стиль явно описывать. А кто тебя изначально заставлял стрелять себе в ногу?

А раст… тоже ничего хорошего, но хоть что-то и нет этого бекграунда многолетнего со всеми его фейлами, тут пока еще есть надежда

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

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

type_traits, chrono, limits, variant, tuple. Выкидываем?

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

Variant — это нереально крутая штука, потому что концепция ADT является одной из самых недооцененных.

Limits — довольно простой модуль, хз почему ты его привел.

Про tuple и chrono не смогу прокомментировать, потому что не знаю (и не хочу знать) кому и зачем они нужны.

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

Цитирую: «Два варианта: либо писать просто копипастой, либо писать сложно обобщениями. Оба печальны в итоге»

1500 строк variant’а, чтобы в итоге сделать switch и cast - это нормально. А 100 строк waker’a, чтобы преобразовать типы и дернуть указатель на функцию, почему-то мозолят глаза.

Не пойму принцип отбора.

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

1500 строк variant’а, чтобы в итоге сделать switch и cast - это нормально

Это не «switch и cast» — это фундаментальная структура данных, которая затыкает чудовищный изъян архитектуры языка C++. Конечно, точнее я мог бы провести оценку, если бы знал, насколько эффективно оно этот изъян затыкает.

И я ни в коем случае не спорю с тем, что в библиотеках C++ тоже любят делать подобное waker.rs.

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

Тип сумма в плане реализации это именно switch&cast для которого компилятор (или, с переменным успехом, библиотеки) предоставляют типобезопасный доступ. Абсолютно та же ситуация, что и с этим пресловутым waker’ом.

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

Что? То есть, ты подразумеваешь, что Rust не заставляет тебя запоминать аспекты своего использоваться? Вот как идеи появляются в голове — так сразу их записываешь и они работают, да? Спасибо расту за это.

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

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

Эх раз еще раз, еще много-много раз. Это пунктик такой, говорить очевидные вещи как аргументы дискуссии? От таких вещей нет спасения. Инструмент владения, контроль мутабельности, искусственные ограничения на этот контроль, аннотирование времени жизни для ссылок, вообще явное аннотирование против неявного «работу этой языковой особенности надо держать в голове». Вот это все, чем больше надо прописывать в коде тем лучше, чем чаще компилятор ругается что не может разобраться что имелось в виду без этих пометок, тем лучше. Это лучше еще по причине того, что человек проводящий ревью вашего кода не будет вынужден домысливать что имелось в виду имея на руках подобного рода аннотации. Вообще я считаю что стоит максимально уходить от любых «соглашений», «допущений», «неявного поведения», «списка правил работы» вместо явного аннотирования в коде этой работы. Да может получается многословно и выглядит как мрак, но С++ выглядит не лучше, тем не менее там над вами постоянно довлеет факт того, что что-то вы забыли или упустили из внимания или просто в виду общей сложности написанного упускаете из виду те самые языковые нюансы. Вы постоянно должны сверяться с гайдлайном и отвергать любые попытки писать не по нему, потому что скорее всего это приведет к проблемам.

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

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

Касательно же итераторов с умными указателями — весь сыр-бор крутится вокруг «небезопасного» стиля писания кода, с интенсивным повторным использованием указателей на структуры. Предпочитай значения указателям/итераторам, и будет твой коды безопаснее… Но и медленнее. Это вообще универсальное правило, независимо от языка, просто Rust сделал его частью компилятора и заставляет небезопасный стиль явно описывать. А кто тебя изначально заставлял стрелять себе в ногу?

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

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

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

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

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

Гы, +100500. :)

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

Полыхает у деда, он столько вложил в D, а всем пофиг. Rust просто лучше сделан

Комментировать токсичность в одном из наименее токсичных сообществ Интернета я не буду.

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

Тип сумма в плане реализации это именно switch&cast для которого компилятор (или, с переменным успехом, библиотеки) предоставляют типобезопасный доступ. Абсолютно та же ситуация, что и с этим пресловутым waker’ом

Если бы в крестах всё было так просто, то модуль variant не был бы такого размера. А большой он потому, что в крестах большой зоопарк типов данных, с которыми нужно творить самые разные вызовы конструкторов-деструкторов, move-copy. Там тысяча строк посвящена только реализации универсального тривально уничтожаемого контейнера, в который засовываются объекты, и конструированию таблиц виртуальных методов этих объектов. Сделай допущение «только самодостаточные объекты и никакого наследования» — и внезапно модуль худеет в разы.

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

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

Если бы в крестах всё было так просто

Если нет поддержки компилятора, то приходится писать ручками и иногда много - это да.

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

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

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

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

Андрей Александреску

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

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

Что? То есть, ты подразумеваешь, что Rust не заставляет тебя запоминать аспекты своего использоваться? Вот как идеи появляются в голове — так сразу их записываешь и они работают, да? Спасибо расту за это.

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

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

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

Эх раз еще раз, еще много-много раз. Это пунктик такой, говорить очевидные вещи как аргументы дискуссии? От таких вещей нет спасения

Есть спасение, называется «читаемость кода». Когда алгоритм прост и ясен, то шанс совершить в нем ошибку намного ниже. Кстати, в лекции Александреску ниже есть интересный фрагмент, где он приводит примеры криптоалгоритма деревьев из libstd++:

https://www.youtube.com/watch?v=9zpHdh70Xdk&t=3240s

Казалось бы, все знают красно-черные деревья, а вот хрен там, реализация деревьев в libstd++ — это совсем другой зверь, и ты будешь вычитывать его часами, чтобы понять, как он работает. Я уверен, что на Rust-е можно писать чистый код, где алгоритм будет алгоритмом, а не стенкой вспомогательных объявлений с редкими строчками реальных действий. Эта же претензия есть и к C++, Rust сделал ситуацию только хуже, потому что теперь ко всем вспомогательным объявлениям добавились еще вспомогательные объявления для соблюдения безопасности операций с указателями. Ткни в любую растовую либу либу — большая ее часть будет вспомогательными объявлениями. Ткни в любую либу шаблонов C++ — там тоже большая часть объявлений будет вспомогательными.

чем больше надо прописывать в коде тем лучше, чем чаще компилятор ругается что не может разобраться что имелось в виду без этих пометок, тем лучше. Это лучше еще по причине того, что человек проводящий ревью вашего кода не будет вынужден домысливать что имелось в виду имея на руках подобного рода аннотации. Вообще я считаю что стоит максимально уходить от любых «соглашений», «допущений», «неявного поведения», «списка правил работы» вместо явного аннотирования в коде этой работы. Да может получается многословно и выглядит как мрак, но С++ выглядит не лучше

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

C++ — плохой и неудобный язык, Rust — плохой и неудобный язык. Но Rust выгоден корпорациям, вот его и форсят. Сиха — плохой и неудобный язык, но при всем при этом он ближе к идеалу, потому что он проще. Завези в Си примитивное RAII, безопасные макросы (они же шаблоны), доработай систему типов, чтобы появились нормальные массивы и ADT, сделай замыкания — и можно выкидывать кресты с растом на помойку. На самом деле, это описание о-о-очень близко к подмножеству C++. И дальше от Rust. Проблема крестов здесь только в том, что в нем присутствует очень много фичей, которые не нужны и которые можно по ошибке или по упоротости задействовать.

А кто тебя изначально заставлял стрелять себе в ногу?

Никто никого не заставляет, а продолжают писать плохо, не хотят, божатся, но продолжают, и дело тут вовсе не в желании или принуждении - инструмент плохой, соблазн большой, репутация «быстрый, мощный, гибкий, для профессионалов» привлекает толпы фанатиков

А я бы посоветовал вспомнить историю рождения C++ — он совсем не с такой репутацией вкатывался на рынок. Он вкатывался как Си с классами. И нифига не мощный, и не гибкий, и не быстрый — и, тем не менее, это привлекало если не толпы фанатиков, то как минимум «толпы» манагеров, создающих спрос на рабочую силу. Это потом, в девяностых, помешательство перешло в терминальную стадию и приобрело знакомую нам форму. Я знакомился с C++ еще до появления C++11, и на тот момент это был неюзабельный треш. Современный же C++ позволяет писать вообще без классов.

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

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

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

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

Андрей Александреску показывает уровень разработчиков стандартной библиотеки Rust и показывает токсичное комьюнити Rust

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

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

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

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

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

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

Закапывай Милнера, он уже 11 лет как умер. Локальный вывод рулит, и он, очевидно, быстрее глобального.

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

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

Но фанбои преподносят Rust именно как язык мечты. А по итогу он недалеко от крестов ушел.

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

Но фанбои преподносят Rust именно как язык мечты. А по итогу он недалеко от крестов ушел.

Или недошёл. В Rust нет static if / if constexpr, так что туже функцию расчёта среднего из видео Александреску не реализовать на Rust. Только аналог через копирование кода…

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

Не так давно я был уверен, что Rust еще и владение данными выводит самостоятельно, но нет — borrow checker-а нужно с ложечки кормить руками.

Lifetime elision есть, но это действительно не «вывод владения данных». Тут язык поступает последовательно: лайфтаймы - это часть сигнатуры и «прячутся» только самые очевидные вещи. При возникновении ошибки в лайфтаймах компилятор, зачастую, подсказывает как можно пофиксить и по этим подсказкам бывает видна разница между «минимальном подходящим лайфтаймом» и тем, что «задумывалось на самом деле». Есть неплохая статья где (в том числе) об этом рассказывается.

это объявления, которые не выполняют никаких алгоритмов, это тупо объявления для компилятора

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

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

Всё. Чисто, просто, понятно.

Ага. Особенно понятно, когда это не примитивная sum, а условная hz_chto с кучей параметров и множественными выходами, которые возвращают разные типы. Нет уж, лучше я буду «спотыкаться» об типы. Не говоря уже о том, что они помогают не только читать код, но и (внезапно!) писать. Если результатом функции будет хотя бы impl Trait, то компилятор мне поможет, если вдруг что-то пойдёт не так, а не молча выведет какой-то ужас.

Ну и на хаскеле ты ведь не пишешь?.. А почему?

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

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

Конкретно неограниченный рост числа трейтов/структур/прочих абстракиций в расте вызван именно помешанностью на безопасности указателей

Опять же, нет. Далеко не все трейты (может даже подавляющее меньшинство) имеют отношение к «безопасности указателей».

Кстати, в хаскеле, на который ты выше ссылаешься, везде классы типов. И что в этом плохого вообще? Трейт/type class - это грубо говоря интерфейс. Если они стандартизированы, то проще стыковать друг с другом библиотеки и писать обобщённый код.

Всё остальное — это служебные функции, которые обслуживают сами себя и имеют смыслом передачу единственного аргумента этой функции wake.

Да, служебные. И что?

И даже drop/clone тоже «имеют смыслом передачу единственного аргумента этой функции wake»?..

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

Вы же не используете в этом проекте ящики от васяна?

Конечно, используем.

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

Пусть васян и проверенный, пусть он много труда вложил в отладку и доводку либы, но это по прежнему не std.

Так и Qt, boost и даже abseil - тоже не std.

Стоит ли эта «фича» усложнения кода и замедления компиляции?

Я (как и ты) для себя на этот вопрос давно ответил.

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

При возникновении ошибки в лайфтаймах компилятор, зачастую, подсказывает как можно пофиксить и по этим подсказкам бывает видна разница между «минимальном подходящим лайфтаймом» и тем, что «задумывалось на самом деле». Есть неплохая статья где (в том числе) об этом рассказывается

Где-то к середине статьи у меня сгорел мозг. Я не подозревал, что всё настолько плохо. То есть, компилятор может вывести время жизни для чистых функций в пару строчек, но ни на что сложнее он уже не способен.

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

Потому что для человека в wake.rs есть одна функция wake и один аргумент для нее. Всё остальное — бесполезная ментальная нагрузка, которая отвлекает от реализации алгоритма.

Особенно понятно, когда это не примитивная sum, а условная hz_chto с кучей параметров и множественными выходами, которые возвращают разные типы. Нет уж, лучше я буду «спотыкаться» об типы. Не говоря уже о том, что они помогают не только читать код, но и (внезапно!) писать. Если результатом функции будет хотя бы impl Trait, то компилятор мне поможет, если вдруг что-то пойдёт не так, а не молча выведет какой-то ужас

Если у тебя функция должна вернуть trait, но вернула что-то не то, тогда возникнет ошибка при использовании этого «чего-то не того».

Ну и на хаскеле ты ведь не пишешь?.. А почему?

Потому что это язык, тщательно спроектированный для того, чтобы на нем нельзя было писать программы с побочными эффектами. Где побочные эффекты — весь ввод-вывод, IPC, и пользовательский интерфейс. Показательно, что на хаскеле почти нет приложений с интерактивным интерфейсом. Я не отношусь к тем поехавшим, которые будут упорно отрицать очевидные факты только потому, что я этот язык выучил и он для меня как родной.

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

Шаблоны — это просто название для механизма обобщенного программирования в C++.

Далеко не все трейты (может даже подавляющее меньшинство) имеют отношение к «безопасности указателей»

Считаем для std::string::String:

impl AsRef — 4 штуки
impl Borrow
impl BorrowMut
impl Clone
impl Deref
impl DerefMut
impl From — 16 штук (кто там говорил про девять конструкторов у крестовых строк?)
impl FromIter - 7 штук
impl FromStr
impl Index — 6 штук
impl IndexMut — 6 штук

Итаво — 45. Больше половины. Можно говорить о том, что какие-то функции From* и Index* имеют функциональное, а не формальное назначение, потому я согласен на ровно половину.

Кстати, в хаскеле, на который ты выше ссылаешься, везде классы типов. И что в этом плохого вообще? Трейт/type class - это грубо говоря интерфейс. Если они стандартизированы, то проще стыковать друг с другом библиотеки и писать обобщённый код

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

И даже drop/clone тоже «имеют смыслом передачу единственного аргумента этой функции wake»?

Они по сути делают «data->drop()» и «data->clone()», то есть, управляют временем жизни аргумента функции wake.

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