Size: a a a

Язык программирования Julia / Julia programming language

2020 April 10

RS

Roman Samarev in Язык программирования Julia / Julia programming language
слайд из моих примеров. Числа Фибоначчи. В первом примере - традиционные итераторы. Во втором - lazy. По цвету отладочных фрагментов виден момент их активации. В первом примере зелёный “потребитель” отработал после вычисления всего.
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Тем, что в случае итератора нужно всю логику внутрь цикла заносить и явно прописывать. То есть это работает, но не очень DRY и усложняет рефакторинг.

Например, если бы вместо 10 захотелось взять 20 элементов, то в lazy примере достаточно было бы вместо take(10) написать take(20), а в случае явного цикла пришлось бы в логике разбираться.

А композиция итераторов, я даже не знаю, есть или нет и насколько она хорошо работает.
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Roman Samarev
слайд из моих примеров. Числа Фибоначчи. В первом примере - традиционные итераторы. Во втором - lazy. По цвету отладочных фрагментов виден момент их активации. В первом примере зелёный “потребитель” отработал после вычисления всего.
Хм.
На самом деле это уже граничит с оптимизацией компилятора.
Помнится, что где-то на дискурсе обсуждали, что если "правильно" написать вычисление чисел Фибоначчи, то оно произойдёт на этапе компиляции, а на этапе исполнения просто вызовется уже готовое значение.
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Ведь по сути в этом примере язык сделал unroll в каком-то смысле, если я правильно понимаю?
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
Roman Samarev
у меня рубический есть пример про lazy:
(1..1.0/0).lazy.select { |x| x**2 % 5 == 0 }.take(10).inject(:+)


Если убрать lazy, то получим переполнение. Но если бы это был не бесконечный перечислитель, а что-то конечное, достаточно убрать вызов метода .lazy, а остальная алгоритмическая часть останется неизменной. И будет работать так же, как и |> в Julia
в этом примере, я могу внутрь select поставить что угодно, включая выборку из БД. Компилятор никак не поможет
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
Андрей Оськин
Ведь по сути в этом примере язык сделал unroll в каком-то смысле, если я правильно понимаю?
с позиции Ruby всё довольно просто. map/select/reduce - все являются декларативными. Поскольку все они принимают функцию отбора/обработки, то то, как их соединить внутри - это дело языка
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
в случае обычных итераторов, функции вызываются в циклах собственных map/select/reduce. В случае же lazy, внутри строится цикл от потребителя, внутрь которого вложены циклы промежуточных этапов
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Так а что всё-таки не так с Transducers?
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
в целом, в Julia можно сделать тоже самое, поскольку map/filter/fold тоже работают с функциями, но для этого надо сделать ещё один комплект стандартных функций под lazy-перечислитель
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
Андрей Оськин
Так а что всё-таки не так с Transducers?
а чего оно синтаксически отличается от |> ?
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Вроде бы он как раз эту задачу  и пытается решить.
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
в Ruby-подходе достаточно вызвать метод lazy в цепочке. Хвост тут же превращается в ленивый. А тут - мне надо другую библиотеку использовать
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Roman Samarev
а чего оно синтаксически отличается от |> ?
Вроде бы ортогональные вещи?
xf = Partition(7) |> Filter(x -> prod(x) % 11 == 0) |> Cat() |> Scan(+)


Вот, вполне себе используются.
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Roman Samarev
в Ruby-подходе достаточно вызвать метод lazy в цепочке. Хвост тут же превращается в ленивый. А тут - мне надо другую библиотеку использовать
Ну, потому что это в принципе подход Julia "batteries not included".
В базе минимум, весь интересный функционал - в библиотеках.
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
не совсем ортогональные. В случае x |> f1 |> f2 - это последовательная передача аргументов, понимая, что f1 и f2 тут же формируют результат. Для lazy эта цепочка превращается в декларативную, где строится конвейер. И только последняя функция-потребитель его запускает
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
lazy, всё же, должна быть компонентом базовых библиотек. Иначе не получится сделать это компактным
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Можно issue открыть на github. Я не шучу.
Звучит здраво, интересно услышать мнение core разработчиков, может быть они согласятся.
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
можно, но не думаю, что среди них нет бывших рубистов, и эти мысли у них не возникали 🙂
источник

АО

Андрей Оськин in Язык программирования Julia / Julia programming language
Ну, тогда они скажут что они по этому поводу придумали.
Может быть есть какое-то решение, о котором не знают в этом чате.
источник

RS

Roman Samarev in Язык программирования Julia / Julia programming language
тогда не появился бы Transducers
источник