LINUX.ORG.RU

Flux — C++20 библиотека алгоритмов с другой моделью итераций

 , ,


4

3

Это header-only (~405 KB) C++20 библиотека в духе C++20 Ranges, Python IterTools, итераторов Rust и других, и предоставляет набор функций, в целом эквивалентный C++20 Ranges, но использует немного другую модель итерации, основанную на курсорах, а не итераторах.
Курсоры Flux - это обобщение индексов массивов, в то время как итераторы STL - обобщение указателей массивов.
Возможности:

  • большой выбор алгоритмов и адаптеров последовательностей для создания мощных (?) и эффективных конвейеров данных;
  • более высокая безопасность по сравнению со стандартными итераторами;
  • более простое использование в распространённых случаях, особенно при определении собственных последовательностей и адаптеров;
  • более эффективное выполнение некоторых распространённых операций;
  • совместимость с существующими стандартными библиотечными типами и концептами.

Документация: https://tristanbrindle.com/flux/index.html
Код: https://github.com/tcbrindle/flux
Лицензия: Boost 1.0.
Пример:

constexpr auto result = flux::ints()                        // 0,1,2,3,...
                         .filter(flux::pred::even)          // 0,2,4,6,...
                         .map([](int i) { return i * 2; })  // 0,4,8,12,...
                         .take(3)                           // 0,4,8
                         .sum();                            // 12

static_assert(result == 12);

Он же в Compiler Explorer: https://flux.godbolt.org/z/KKcEbYnTx.


Проект от автора библиотеки NanoRange – C++20 Ranges для C++17.

★★★★★

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

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

Ну вот такие умные компиляторы пошли! :)

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

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

Но этот шаблон синтаксически записан как присвоение стековой переменной экземпляра лямбы с известными типами.

Вот в чём мой вопрос.

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

При поиске одной валидной utf-последовательности в другой валидной utf-последовательности вторая ломается к херам?

У него проверяется, соответствует ли начало строки любой из «0»..«9»/«one»..«nine». Если нет, то строка сдвигается на 1 байт. Нельзя сдвигать unicode строки побайтово.

0x30..0x39 могут быть внутри юникодного символа? А пруфы будут?

В невалидном UTF-8 - легко. А любой парсер юникода должен такое обрабатывать. Если он некорректный символ воспринимает как корректную последовательность - это плохой, негодный парсер.

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

Чувак, какой юникод, иди почитай, что такое AoC.

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

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

у которой нам неизвестны типы аргументов и результата

С чего бы?

Аргументы – std::pair<int, int>, результат – bool.

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

Почему нельзя? Что страшного произойдёт?

Вы прикалываетесь? Вам придёт «АБВ» на вход, вы первым сдвигом поломаете букву А. И начнете проверять не соответствуют ли заданным значениям её кишки.

Ну и да, я обратил внимание, что строка «bones» превратится в «ones». найс алгоритм.

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

Так а нахрена это тогда рекламировать, если это написано левой пяткой неспавшим 3 дня чумазым индусом?

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

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

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

И начнете проверять не соответствуют ли заданным значениям её кишки.

И начну проверять, соответствует ли половинка от русской буквы А английской букве o. Не соотвествует.

Так что страшного произойдёт?

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

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

Так что страшного произойдёт?

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

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

Притащив этот неоптимизированный кусок

Я притащил?! Перечитай тред внимательнее.

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

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

Еще раз.

Не увидел ответа на поставленный вопрос. Что произойдёт, если начать сравнение с середины utf8 символа?

Сгорит компьютер?

Начнётся эпидемия гриппа?

Высадится десант инопланетян?

Ваши варианты?

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

  1. Автор новости этот «кусок» не притаскивал.
  2. Ни автор новости, ни кто ли еще указанный «кусок» не рекламировали.
  3. Притасканный кусок не имеет никакого отношения к сабжу в новости.

А я показываю, что они делает 75% лишних проверок

Не показываете. Или показываете, но не нам. Покажите нам.

некорректно режет юникод в процессе

Не режет. Не некорректно.

и ломается на такой простой строке как «bone 5».

Без комментариев))

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

Ладно, пажи, сейчас напишу автору, что он не прошел контроль качества от PPP328

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

В c++ 20 лет назад была романтика, достаточно вспомнить труды Александреску.

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

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

Вообще частенько итерация по коллекции или зипу с indexed позволяет лишний раз не выстрелить в ногу

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

Мне не нравится буквальный перевод слова powerful в этом контексте. Предлагайте варианты! :)

«Фичастых» же! :-)

(Но вообще плюсую «функциональных»)

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

Язык из инструмента для нердов превращается в удобоваримое для масс средство. Какая боль!

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

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

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

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

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

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

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

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

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

Если язык следует некоторой самостоятельной парадигме

А он следует? C++ просто тянет в себя пылесосом всё перспективное, что появляется. И это на самом деле не плохо, это фича языка. Должен же быть в мире язык и вот с такой причиной существования.

Я неиллюзорно жду завоза в кресты афинных и линейных типов.

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

Самый частый вариант когда возвр ссылка на самого себя, т.е. тип либо фигурирует ДО вложенной конструкции, либо (если там всякие Auto) то претензии у уже не ко вложенной конструкции.

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

Собственно, а что у тебя такая резкая реакция на эти вещи? Сиквенсы хорошо зарекоммендовали себя в функциональных языках.

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

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

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

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

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

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

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

А что плохого? Скопировал один хедер себе в проект и всё. Или cmake-овым FetchContent опять же без необходимости сборки отдельной библиотеки.

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

Нишу инструмента для нердов занял раст нынче

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

Это тебе только кажется. На самом деле чем дальше в лес, тем больше когнитивная нагрузка.

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

Не все, где нет коммитов, заброшено. Оно может быть просто доделано.

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

Так Scala же есть, зачем в плюсы тащить что-то, для чего они не были предназначены? Haskell опять же есть, Standard ML. Что у нас еще из математических языков?

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

Хммм, а разве плюсы исходно были для такого предназначены?

constexpr auto result = flux::ints()                        // 0,1,2,3,...
                         .filter(flux::pred::even)          // 0,2,4,6,...
                         .map([](int i) { return i * 2; })  // 0,4,8,12,...
                         .take(3)                           // 0,4,8
                         .sum();                            // 12

static_assert(result == 12);
wandrien ★★
()
Ответ на: комментарий от wandrien

Это левая библиотека, а я про возможности языка в принципе к таким вещам. Понятно, что и в C++98 можно было лямбду наворотить, но зачем если есть иные инструменты, где лямбды и так есть?

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

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

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

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

Ничего не знаю про PL/I, но могу только предполагать, что он не сможет свернуть пример из ОП в константу времени компиляции.

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

А теперь попробуй это скомпилировать при условии, что модули у тебя - это «возьми этот файл, вставь в вон тот».

Я некоторое время поразмышлял над этим, но не понял, что ты имеешь в виду.

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

А то, что в процессе компиляции размер этой самой единицы компиляции после всех проходов препроцессора может вырасти кратно. Это болезнь всех header only библиотек и вообще нарушение главных правил наполнения header файлов: только константы, только объявления типов, только макросы, только объявления функций. Больше ничего там быть не должно. А в итоге имеем необходимость в сборочной ферме и компиляции посредством ccache и distcc.

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

Ничего не сделать с этим – в этом смысл шаблонов.

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

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

std::cout << "Hello" << " " << "world!" << std::endl;

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

necromant ★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.