@Fsharp_chat

Страница 464 из 772
Vladimir
01.02.2018
07:51:42
Обычно рекомендуется избавляться от явной рекурсии
ну тут не согласен) рекурсия очень даже идиоматична для фп

Fill
01.02.2018
07:52:02
В ФП принято использовать всякие комбинаторы и т.п. вроде fold
я всё же не очень понимаю, можно подробнее?

Aleksey
01.02.2018
07:54:18
Свёртка - это паттерн. Паттерны, это хорошо

Правильно написать рекурсию может не каждый, да и выделение повторяющейся логики - обработки edge cases, отделения головы от хвоста - стоит выносить. Вот и вынесли уже в функции свёртки

Google
Aleksey
01.02.2018
07:55:45
Никто же не переписывает код с map на ручную рекурсию. Вот и со свёрткой та же ситуация

Ручной рекурсии место там, где по-другому никак. Mutual recursion например

"Пишешь рекурсию с аккумулятором? Скорее всего тебе нужна свёртка!"

john
01.02.2018
07:57:47
фильтер, мап, редюс

Aleksey
01.02.2018
07:58:24
в математике это свёртка, поэтому названия типа reduce (или inject вообще) - только запутывают людей :) Только fold!

john
01.02.2018
07:59:18
математика, люди синуса не знают а вы о математике

Aleksey
01.02.2018
07:59:57
А зачем тогда они в ФП лезут вообще? Придётся же всё равно хоть в каком-то объеме изучить :)

Fill
01.02.2018
08:02:14
А зачем тогда они в ФП лезут вообще? Придётся же всё равно хоть в каком-то объеме изучить :)
Затем же, зачем математики лезут в программирование. Тоже ничего не понимают, но очень хочется

А за объяснение спасибо

Aleksey
01.02.2018
08:02:49
Если деуствительно хочется, то и математики небольшого кол-ва не испугаются :)

Fill
01.02.2018
08:04:11
Да, не испугаются. Но насколько я вижу, ФП требует понимания программирования, а не понимания математики

Alexander
01.02.2018
08:05:09
Да кстати не всегда, квантовую химию сложно понять, а вот объяснить ещё сложнеею Про квант мех я вообще молчу

Пока писал уже удалил)

Google
john
01.02.2018
08:06:05
побоялся что поколотят

Alexander
01.02.2018
08:06:34
побоялся что поколотят
21 век, бояться что поколотят в чате телеграма

john
01.02.2018
08:06:51
просто есть проблема "бродячих мифов" то от рекурсии надо избавляться то еще чтонибудь

вот и избавляются от рекурсий и пишут циклы

Aleksey
01.02.2018
08:07:43
не надо избавляться от рекурсии. Просто рекурсию с аккумулятором, написанную руками, можно и нужно упрощать до свёртки

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

Aleksey
01.02.2018
08:14:02
Ваш конкретный пример вполне нормально написан - тут рекурсия к месту, ИМХО

Fill
01.02.2018
08:15:02
Ну я понял, да. Но вот стейтмент - фолд всегда, когда возможно я не слышал раньше, так что спасибо)

A64m
01.02.2018
08:23:03
если оптимизаций особых нет, ФВП может просто заметно тормозить в каком-нибудь горячем месте, так что раннее завершение точно не единственная причина рекурсивную лапшу писать

цикл в F# кстати тоже может заметно тормозить из-за того во что всякие n .. 2 .. k компилируются

Aleksey
01.02.2018
08:28:47
Внутри свёртки может быть цикл :) Но выглядет будет функциональненько :)

A64m
01.02.2018
08:31:41
внутри-то может, проблема в том что все эти изкоробочные свертки не инлайнящиеся и вызовы переданных в них функций довольно дорогие

так же дотнетный IEnumerable<T> довольно тормозной по сравнению со своими аналогами из других языков

Aleksey
01.02.2018
08:34:03
Печаль

A64m
01.02.2018
08:34:28
поэтому в горячем месте со всем этим комбинированием комбинаторов в F# особо не разгуляешься.

Aleksey
01.02.2018
08:36:01
В более прохладных местах то можно :)

A64m
01.02.2018
08:37:12
вот так всегда неделанье оптимизаций и обосновывают!

Google
Bonart
01.02.2018
08:40:04
Оптимизировать корректное всегда проще, чем корректировать оптимизированное

Most
01.02.2018
08:40:47
вот так всегда неделанье оптимизаций и обосновывают!
если у тебя IO работает 300 ms, то выгрызать ns у fold ты не будешь :)

и какое-то довольно громкое заявление про IEnumerable<T>) Лев Толстой, поди

A64m
01.02.2018
08:43:52
Оптимизировать корректное всегда проще, чем корректировать оптимизированное
так тормозные базовые инструменты к таким проблемам как раз и приводят. Энумераблы тормозные, так что те кто писал Лист решил сэкономить на спичках и сделать итератор на велью-типе, а от итераторов на велью-типах смешной баг с форичем бывает, про который Липперт 10 лет писал что теперь нельзя исправлять, а все равно потом исправить пришлось

если у тебя IO работает 300 ms, то выгрызать ns у fold ты не будешь :)
ну вот в яве из-за таких проблем все-таки сделали новые стримы совсем по-другому устроенные, а там-то они, конечно, всегда торопяться ненужную фичу делать, лишь бы была.

Bonart
01.02.2018
08:46:10
К проблемам приводит забивание гвоздей микроскопом. В 99% случаев производительности хватает и так, а в 1% все равно нужна возможность подхачить ручками.

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

A64m
01.02.2018
08:47:18
ну так надо чтоб базовые инструменты с нормальной скоростью работали, чтоб программист не думал вот сейчас можно себе тормоза позволить или нет, а работу работал

Most
01.02.2018
08:47:59
» с нормальной скоростью работали what is normalnaya skorost`?)

Bonart
01.02.2018
08:47:59
А не надо думать про тормоза до того как они возникают - преждевременная оптимизация что у нас по Кнуту?

A64m
01.02.2018
08:48:08
В яве нет генериков в рантайме и непримитивных значений - это как раз мешает сделать код быстрее даже руками
и на это они не могут наплевать, а специализированные версии методов для примитивов накостыливают

Bonart
01.02.2018
08:48:37
Evgeniy
01.02.2018
08:48:53
Я предлагаю направить разговор в другом направлении: вот код, вот бенчмарк, давайте обсуждать.

Bonart
01.02.2018
08:49:08
А в шарпе - сделал чтобы работало, потом МОЖЕТ БЫТЬ в 1 месте из 100 нужно (и можно) подхачить

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

A64m
01.02.2018
08:51:16
А для непримитивов даже накостылять не могут. Вот это бяда
специализация для генериков в дотнетном джите, это, конечно, очень крутая фича, поминать про нее при обсуждении любого недостатка - не очень конструктивный подход

A64m
01.02.2018
08:53:51
Как и напоминать про тормозные итераторы в том же дотнете ;)
напоминать про тормозные итераторы - подход конструктиный. Потому что это проблема не решенная, а говорить ну и что что есть нерешенные проблемы, вот у нас когда-то проблему с дженериками решили, давайте лучше теперь этому до пенсии радоваться - не конструктивно. Обсуждение больше-не-проблемы вообще бессмысленное занятие, от этого ничего лучше не станет. А обсуждение проблемы - первый шаг к ее решению

Bonart
01.02.2018
08:55:09
> Потому что это проблема не решенная Как именно не решенная? Код на итераторах можно руками превратить в быстрый. В 99% случаев медленность итераторов вообще не трогает.

Google
A64m
01.02.2018
08:57:35
почему без предложения? Я приводил пример имплементации более эффективных "итераторов" в другом языке.

Bonart
01.02.2018
08:58:59
почему без предложения? Я приводил пример имплементации более эффективных "итераторов" в другом языке.
И как это переносится на дотнет? В хаскеле куча очень быстрая и транзакционная память есть, но в дотнет это не переносится никак.

A64m
01.02.2018
09:02:23
существует вполне рабочий подход для эффективной имплементации таких штук как "свертки" (обычно там не чистая свертка, так что в кавычках) существуют даже костыли, которые эмитят оптимизированный код или используют уже существующие оптимизации (не очень успешно) https://arxiv.org/pdf/1406.6631.pdf просто это все должно в компиляторе быть, а не прикостылено

Fill
01.02.2018
09:04:41
Как по мне, использование коробочных решений by default предпочтительнее, ведь их рано или поздно опимизируют в отличае от моего кода

Bonart
01.02.2018
09:05:20
Как по мне, использование коробочных решений by default предпочтительнее, ведь их рано или поздно опимизируют в отличае от моего кода
Именно. Нет смысла оптимизовать руками, пока к этому не принуждает проект здесь и сейчас

Fill
01.02.2018
09:05:57
Я обычно понимаю оптимизацию, как правильную комбинацию коробочных инструментов

а не написание своих

Evgeniy
01.02.2018
09:06:29
Переписывание Seq в F#, кстати, застопорилось. https://github.com/Microsoft/visualfsharp/pull/2745

A64m
01.02.2018
09:06:41
ну так я и говорю, что это должно быть из коробки, понятно что использовать какую-то стороннюю библиотеку типа стримс которая и не работает особо а может просто сдохнуть или тем более какой-нибудь адовый линкоптимайзер, который в рантайме что-то компиляет, ради такого никто не будет

это просто пруф оф концепт для того что должно быть в компиляторе ФЯ но нету

Bonart
01.02.2018
09:07:51
Кому должно и зачем? Возможно у разработчиков компилятора есть более приоритетные фичи. Кстати, структуры по ссылке в 7.2 как раз добавляют коробочных оптимизаций

A64m
01.02.2018
09:08:46
конечно есть, ФЯ же вечно полтора человека делают, там ресурсов ни на что не хватает, это правда не значит что ничего и не надо

Evgeniy
01.02.2018
09:11:37
А из-за чего начали переписывать?
Производительность хотели улучшить.

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

То есть уже третий PR к ряду, и там около 8к LoC нового кода с конфликтами.

Fill
01.02.2018
09:15:26
всем чатиком пулим и резолвим

Google
A64m
01.02.2018
09:16:08
Это очень долгая тема, я уже не верю, что когда-нибудь смержат.
а были/есть какие-нибудь работы по оптимизации ренджей в генераторах массивов и форах? Чтоб это все в нормальные циклы компилялось, а не через инумераблы?

Pavel
01.02.2018
11:07:01
всем добрый день, вопрос такой: если мэтчим, например, простой инт, то можем перечислять несколько вариантов таким образом: match x with | 1 | 3 | 8 -> "good" | _ -> "bad" если же мэтчим опциональный тип с каким-то условием, было бы классно писать что-то типа match option with | None | Some when <...> -> "good" | _ -> "bad", но компилироваться это не хочет, приходится писать match option with | None -> "good"| Some when <...> -> "good" | _ -> "bad", т.е. если вместо "good" будет что-то достаточно большое, придётся либо копипастить, либо выносить в функцию (но кода всё равно становится больше, его модификация требует лезть уже как минимум в два места) можно ли как-то это обойти штатными методами?

как вариант вижу попользовать AP, наверное

Pavel
01.02.2018
11:28:48
нет

Pavel
01.02.2018
11:29:25
match option with | None | Some when <...> -> "good" | _ -> "bad"
говорит что-то вроде "биндятся разные наборы параметров, поэтому нельлзя"

Roman
01.02.2018
11:29:32
А если написать все же None | Some 1 | Some 3 | Some 8 -> good

Pavel
01.02.2018
11:30:50
А если написать все же None | Some 1 | Some 3 | Some 8 -> good
да, так работает, но бывают нужны более сложные условия :)

Klei
01.02.2018
11:31:11
Если параметр в Some используется, то возникает различный набор переменных, в случае None такой переменной не существует, вот он и ругается.

Pavel
01.02.2018
11:31:52
да, причины понятны, ограничить скобочками никак нельзя, насколько я понимаю

просто вдруг уже есть какой-то стандартный active pattern для подобных вещей

Klei
01.02.2018
11:33:35
А можно пример синтаксиса такого шаблона?

А то мне в голову не приходит, как его можно зауниверсалить.

Pavel
01.02.2018
11:37:27
пытаюсь написать, но, похоже, я тупой

вот это компилируется: let (|NoneOrCond|Other|) condition option = match option with | None -> NoneOrCond | Some x when condition x -> NoneOrCond | _ -> Other

но я теперь не знаю как это использовать потому что на let test cond t = match t with | NoneOrCond cond -> "good" | Other cond -> "bad" компилятор ругается

Григорий
01.02.2018
11:44:59
а что если "разобрать" значение опционального типа и после уже сравнивать в match?

Pavel
01.02.2018
11:46:18
всм всё это делать в AP?

Страница 464 из 772