Такой задачи нету. For/while строго мощнее любого другого специального сахарка. А если хотите свое, то с++ это легко позваляет сделать, хоть for(auto i : iota(a,b)), хоть boost::irange хоть что угодно с какими захотите проверками и азертами.
Так этот старый-добрый как раз и не является нормальным циклом. Не каждый осилит с первого раза правильно написать цикл от a до b включительно с итератором того же типа, особенно если шаг цикла больше 1. В то время как даже в древнем паскале это не проблема вообще.
Больше троих на что? Там у аппл есть и swift и obj-c и куча задач по интерации платформы и своего железа. Но допустим даже трое от аппла на шланг фронтенд, еще трое от гугла. Майкрософт не берём у них свой. Итого шесть. Мне сообщили что в кланг фултайм мейнтейнеров около пяти. Выходит что вложения весьма скромные.
То как было использована иота в изначальном примере - это явно усложнение потому что там рэнж создавался отдельно от логики его использования. Это дополнительная абстракция. Если не нравятся операторы сравнения напишите for (auto i : iota(0, n))
По поводу свёртки мапов, если компилятор может ходить в тело функций и анализировать/оптимизировать цепочку трансформаций, то это хорошо.
По поводу Vector всё же я не очень понял. Что значит создать из чего угодно за О(1)? Если это был слайс другого вектора, то что будет? Или допустим вообще из MVector? Трюкам с ленивостью и иммутабельностью я не доверяю после примера с qsort.
Вы как-то на ходу меняете условие. То вам нужно было создать из списка с известной длиной, то длина неизвестна. Можно как-то определиться?
Оба нужно. Я хочу заучить один collect<> или ranges::to<> и не думать когда там в коде у меня известна длина а когда неизвестна. Хочу сделать какой то трансформатор из ренж в ренж, который будет сохранять эту информацию. В вашем же примере мне надо писать каждый раз теперь
EIther (Int -> a) (Int, Int -> a)
матчить его при каждом использовании, а потом заворачивать обратно в Either. В итоге весь код превращается в такой бойлерплейт, с потенциальными проблемами при оптимизации.
STM в вашем мире не существует?
Выглядит как просто примитивы завёрнутые в мутекс, но не как инструмент для определения самих примитив и ограничений на их многопоточное использование. Поправте если он позволяет добится Send/Sync из раста.
Так мы хаскель-код компилятором хаскеля компилируем, если что, а не плюсов.
Во-первых есть ллвм бэкенд. Во-вторых уб легко получить если завязать какую то дополнительную логику на использование этой переменной
case (readIOref x < n)
true => getUnchecked v $ readIOref x
false => _
(пвсевдо код)
Апд.: подправил, случайно раньше времени отправилось
Отлично. А в одной крупной компании, где я работал, ровно поэтому было рекомендовано не использовать unsigned-типы (и они были забанены в основных библиотеках) — потому что при оставлении >= там легко получить бесконечный цикл.
отвратительно. Как раз unsigned выражает в типах что число неотрицательное и не содержит уб на переполнение, всё как вы любите. А на >= выдаст варн "expression is always true".
А ключевая фишка 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 не используется совсем.
Где я это утверждал? Что значит совсем? Вообще в мире?
Такой задачи нету. For/while строго мощнее любого другого специального сахарка. А если хотите свое, то с++ это легко позваляет сделать, хоть
for(auto i : iota(a,b))
, хотьboost::irange
хоть что угодно с какими захотите проверками и азертами.И где тут решили шаг больше 1?
Больше троих на что? Там у аппл есть и swift и obj-c и куча задач по интерации платформы и своего железа. Но допустим даже трое от аппла на шланг фронтенд, еще трое от гугла. Майкрософт не берём у них свой. Итого шесть. Мне сообщили что в кланг фултайм мейнтейнеров около пяти. Выходит что вложения весьма скромные.
То как было использована иота в изначальном примере - это явно усложнение потому что там рэнж создавался отдельно от логики его использования. Это дополнительная абстракция. Если не нравятся операторы сравнения напишите
for (auto i : iota(0, n))
По поводу свёртки мапов, если компилятор может ходить в тело функций и анализировать/оптимизировать цепочку трансформаций, то это хорошо.
По поводу Vector всё же я не очень понял. Что значит создать из чего угодно за О(1)? Если это был слайс другого вектора, то что будет? Или допустим вообще из MVector? Трюкам с ленивостью и иммутабельностью я не доверяю после примера с qsort.
Оба нужно. Я хочу заучить один
collect<>
илиranges::to<>
и не думать когда там в коде у меня известна длина а когда неизвестна. Хочу сделать какой то трансформатор из ренж в ренж, который будет сохранять эту информацию. В вашем же примере мне надо писать каждый раз теперьматчить его при каждом использовании, а потом заворачивать обратно в Either. В итоге весь код превращается в такой бойлерплейт, с потенциальными проблемами при оптимизации.
Выглядит как просто примитивы завёрнутые в мутекс, но не как инструмент для определения самих примитив и ограничений на их многопоточное использование. Поправте если он позволяет добится Send/Sync из раста.
Во-первых есть ллвм бэкенд. Во-вторых уб легко получить если завязать какую то дополнительную логику на использование этой переменной
(пвсевдо код)
Апд.: подправил, случайно раньше времени отправилось
отвратительно. Как раз unsigned выражает в типах что число неотрицательное и не содержит уб на переполнение, всё как вы любите. А на
>=
выдаст варн "expression is always true".Имхо такой вариант самый простой
Смешной прикол
Спасибо
Основное значение "оператор" и 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" сама по себе не имеет смысла. Что именно проверили? Что правила не противоречивы между собой? Выражайтесь в следущий раз яснее. Возможно для этого полезно ознакомится с темой более глубоко прежде чем делать громкие заявления.
Где я это утверждал? Что значит совсем? Вообще в мире?