А ключевая фишка eigen в составлении пайплайнов вычисления, а потом его обработке. Эту тему я уже затрагивал тут в комментах на примере ренжей. https://devdocs.io/eigen3/topicinsideeigenexample В расте такого нету и сделать невозможно. Там сложение создаёт новую матрицу, а для всех симд операций отдельно захардкодены явные методы (если вообще захардкодены). Похожая идея есть и в numpy, больше в pytorch, но в питоне это всё в рантайме. С++ даёт это выразить в компайл тайм. В nalgebra даже transpose() копирует матрицу, а transpose().transpose() делает две копии. В то время как в нормальном фреймворке эти операции не делают ничего вообще.
Как раз то что ансейф есть в 1/5 крейтов это ок. Я вам это и сказал в первом сообщении. А все остальные цитаты и выводы из поста что вы привели, - это уже потенциально реклама.
Но если подсчитать, то может внезапно выясниться, что среди тех 19.11% крейтов многие написаны во времена выхода Rust 1.0 и не поддерживаются (аналогичные проблемы есть и в других пакетных менеджерах, например npm).
то же самое может внезапно оказаться для оставшихся 80%
Кроме того надо еще исключить пакеты с 10 строчками кода, выложенные ну просто потому что хотелось попробовать выложить (опять те же претензии к npm).
их же надо исключить из 80% пакетов без ансейф. И я уверен что те кто хотели просто "попробовать выложить" или выложить свое домашнее задание из универа выкладывали как раз крейты без ансейф. В итоге доля реальных библиотек с ансейф увеличивается.
Не возможно и не нужно переписывать все библиотеки мира на Rust.
Скажите это растоманам которые бегают по гитхабу и создают ишью вида "consider rewriting in rust". Недавно один уникум даже в Qt багтрекере такое создал. Но наверное на созданиях тикетов деятельность по переписыванию на раст обычно и заканчивается =)
На Python вообще половина PyPi это обертки над С, но никто не жалуется.
Питон не позиционирует себя как замену Си. Питон наоборот позиционирует себя как язык клей с реплом и прочим. И используется например как конфигуратор C++ ML библиотек.
Напомню ветка началась с обсуждения зависимостей. Вы жаловаолись что зависимости на си или си++ это плохо, они могут быть не протестированы санитайзерами, не следовать современным практикам и т п... А теперь оказывается "это обертки над С, но никто не жалуется" :-D
Не только. Это и вполне себе слайс тоже, например.
Т.е. хаскель Vector это таки span? Что делает V.map f? Он создаёт новый вектор или лениво ходит в старый и применяет f?
Остальные ответы тоже про вопрос об отличии хаскель Vector от С++/rust вектора. Например это
(V.generate len theGen)
Что это сделает, возьмёт theGen например тот же iota достанет из него елементы и положит в контейнер? Т.е на лету из iota уже доставать нельзя?
Пример с Foo выражается как Int → Foo
Вы это тоже не выразите не определив что такое Foo + Int.
мы точно всё ещё про неограниченные последовательности говорим? Но конец тоже можно передать, кто мешает?
Эту всю информацию надо иметь в каком то тайпклассе или нескольких. Все ваши примеры покрывают только очень частные случаию.
fromListN
так это мне никак не поможет. У меня есть функция которая вернула -> [a] без размера. Я не смогу к ней приклеить fromListN никак.
Где уб? Там нет уб в плюсовом смысле.
там же чтение/запись памяти из разных потоков. Во что это хаскель скомпилирует? В просто обычный доступ в память? Тогда это уб потому что типичные оптимизации не предполагают это.
Смотрите, span нифига не помогает, потому что я могу сделать
Ага, именно такие примеры вы и приводите как критику плюсов. А когда такие же против хаскеля то вам не нравится :) Ведь незаметить &*list.begin() можно, а сделать ошибку внутри IO блока никак нельзя.
Но поинт той отссылки к раст Send/Sync не в этом. А в том что в хаскель нету способа выразить нужный инвариант. Либо IO и сразу минное поле, либо не шарим/муваем данные между потоками.
Так замеры делало rust foundation. Всё что написано в этой статье нельзя считать объективной информацией. Понятно что задача раст евангилистов убедить нас в том что это нестрашно, рассказать что это виновата ОС и кто угодно кроме них. А чтобы оценить сколько реально ансейф процентов в итоговом продукте, надо сравнивать сколько функционала за теми С/С++ обертками. При том как то умнее чем просто по количеству строк, потому что раст очень вербозный.
к тому и веду, что вы тоже были не правы, coq совсем не используется. А сейчас выяснилось, что вы читали первоисточник, и все-же категорично утверждали обратное.
Утверждал что не используют для верифиакции библиотек. То что модель мири как-то покрутили в коке на предмет совместимости с какой-то моделью оптимизаций - не знал.
coq уже больше похоже на правду, но реально им никто не пользуется Вы утверждали, что coq никто не пользуется в Rust
Так а сколько кода реально верифицировано? Думаю мало. В коммерческой разработке я думаю это не выгодно. А так да, можно вспомнить https://frama-c.com/ , тоже верификация. Тут утилита семантику си понимает. В случае с растом была история c проверкой std::, но афаик было много ручной работы всё равно. И с тех пор уже сколько изменений внесли в код, а статью выпустили один раз, грант отработали и всё. Что-то автоматическое есть по вашей ссылке, но там собственно самих пруфов не видно. Так что пока это всё реклама.
Предлагаю вам ознакомиться с первоисточником
С таким успехом я могу первоисточник сам прочесть. Зачем на хабр заходить...
Если вам нужен i-ый элемент после a для Enum a, то вы делаете toEnum $ fromEnum a + i
Теперь ясно, мне эти наименования интуитивно непонятны.
Поэтому не надо писать, что iota в плюсах сразу даёт O(1)-доступ
Мы тут опустились на уровень "Давно вы бросили пить коньяк по утрам?".
Если вам вдруг надо обращаться к i-му элементу за O(1) у генератора, то вы делаете что-то интересное, и мне такое тоже интересно!
так тут не генераторы а ренжи. Например взять подмассив какого то массива, поверх transform и перемножить на iota. В С++ вся информация о размере и рандом акссес сохраняется.
сделайте Vector
Это сторадж данных. Не надо завязывать обработку на конкретный контейнер. Что-то слабовато с абстракциями в вашем хаскель, если возникают такие мысли. Растеры хотя бы span предложили бы.
(Int -> a)
это малова-то нужно иметь еще размер или начало/конец. Еще почему только Int, где ваш пример с Foo? Вот еще пример из раста можно вспомнить. Там у итератора есть collect<Vec<_>>() метод (или как-то так), и если известен размер заранее то там реализована специализация (эксперементальная фича, используется только в стд либе) которая преаллоцирует нужный размер. Можно ли в хаскеле сделать такую специализацию для [a] ?
Я не понял проблему по ссылке, что именно там у них небезопасно. Что шаренные данные могут шариться между тредами
Там претензия что нету Sync/Send трейтов которые говорят можно или нет пересылать структуру данных между потоками. Соответсвенно если в read/writeIORef нету лока/атомика то будет уб.
последних оставшихся оградок в виде документации
о как вы запели, про С++ точно так же можно сказать =)
Если я завожу IORef, то я этим и говорю, что ожидаю, что её будет менять кто угодно.
Это какая-то мантра схожая с unsafe в раст. Написали и всё "мы в домике". Нужны способы абстрагирования и инкапсуляции этого всего, и критерий как раз то насколько они мощные (бч в расте например не очень мощный, для задач перекладывания жсона хватает). Без Sync/Send я не вижу чтобы они были достаточно мощные. Но я в хаскель не специалист.
Так почему нельзя сделать рейндж того же типа, который выдаётся переданным генератором, но пустой
Зачем для пустого рейнджа что-то куда-то захватывать?
если мы говорим о типе с точки зрения С++, то нельзя потому что в типе хранится весь пайплайн преобразования. Для пустого ренжа он пустой, для другого другой (в том числе с захватами). Поэтому надо привести к обшему типу с динамическим диспатчем. Или как вы любите упростить задачу и вернуть optional<rng>.
В стд есть проблемы с тем что им приходится писать везде __ чтобы не было конфликта с пользовательскими макросами. Это сигнал о том что разработчики стандартной библиотеки просто себя не уважают. А нам этот мусор ещё и читать приходится. Проблему с макросами можно было бы уже давно решить. А концепты invocable или weakly_equality_comparable_with нёсут семантику, которая важна для логики программы. В то время как unsafe, unchecked, as mut T* с точки зрения логики програмы ничего не меняют. Просто вставляют азерты.
Кроме того проверять нужно только крейты, который активно используют unsafe, но при этом нет unsafe во внешнем API.
таких 20 процентов согласно раст статистике
Тем что стандартная библиотека Rust почти на 100% формально верифицирована именно чтобы устранить баги с unsafe. <Ссылка miri-test-libstd>
Вот тут вы рассказли про верефикацию стд библиотеки и привели ссылку на мири. Мири не делает формальную верификацию стд библиотеки потому что мири это санитайзер. Вы ошиблись. Я указал вам на эту ошибку.
Нет, пример был про Miri, в нем формально проверили правила borrow checker
Фраза "формально проверили правила borrow checker" сама по себе не имеет смысла. Что именно проверили? Что правила не противоречивы между собой? Выражайтесь в следущий раз яснее. Возможно для этого полезно ознакомится с темой более глубоко прежде чем делать громкие заявления.
Вы же утверждали, что coq не используется совсем.
Где я это утверждал? Что значит совсем? Вообще в мире?
cписок диагностик у гцц и кланг плюс-минус один и тот же. Не вижу смысла. В любом случае это просто фича которого другие язык с единственой реализацией лишены. Я считаю что цена фичи себя не оправдывает.
да и компиляция несколькими компиляторами помогает быстрее найти несоответствия стандарту.
Если вы не разрабатываете библиотеку для широкого использования, то в этом ноль смылсла. Цель сделать рабочий проект, для этого достаточно соответствовать одной реализации С++, которая есть в вашем любимом компиляторе, в которой есть еще и различные расширения, которые можно использовать.
Когда как, иногда много раз, когда, например, между проектами переключаюсь,
Давно у хаскеля много компиляторов? Стандарт вы тоже строго Haskell 2010 используете?
среди 180 строк это найти очень легко
гораздо легче чем в ваших страшилках это описывается
Вообще-то выдаёт, и топ-левел-цель, и конкретную ошибку.
увы мне оно абсолютно ниочем не говорило, может какого флажка не хватало в репле (я что должен их все знать?) может какой-то баг.
Получается структура данных struct list { list* next; }. Это же катастрофически неэффективно. Во всяком случае если сделать в каком то расте. В хаскель не знаю что будет. Если весь язык заточен на линкед листы, то понятно что там будет все из коробки, но рандом ренж уже не выразить.
Не очень понял, вы хотите просто по рантайм условию обрубить ренж? псевдо код wantEmpty ? (r | take(0)) : r? У нас есть rng(args...), можно ли это вообще вызывать если pred(args...) == false? А потом, ну получили мы тип не факт что он default constructible и его дефолт это пустой ренж. Может там захватывается ссылка на какой то контейнер.
Смешной прикол
Спасибо
Основное значение "оператор" и operator в русском и английском совпадают. Значит "operator" переводится в "оператор".
До const-generics сделать что-то отдаленно похожее на eigen в расте было нельзя совсем. Сейчас const-generic тоже могут мало, для поднятия на уровень типов приходится городить такие приколы
https://docs.rs/nalgebra/0.32.1/nalgebra/base/dimension/trait.ToTypenum.html
https://docs.rs/nalgebra/0.32.1/nalgebra/base/dimension/trait.ToConst.html
с конвертацией через S-List. Кстати очень приятно потом лицезреть эти типы в километровых ошибках компиляции.
Это даже по сравнению с С++ нулевых годов смешно.
А ключевая фишка eigen в составлении пайплайнов вычисления, а потом его обработке. Эту тему я уже затрагивал тут в комментах на примере ренжей.
https://devdocs.io/eigen3/topicinsideeigenexample
В расте такого нету и сделать невозможно. Там сложение создаёт новую матрицу, а для всех симд операций отдельно захардкодены явные методы (если вообще захардкодены). Похожая идея есть и в numpy, больше в pytorch, но в питоне это всё в рантайме. С++ даёт это выразить в компайл тайм.
В nalgebra даже
transpose()копирует матрицу, а transpose().transpose() делает две копии. В то время как в нормальном фреймворке эти операции не делают ничего вообще.Как раз то что ансейф есть в 1/5 крейтов это ок. Я вам это и сказал в первом сообщении. А все остальные цитаты и выводы из поста что вы привели, - это уже потенциально реклама.
то же самое может внезапно оказаться для оставшихся 80%
их же надо исключить из 80% пакетов без ансейф. И я уверен что те кто хотели просто "попробовать выложить" или выложить свое домашнее задание из универа выкладывали как раз крейты без ансейф. В итоге доля реальных библиотек с ансейф увеличивается.
Скажите это растоманам которые бегают по гитхабу и создают ишью вида "consider rewriting in rust". Недавно один уникум даже в Qt багтрекере такое создал. Но наверное на созданиях тикетов деятельность по переписыванию на раст обычно и заканчивается =)
Питон не позиционирует себя как замену Си. Питон наоборот позиционирует себя как язык клей с реплом и прочим. И используется например как конфигуратор C++ ML библиотек.
Напомню ветка началась с обсуждения зависимостей. Вы жаловаолись что зависимости на си или си++ это плохо, они могут быть не протестированы санитайзерами, не следовать современным практикам и т п... А теперь оказывается "это обертки над С, но никто не жалуется" :-D
Т.е. хаскель Vector это таки span? Что делает V.map f? Он создаёт новый вектор или лениво ходит в старый и применяет f?
Остальные ответы тоже про вопрос об отличии хаскель Vector от С++/rust вектора. Например это
Что это сделает, возьмёт
theGenнапример тот жеiotaдостанет из него елементы и положит в контейнер? Т.е на лету из iota уже доставать нельзя?Вы это тоже не выразите не определив что такое
Foo + Int.Эту всю информацию надо иметь в каком то тайпклассе или нескольких. Все ваши примеры покрывают только очень частные случаию.
так это мне никак не поможет. У меня есть функция которая вернула
-> [a]без размера. Я не смогу к ней приклеитьfromListNникак.там же чтение/запись памяти из разных потоков. Во что это хаскель скомпилирует? В просто обычный доступ в память? Тогда это уб потому что типичные оптимизации не предполагают это.
Ага, именно такие примеры вы и приводите как критику плюсов. А когда такие же против хаскеля то вам не нравится :) Ведь незаметить
&*list.begin()можно, а сделать ошибку внутри IO блока никак нельзя.Но поинт той отссылки к раст Send/Sync не в этом. А в том что в хаскель нету способа выразить нужный инвариант. Либо IO и сразу минное поле, либо не шарим/муваем данные между потоками.
Так замеры делало rust foundation. Всё что написано в этой статье нельзя считать объективной информацией. Понятно что задача раст евангилистов убедить нас в том что это нестрашно, рассказать что это виновата ОС и кто угодно кроме них. А чтобы оценить сколько реально ансейф процентов в итоговом продукте, надо сравнивать сколько функционала за теми С/С++ обертками. При том как то умнее чем просто по количеству строк, потому что раст очень вербозный.
Утверждал что не используют для верифиакции библиотек. То что модель мири как-то покрутили в коке на предмет совместимости с какой-то моделью оптимизаций - не знал.
тут https://foundation.rust-lang.org/
Так а сколько кода реально верифицировано? Думаю мало. В коммерческой разработке я думаю это не выгодно. А так да, можно вспомнить https://frama-c.com/ , тоже верификация. Тут утилита семантику си понимает. В случае с растом была история c проверкой
std::, но афаик было много ручной работы всё равно. И с тех пор уже сколько изменений внесли в код, а статью выпустили один раз, грант отработали и всё. Что-то автоматическое есть по вашей ссылке, но там собственно самих пруфов не видно. Так что пока это всё реклама.С таким успехом я могу первоисточник сам прочесть. Зачем на хабр заходить...
Там был локфри ринг буффер. С mmap, futex, поинтерами и подобным плотным взаимодействием с линукс апи. Прототип на си говорит получился понятнее.
Теперь ясно, мне эти наименования интуитивно непонятны.
Мы тут опустились на уровень "Давно вы бросили пить коньяк по утрам?".
так тут не генераторы а ренжи. Например взять подмассив какого то массива, поверх transform и перемножить на iota. В С++ вся информация о размере и рандом акссес сохраняется.
Это сторадж данных. Не надо завязывать обработку на конкретный контейнер. Что-то слабовато с абстракциями в вашем хаскель, если возникают такие мысли. Растеры хотя бы span предложили бы.
это малова-то нужно иметь еще размер или начало/конец. Еще почему только Int, где ваш пример с Foo? Вот еще пример из раста можно вспомнить. Там у итератора есть
collect<Vec<_>>()метод (или как-то так), и если известен размер заранее то там реализована специализация (эксперементальная фича, используется только в стд либе) которая преаллоцирует нужный размер. Можно ли в хаскеле сделать такую специализацию для [a] ?Там претензия что нету Sync/Send трейтов которые говорят можно или нет пересылать структуру данных между потоками. Соответсвенно если в read/writeIORef нету лока/атомика то будет уб.
о как вы запели, про С++ точно так же можно сказать =)
Это какая-то мантра схожая с unsafe в раст. Написали и всё "мы в домике". Нужны способы абстрагирования и инкапсуляции этого всего, и критерий как раз то насколько они мощные (бч в расте например не очень мощный, для задач перекладывания жсона хватает). Без Sync/Send я не вижу чтобы они были достаточно мощные. Но я в хаскель не специалист.
если мы говорим о типе с точки зрения С++, то нельзя потому что в типе хранится весь пайплайн преобразования. Для пустого ренжа он пустой, для другого другой (в том числе с захватами). Поэтому надо привести к обшему типу с динамическим диспатчем. Или как вы любите упростить задачу и вернуть
optional<rng>.какие?
В стд есть проблемы с тем что им приходится писать везде
__чтобы не было конфликта с пользовательскими макросами. Это сигнал о том что разработчики стандартной библиотеки просто себя не уважают. А нам этот мусор ещё и читать приходится. Проблему с макросами можно было бы уже давно решить.А концепты invocable или weakly_equality_comparable_with нёсут семантику, которая важна для логики программы. В то время как
unsafe,unchecked,as mut T*с точки зрения логики програмы ничего не меняют. Просто вставляют азерты.таких 20 процентов согласно раст статистике
Вот тут вы рассказли про верефикацию стд библиотеки и привели ссылку на мири. Мири не делает формальную верификацию стд библиотеки потому что мири это санитайзер. Вы ошиблись. Я указал вам на эту ошибку.
Фраза "формально проверили правила borrow checker" сама по себе не имеет смысла. Что именно проверили? Что правила не противоречивы между собой? Выражайтесь в следущий раз яснее. Возможно для этого полезно ознакомится с темой более глубоко прежде чем делать громкие заявления.
Где я это утверждал? Что значит совсем? Вообще в мире?
Да, у Саттера совсем смешная поделка. Даже стыдно что такие эксперты являются идолами цпп общества
открыл блог. похоже он занимается каким то игрушками вроде карбон вместо работы
cписок диагностик у гцц и кланг плюс-минус один и тот же. Не вижу смысла. В любом случае это просто фича которого другие язык с единственой реализацией лишены. Я считаю что цена фичи себя не оправдывает.
Если вы не разрабатываете библиотеку для широкого использования, то в этом ноль смылсла. Цель сделать рабочий проект, для этого достаточно соответствовать одной реализации С++, которая есть в вашем любимом компиляторе, в которой есть еще и различные расширения, которые можно использовать.
Давно у хаскеля много компиляторов? Стандарт вы тоже строго Haskell 2010 используете?
гораздо легче чем в ваших страшилках это описывается
увы мне оно абсолютно ниочем не говорило, может какого флажка не хватало в репле (я что должен их все знать?) может какой-то баг.
Получается структура данных
struct list { list* next; }. Это же катастрофически неэффективно. Во всяком случае если сделать в каком то расте. В хаскель не знаю что будет. Если весь язык заточен на линкед листы, то понятно что там будет все из коробки, но рандом ренж уже не выразить.И какой размер команды не подскажете?
Крупным проектам хотя бы на с++20 перейти
Не очень понял, вы хотите просто по рантайм условию обрубить ренж?
псевдо код
wantEmpty ? (r | take(0)) : r?У нас есть
rng(args...), можно ли это вообще вызывать еслиpred(args...) == false? А потом, ну получили мы тип не факт что он default constructible и его дефолт это пустой ренж. Может там захватывается ссылка на какой то контейнер.